diff options
Diffstat (limited to 'httemplate')
43 files changed, 725 insertions, 451 deletions
diff --git a/httemplate/browse/agent.cgi b/httemplate/browse/agent.cgi index 246500941..cff111ca4 100755 --- a/httemplate/browse/agent.cgi +++ b/httemplate/browse/agent.cgi @@ -1,6 +1,5 @@ <!-- mason kludge --> <% - #Begin silliness # #use FS::UI::CGI; @@ -11,23 +10,25 @@ #exit; #__END__ #End silliness +%> -print header('Agent Listing', menubar( +<%= header('Agent Listing', menubar( 'Main Menu' => $p, 'Agent Types' => $p. 'browse/agent_type.cgi', # 'Add new agent' => '../edit/agent.cgi' -)), <<END; +)) %> Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type).<BR><BR> -END -print &table(), <<END; - <TR> - <TH COLSPAN=2>Agent</TH> - <TH>Type</TH> - <TH><FONT SIZE=-1>Freq.</FONT></TH> - <TH><FONT SIZE=-1>Prog.</FONT></TH> - </TR> -END +<A HREF="<%= $p %>edit/agent.cgi"><I>Add a new agent</I></A><BR><BR> + +<%= table() %> +<TR> + <TH COLSPAN=2>Agent</TH> + <TH>Type</TH> + <TH><FONT SIZE=-1>Freq.</FONT></TH> + <TH><FONT SIZE=-1>Prog.</FONT></TH> +</TR> +<% # <TH><FONT SIZE=-1>Agent #</FONT></TH> # <TH>Agent</TH> @@ -54,12 +55,7 @@ END } print <<END; - <TR> - <TD COLSPAN=2><A HREF="${p}edit/agent.cgi"><I>Add a new agent</I></A></TD> - <TD><A HREF="${p}edit/agent_type.cgi"><I>Add a new agent type</I></A></TD> - </TR> </TABLE> - </BODY> </HTML> END diff --git a/httemplate/browse/agent_type.cgi b/httemplate/browse/agent_type.cgi index eb20c6404..5a8438589 100755 --- a/httemplate/browse/agent_type.cgi +++ b/httemplate/browse/agent_type.cgi @@ -1,16 +1,19 @@ <!-- mason kludge --> -<% - -print header("Agent Type Listing", menubar( +<%= header("Agent Type Listing", menubar( 'Main Menu' => $p, -)), "Agent types define groups of packages that you can then assign to". - " particular agents.<BR><BR>", &table(), <<END; - <TR> - <TH COLSPAN=2>Agent Type</TH> - <TH COLSPAN=2>Packages</TH> - </TR> -END + 'Agents' => $p. 'browse/agent.cgi', +)) %> +Agent types define groups of packages that you can then assign to particular +agents.<BR><BR> +<A HREF="<%= $p %>edit/agent_type.cgi"><I>Add a new agent type</I></A><BR><BR> + +<%= table() %> +<TR> + <TH COLSPAN=2>Agent Type</TH> + <TH COLSPAN=2>Packages</TH> +</TR> +<% foreach my $agent_type ( sort { $a->getfield('typenum') <=> $b->getfield('typenum') } qsearch('agent_type',{}) ) { @@ -47,7 +50,6 @@ END } print <<END; - <TR><TD COLSPAN=4><I><A HREF="${p}edit/agent_type.cgi">Add a new agent type</A></I></TD></TR> </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/part_bill_event.cgi b/httemplate/browse/part_bill_event.cgi index 1d674f749..670474d48 100755 --- a/httemplate/browse/part_bill_event.cgi +++ b/httemplate/browse/part_bill_event.cgi @@ -15,6 +15,8 @@ my $total = scalar(@part_bill_event); <%= header('Invoice Event Listing', menubar( 'Main Menu' => $p) ) %> Invoice events are actions taken on overdue invoices.<BR><BR> +<A HREF="<%= $p %>edit/part_bill_event.cgi"><I>Add a new invoice event</I></A> +<BR><BR> <%= $total %> events <%= $cgi->param('showdisabled') ? do { $cgi->param('showdisabled', 0); @@ -64,10 +66,6 @@ my $total = scalar(@part_bill_event); <%= $part_bill_event->eventcode %></FONT></TD> </TR> <% } %> - - <TR> - <TD COLSPAN=8><A HREF="<%= $p %>edit/part_bill_event.cgi"><I>Add a new invoice event</I></A></TD> - </TR> </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/part_export.cgi b/httemplate/browse/part_export.cgi index e9d9fa3d4..76662e0c9 100755 --- a/httemplate/browse/part_export.cgi +++ b/httemplate/browse/part_export.cgi @@ -1,7 +1,7 @@ <!-- mason kludge --> -<%= header("Export Listing", menubar( 'Main Menu' => $p )) %> +<%= header("Export Listing", menubar( 'Main Menu' => "$p#sysadmin" )) %> Provisioning services to external machines, databases and APIs.<BR><BR> - +<A HREF="<%= $p %>edit/part_export.cgi"><I>Add a new export</I></A><BR><BR> <SCRIPT> function part_export_areyousure(href) { if (confirm("Are you sure you want to delete this export?") == true) @@ -34,9 +34,6 @@ function part_export_areyousure(href) { <% } %> - <TR> - <TD COLSPAN=3><A HREF="<%= $p %>edit/part_export.cgi"><I>Add a new export</I></A></TD> - </TR> </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index c20811491..58422c67d 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -11,13 +11,16 @@ if ( $cgi->param('showdisabled') ) { my @part_pkg = qsearch('part_pkg', \%search ); my $total = scalar(@part_pkg); -print header("Package Definition Listing",menubar( - 'Main Menu' => $p, -)). "One or more services are grouped together into a package and given". - " pricing information. Customers purchase packages". - " rather than purchase services directly.<BR><BR>". - "$total packages "; +%> +<%= header("Package Definition Listing",menubar( 'Main Menu' => $p )) %> +One or more services are grouped together into a package and given pricing +information. Customers purchase packages rather than purchase services +directly.<BR><BR> +<A HREF="<%= $p %>edit/part_pkg.cgi"><I>Add a new package definition</I></A> +<BR><BR> +<%= $total %> packages +<% if ( $cgi->param('showdisabled') ) { $cgi->param('showdisabled', 0); print qq!( <a href="!. $cgi->self_url. qq!">hide disabled packages</a> )!; @@ -91,7 +94,7 @@ END $colspan = $cgi->param('showdisabled') ? 8 : 9; print <<END; - <TR><TD COLSPAN=$colspan><I><A HREF="${p}edit/part_pkg.cgi">Add a new package definition</A></I></TD></TR> + </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/part_referral.cgi b/httemplate/browse/part_referral.cgi index 93a6976e1..084c21bd0 100755 --- a/httemplate/browse/part_referral.cgi +++ b/httemplate/browse/part_referral.cgi @@ -1,15 +1,19 @@ <!-- mason kludge --> -<% - -print header("Advertising source Listing", menubar( +<%= header("Advertising source Listing", menubar( 'Main Menu' => $p, # 'Add new referral' => "../edit/part_referral.cgi", -)), "Where a customer heard about your service. Tracked for informational purposes.<BR><BR>", &table(), <<END; - <TR> - <TH COLSPAN=2>Advertising source</TH> - </TR> -END +)) %> +Where a customer heard about your service. Tracked for informational purposes. +<BR><BR> +<A HREF="<%= $p %>edit/part_referral.cgi"><I>Add a new advertising source</I></A> +<BR><BR> +<%= table() %> +<TR> + <TH COLSPAN=2>Advertising source</TH> +</TR> + +<% foreach my $part_referral ( sort { $a->getfield('refnum') <=> $b->getfield('refnum') } qsearch('part_referral',{}) ) { @@ -26,9 +30,6 @@ END } print <<END; - <TR> - <TD COLSPAN=2><A HREF="${p}edit/part_referral.cgi"><I>Add a new advertising source</I></A></TD> - </TR> </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/part_svc.cgi b/httemplate/browse/part_svc.cgi index 5c33e68a4..9fb359d1d 100755 --- a/httemplate/browse/part_svc.cgi +++ b/httemplate/browse/part_svc.cgi @@ -8,7 +8,9 @@ if ( $cgi->param('showdisabled') ) { %search = ( 'disabled' => '' ); } -my @part_svc = qsearch('part_svc', \%search ); +my @part_svc = + sort { $a->getfield('svcpart') <=> $b->getfield('svcpart') } + qsearch('part_svc', \%search ); my $total = scalar(@part_svc); %> @@ -22,6 +24,14 @@ function part_export_areyousure(href) { </SCRIPT> Services are items you offer to your customers.<BR><BR> + +<FORM METHOD="POST" ACTION="<%= $p %>edit/part_svc.cgi"><A HREF="<%= $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A> or <SELECT NAME="clone"><OPTION></OPTION> +<% foreach my $part_svc ( @part_svc ) { %> + <OPTION VALUE="<%= $part_svc->svcpart %>"><%= $part_svc->svc %></OPTION> +<% } %> +</SELECT><INPUT TYPE="submit" VALUE="Clone existing service"> +</FORM><BR> + <%= $total %> services <%= $cgi->param('showdisabled') ? do { $cgi->param('showdisabled', 0); @@ -38,9 +48,7 @@ function part_export_areyousure(href) { <TH COLSPAN=2>Modifier</TH> </TR> -<% foreach my $part_svc ( sort { - $a->getfield('svcpart') <=> $b->getfield('svcpart') - } @part_svc ) { +<% foreach my $part_svc ( @part_svc ) { my $hashref = $part_svc->hashref; my $svcdb = $hashref->{svcdb}; my @dfields = fields($svcdb); @@ -94,10 +102,6 @@ map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export %> </TR> <% } %> - - <TR> - <TD COLSPAN=<%= $cgi->param('showdisabled') ? 7 : 8 %>><A HREF="<%= $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A></TD> - </TR> </TABLE> </BODY> </HTML> diff --git a/httemplate/browse/svc_acct_pop.cgi b/httemplate/browse/svc_acct_pop.cgi index f8ee58c05..e890f07bf 100755 --- a/httemplate/browse/svc_acct_pop.cgi +++ b/httemplate/browse/svc_acct_pop.cgi @@ -3,7 +3,10 @@ print header('Access Number Listing', menubar( 'Main Menu' => $p, -)), "Points of Presence<BR><BR>", &table(), <<END; +)) %> +Points of Presence<BR><BR> +<A HREF="<%= $p %>edit/svc_acct_pop.cgi"><I>Add new Access Number</I></A><BR><BR> +<%= table() %> <TR> <TH></TH> <TH>City</TH> @@ -12,8 +15,8 @@ print header('Access Number Listing', menubar( <TH>Exchange</TH> <TH>Local</TH> </TR> -END +<% foreach my $svc_acct_pop ( sort { #$a->getfield('popnum') <=> $b->getfield('popnum') $a->state cmp $b->state || $a->city cmp $b->city @@ -41,7 +44,6 @@ END print <<END; <TR> - <TD COLSPAN=5><A HREF="${p}edit/svc_acct_pop.cgi"><I>Add new Access Number</I></A></TD> </TR> </TABLE> </BODY> 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/config/config-view.cgi b/httemplate/config/config-view.cgi index f0ae2b2fd..bafe5a8e7 100644 --- a/httemplate/config/config-view.cgi +++ b/httemplate/config/config-view.cgi @@ -5,13 +5,13 @@ <% my $conf = new FS::Conf; my @config_items = $conf->config_items; %> <% foreach my $section ( qw(required billing username password UI session - shell mail radius apache BIND + shell mail apache BIND ), '', 'deprecated') { %> <A NAME="<%= $section || 'unclassified' %>"></A> <FONT SIZE="-2"> <% foreach my $nav_section ( qw(required billing username password UI session - shell mail radius apache BIND + shell mail apache BIND ), '', 'deprecated') { %> <% if ( $section eq $nav_section ) { %> diff --git a/httemplate/config/config.cgi b/httemplate/config/config.cgi index 2817e5f84..fd9a82958 100644 --- a/httemplate/config/config.cgi +++ b/httemplate/config/config.cgi @@ -25,13 +25,13 @@ function SafeOnsubmit() { <form name="OneTrueForm" action="config-process.cgi" METHOD="POST" onSubmit="SafeOnsubmit()"> <% foreach my $section ( qw(required billing username password UI session - shell mail radius apache BIND + shell mail apache BIND ), '', 'deprecated') { %> <A NAME="<%= $section || 'unclassified' %>"></A> <FONT SIZE="-2"> <% foreach my $nav_section ( qw(required billing username password UI session - shell mail radius apache BIND + shell mail apache BIND ), '', 'deprecated') { %> <% if ( $section eq $nav_section ) { %> @@ -70,7 +70,7 @@ function SafeOnsubmit() { <option value="<%= $value %>"<%= $value eq $conf->config($i->key) || ( $type eq 'selectmultiple' && grep { $_ eq $value } $conf->config($i->key) ) ? ' SELECTED' : '' %>><%= $value %> <% } %> <% if ( $conf->exists($i->key) && $conf->config($i->key) && ! grep { $conf->config($i->key) eq $_ } @{$i->select_enum}) { %> - <option value=<%= $conf->config($i->key) %> SELECTED><%= conf->config($i->key) %> + <option value=<%= $conf->config($i->key) %> SELECTED><%= $conf->config($i->key) %> <% } %> </select> <% } elsif ( $type eq 'editlist' ) { %> diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html index 26fa34dd1..db2141619 100644 --- a/httemplate/docs/install.html +++ b/httemplate/docs/install.html @@ -10,12 +10,11 @@ Before installing, you need: <li><a href="http://perl.apache.org/">mod_perl</a> (if compiling your own mod_perl, make sure you set the <a href="http://perl.apache.org/guide/install.html#EVERYTHING">EVERYTHING</a>=1 compile-time option) <li><a href="http://www.openssh.com/">SSH</a> (<a href="http://www.openssh.com//">OpenSSH</a> is recommended. SSH Communications Security <a href="http://www.ssh.com/products/ssh/download.cfm">commercial SSH version 3</a> has been reported incompatible with Freeside.) <li><a href="http://rsync.samba.org/">rsync</a> - <li>A <b>transactional</b> database engine supported by Perl's <a href="http://www.hermetica.com/technologia/DBI/">DBI</a>. + <li>A <b>transactional</b> database engine <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">supported</a> by Perl's <a href="http://dbi.perl.org">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> @@ -52,12 +51,12 @@ Before installing, you need: <li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a> <li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a> <li><a href="http://search.cpan.org/search?dist=Storable">Storable</a> - <li><a href="http://search.cpan.org/search?dist=Apache-DBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i> + <li><a href="http://search.cpan.org/search?dist=ApacheDBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i> </ul> </ul> Install the Freeside distribution: <ul> - <li>Add the user `freeside' to your system. + <li>Add the user and group `freeside' to your system. <li>Allow the freeside user full access to the freeside database. <ul> <li> with <a href="http://www.postgresql.org/users-lounge/docs/7.1/postgres/user-manag.html#DATABASE-USERS">PostgreSQL</a>: @@ -78,7 +77,7 @@ mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP on freeside.* T <!-- <li>Unpack the tarball: <pre>gunzip -c fs-x.y.z.tar.gz | tar xvf -</pre>--> <li>Edit the top-level Makefile: <ul> - <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.20/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:host=localhost;dbname=freeside</tt> for PostgresSQL or <tt>DBI:mysql:freeside</tt> for MySQL. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.20/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD">manpage for your DBD</a> for the exact syntax of a DBI data source. + <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:host=localhost;dbname=freeside</tt> for PostgresSQL or <tt>DBI:mysql:freeside</tt> for MySQL. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source. <li>Set <tt>DB_PASSWORD</tt> to the freeside database user's password. </ul> <li>Add the freeside database to your database engine: @@ -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/docs/ssh.html b/httemplate/docs/ssh.html new file mode 100755 index 000000000..5503a242e --- /dev/null +++ b/httemplate/docs/ssh.html @@ -0,0 +1,15 @@ +<head> + <title>Unattended SSH</title> +</head> +<body> + <h1>Unattended SSH</h1> + <br><a name=ssh>Unattended remote login</a> - Freeside can login to remote machines unattended using SSH. This can pose a security risk if not configured correctly, and will allow an intruder who breaks into your freeside machine full access to your remote machines. <b>Do not use this feature unless you understand what you are doing!</b> + <ul> + <li>As the freeside user (on your freeside machine), generate an authentication key using <a href="http://www.tac.eu.org/cgi-bin/man-cgi?ssh-keygen+1">ssh-keygen</a>. Since this is for unattended operation, use a blank passphrase. + <li>Append the newly-created <code>identity.pub</code> file to <code>~root/.ssh/authorized_keys</code> on the remote machine(s). + <li>Some new SSH v2 implementation accept v2 style keys only. Use the <code>-t</code> option to <a href="http://www.tac.eu.org/cgi-bin/man-cgi?ssh-keygen+1">ssh-keygen</a>, and append the created <code>id_dsa.pub</code> or <code>id_rsa.pub</code> to <code>~root/.ssh/authorized_keys2</code> on the remote machine(s). + <li>You may need to set <code>PermitRootLogin without-password</code> (meaning with keys only) in your <code>sshd_config</code> file on the remote machine(s). + </ul> + +</body> + diff --git a/httemplate/docs/upgrade8.html b/httemplate/docs/upgrade8.html index e6184df14..75155407c 100644 --- a/httemplate/docs/upgrade8.html +++ b/httemplate/docs/upgrade8.html @@ -7,7 +7,7 @@ <li>If migrating from less than 1.3.1, see these <a href="upgrade7.html">instructions</a> first. <li><font size="+2" color="#ff0000">Backup your database and current Freeside installation.</font> (with <a href="http://www.ca.postgresql.org/devel-corner/docs/postgres/backup.html">PostgreSQL</a>) (with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Backup">MySQL</a>) <li><a href="http://perl.apache.org/">mod_perl</a> is now required. - <li>Install <a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>, <a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a> and <a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>. + <li>Install <a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>, <a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a> and <a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a> (minimum version 0.02). <li>Install <a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>. <li>Install <a href="http://rsync.samba.org/">rsync</a> </ul> @@ -69,6 +69,12 @@ CREATE TABLE svc_forward ( dst varchar(80), PRIMARY KEY (svcnum) ); +ALTER TABLE part_svc ADD svc_forward__srcsvc varchar(80) NULL; +ALTER TABLE part_svc ADD svc_forward__srcsvc_flag char(1) NULL; +ALTER TABLE part_svc ADD svc_forward__dstsvc varchar(80) NULL; +ALTER TABLE part_svc ADD svc_forward__dstsvc_flag char(1) NULL; +ALTER TABLE part_svc ADD svc_forward__dst varchar(80) NULL; +ALTER TABLE part_svc ADD svc_forward__dst_flag char(1) NULL; CREATE TABLE cust_credit_bill ( creditbillnum int primary key, @@ -213,9 +219,12 @@ CREATE TABLE cust_tax_exempt ( ); CREATE UNIQUE INDEX cust_tax_exempt1 ON cust_tax_exempt ( taxnum, year, month ); -ALTER TABLE svc_acct ADD domsvc integer NOT NULL; +ALTER TABLE svc_acct ADD domsvc integer NULL; +ALTER TABLE part_svc ADD svc_acct__domsvc varchar(80) NULL; +ALTER TABLE part_svc ADD svc_acct__domsvc_flag char(1) NULL; ALTER TABLE svc_domain ADD catchall integer NULL; ALTER TABLE cust_main ADD referral_custnum integer NULL; +ALTER TABLE cust_main ADD comments text NULL; ALTER TABLE cust_pay ADD custnum integer; ALTER TABLE cust_pay_batch ADD paybatchnum integer; ALTER TABLE cust_refund ADD custnum integer; @@ -233,6 +242,8 @@ ALTER TABLE cust_refund ADD closed char(1) NULL; ALTER TABLE cust_bill_event ADD status varchar(80); ALTER TABLE cust_bill_event ADD statustext text NULL; ALTER TABLE svc_acct ADD sec_phrase varchar(80) NULL; +ALTER TABLE part_svc ADD svc_acct__sec_phrase varchar(80) NULL; +ALTER TABLE part_svc ADD svc_acct__sec_phrase_flag char(1) NULL; ALTER TABLE part_pkg ADD taxclass varchar(80) NULL; ALTER TABLE cust_main_county ADD taxclass varchar(80) NULL; ALTER TABLE cust_main_county ADD exempt_amount decimal(10,2); @@ -276,7 +287,6 @@ CREATE UNIQUE INDEX svc_acct_pop_pkey ON svc_acct_pop ( popnum ); CREATE UNIQUE INDEX svc_acct_sm_pkey ON svc_acct_sm ( svcnum ); CREATE UNIQUE INDEX svc_domain_pkey ON svc_domain ( svcnum ); CREATE UNIQUE INDEX svc_www_pkey ON svc_www ( svcnum ); -CREATE UNIQUE INDEX type_pkgs_pkey ON type_pkgs ( typenum ); </pre> <li>If you wish to enable service/shipping addresses, apply the following changes to your database: @@ -294,23 +304,24 @@ ALTER TABLE cust_main ADD COLUMN ship_country char(2) NULL; ALTER TABLE cust_main ADD COLUMN ship_daytime varchar(20) NULL; ALTER TABLE cust_main ADD COLUMN ship_night varchar(20) NULL; ALTER TABLE cust_main ADD COLUMN ship_fax varchar(12) NULL; -CREATE INDEX cust_main1 ON cust_main ( ship_last ); -CREATE INDEX cust_main2 ON cust_main ( ship_company ); -</pre> - <li>If you wish to enable customer comments, apply the following change to - your database: -<pre> -ALTER TABLE cust_main ADD COLUMN comments text NULL; +CREATE INDEX cust_main4 ON cust_main ( ship_last ); +CREATE INDEX cust_main5 ON cust_main ( ship_company ); </pre> <li>If you are using the signup server, reinstall it according to the <a href="signup.html">instructions</a>. The 1.3.x signup server is not compatible with 1.4.x. - <li>Run bin/dbdef-create. + <li>Run <tt>bin/dbdef-create <i>username</i></tt> <li>If you have svc_acct_sm records or service definitions: <ul> <li>Create a service definition with table svc_forward - <li>Run bin/fs-migrate-svc_acct_sm + <li>Run <tt>bin/fs-migrate-svc_acct_sm <i>username</i></tt> + </ul> + <li>Or if you just have svc_acct records: + <ul> + <li>Order and provision a package for your default domain and note down the <b>Service #</b> or <i>svcnum</i>. + <li><tt>UPDATE svc_acct SET domsvc = </tt><i>svcnum</i> + <li>Update your service definitions to have default (or fixed) <b>domsvc</b>. </ul> - <li>Run bin/fs-migrate-payref - <li>Run bin/fs-migrate-part_svc + <li>Run <tt>bin/fs-migrate-payref<i>username</i></tt> + <li>Run <tt>bin/fs-migrate-part_svc<i>username</i></tt> <li><b>After running bin/fs-migrate-payref</b>, apply the following changes to your database: <table border><tr><th>PostgreSQL</th><th>MySQL, others</th></tr> <tr><td> @@ -322,9 +333,10 @@ CREATE TABLE cust_pay_temp ( _date int null, payby char(4) not null, payinfo varchar(16) null, - paybatch varchar(80) null + paybatch varchar(80) null, + closed char(1) null ); -INSERT INTO cust_pay_temp SELECT * from cust_pay; +INSERT INTO cust_pay_temp SELECT paynum, custnum, paid, _date, payby, payinfo, paybatch, closed FROM cust_pay; DROP TABLE cust_pay; ALTER TABLE cust_pay_temp RENAME TO cust_pay; CREATE UNIQUE INDEX cust_pay1 ON cust_pay (paynum); @@ -337,9 +349,10 @@ CREATE TABLE cust_refund_temp ( reason varchar(80) not null, payby char(4) not null, payinfo varchar(16) null, - paybatch varchar(80) null + paybatch varchar(80) null, + closed char(1) null ); -INSERT INTO cust_refund_temp SELECT * from cust_refund; +INSERT INTO cust_refund_temp SELECT refundnum, custnum, _date, refund, otaker, reason, payby, payinfo, '', closed from cust_refund; DROP TABLE cust_refund; ALTER TABLE cust_refund_temp RENAME TO cust_refund; CREATE UNIQUE INDEX cust_refund1 ON cust_refund (refundnum); @@ -350,9 +363,11 @@ ALTER TABLE cust_pay DROP COLUMN invnum; ALTER TABLE cust_refund DROP COLUMN crednum; </pre></font> </td></tr></table> - <li><b>IMPORTANT: After applying the second set of database changes</b>, run bin/dbdef-create again. - <li><b>IMPORTANT</b>: run bin/create-history-tables - <li><b>IMPORTANT: After running bin/create-history-tables</b>, run bin/dbdef-create again. + <li><b>IMPORTANT: After applying the second set of database changes</b>, run <tt>bin/dbdef-create <i>username</i></tt> again. + <li><b>IMPORTANT</b>: run <tt>bin/create-history-tables <i>username</i></tt> + <li><b>IMPORTANT: After running bin/create-history-tables</b>, run <tt>bin/dbdef-create <i>username</i></tt> again. + <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <i>username</i></tt +> to populate the message catalog <li>set the <a href="../config/config.cgi#username_policy">user_policy configuration value</a> as appropriate for your site. <li>set the <a href="../config/config.cgi#locale">locale configuration value</a> to en_US. <li>the mxmachines, nsmachines, arecords and cnamerecords configuration values have been deprecated. Set the <a href="../config/config.cgi#defaultrecords">defaultrecords configuration value</a> instead. diff --git a/httemplate/edit/cust_bill_pay.cgi b/httemplate/edit/cust_bill_pay.cgi index d90659724..8cdf4509a 100755 --- a/httemplate/edit/cust_bill_pay.cgi +++ b/httemplate/edit/cust_bill_pay.cgi @@ -59,14 +59,13 @@ foreach my $cust_bill ( @cust_bill ) { END } -#print <<END; # if ( cust_bill == "Refund" ) { # what.form.amount.value = "$credited"; # } -#} -#</SCRIPT> -#END -print "</SCRIPT>\n"; +print <<END; +} +</SCRIPT> +END print qq!<BR>Invoice #<SELECT NAME="invnum" SIZE=1 onChange="changed(this)">!, '<OPTION VALUE="">'; diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index af89c4ead..486bd4300 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -45,15 +45,32 @@ 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 'textarea' ) { + $html .= qq!<TEXTAREA NAME="$option">$value</TEXTAREA>!; + } 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_pkg.cgi b/httemplate/edit/part_pkg.cgi index e03017db4..b6ecff2d0 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -69,7 +69,7 @@ print "Package Part #", $hashref->{pkgpart} ? $hashref->{pkgpart} : "(NEW)"; print ntable("#cccccc",2), <<END; <TR><TD ALIGN="right">Package (customer-visable)</TD><TD><INPUT TYPE="text" NAME="pkg" SIZE=32 VALUE="$hashref->{pkg}"></TD></TR> <TR><TD ALIGN="right">Comment (customer-hidden)</TD><TD><INPUT TYPE="text" NAME="comment" SIZE=32 VALUE="$hashref->{comment}"></TD></TR> -<TR><TD ALIGN="right">Frequency (months) of recurring fee</TD><TD><INPUT TYPE="text" NAME="freq" VALUE="$hashref->{freq}" SIZE=3></TD></TR> +<TR><TD ALIGN="right">Frequency (months) of recurring fee</TD><TD><INPUT TYPE="text" NAME="freq" VALUE="$hashref->{freq}" SIZE=3> <I>0=no recurring fee, 1=monthly, 3=quarterly, 12=yearly</TD></TR> <TR><TD ALIGN="right">Setup fee tax exempt</TD><TD> END @@ -89,6 +89,7 @@ print '>'; print '</TD></TR>'; my $conf = new FS::Conf; +#false laziness w/ view/cust_main.cgi quick order if ( $conf->exists('enable_taxclasses') ) { print '<TR><TD ALIGN="right">Tax class</TD><TD><SELECT NAME="taxclass">'; my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') @@ -240,7 +241,7 @@ tie my %plans, 'Tie::IxHash', }, 'flat_comission_cust' => { - 'name' => 'Flat rate with recurring comission per active customer', + 'name' => 'Flat rate with recurring commission per active customer', 'fields' => { 'setup_fee' => { 'name' => 'Setup fee for this package', 'default' => 0, @@ -248,7 +249,7 @@ tie my %plans, 'Tie::IxHash', 'recur_fee' => { 'name' => 'Recurring fee for this package', 'default' => 0, }, - 'comission_amount' => { 'name' => 'Comission amount per month (per active customer)', + 'comission_amount' => { 'name' => 'Commission amount per month (per active customer)', 'default' => 0, }, 'comission_depth' => { 'name' => 'Number of layers', @@ -261,7 +262,7 @@ tie my %plans, 'Tie::IxHash', }, 'flat_comission' => { - 'name' => 'Flat rate with recurring comission per (any) active package', + 'name' => 'Flat rate with recurring commission per (any) active package', 'fields' => { 'setup_fee' => { 'name' => 'Setup fee for this package', 'default' => 0, @@ -269,7 +270,7 @@ tie my %plans, 'Tie::IxHash', 'recur_fee' => { 'name' => 'Recurring fee for this package', 'default' => 0, }, - 'comission_amount' => { 'name' => 'Comission amount per month (per active package)', + 'comission_amount' => { 'name' => 'Commission amount per month (per active package)', 'default' => 0, }, 'comission_depth' => { 'name' => 'Number of layers', @@ -282,7 +283,7 @@ tie my %plans, 'Tie::IxHash', }, 'flat_comission_pkg' => { - 'name' => 'Flat rate with recurring comission per (selected) active package', + 'name' => 'Flat rate with recurring commission per (selected) active package', 'fields' => { 'setup_fee' => { 'name' => 'Setup fee for this package', 'default' => 0, @@ -290,7 +291,7 @@ tie my %plans, 'Tie::IxHash', 'recur_fee' => { 'name' => 'Recurring fee for this package', 'default' => 0, }, - 'comission_amount' => { 'name' => 'Comission amount per month (per uncancelled package)', + 'comission_amount' => { 'name' => 'Commission amount per month (per uncancelled package)', 'default' => 0, }, 'comission_depth' => { 'name' => 'Number of layers', diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi index e9c571f9c..4ccb770fb 100755 --- a/httemplate/edit/part_svc.cgi +++ b/httemplate/edit/part_svc.cgi @@ -1,10 +1,17 @@ <!-- mason kludge --> <% my $part_svc; + my $clone = ''; if ( $cgi->param('error') ) { #error $part_svc = new FS::part_svc ( { map { $_, scalar($cgi->param($_)) } fields('part_svc') } ); + } elsif ( $cgi->param('clone') && $cgi->param('clone') =~ /^(\d+)$/ ) {#clone + #$cgi->param('clone') =~ /^(\d+)$/ or die "malformed query: $query"; + $part_svc = qsearchs('part_svc', { 'svcpart'=>$1 } ) + or die "unknown svcpart: $1"; + $clone = $part_svc->svcpart; + $part_svc->svcpart(''); } elsif ( $cgi->keywords ) { #edit my($query) = $cgi->keywords; $query =~ /^(\d+)$/ or die "malformed query: $query"; @@ -137,17 +144,17 @@ my %defs = ( my $columns = 3; my $count = 0; my @part_export = - grep { $layer eq FS::part_export::exporttype2svcdb($_->exporttype) } - qsearch( 'part_export', {} ); - $html .= '<BR><BR>'. table(). + map { qsearch( 'part_export', {exporttype => $_ } ) } + keys %{FS::part_export::export_info($layer)}; + $html .= '<BR><BR>'. table(). table(). "<TR><TH COLSPAN=$columns>Exports</TH></TR><TR>"; foreach my $part_export ( @part_export ) { $html .= '<TD><INPUT TYPE="checkbox"'. ' NAME="exportnum'. $part_export->exportnum. '" VALUE="1" '; $html .= 'CHECKED' if qsearchs( 'export_svc', { - exportnum => $part_export->exportnum, - svcpart => $part_svc->svcpart }); + exportnum => $part_export->exportnum, + svcpart => $clone || $part_svc->svcpart }); $html .= '> '. $part_export->exporttype. ' to '. $part_export->machine. '</TD>'; $count++; @@ -161,6 +168,7 @@ my %defs = ( ? grep { $_ ne 'svcnum' } fields($layer) : (); push @fields, 'usergroup' if $layer eq 'svc_acct'; #kludge + $part_svc->svcpart($clone) if $clone; #haha, undone below foreach my $field (@fields) { my $part_svc_column = $part_svc->part_svc_column($field); my $value = $cgi->param('error') @@ -206,6 +214,7 @@ my %defs = ( } $html .= "</TD></TR>\n"; } + $part_svc->svcpart('') if $clone; #undone $html .= "</TABLE>"; $html .= '<BR><INPUT TYPE="submit" VALUE="'. diff --git a/httemplate/edit/process/domain_record.cgi b/httemplate/edit/process/domain_record.cgi new file mode 100755 index 000000000..b8c3f62a1 --- /dev/null +++ b/httemplate/edit/process/domain_record.cgi @@ -0,0 +1,34 @@ +<% + +my $recnum = $cgi->param('recnum'); + +my $old = qsearchs('agent',{'recnum'=>$recnum}) if $recnum; + +my $new = new FS::domain_record ( { + map { + $_, scalar($cgi->param($_)); + } fields('domain_record') +} ); + +my $error; +if ( $recnum ) { + $error=$new->replace($old); +} else { + $error=$new->insert; + $recnum=$new->getfield('recnum'); +} + +if ( $error ) { +# $cgi->param('error', $error); +# print $cgi->redirect(popurl(2). "agent.cgi?". $cgi->query_string ); + #no edit screen to send them back to +%> +<!-- mason kludge --> +<% + eidiot($error); +} else { + my $svcnum = $new->svcnum; + print $cgi->redirect(popurl(3). "view/svc_domain.cgi?$svcnum"); +} + +%> diff --git a/httemplate/edit/process/part_export.cgi b/httemplate/edit/process/part_export.cgi index 6b4d007e4..fa009edbb 100644 --- a/httemplate/edit/process/part_export.cgi +++ b/httemplate/edit/process/part_export.cgi @@ -6,7 +6,11 @@ my $old = qsearchs('part_export', { 'exportnum'=>$exportnum } ) if $exportnum; #fixup options #warn join('-', split(',',$cgi->param('options'))); -my %options = map { $_=>$cgi->param($_) } split(',',$cgi->param('options')); +my %options = map { + my $value = $cgi->param($_); + $value =~ s/\r\n/\n/g; #browsers? (textarea) + $_ => $value; +} split(',', $cgi->param('options')); my $new = new FS::part_export ( { map { diff --git a/httemplate/edit/process/quick-charge.cgi b/httemplate/edit/process/quick-charge.cgi new file mode 100644 index 000000000..477f58508 --- /dev/null +++ b/httemplate/edit/process/quick-charge.cgi @@ -0,0 +1,32 @@ +<% + +#untaint custnum +$cgi->param('custnum') =~ /^(\d+)$/ + or die 'illegal custnum '. $cgi->param('custnum'); +my $custnum = $1; + +$cgi->param('amount') =~ /^\s*(\d+(\.\d{1,2})?)\s*$/ + or die 'illegal amount '. $cgi->param('amount'); +my $amount = $1; + +my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or die "unknown custnum $custnum"; + +my $error = $cust_main->charge( + $amount, + $cgi->param('pkg'), + '$'. sprintf("%.2f",$amount), + $cgi->param('taxclass') +); + +if ($error) { +%> +<!-- mason kludge --> +<% + eidiot($error); +} else { + print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum" ); +} + +%> + diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi index c663dce32..a8f5b1453 100644 --- a/httemplate/edit/process/quick-cust_pkg.cgi +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -2,10 +2,10 @@ #untaint custnum $cgi->param('custnum') =~ /^(\d+)$/ - or eidiot 'illegal custnum '. $cgi->param('custnum'); + or die 'illegal custnum '. $cgi->param('custnum'); my $custnum = $1; $cgi->param('pkgpart') =~ /^(\d+)$/ - or eidiot 'illegal pkgpart '. $cgi->param('pkgpart'); + or die 'illegal pkgpart '. $cgi->param('pkgpart'); my $pkgpart = $1; my @cust_pkg = (); diff --git a/httemplate/edit/process/svc_www.cgi b/httemplate/edit/process/svc_www.cgi index 38d5e1c79..40913145a 100644 --- a/httemplate/edit/process/svc_www.cgi +++ b/httemplate/edit/process/svc_www.cgi @@ -5,8 +5,8 @@ my $svcnum = $1; my $old; if ( $svcnum ) { - $old = qsearchs('svc_acct', { 'svcnum' => $svcnum } ) - or die "fatal: can't find account (svcnum $svcnum)!"; + $old = qsearchs('svc_www', { 'svcnum' => $svcnum } ) + or die "fatal: can't find website (svcnum $svcnum)!"; } else { $old = ''; } diff --git a/httemplate/edit/svc_forward.cgi b/httemplate/edit/svc_forward.cgi index 5f1466bbb..bc19fe1de 100755 --- a/httemplate/edit/svc_forward.cgi +++ b/httemplate/edit/svc_forward.cgi @@ -119,105 +119,58 @@ my($srcsvc,$dstsvc,$dst)=( #display -my $p1 = popurl(1); -print header("Mail Forward $action", '', - " onLoad=\"visualize()\""); - %> -<SCRIPT> -function visualize(what){ - if (document.getElementById) { - document.getElementById('dother').style.visibility = '<%= $dstsvc ? 'hidden' : 'visible' %>'; - } -} -function fixup(what){ - if (document.getElementById) { - if (document.getElementById('dother').style.visibility == 'hidden') { - what.dst.value=''; - } - } -} -</SCRIPT> - -<% - -print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), - "</FONT>" - if $cgi->param('error'); +<%= header("Mail Forward $action") %> -print qq!<FORM ACTION="${p1}process/svc_forward.cgi" onSubmit="fixup(this)" METHOD=POST>!; +<% if ( $cgi->param('error') ) { %> + <FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT> + <BR><BR> +<% } %> -#svcnum -print qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!; -print qq!Service #<FONT SIZE=+1><B>!, $svcnum ? $svcnum : " (NEW)", "</B></FONT>"; -print qq!<BR>!; +Service #<%= $svcnum ? "<B>$svcnum</B>" : " (NEW)" %><BR> +Service: <B><%= $part_svc->svc %></B><BR><BR> -#pkgnum -print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!; - -#svcpart -print qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!; - -#srcsvc -print qq!\n\nMail to <SELECT NAME="srcsvc" SIZE=1>!; -foreach $_ (keys %email) { - print "<OPTION", $_ eq $srcsvc ? " SELECTED" : "", - qq! VALUE="$_">$email{$_}!; -} -print "</SELECT>"; +<FORM NAME="dummy"> -#dstsvc -print qq! forwards to <SELECT NAME="dstsvc" SIZE=1 onChange="changed(this)">!; -foreach $_ (keys %email) { - print "<OPTION", $_ eq $dstsvc ? " SELECTED" : "", - qq! VALUE="$_">$email{$_}!; -} -print "<OPTION", 0 eq $dstsvc ? " SELECTED" : "", - qq! VALUE="0">(other)!; -print "</SELECT> mailbox."; - -%> - -<SCRIPT> -var selectchoice = null; -function changed(what) { - selectchoice = what.options[what.selectedIndex].value; - if (selectchoice == "0") { - if (document.getElementById) { - document.getElementById('dother').style.visibility = "visible"; - } - }else{ - if (document.getElementById) { - document.getElementById('dother').style.visibility = "hidden"; - } - } -} -if (document.getElementById) { - document.write("<DIV ID=\"dother\" STYLE=\"visibility: hidden\">"); -} -</SCRIPT> +<%= ntable("#cccccc",2) %> +<TR><TD ALIGN="right">Email to</TD><TD><SELECT NAME="srcsvc" SIZE=1> +<% foreach $_ (keys %email) { %> + <OPTION<%= $_ eq $srcsvc ? " SELECTED" : "" %> VALUE="<%= $_ %>"><%= $email{$_} %></OPTION> +<% } %> +</SELECT></TD></TR> <% -print qq! Other destination: <INPUT TYPE="text" NAME="dst" VALUE="$dst">!; + tie my %tied_email, 'Tie::IxHash', + '' => 'SELECT DESTINATION', + %email, + '0' => '(other email address)'; + my $widget = new HTML::Widgets::SelectLayers( + 'selected_layer' => $dstsvc, + 'options' => \%tied_email, + 'form_name' => 'dummy', + 'form_action' => 'process/svc_forward.cgi', + 'form_select' => ['srcsvc'], + 'html_between' => '</TD></TR></TABLE>', + 'layer_callback' => sub { + my $layer = shift; + my $html = qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!. + qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!. + qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!. + qq!<INPUT TYPE="hidden" NAME="dstsvc" VALUE="$layer">!; + if ( $layer eq '0' ) { + $html .= ntable("#cccccc",2). + '<TR><TD ALIGN="right">Destination email</TD>'. + qq!<TD><INPUT TYPE="text" NAME="dst" VALUE="$dst"></TD>!. + '</TR></TABLE>'; + } + $html .= '<BR><INPUT TYPE="submit" VALUE="Submit">'; + $html; + }, + ); %> -<SCRIPT> -if (document.getElementById) { - document.write("</DIV>"); -} -</SCRIPT> - -<CENTER><INPUT TYPE="submit" VALUE="Submit"></CENTER> -</FORM> - -<TAG onLoad=" - if (document.getElementById) { - document.getElementById('dother').style.visibility = '<%= $dstsvc ? 'hidden' : 'visible' %>'; - document.getElementById('dlabel').style.visibility = '<%= $dstsvc ? 'hidden' : 'visible' %>'; - } -"> - - +<TR><TD ALIGN="right">Forwards to</TD> +<TD><%= $widget->html %> </BODY> </HTML> diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index e1a914f1a..d2c9ade5c 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -175,5 +175,4 @@ print <<END; </BODY> </HTML> END - - +%> diff --git a/httemplate/index.html b/httemplate/index.html index 3e657025f..29dd3b471 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> or <A HREF="search/svc_acct.cgi?uid">uid</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/misc/cancel-unaudited.cgi b/httemplate/misc/cancel-unaudited.cgi index ecfaef29f..f1fb15341 100755 --- a/httemplate/misc/cancel-unaudited.cgi +++ b/httemplate/misc/cancel-unaudited.cgi @@ -7,15 +7,18 @@ my($query) = $cgi->keywords; $query =~ /^(\d+)$/; my $svcnum = $1; -my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$svcnum}); -die "Unknown svcnum!" unless $svc_acct; +#my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$svcnum}); +#die "Unknown svcnum!" unless $svc_acct; my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$svcnum}); +die "Unknown svcnum!" unless $cust_svc; &eidiot(qq!This account has already been audited. Cancel the <A HREF="!. popurl(2). qq!view/cust_pkg.cgi?! . $cust_svc->getfield('pkgnum') . qq!pkgnum"> package</A> instead.!) if $cust_svc->pkgnum ne '' && $cust_svc->pkgnum ne '0'; +my $svc_x = $cust_svc->svc_x; + local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; @@ -24,8 +27,8 @@ local $SIG{TSTP} = 'IGNORE'; local $FS::UID::AutoCommit = 0; -my $error = $svc_acct->cancel; -$error ||= $svc_acct->delete; +my $error = $svc_x->cancel; +$error ||= $svc_x->delete; $error ||= $cust_svc->delete; if ( $error ) { diff --git a/httemplate/misc/delete-customer.cgi b/httemplate/misc/delete-customer.cgi index 7016c9166..430231737 100755 --- a/httemplate/misc/delete-customer.cgi +++ b/httemplate/misc/delete-customer.cgi @@ -36,7 +36,7 @@ print <<END; This will <b>completely remove</b> all traces of this customer record. This is <B>not</B> what you want if this is a real customer who has simply canceled service with you. For that, cancel all of the customer's packages. -(you can optionally hide cancelled customers with the <a href="../docs/config.html#hidecancelledcustomers">hidecancelledcustomers</a> configuration file) +(you can optionally hide cancelled customers with the <a href="../config/config-view.cgi#hidecancelledcustomers">hidecancelledcustomers</a> configuration option) <br> <br>Are you <b>absolutely sure</b> you want to delete this customer? <br><input type="submit" value="Yes"> diff --git a/httemplate/misc/delete-domain_record.cgi b/httemplate/misc/delete-domain_record.cgi new file mode 100755 index 000000000..dcc2d5022 --- /dev/null +++ b/httemplate/misc/delete-domain_record.cgi @@ -0,0 +1,15 @@ +<% + +#untaint recnum +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/ || die "Illegal recnum"; +my $recnum = $1; + +my $domain_record = qsearchs('domain_record',{'recnum'=>$recnum}); + +my $error = $domain_record->delete; +eidiot($error) if $error; + +print $cgi->redirect($p. "view/svc_domain.cgi?". $domain_record->svcnum); + +%> diff --git a/httemplate/misc/delete-part_export.cgi b/httemplate/misc/delete-part_export.cgi index 34ef06b96..7c4ab8b9d 100755 --- a/httemplate/misc/delete-part_export.cgi +++ b/httemplate/misc/delete-part_export.cgi @@ -1,6 +1,6 @@ <% -#untaint paynum +#untaint exportnum my($query) = $cgi->keywords; $query =~ /^(\d+)$/ || die "Illegal exportnum"; my $exportnum = $1; diff --git a/httemplate/misc/queue.cgi b/httemplate/misc/queue.cgi index 8c1e5362d..ce9c8fbd3 100644 --- a/httemplate/misc/queue.cgi +++ b/httemplate/misc/queue.cgi @@ -9,7 +9,8 @@ if ( $action eq 'new' || $action eq 'del' ) { $cgi->param('jobnum') =~ /^(\d+)$/ or die "Illegal jobnum"; my $jobnum = $1; $job = qsearchs('queue', { 'jobnum' => $1 }) - or die "unknown jobnum $jobnum"; + or die "unknown jobnum $jobnum - ". + "it probably completed normally or was removed by another user"; } if ( $action eq 'new' ) { 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..421bd98a4 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -206,8 +206,7 @@ print '<BR>'; if ( $cust_main->payby eq 'CARD' ) { my $payinfo = $cust_main->payinfo; - $payinfo = substr($payinfo,0,4). 'x'x(length($payinfo)-4); - + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)); print 'Credit card</TD></TR>', '<TR><TD ALIGN="right">Card number</TD><TD BGCOLOR="#ffffff">', $payinfo, '</TD></TR>', @@ -266,12 +265,37 @@ foreach my $type_pkgs ( qsearch('type_pkgs',{'typenum'=> $agent->typenum }) ) { $part_pkg->comment; } -print '</SELECT><INPUT TYPE="submit" VALUE="Order Package"><BR>'; +print '</SELECT><INPUT TYPE="submit" VALUE="Order Package"></FORM><BR>'; + +print '<BR>'. + qq!<FORM ACTION="${p}edit/process/quick-charge.cgi" METHOD="POST">!. + qq!<INPUT TYPE="hidden" NAME="custnum" VALUE="$custnum">!. + qq!Description:<INPUT TYPE="text" NAME="pkg">!. + qq! Amount:<INPUT TYPE="text" NAME="amount" SIZE=6>!. + qq! !; + +#false laziness w/ edit/part_pkg.cgi +if ( $conf->exists('enable_taxclasses') ) { + print '<SELECT NAME="taxclass">'; + my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') + or die dbh->errstr; + $sth->execute or die $sth->errstr; + foreach my $taxclass ( map $_->[0], @{$sth->fetchall_arrayref} ) { + print qq!<OPTION VALUE="$taxclass"!; + #print ' SELECTED' if $taxclass eq $hashref->{taxclass}; + print qq!>$taxclass</OPTION>!; + } + print '</SELECT>'; +} else { + print '<INPUT TYPE="hidden" NAME="taxclass" VALUE="">'; +} + +print qq!<INPUT TYPE="submit" VALUE="One-time charge"></FORM><BR>!; print <<END; <SCRIPT> function cust_pkg_areyousure(href) { - if (confirm("Permanantly delete included services and cancel this package?") == true) + if (confirm("Permanently delete included services and cancel this package?") == true) window.location.href = href; } </SCRIPT> @@ -364,7 +388,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>', ; @@ -459,7 +484,7 @@ foreach my $bill (@bills) { $payment->payinfo, $cust_bill_pay->amount, ); - $payinfo = substr($payinfo,0,4). 'x'x(length($payinfo)-4) + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) if $payby eq 'CARD'; my $target = "$payby$payinfo"; $payby =~ s/^BILL$/Check #/ if $payinfo; @@ -542,7 +567,7 @@ foreach my $payment (@unapplied_payments) { my $payby = $payment->payby; my $payinfo = $payment->payinfo; #false laziness w/above - $payinfo = substr($payinfo,0,4). 'x'x(length($payinfo)-4) + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) if $payby eq 'CARD'; my $target = "$payby$payinfo"; $payby =~ s/^BILL$/Check #/ if $payinfo; @@ -597,10 +622,10 @@ foreach my $item (sort keyfield_numerically @history) { ( $charge ? "\$".sprintf("%.2f",$charge) : '' ), "</FONT></TD>", "<TD><FONT SIZE=-1>", - ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ), + ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ), "</FONT></TD>", "<TD><FONT SIZE=-1>", - ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ), + ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ), "</FONT></TD>", "<TD><FONT SIZE=-1>", ( $refund ? "\$".sprintf("%.2f",$refund) : '' ), diff --git a/httemplate/view/cust_pkg.cgi b/httemplate/view/cust_pkg.cgi index 75fe983b4..09a2a7a8b 100755 --- a/httemplate/view/cust_pkg.cgi +++ b/httemplate/view/cust_pkg.cgi @@ -38,7 +38,7 @@ my $otaker = $cust_pkg->getfield('otaker'); print <<END; <SCRIPT> function areyousure(href) { - if (confirm("Permanantly delete included services and cancel this package?") == true) + if (confirm("Permanently delete included services and cancel this package?") == true) window.location.href = href; } </SCRIPT> diff --git a/httemplate/view/svc_acct.cgi b/httemplate/view/svc_acct.cgi index fd2a32547..f6c1b026c 100755 --- a/httemplate/view/svc_acct.cgi +++ b/httemplate/view/svc_acct.cgi @@ -39,16 +39,27 @@ if ( $svc_acct->domsvc ) { $domain = $mydomain; } -print header('Account View', menubar( +%> + +<SCRIPT> +function areyousure(href) { + if (confirm("Permanently delete this account?") == true) + window.location.href = href; +} +</SCRIPT> + +<%= header('Account View', menubar( ( ( $pkgnum || $custnum ) ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum", "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum", ) : ( "Cancel this (unaudited) account" => - "${p}misc/cancel-unaudited.cgi?$svcnum" ) + "javascript:areyousure(\'${p}misc/cancel-unaudited.cgi?$svcnum\')" ) ), "Main menu" => $p, -)); +)) %> + +<% #print qq!<BR><A HREF="../misc/sendconfig.cgi?$svcnum">Send account information</A>!; diff --git a/httemplate/view/svc_domain.cgi b/httemplate/view/svc_domain.cgi index 61194a26d..b70ac8f90 100755 --- a/httemplate/view/svc_domain.cgi +++ b/httemplate/view/svc_domain.cgi @@ -30,33 +30,77 @@ if ($svc_domain->catchall) { my $domain = $svc_domain->domain; -print header('Domain View', menubar( +%> + +<%= header('Domain View', menubar( ( ( $pkgnum || $custnum ) ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum", "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum", ) - : ( "Cancel this (unaudited) account" => + : ( "Cancel this (unaudited) domain" => "${p}misc/cancel-unaudited.cgi?$svcnum" ) ), "Main menu" => $p, -)), - "Service #$svcnum", - "<BR>Service: <B>", $part_svc->svc, "</B>", - "<BR>Domain name: <B>$domain</B>.", - qq!<BR>Catch all email <A HREF="${p}misc/catchall.cgi?$svcnum">(change)</A>:!, - $email ? "<B>$email</B>." : "<I>(none)<I>", - qq!<BR><BR><A HREF="http://www.geektools.com/cgi-bin/proxy.cgi?query=$domain;targetnic=auto">View whois information.</A>!, - '<BR><BR>', ntable("",2), - '<tr><th>Zone</th><th>Type</th><th>Data</th></tr>', -; - -foreach my $domain_record ( qsearch('domain_record', { svcnum => $svcnum } ) ) { - print '<tr><td>'. $domain_record->reczone. '</td>'. - '<td>'. $domain_record->recaf. ' '. $domain_record->rectype. '</td>'. - '<td>'. $domain_record->recdata. '</td></tr>'; -} -print '</table>'. - '<BR>'. joblisting({'svcnum'=>$svcnum}, 1). - '</BODY></HTML>'; +)) %> -%> +Service #<%= $svcnum %> +<BR>Service: <B><%= $part_svc->svc %></B> +<BR>Domain name: <B><%= $domain %></B> +<BR>Catch all email <A HREF="${p}misc/catchall.cgi?<%= $svcnum %>">(change)</A>: +<%= $email ? "<B>$email</B>" : "<I>(none)<I>" %> +<BR><BR><A HREF="http://www.geektools.com/cgi-bin/proxy.cgi?query=<%=$domain%>;targetnic=auto">View whois information.</A> +<BR><BR> +<SCRIPT> + function areyousure(href) { + if ( confirm("Remove this record?") == true ) + window.location.href = href; + } +</SCRIPT> + +<% my @records; if ( @records = $svc_domain->domain_record ) { %> + <%= ntable("",2) %> + <tr><th>Zone</th><th>Type</th><th>Data</th></tr> + + <% foreach my $domain_record ( @records ) { + my $type = $domain_record->rectype eq '_mstr' + ? "(slave)" + : $domain_record->recaf. ' '. $domain_record->rectype; + %> + + <tr><td><%= $domain_record->reczone %></td> + <td><%= $type %></td> + <td><%= $domain_record->recdata %> + + <% unless ( $domain_record->rectype eq 'SOA' ) { %> + (<A HREF="javascript:areyousure('<%=$p%>misc/delete-domain_record.cgi?<%=$domain_record->recnum%>')">delete</A>) + <% } %> + </td></tr> + <% } %> + </table> +<% } %> + +<BR> +<FORM METHOD="POST" ACTION="<%=$p%>edit/process/domain_record.cgi"> +<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>"> +<INPUT TYPE="text" NAME="reczone"> +<INPUT TYPE="hidden" NAME="recaf" VALUE="IN"> IN + <SELECT NAME="rectype"> +<% foreach (qw( A NS CNAME MX) ) { %> + <OPTION VALUE="<%=$_%>"><%=$_%></OPTION> +<% } %> + </SELECT> +<INPUT TYPE="text" NAME="recdata"> <INPUT TYPE="submit" VALUE="Add record"> +</FORM><BR><BR>or<BR><BR> +<FORM METHOD="POST" ACTION="<%=$p%>edit/process/domain_record.cgi"> +<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>"> + +<% if ( @records ) { %> Delete all records and <% } %> +Slave from nameserver IP +<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>"> +<INPUT TYPE="hidden" NAME="reczone" VALUE="@"> +<INPUT TYPE="hidden" NAME="recaf" VALUE="IN"> +<INPUT TYPE="hidden" NAME="rectype" VALUE="_mstr"> +<INPUT TYPE="text" NAME="recdata"> <INPUT TYPE="submit" VALUE="Slave domain"> +</FORM> +<BR><BR><%= joblisting({'svcnum'=>$svcnum}, 1) %> +</BODY></HTML> diff --git a/httemplate/view/svc_forward.cgi b/httemplate/view/svc_forward.cgi index 8d2afc823..c8d1d6213 100755 --- a/httemplate/view/svc_forward.cgi +++ b/httemplate/view/svc_forward.cgi @@ -53,9 +53,15 @@ if ($dstsvc) { } print qq!<A HREF="${p}edit/svc_forward.cgi?$svcnum">Edit this information</A>!. - "<BR>Service #$svcnum". - "<BR>Service: <B>$svc</B>". - qq!<BR>Mail to <B>$source</B> forwards to <B>$destination</B> mailbox.!. + ntable("#cccccc",2). + '<TR><TD ALIGN="right">Service number</TD>'. + qq!<TD BGCOLOR="#ffffff">$svcnum</TD></TR>!. + '<TR><TD ALIGN="right">Service</TD>'. + qq!<TD BGCOLOR="#ffffff">$svc</TD></TR>!. + qq!<TR><TD ALIGN="right">Email to</TD>!. + qq!<TD BGCOLOR="#ffffff">$source</TD></TR>!. + qq!<TR><TD ALIGN="right">Forwards to </TD>!. + qq!<TD BGCOLOR="#ffffff">$destination</TD></TR></TABLE>!. '<BR>'. joblisting({'svcnum'=>$svcnum}, 1). '</BODY></HTML>' ; diff --git a/httemplate/view/svc_www.cgi b/httemplate/view/svc_www.cgi index 70a7a1be4..9fa9661b1 100644 --- a/httemplate/view/svc_www.cgi +++ b/httemplate/view/svc_www.cgi @@ -20,8 +20,13 @@ if ($pkgnum) { } #eofalse +my $usersvc = $svc_www->usersvc; +my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $usersvc } ) + or die "svc_www: Unknown usersvc $usersvc"; +my $email = $svc_acct->email; + my $domain_record = qsearchs('domain_record', { 'recnum' => $svc_www->recnum } ) - or die "svc_www: Unknown recnum". $svc_www->recnum; + or die "svc_www: Unknown recnum ". $svc_www->recnum; my $www = $domain_record->reczone; unless ( $www =~ /\.$/ ) { @@ -39,8 +44,15 @@ print header('Website View', menubar( ), "Main menu" => $p, )). - "Service #$svcnum". - qq!<BR>Website name: <B><A HREF="http://$www">$www</A></B>!. + qq!<A HREF="${p}edit/svc_www.cgi?$svcnum">Edit this information</A><BR>!. + ntable("#cccccc"). '<TR><TD>'. ntable("#cccccc",2). + qq!<TR><TD ALIGN="right">Service number</TD>!. + qq!<TD BGCOLOR="#ffffff">$svcnum</TD></TR>!. + qq!<TR><TD ALIGN="right">Website name</TD>!. + qq!<TD BGCOLOR="#ffffff"><A HREF="http://$www">$www<A></TD></TR>!. + qq!<TR><TD ALIGN="right">Account</TD>!. + qq!<TD BGCOLOR="#ffffff"><A HREF="${p}view/svc_acct.cgi?$usersvc">$email</A></TD></TR>!. + '</TABLE></TD></TR></TABLE>'. '<BR>'. joblisting({'svcnum'=>$svcnum}, 1). '</BODY></HTML>' ; |