diff options
Diffstat (limited to 'httemplate')
-rw-r--r-- | httemplate/classic.html | 108 | ||||
-rw-r--r-- | httemplate/docs/install.html | 13 | ||||
-rwxr-xr-x | httemplate/docs/legacy.html | 4 | ||||
-rw-r--r-- | httemplate/docs/mysql.html | 13 | ||||
-rw-r--r-- | httemplate/edit/part_export.cgi | 23 | ||||
-rwxr-xr-x | httemplate/edit/part_svc.cgi | 8 | ||||
-rw-r--r-- | httemplate/index.html | 12 | ||||
-rwxr-xr-x | httemplate/misc/bill.cgi | 7 | ||||
-rwxr-xr-x | httemplate/search/cust_main.cgi | 149 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg.cgi | 73 | ||||
-rwxr-xr-x | httemplate/search/svc_acct.cgi | 75 | ||||
-rwxr-xr-x | httemplate/view/cust_main.cgi | 3 |
12 files changed, 289 insertions, 199 deletions
diff --git a/httemplate/classic.html b/httemplate/classic.html deleted file mode 100644 index e56d04d8d..000000000 --- a/httemplate/classic.html +++ /dev/null @@ -1,108 +0,0 @@ -<HTML> - <HEAD> - <TITLE> - Freeside Main Menu - </TITLE> - </HEAD> - <BODY BGCOLOR="#FFFFFF"> - <table width="100%"> - <tr><td> - <IMG BORDER=0 ALT="Silicon Interactive Software Design" SRC="images/small-logo.png"> - </td><td> - <font color="#ff0000" size=7>freeside main menu</font> - </td><td align=right valign=bottom> - version 1.4.0 - <BR><A HREF="http://www.sisd.com/freeside">Freeside home page</A> - <BR><A HREF="docs/">Documentation</A> - <BR><A HREF="index.html">New interface</A> - </td></tr> - </table> - <hr noshade> - <ul> - <li><A HREF="edit/cust_main.cgi">New Customer</A> - <li><A NAME="search">Search</A> - <ul> - <LI><A HREF="search/cust_main.html">customers (by last name and/or company)</A> - <LI><A HREF="search/cust_main-payinfo.html">customers (by credit card number)</A> - <LI><A HREF="search/svc_acct.html">accounts (by username)</A> - <LI><A HREF="search/svc_domain.html">domains (by domain)</A> -<!-- <LI><A HREF="search/svc_acct_sm.html">mail aliases (by domain, and optionally username)</A>--> -<!-- <LI><A HREF="search/svc_forward.html">mail forwards (by ?)</A>--> - <LI><A HREF="search/cust_bill.html">invoices (by invoice number)</A> - <LI><A HREF="search/cust_pay.html">checks (by check number)</A> - </ul> - <li><A NAME="browse">Browse</A> - <ul> - <LI>customers (<A HREF="search/cust_main.cgi?browse=custnum">by customer number</A>) (<A HREF="search/cust_main.cgi?browse=last">by last name</A>) (<A HREF="search/cust_main.cgi?browse=company">by company</A>) - <LI>invoices - <UL> - <LI>open invoices (<A HREF="search/cust_bill.cgi?OPEN_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN_custnum">by customer number</A>) - <LI>30 day open invoices (<A HREF="search/cust_bill.cgi?OPEN30_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN30_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN30_custnum">by customer number</A>) - <LI>60 day open invoices (<A HREF="search/cust_bill.cgi?OPEN60_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN60_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN60_custnum">by customer number</A>) - <LI>90 day open invoices (<A HREF="search/cust_bill.cgi?OPEN90_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN90_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN90_custnum">by customer number</A>) - <LI>120 day open invoices (<A HREF="search/cust_bill.cgi?OPEN120_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN120_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN120_custnum">by customer number</A>) - <LI>all invoices (<A HREF="search/cust_bill.cgi?invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?date">by date</A>) (<A HREF="search/cust_bill.cgi?custnum">by customer number</A>) - </UL> - <LI>financials - <UL> - <LI><A HREF="search/report_receivables.cgi">receivables report</A> - <LI><A HREF="search/report_tax.html">tax reports</A> - <LI><A HREF="search/report_cc.html">credit card receipts</A> - <LI><A HREF="search/report_credit.html">in house credits</A> - </UL> - <LI>packages - <UL> - <LI><A HREF="search/cust_pkg.cgi?pkgnum">packages (by package number)</A> - <LI><A HREF="search/cust_pkg.cgi?APKG_pkgnum">packages with unconfigured services (by package number)</A> - </UL> - <LI>services - <UL> - <LI>accounts (<A HREF="search/svc_acct.cgi?svcnum">by service number</A>) (<A HREF="search/svc_acct.cgi?username">by username</A>) (<A HREF="search/svc_acct.cgi?uid">by uid</A>) - <LI>mail forwards (<A HREF="search/svc_forward.cgi?svcnum">by service number</A>) (by ?)) - <LI>domains (<A HREF="search/svc_domain.cgi?svcnum">by service number</A>) (<A HREF="search/svc_domain.cgi?domain">by domain</A>) - </UL> - <LI>unlinked services - <UL> - <LI>unlinked accounts (<A HREF="search/svc_acct.cgi?UN_svcnum">by service number</A>) (<A HREF="search/svc_acct.cgi?UN_username">by username</A>) (<A HREF="search/svc_acct.cgi?UN_uid">by uid</A>) - <LI>unlinked mail forwards (<A HREF="search/svc_forward.cgi?UN_svcnum">by service number</A>) (by ?)) - <LI>unlinked domains (<A HREF="search/svc_domain.cgi?UN_svcnum">by service number</A>) (<A HREF="search/svc_domain.cgi?UN_domain">by domain</A>) - </UL> - <LI><A HREF="browse/nas.cgi">NAS ports</A> - <LI><A HREF="browse/queue.cgi">Job queue</A> - <LI><A HREF="browse/cust_pay_batch.cgi">Pending credit card batch</A> - </ul> - <li>Miscellaneous - <ul> - <li><A HREF="search/cust_main-quickpay.html">Quick payment entry</A> - </ul> - </ul> - <hr noshade> - <ul> - <li><A NAME="config" HREF="config/config-view.cgi">Configuration</a><!-- - <font size="+2" color="#ff0000">start here</font> --> - <li><A NAME="admin">Administration</a> - <ul> - <LI><A HREF="browse/part_svc.cgi">View/Edit service definitions</A> - - Services are items you offer to your customers. - <LI><A HREF="browse/part_pkg.cgi">View/Edit package definitions</A> - - One or more services are grouped together into a package and - given pricing information. Customers purchase packages, not - services. - <LI><A HREF="browse/agent_type.cgi">View/Edit agent types</A> - - Agent types define groups of package definitions that you can - then assign to particular agents. - <LI><A HREF="browse/agent.cgi">View/Edit agents</A> - - Agents are resellers of your service. Agents may be limited - to a subset of your full offerings (via their type). - <LI><A HREF="browse/part_referral.cgi">View/Edit referrals</A> - - Where a customer heard about your service. Tracked for - informational purposes. - <LI><A HREF="browse/cust_main_county.cgi">View/Edit locales and tax rates</A> - - Change tax rates, or break down a country into states, or a state - into counties and assign different tax rates to each. - <LI><A HREF="browse/svc_acct_pop.cgi">View/Edit Access Numbers</A> - - Points of Presence - <LI><A HREF="browse/part_bill_event.cgi">View/Edit invoice events</A> - Actions for overdue invoices - </ul> - </ul> - </BODY> -</HTML> diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html index 355721821..56cee80e5 100644 --- a/httemplate/docs/install.html +++ b/httemplate/docs/install.html @@ -13,9 +13,8 @@ Before installing, you need: <li>A <b>transactional</b> database engine supported by Perl's <a href="http://www.hermetica.com/technologia/DBI/">DBI</a>. <ul> <li><a href="http://www.postgresql.org/">PostgreSQL</a> (v7 or higher) is recommended. - <li><b>MySQL is NOT supported at this time.</b> If you are a developer who wishes to contribute MySQL support, see the <a href="mysql.html">MySQL notes</a>. - <!-- <li>MySQL has been reported to work. --> - <!-- <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you really want to use MySQL, you need to use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>.--> + <li>MySQL has been reported to work. + <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type when running fs-setup using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. </ul> <li>Perl modules (<a href="http://theoryx5.uwinnipeg.ca/CPAN/perl/CPAN.html">CPAN</a> will query, download and build perl modules automatically) <ul> @@ -176,17 +175,19 @@ $ <a href="man/bin/freeside-adduser.html">freeside-adduser</a> -c -h /usr/local/ $ <a href="man/bin/freeside-adduser.html">freeside-adduser</a> -h /usr/local/etc/freeside/htpasswd <i>username</i></pre></font> </ul> <i>(using other auth types, add each user to your <a href="http://httpd.apache.org/docs/misc/FAQ.html#user-authentication">Apache authentication</a> and then run: <tt>freeside-adduser <b>username</b></tt></i> - <li>As the freeside UNIX user, run <tt>bin/fs-setup <b>username</b></tt> to create the database tables, passing the username of a Freeside user you created above: + <li>As the freeside UNIX user, run <tt>bin/fs-setup <b>username</b></tt> (in the untar'ed freeside directory) to create the database tables, passing the username of a Freeside user you created above: <pre> $ su freeside +$ cd <b>/path/to/freeside-1.4.0/</b> $ bin/fs-setup <b>username</b> </pre> - <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <b>username</b></tt> to populate the message catalog, passing the username of a Freeside user you created above: + <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <b>username</b></tt> (in the untar'ed freeside directory) to populate the message catalog, passing the username of a Freeside user you created above: <pre> $ su freeside +$ cd <b>/path/to/freeside-1.4.0/</b> $ bin/populate-msgcat <b>username</b> </pre> - <li><tt>freeside-queued</tt> was installed with the Perl modules. Start it now and ensure that is run upon system startup (Do this manually, or, edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your system, and run <tt>make install-init</tt>. + <li><tt>freeside-queued</tt> was installed with the Perl modules. Start it now and ensure that is run upon system startup (Do this manually, or edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your system, and run <tt>make install-init</tt>) <li>Now proceed to the initial <a href="admin.html">administration</a> of your installation. </ul> </body> diff --git a/httemplate/docs/legacy.html b/httemplate/docs/legacy.html index cceeb05d0..161690b62 100755 --- a/httemplate/docs/legacy.html +++ b/httemplate/docs/legacy.html @@ -5,8 +5,8 @@ <h1>Importing legacy data</h1> <font size="+2">In most cases, legacy data import all cases will require writing custom code to deal with your particular legacy data. The example scripts here will not work "out-of-the-box". Importing your legacy data will most probably involve some hacking on the example scripts noted below. Contributions to the import process are welcome.</font> <ul> - <li><a name="svc_domain">bin/svc_domain.import</a> - Import domain information from BIND named - <li><a name="svc_acct">bin/passwd.import</a> - Just import `passwd' and `shadow' or `master.passwd', no RADIUS import. + <li><a name="bind">bin/bind.import</a> - Import domain information from BIND named + <li><a name="passwd">bin/passwd.import</a> - Just import `passwd' and `shadow' or `master.passwd', no RADIUS import. <li><a name="svc_acct">bin/svc_acct.import</a> - Import `passwd', ( `shadow' or `master.passwd' ) and RADIUS `users'. Before running bin/svc_acct.import, you need <a href="../browse/part_svc.cgi">services</a> (with table svc_acct) as follows: <ul> <li>Most accounts probably have entries in passwd and users (with Port-Limit nonexistant or 1) diff --git a/httemplate/docs/mysql.html b/httemplate/docs/mysql.html deleted file mode 100644 index 11af518e1..000000000 --- a/httemplate/docs/mysql.html +++ /dev/null @@ -1,13 +0,0 @@ -<head> - <title>MySQL notes</title> -</head> -<body> - <h1>MySQL notes</h1> -<font size=+2><b>MySQL is NOT supported at this time.</b></font> -<i>The following information is provided for developers who wish to contribute MySQL support. Note that <b>ALL</b> of the items listed below need to be resolved to support MySQL. -<ul> - <li>See ticket <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=300">#300</a> in the bug-tracking system. - <li><b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">My -ISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. You need to use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. -</ul> -</body> diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index af89c4ead..fbc698e8b 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -45,15 +45,30 @@ my $widget = new HTML::Widgets::SelectLayers( if $layer; foreach my $option ( keys %{$exports->{$layer}{options}} ) { -# foreach my $option ( qw(url login password groupID ) ) { my $optinfo = $exports->{$layer}{options}{$option}; my $label = $optinfo->{label}; + my $type = defined($optinfo->{type}) ? $optinfo->{type} : 'text'; my $value = $cgi->param($option) || $part_export->option($option) || (exists $optinfo->{default} ? $optinfo->{default} : ''); - $html .= qq!<TR><TD ALIGN="right">$label</TD>!. - qq!<TD><INPUT TYPE="text" NAME="$option" VALUE="$value" SIZE=64></TD>!. - '</TR>'; + $html .= qq!<TR><TD ALIGN="right">$label</TD><TD>!; + if ( $type eq 'select' ) { + $html .= qq!<SELECT NAME="$option">!; + foreach my $select_option ( @{$optinfo->{options}} ) { + #if ( ref($select_option) ) { + #} else { + $selected = $select_option eq $value ? ' SELECTED' : ''; + $html .= qq!<OPTION VALUE="$select_option"$selected>!. + qq!$select_option</OPTION>!; + #} + } + $html .= '</SELECT>'; + } elsif ( $type eq 'text' ) { + $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="$value" SIZE=64>!; + } else { + $html .= "unknown type $type"; + } + $html .= '</TD></TR>'; } $html .= '</TABLE>'; diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index 36f764140..f2073f935 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -144,11 +144,9 @@ my %defs = ( my $columns = 3; my $count = 0; my @part_export = -# grep { $layer eq FS::part_export::exporttype2svcdb($_->exporttype) } -# qsearch( 'part_export', {} ); - map { qsearch( 'part_export', {exporttype => $_ } ) } - keys(%{FS::part_export::export_info($layer)}); - $html .= '<BR><BR>'. table(). + grep { $layer eq FS::part_export::exporttype2svcdb($_->exporttype) } + qsearch( 'part_export', {} ); + $html .= '<BR><BR>'. table(). table(). "<TR><TH COLSPAN=$columns>Exports</TH></TR><TR>"; foreach my $part_export ( @part_export ) { $html .= '<TD><INPUT TYPE="checkbox"'. diff --git a/httemplate/index.html b/httemplate/index.html index 3e657025f..8710b1798 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -14,7 +14,6 @@ version 1.4.0 <BR><A HREF="http://www.sisd.com/freeside">Freeside home page</A> <BR><A HREF="docs/">Documentation</A> - <BR><A HREF="classic.html">Classic interface</A> </td></tr> </table> @@ -28,10 +27,13 @@ <TR><TD> <BR><FONT SIZE="+1"><A HREF="edit/cust_main.cgi">New Customer</A></FONT> <BR> - <BR><FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="last_on" VALUE="1">Last name <INPUT TYPE="text" NAME="last_text"><SELECT NAME="last_type"><OPTION SELECTED VALUE="All">(all)</OPTION><OPTION>Fuzzy<OPTION>Substring</OPTION><OPTION>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/cust_main.cgi?browse=last">all customers by last name</A></FORM> - <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="company_on" VALUE="1">Company <INPUT TYPE="text" NAME="company_text"><SELECT NAME="last_type"><OPTION SELECTED VALUE="All">(all)</OPTION><OPTION>Fuzzy<OPTION>Substring</OPTION><OPTION>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/cust_main.cgi?browse=company">all customers by company</A></FORM> - <FORM ACTION="search/svc_acct.cgi" METHOD="POST">Username <INPUT TYPE="text" NAME="username"><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_acct.cgi?username">all accounts by username</A></FORM> - <FORM ACTION="search/svc_domain.cgi" METHOD="POST">Domain <INPUT TYPE="text" NAME="domain"><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_domain.cgi?domain">all domains</A></FORM> + <BR><FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="custnum_on" VALUE="1">Customer # <INPUT TYPE="text" NAME="custnum_text"><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/cust_main.cgi?browse=custnum">all customers by customer number</A></FORM> + <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="last_on" VALUE="1">Last name <INPUT TYPE="text" NAME="last_text"><SELECT NAME="last_type"><OPTION SELECTED VALUE="All">(all)</OPTION><OPTION>Fuzzy<OPTION>Substring</OPTION><OPTION>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/cust_main.cgi?browse=last">all customers by last name</A></FORM> + <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="company_on" VALUE="1">Company <INPUT TYPE="text" NAME="company_text"><SELECT NAME="company_type"><OPTION SELECTED VALUE="All">(all)</OPTION><OPTION>Fuzzy<OPTION>Substring</OPTION><OPTION>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/cust_main.cgi?browse=company">all customers by company</A></FORM> +<!-- <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="address2_on" VALUE="1">Unit <INPUT TYPE="text" NAME="address2_text"><INPUT TYPE="submit" VALUE="Search"></FORM>--> + <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="phone_on" VALUE="1">Phone # <INPUT TYPE="text" NAME="phone_text"><INPUT TYPE="submit" VALUE="Search"></FORM> + <BR><FORM ACTION="search/svc_acct.cgi" METHOD="POST">Username <INPUT TYPE="text" NAME="username"><SELECT NAME="username_type"><OPTION VALUE="All">(all)</OPTION><OPTION>Fuzzy</OPTION><OPTION>Substring</OPTION><OPTION SELECTED>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_acct.cgi?username">all accounts by username</A></FORM> + <BR><FORM ACTION="search/svc_domain.cgi" METHOD="POST">Domain <INPUT TYPE="text" NAME="domain"><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_domain.cgi?domain">all domains</A></FORM> <!-- <LI><A HREF="search/svc_acct_sm.html">mail aliases (by domain, and optionally username)</A>--> <!-- <LI><A HREF="search/svc_forward.html">mail forwards (by ?)</A>--> <BR> diff --git a/httemplate/misc/bill.cgi b/httemplate/misc/bill.cgi index 6f523a52c..f048e5559 100755 --- a/httemplate/misc/bill.cgi +++ b/httemplate/misc/bill.cgi @@ -18,9 +18,10 @@ unless ( $error ) { $error = $cust_main->collect( # 'invoice-time'=>$time, - # 'batch_card'=> 'yes', - 'batch_card'=> 'no', - 'report_badcard'=> 'yes', + #'batch_card'=> 'yes', + #'batch_card'=> 'no', + #'report_badcard'=> 'yes', + 'retry_card' => 'yes', ); } #&eidiot($error) if $error; diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index 2e255cfa2..586f8d991 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -80,23 +80,52 @@ if ( $cgi->param('browse') my $ncancelled = ''; + if ( driver_name eq 'mysql' ) { + + my $query = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM + SELECT cust_pkg.custnum,COUNT(*) as count + FROM cust_pkg,cust_main + WHERE cust_pkg.custnum = cust_main.custnum + AND ( cust_pkg.cancel IS NULL + OR cust_pkg.cancel = 0 ) + GROUP BY cust_pkg.custnum"; + my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + $query = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM + SELECT cust_pkg.custnum,COUNT(*) as count + FROM cust_pkg,cust_main + WHERE cust_pkg.custnum = cust_main.custnum + GROUP BY cust_pkg.custnum"; + my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + } + if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me || ( $conf->exists('hidecancelledcustomers') && ! $cgi->param('showcancelledcustomers') ) ) { #grep { $_->ncancelled_pkgs || ! $_->all_pkgs } - #needed for MySQL??? OR cust_pkg.cancel = \"\" - $ncancelled = " - 0 < ( SELECT COUNT(*) FROM cust_pkg - WHERE cust_pkg.custnum = cust_main.custnum - AND ( cust_pkg.cancel IS NULL - OR cust_pkg.cancel = 0 - ) - ) - OR 0 = ( SELECT COUNT(*) FROM cust_pkg - WHERE cust_pkg.custnum = cust_main.custnum - ) - "; + if ( driver_name eq 'mysql' ) { + $ncancelled = " + temp1_$$.custnum = cust_main.custnum + AND temp2_$$.custnum = cust_main.custnum + AND (temp1_$$.count > 0 + OR temp2_$$.count = 0 ) + "; + } else { + $ncancelled = " + 0 < ( SELECT COUNT(*) FROM cust_pkg + WHERE cust_pkg.custnum = cust_main.custnum + AND ( cust_pkg.cancel IS NULL + OR cust_pkg.cancel = 0 + ) + ) + OR 0 = ( SELECT COUNT(*) FROM cust_pkg + WHERE cust_pkg.custnum = cust_main.custnum + ) + "; + } + } #EWWWWWW @@ -109,10 +138,14 @@ if ( $cgi->param('browse') } $qual = " WHERE $qual" if $qual; - - my $statement = "SELECT COUNT(*) FROM cust_main $qual"; - my $sth = dbh->prepare($statement) - or die dbh->errstr. " doing $statement"; + my $statement; + if ( driver_name eq 'mysql' ) { + $statement = "SELECT COUNT(*) FROM cust_main"; + $statement .= ", temp1_$$, temp2_$$ $qual" if $qual; + } else { + $statement = "SELECT COUNT(*) FROM cust_main $qual"; + } + my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement"; $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; $total = $sth->fetchrow_arrayref->[0]; @@ -124,10 +157,20 @@ if ( $cgi->param('browse') $ncancelled = " WHERE $ncancelled"; } } - my @just_cust_main = qsearch('cust_main', \%search, '', - "$ncancelled $orderby $limit" - ); + my @just_cust_main; + if ( driver_name eq 'mysql' ) { + @just_cust_main = qsearch('cust_main', \%search, 'cust_main.*', + ",temp1_$$,temp2_$$ $ncancelled $orderby $limit"); + } else { + @just_cust_main = qsearch('cust_main', \%search, '', + "$ncancelled $orderby $limit" ); + } + if ( driver_name eq 'mysql' ) { + $query = "DROP TABLE temp1_$$,temp2_$$;"; + my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + } @cust_main = @just_cust_main; # foreach my $cust_main ( @just_cust_main ) { @@ -149,12 +192,18 @@ if ( $cgi->param('browse') @cust_main=(); $sortby = \*last_sort; + push @cust_main, @{&custnumsearch} + if $cgi->param('custnum_on') && $cgi->param('custnum_text'); push @cust_main, @{&cardsearch} if $cgi->param('card_on') && $cgi->param('card'); push @cust_main, @{&lastsearch} if $cgi->param('last_on') && $cgi->param('last_text'); push @cust_main, @{&companysearch} if $cgi->param('company_on') && $cgi->param('company_text'); + push @cust_main, @{&address2search} + if $cgi->param('address2_on') && $cgi->param('address2_text'); + push @cust_main, @{&phonesearch} + if $cgi->param('phone_on') && $cgi->param('phone_text'); push @cust_main, @{&referralsearch} if $cgi->param('referral_custnum'); @@ -403,6 +452,16 @@ sub custnum_sort { $a->getfield('custnum') <=> $b->getfield('custnum'); } +sub custnumsearch { + + my $custnum = $cgi->param('custnum_text'); + $custnum =~ s/\D//g; + $custnum =~ /^(\d{1,23})$/ or eidiot "Illegal customer number\n"; + my $custnum = $1; + + [ qsearchs('cust_main', { 'custnum' => $custnum } ) ]; +} + sub cardsearch { my($card)=$cgi->param('card'); @@ -498,9 +557,10 @@ sub companysearch { $company_type{$_}++ }; - $cgi->param('company_text') =~ /^([\w \,\.\-\']*)$/ - or eidiot "Illegal company"; - my($company)=$1; + $cgi->param('company_text') =~ + /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/ + or eidiot "Illegal company"; + my $company = $1; if ( $company_type{'Exact'} || $company_type{'Fuzzy'} ) { push @cust_main, qsearch( 'cust_main', @@ -551,4 +611,49 @@ sub companysearch { \@cust_main; } + +sub address2search { + my @cust_main; + + $cgi->param('address2_text') =~ + /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/ + or eidiot "Illegal address2"; + my $address2 = $1; + + push @cust_main, qsearch( 'cust_main', + { 'address2' => { 'op' => 'ILIKE', + 'value' => $address2 } } ); + push @cust_main, qsearch( 'cust_main', + { 'address2' => { 'op' => 'ILIKE', + 'value' => $address2 } } ) + if defined dbdef->table('cust_main')->column('ship_last'); + + \@cust_main; +} + +sub phonesearch { + my @cust_main; + + my $phone = $cgi->param('phone_text'); + + #false laziness with Record::ut_phonen, only works with US/CA numbers... + $phone =~ s/\D//g; + $phone =~ /^(\d{3})(\d{3})(\d{4})(\d*)$/ + or eidiot gettext('illegal_phone'). ": $phone"; + $phone = "$1-$2-$3"; + $phone .= " x$4" if $4; + + my @fields = qw(daytime night fax); + push @fields, qw(ship_daytime ship_night ship_fax) + if defined dbdef->table('cust_main')->column('ship_last'); + + for my $field ( @fields ) { + push @cust_main, qsearch ( 'cust_main', + { $field => { 'op' => 'LIKE', + 'value' => "$phone%" } } ); + } + + \@cust_main; +} + %> diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi index ec1bda900..abf6eee4c 100755 --- a/httemplate/search/cust_pkg.cgi +++ b/httemplate/search/cust_pkg.cgi @@ -34,8 +34,7 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { #false laziness with below my $statement = "SELECT COUNT(*) FROM cust_pkg $range"; warn $statement; - my $sth = dbh->prepare($statement) - or die dbh->errstr. " doing $statement"; + my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement"; $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; $total = $sth->fetchrow_arrayref->[0]; @@ -52,17 +51,6 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { $sortby=\*pkgnum_sort; - $unconf = " - WHERE 0 < - ( SELECT count(*) FROM pkg_svc - WHERE pkg_svc.pkgpart = cust_pkg.pkgpart - AND pkg_svc.quantity > ( SELECT count(*) FROM cust_svc - WHERE cust_svc.pkgnum = cust_pkg.pkgnum - AND cust_svc.svcpart = pkg_svc.svcpart - ) - ) - "; - #@cust_pkg=(); ##perhaps this should go in cust_pkg as a qsearch-like constructor? #my($cust_pkg); @@ -86,20 +74,71 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { # } # push @cust_pkg, $cust_pkg if $flag; #} + + if ( driver_name eq 'mysql' ) { + #$query = "DROP TABLE temp1_$$,temp2_$$;"; + #my $sth = dbh->prepare($query); + #$sth->execute; + + $query = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM + SELECT cust_svc.pkgnum,cust_svc.svcpart,COUNT(*) as count + FROM cust_pkg,cust_svc,pkg_svc + WHERE cust_pkg.pkgnum = cust_svc.pkgnum + AND cust_svc.svcpart = pkg_svc.svcpart + AND cust_pkg.pkgpart = pkg_svc.pkgpart + GROUP BY cust_svc.pkgnum,cust_svc.svcpart"; + $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + + $query = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM + SELECT cust_pkg.pkgnum FROM cust_pkg + LEFT JOIN pkg_svc ON (cust_pkg.pkgpart=pkg_svc.pkgpart) + LEFT JOIN temp1_$$ ON (cust_pkg.pkgnum = temp1_$$.pkgnum + AND pkg_svc.svcpart=temp1_$$.svcpart) + WHERE ( pkg_svc.quantity > temp1_$$.count + OR temp1_$$.pkgnum IS NULL ) + AND pkg_svc.quantity != 0;"; + $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + $unconf = " LEFT JOIN temp2_$$ ON cust_pkg.pkgnum = temp2_$$.pkgnum + WHERE temp2_$$.pkgnum IS NOT NULL"; + + } else { + + $unconf = " + WHERE 0 < + ( SELECT count(*) FROM pkg_svc + WHERE pkg_svc.pkgpart = cust_pkg.pkgpart + AND pkg_svc.quantity > ( SELECT count(*) FROM cust_svc + WHERE cust_svc.pkgnum = cust_pkg.pkgnum + AND cust_svc.svcpart = pkg_svc.svcpart + ) + ) + "; + + } } else { die "Empty QUERY_STRING!"; } my $statement = "SELECT COUNT(*) FROM cust_pkg $unconf"; - my $sth = dbh->prepare($statement) - or die dbh->errstr. " doing $statement"; + my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement"; $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; $total = $sth->fetchrow_arrayref->[0]; - - @cust_pkg = qsearch('cust_pkg',{}, '', "$unconf ORDER BY pkgnum $limit" ); + my $tblname = driver_name eq 'mysql' ? 'cust_pkg.' : ''; + @cust_pkg = + qsearch('cust_pkg',{}, '', "$unconf ORDER BY ${tblname}pkgnum $limit" ); + + if ( driver_name eq 'mysql' ) { + $query = "DROP TABLE temp1_$$,temp2_$$;"; + my $sth = dbh->prepare($query) or die dbh->errstr. " doing $query"; + $sth->execute; # or die "Error executing \"$query\": ". $sth->errstr; + } + } if ( scalar(@cust_pkg) == 1 ) { diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi index e28e00e61..549231d3f 100755 --- a/httemplate/search/svc_acct.cgi +++ b/httemplate/search/svc_acct.cgi @@ -21,26 +21,35 @@ $query ||= ''; #to avoid use of unitialized value errors my $unlinked = ''; if ( $query =~ /^UN_(.*)$/ ) { $query = $1; - my $empty = driver_name =~ /^Pg$/i ? qq('') : qq(""); - $unlinked = " - WHERE 0 < - ( SELECT count(*) FROM cust_svc - WHERE cust_svc.svcnum = svc_acct.svcnum - AND ( pkgnum IS NULL OR pkgnum = 0 OR pkgnum = $empty ) - ) - "; + my $empty = driver_name eq 'Pg' ? qq('') : qq(""); + if ( driver_name eq 'mysql' ) { + $unlinked = "LEFT JOIN cust_svc ON cust_svc.svcnum = svc_acct.svcnum + WHERE cust_svc.pkgnum IS NULL + OR cust_svc.pkgnum = 0 + OR cust_svc.pkgnum = $empty"; + } else { + $unlinked = " + WHERE 0 < + ( SELECT count(*) FROM cust_svc + WHERE cust_svc.svcnum = svc_acct.svcnum + AND ( pkgnum IS NULL OR pkgnum = 0 OR pkgnum = $empty ) + ) + "; + } } +my $tblname = driver_name eq 'mysql' ? 'svc_acct.' : ''; my(@svc_acct, $sortby); if ( $query eq 'svcnum' ) { $sortby=\*svcnum_sort; - $orderby = 'ORDER BY svcnum'; + $orderby = "ORDER BY ${tblname}svcnum"; } elsif ( $query eq 'username' ) { $sortby=\*username_sort; - $orderby = 'ORDER BY username'; + $orderby = "ORDER BY ${tblname}username"; } elsif ( $query eq 'uid' ) { $sortby=\*uid_sort; - $orderby = ( $unlinked ? 'AND' : 'WHERE' ). ' uid IS NOT NULL ORDER BY uid'; + $orderby = ( $unlinked ? 'AND' : 'WHERE' ). + " ${tblname}uid IS NOT NULL ORDER BY ${tblname}uid"; } else { $sortby=\*uid_sort; @svc_acct = @{&usernamesearch}; @@ -235,10 +244,50 @@ sub uid_sort { sub usernamesearch { + my @svc_acct; + + my %username_type; + foreach ( $cgi->param('username_type') ) { + $username_type{$_}++; + } + $cgi->param('username') =~ /^([\w\-\.\&]+)$/; #untaint username_text - my($username)=$1; + my $username = $1; + + if ( $username_type{'Exact'} || $username_type{'Fuzzy'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => $username } } ); + } + + if ( $username_type{'Substring'} || $username_type{'All'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => "%$username%" } } ); + } + + if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { + &FS::svc_acct::check_and_rebuild_fuzzyfiles; + my $all_username = &FS::svc_acct::all_username; + + my %username; + if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { + foreach ( amatch($username, [ qw(i) ], @$all_username) ) { + $username{$_}++; + } + } + + #if ($username_type{'Sound-alike'}) { + #} + + foreach ( keys %username ) { + push @svc_acct, qsearch('svc_acct',{'username'=>$_}); + } + + } - [ qsearch('svc_acct',{'username'=>$username}) ]; + #[ qsearch('svc_acct',{'username'=>$username}) ]; + \@svc_acct; } diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index 52d85deff..c5a8c82dd 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -364,7 +364,8 @@ foreach my $package (@packages) { for ( qw( setup bill susp expire cancel ) ) { print "<TD ROWSPAN=$rowspan><FONT SIZE=-1>", ( $package->getfield($_) - ? time2str("%D", $package->getfield($_) ) + ? time2str("%D</FONT><BR><FONT SIZE=-3>%l:%M:%S%P %z</FONT>", + $package->getfield($_) ) : ' ' ), '</FONT></TD>', ; |