summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rwxr-xr-xhttemplate/browse/agent.cgi30
-rwxr-xr-xhttemplate/browse/agent_type.cgi24
-rwxr-xr-xhttemplate/browse/part_bill_event.cgi6
-rwxr-xr-xhttemplate/browse/part_export.cgi7
-rwxr-xr-xhttemplate/browse/part_pkg.cgi17
-rwxr-xr-xhttemplate/browse/part_referral.cgi23
-rwxr-xr-xhttemplate/browse/part_svc.cgi21
-rwxr-xr-xhttemplate/browse/svc_acct_pop.cgi8
-rw-r--r--httemplate/config/config-view.cgi4
-rw-r--r--httemplate/config/config.cgi6
-rw-r--r--httemplate/docs/index.html1
-rw-r--r--httemplate/docs/install.html31
-rwxr-xr-xhttemplate/docs/legacy.html1
-rw-r--r--httemplate/docs/schema.diabin11452 -> 14414 bytes
-rw-r--r--httemplate/docs/schema.pngbin496268 -> 681043 bytes
-rw-r--r--httemplate/docs/upgrade8.html3
-rw-r--r--httemplate/docs/upgrade9.html13
-rwxr-xr-xhttemplate/edit/REAL_cust_pkg.cgi19
-rwxr-xr-xhttemplate/edit/cust_main.cgi6
-rwxr-xr-xhttemplate/edit/part_bill_event.cgi24
-rw-r--r--httemplate/edit/part_export.cgi5
-rwxr-xr-xhttemplate/edit/part_pkg.cgi15
-rwxr-xr-xhttemplate/edit/process/REAL_cust_pkg.cgi1
-rwxr-xr-xhttemplate/edit/process/part_bill_event.cgi2
-rw-r--r--httemplate/edit/process/quick-charge.cgi7
-rwxr-xr-xhttemplate/edit/svc_acct.cgi12
-rwxr-xr-xhttemplate/edit/svc_forward.cgi133
-rw-r--r--httemplate/index.html4
-rwxr-xr-xhttemplate/misc/cancel-unaudited.cgi18
-rw-r--r--httemplate/misc/cust_main-import.cgi51
-rw-r--r--httemplate/misc/cust_main-import_charges.cgi14
-rw-r--r--httemplate/misc/process/cust_main-import.cgi30
-rw-r--r--httemplate/misc/process/cust_main-import_charges.cgi26
-rwxr-xr-xhttemplate/misc/unprovision.cgi33
-rwxr-xr-xhttemplate/search/cust_bill.cgi143
-rwxr-xr-xhttemplate/search/cust_pkg.cgi10
-rwxr-xr-xhttemplate/view/cust_main.cgi46
-rwxr-xr-xhttemplate/view/cust_pkg.cgi2
-rwxr-xr-xhttemplate/view/svc_acct.cgi19
-rwxr-xr-xhttemplate/view/svc_domain.cgi2
-rwxr-xr-xhttemplate/view/svc_forward.cgi12
41 files changed, 521 insertions, 308 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 933554cd5..0a06d8ddb 100755
--- a/httemplate/browse/part_svc.cgi
+++ b/httemplate/browse/part_svc.cgi
@@ -24,6 +24,16 @@ 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><% if ( @part_svc ) { %>&nbsp;or&nbsp;<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);
@@ -94,17 +104,6 @@ map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export
%>
</TR>
<% } %>
-
- <TR>
- <TD COLSPAN=<%= $cgi->param('showdisabled') ? 7 : 8 %>>
- <FORM METHOD="POST" ACTION="<%= $p %>edit/part_svc.cgi"><A HREF="<%= $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A>&nbsp;or&nbsp;<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>
- </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/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/index.html b/httemplate/docs/index.html
index 00c863b0c..eaa5b9b92 100644
--- a/httemplate/docs/index.html
+++ b/httemplate/docs/index.html
@@ -11,6 +11,7 @@
<li><a href="upgrade6.html">Upgrading from 1.2.3 to 1.3.0</a>
<li><a href="upgrade7.html">Upgrading from 1.3.0 to 1.3.1</a>
<li><a href="upgrade8.html">Upgrading from 1.3.1 to 1.4.0</a>
+ <li><a href="upgrade9.html">Upgrading from 1.4.0 to 1.4.1</a>
<!--
<li><a href="config.html">Configuration files</a>
!-->
diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html
index 1f271e6d2..75f039dd1 100644
--- a/httemplate/docs/install.html
+++ b/httemplate/docs/install.html
@@ -13,16 +13,17 @@ Before installing, you need:
<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>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>.
+ <li>MySQL versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>. If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list.
+<!-- <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 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>
- <li><a href="http://search.cpan.org/search?dist=Array-PrintCols">Array-PrintCols</a>
- <li><a href="http://search.cpan.org/search?dist=Term-Query">Term-Query</a> (make test broken; install manually)
+<!-- <li><a href="http://search.cpan.org/search?dist=Array-PrintCols">Array-PrintCols</a>
+ <li><a href="http://search.cpan.org/search?dist=Term-Query">Term-Query</a> (make test broken; install manually) -->
<li><a href="http://search.cpan.org/search?dist=MIME-Base64">MIME-Base64</a>
<li><a href="http://search.cpan.org/search?dist=Digest-MD5">Digest-MD5</a>
- <li><a href="http://search.cpan.org/search?dist=MD5">MD5</a>
+<!-- <li><a href="http://search.cpan.org/search?dist=MD5">MD5</a> -->
<li><a href="http://search.cpan.org/search?dist=URI">URI</a>
<li><a href="http://search.cpan.org/search?dist=HTML-Tagset">HTML-Tagset</a>
<li><a href="http://search.cpan.org/search?dist=HTML-Parser">HTML-Parser</a>
@@ -31,7 +32,7 @@ Before installing, you need:
<li><a href="http://search.cpan.org/search?dist=Net-Whois">Net-Whois</a>
<li><a href="http://search.cpan.org/search?dist=libwww-perl">libwww-perl</a>
<li><a href="http://search.cpan.org/search?dist=Business-CreditCard">Business-CreditCard</a>
- <li><a href="http://search.cpan.org/search?dist=Data-ShowTable">Data-ShowTable</a>
+<!-- <li><a href="http://search.cpan.org/search?dist=Data-ShowTable">Data-ShowTable</a> -->
<li><a href="http://search.cpan.org/search?dist=MailTools">MailTools</a>
<li><a href="http://search.cpan.org/search?dist=TimeDate">TimeDate</a>
<li><a href="http://search.cpan.org/search?dist=DateManip">DateManip</a>
@@ -40,23 +41,24 @@ Before installing, you need:
<li><a href="http://search.cpan.org/search?dist=String-Approx">String-Approx</a>
<li><a href="http://search.cpan.org/search?dist=Text-Template">Text-Template</a>
<li><a href="http://search.cpan.org/search?dist=DBI">DBI</a>
- <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL)
+ <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL<!--, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL-->)
<li><a href="http://search.cpan.org/search?dist=DBIx-DataSource">DBIx-DataSource</a>
<li><a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx-DBSchema</a>
<li><a href="http://search.cpan.org/search?dist=Net-SSH">Net-SSH</a>
<li><a href="http://search.cpan.org/search?dist=String-ShellQuote">String-ShellQuote</a>
<li><a href="http://search.cpan.org/search?dist=Net-SCP">Net-SCP</a>
- <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>
+ <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> (use version 1.0x - Freeside is not yet compatible with version 1.1x)
<li><a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a>
<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>
+<!-- MyAccounts, maybe only for dev <li><a href="http://search.cpan.org/search?dist=Cache-Cache">Cache::Cache</a> -->
<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>:
@@ -68,16 +70,17 @@ Enter it again:
Shall the new user be allowed to create databases? (y/n) y
Shall the new user be allowed to create more new users? (y/n) n
CREATE USER</pre>
- <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
+<!-- <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
<pre>
$ mysqladmin -u root password '<i>set_a_root_database_password</i>'
$ mysql -u root -p
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP on freeside.* TO freeside@localhost IDENTIFIED BY '<i>set_a_freeside_database_password</i>';</pre>
+-->
</ul>
<!-- <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.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>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:
@@ -88,9 +91,10 @@ $ su
<pre>
$ su freeside
$ createdb freeside</pre>
- (with MySQL:)
+<!-- (with MySQL:)
<pre>
$ mysqladmin -u freeside -p create freeside </pre>
+-->
<li>Build and install the Perl modules:
<pre>
$ make perl-modules
@@ -135,6 +139,7 @@ PerlSetVar Debug 2
</pre></font>
</ul></td>
<td><ul>
+ <li>(use version 1.0x - Freeside is not yet compatible with version 1.1x)
<li>Run <tt>make masondocs</tt>
<li>Copy <tt>masondocs/</tt> to your web server's document space.
<li>Copy <tt>htetc/handler.pl</tt> to your web server's configuration directory.
@@ -187,7 +192,7 @@ $ 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 systemand QUEUED_USER with the username of a Freeside user you created above, 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 161690b62..2db9edb0f 100755
--- a/httemplate/docs/legacy.html
+++ b/httemplate/docs/legacy.html
@@ -4,6 +4,7 @@
<body>
<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>
+<br><br><i>Some import scripts may require installation of the <a href="http://search.cpan.org/search?dist=Array-PrintCols">Array-PrintCols</a> and <a href="http://search.cpan.org/search?dist=Term-Query">Term-Query</a> (make test broken; install manually) modules.</i><br>
<ul>
<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.
diff --git a/httemplate/docs/schema.dia b/httemplate/docs/schema.dia
index c22a470e0..092d2f88b 100644
--- a/httemplate/docs/schema.dia
+++ b/httemplate/docs/schema.dia
Binary files differ
diff --git a/httemplate/docs/schema.png b/httemplate/docs/schema.png
index ba22f59c2..d0392e76f 100644
--- a/httemplate/docs/schema.png
+++ b/httemplate/docs/schema.png
Binary files differ
diff --git a/httemplate/docs/upgrade8.html b/httemplate/docs/upgrade8.html
index 75155407c..0210430ef 100644
--- a/httemplate/docs/upgrade8.html
+++ b/httemplate/docs/upgrade8.html
@@ -8,7 +8,7 @@
<li><font size="+2" color="#ff0000">Backup your database and current Freeside installation.</font> (with&nbsp;<a href="http://www.ca.postgresql.org/devel-corner/docs/postgres/backup.html">PostgreSQL</a>) (with&nbsp;<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> (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://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> (use version 1.0x - Freeside is not yet compatible with version 1.1x).
<li>Install <a href="http://rsync.samba.org/">rsync</a>
</ul>
<table>
@@ -36,6 +36,7 @@ PerlSetVar Global /usr/local/etc/freeside/asp-global/
</pre></font>
</ul></td>
<td><ul>
+ <li>(use version 1.0x - Freeside is not yet compatible with version 1.1x)
<li>Run <tt>make masondocs</tt>
<li>Copy <tt>masondocs/</tt> to your web server's document space.
<li>Copy <tt>htetc/handler.pl</tt> to your web server's configuration directory.
diff --git a/httemplate/docs/upgrade9.html b/httemplate/docs/upgrade9.html
new file mode 100644
index 000000000..fff1d8690
--- /dev/null
+++ b/httemplate/docs/upgrade9.html
@@ -0,0 +1,13 @@
+<head>
+ <title>Upgrading to 1.4.1</title>
+</head>
+<body>
+<h1>Upgrading to 1.4.1 from 1.4.0</h1>
+<ul>
+ <li>If migrating from less than 1.4.0, see these <a href="upgrade8.html">instructions</a> first.
+ <li>Back up your data and current Freeside installation.
+ <li>Run <code>make aspdocs</code> or <code>make masondocs</code>.
+ <li>Copy <code>aspdocs/</code> or <code>masondocs/</code> to your web server's document space.
+ <li>Run <code>make install-perl-modules</code>.
+ <li>Restart Apache and freeside-queued.
+</body>
diff --git a/httemplate/edit/REAL_cust_pkg.cgi b/httemplate/edit/REAL_cust_pkg.cgi
index 580313e88..0d2f1c238 100755
--- a/httemplate/edit/REAL_cust_pkg.cgi
+++ b/httemplate/edit/REAL_cust_pkg.cgi
@@ -1,6 +1,6 @@
<!-- mason kludge -->
<%
-# <!-- $Id: REAL_cust_pkg.cgi,v 1.3 2002-04-23 07:32:49 ivan Exp $ -->
+# <!-- $Id: REAL_cust_pkg.cgi,v 1.4 2002-07-08 13:07:40 ivan Exp $ -->
my $error ='';
my $pkgnum = '';
@@ -45,7 +45,7 @@ print '<FORM NAME="formname" ACTION="process/REAL_cust_pkg.cgi" METHOD="POST">',
print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT>!
if $error;
-print &ntable("#cccccc"), '<TR><TD>', &ntable("#cccccc",2),
+print ntable("#cccccc",2),
'<TR><TD ALIGN="right">Package number</TD><TD BGCOLOR="#ffffff">',
$pkgnum, '</TD></TR>',
'<TR><TD ALIGN="right">Package</TD><TD BGCOLOR="#ffffff">',
@@ -66,16 +66,23 @@ print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">',
time2str("%D",$susp), '</TD></TR>'
if $susp;
-print '<TR><TD ALIGN="right">Expiration date</TD><TD BGCOLOR="#ffffff">',
- time2str("%D",$expire), '</TD></TR>'
- if $expire;
+#print '<TR><TD ALIGN="right">Expiration date</TD><TD BGCOLOR="#ffffff">',
+# time2str("%D",$expire), '</TD></TR>'
+# if $expire;
+print '<TR><TD ALIGN="right">Expiration date'.
+ '</TD><TD>',
+ '<INPUT TYPE="text" NAME="expire" SIZE=32 VALUE="',
+ ( $expire ? time2str("%c %z (%Z)",$expire) : "" ), '">'.
+ '<BR><FONT SIZE=-1>(will <b>cancel</b> this package'.
+ ' when the date is reached)</FONT>'.
+ '</TD></TR>';
print '<TR><TD ALIGN="right">Cancellation date</TD><TD BGCOLOR="#ffffff">',
time2str("%D",$cancel), '</TD></TR>'
if $cancel;
%>
-</TABLE></TD></TR></TABLE>
+</TABLE>
<BR><INPUT TYPE="submit" VALUE="Apply Changes">
</FORM>
</BODY>
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
index cf8de2f13..3a5df086f 100755
--- a/httemplate/edit/cust_main.cgi
+++ b/httemplate/edit/cust_main.cgi
@@ -73,7 +73,7 @@ my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
my @agents = qsearch( 'agent', {} );
#die "No agents created!" unless @agents;
-die "You have not created any agents. You must create at least one agent before adding a customer. Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents;
+eidiot "You have not created any agents. You must create at least one agent before adding a customer. Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents;
my $agentnum = $cust_main->agentnum || $agents[0]->agentnum; #default to first
if ( scalar(@agents) == 1 ) {
print qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$agentnum">!;
@@ -99,7 +99,7 @@ if ( $custnum && ! $conf->exists('editreferrals') ) {
} else {
my(@referrals) = qsearch('part_referral',{});
if ( scalar(@referrals) == 0 ) {
- die "You have not created any advertising sources. You must create at least one advertising source before adding a customer. Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources.";
+ eidiot "You have not created any advertising sources. You must create at least one advertising source before adding a customer. Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources.";
} elsif ( scalar(@referrals) == 1 ) {
$refnum ||= $referrals[0]->refnum;
print qq!<INPUT TYPE="hidden" NAME="refnum" VALUE="$refnum">!;
@@ -231,7 +231,7 @@ END
print '<BR>Service address ',
'(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)"';
- unless ( $cust_main->ship_last ) {
+ unless ( $cust_main->ship_last && $cgi->param('same') ne 'Y' ) {
print ' CHECKED';
foreach (
qw( last first company address1 address2 city county state zip country
diff --git a/httemplate/edit/part_bill_event.cgi b/httemplate/edit/part_bill_event.cgi
index 324daeb90..a10a186a9 100755
--- a/httemplate/edit/part_bill_event.cgi
+++ b/httemplate/edit/part_bill_event.cgi
@@ -134,6 +134,30 @@ tie my %events, 'Tie::IxHash',
'weight' => 50,
},
+ 'send_csv_ftp' => {
+ 'name' => 'Upload CSV invoice data to an FTP server',
+ 'code' => '$cust_bill->send_csv( protocol => \'ftp\',
+ server => \'%%%ftpserver%%%\',
+ username => \'%%%ftpusername%%%\',
+ password => \'%%%ftppassword%%%\',
+ dir => \'%%%ftpdir%%%\' );',
+ 'html' =>
+ '<TABLE BORDER=0><TR><TD ALIGN="right">FTP server: </TD>'.
+ '<TD><INPUT TYPE="text" NAME="ftpserver" VALUE="%%%ftpserver%%%">'.
+ '</TD></TR>'.
+ '<TR><TD ALIGN="right">FTP username: </TD><TD>'.
+ '<INPUT TYPE="text" NAME="ftpusername" VALUE="%%%ftpusername%%%">'.
+ '</TD></TR>'.
+ '<TR><TD ALIGN="right">FTP password: </TD><TD>'.
+ '<INPUT TYPE="text" NAME="ftppassword" VALUE="%%%ftppassword%%%">'.
+ '</TD></TR>'.
+ '<TR><TD ALIGN="right">FTP directory: </TD>'.
+ '<TD><INPUT TYPE="text" NAME="ftpdir" VALUE="%%%ftpdir%%%">'.
+ '</TD></TR>'.
+ '</TABLE>',
+ 'weight' => 50,
+ },
+
'bill' => {
'name' => 'Generate invoices (normally only used with a <i>Late Fee</i> event)',
'code' => '$cust_main->bill();',
diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi
index 486bd4300..bd427aa40 100644
--- a/httemplate/edit/part_export.cgi
+++ b/httemplate/edit/part_export.cgi
@@ -50,7 +50,10 @@ my $widget = new HTML::Widgets::SelectLayers(
my $type = defined($optinfo->{type}) ? $optinfo->{type} : 'text';
my $value = $cgi->param($option)
|| $part_export->option($option)
- || (exists $optinfo->{default} ? $optinfo->{default} : '');
+ || ( (exists $optinfo->{default} && !$part_export->exportnum)
+ ? $optinfo->{default}
+ : ''
+ );
$html .= qq!<TR><TD ALIGN="right">$label</TD><TD>!;
if ( $type eq 'select' ) {
$html .= qq!<SELECT NAME="$option">!;
diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi
index 19545bd12..38d7358a5 100755
--- a/httemplate/edit/part_pkg.cgi
+++ b/httemplate/edit/part_pkg.cgi
@@ -67,7 +67,7 @@ print '<FORM NAME="dummy">';
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">Package (customer-visible)</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>&nbsp;&nbsp;<I>0=no recurring fee, 1=monthly, 3=quarterly, 12=yearly</TD></TR>
<TR><TD ALIGN="right">Setup fee tax exempt</TD><TD>
@@ -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/process/REAL_cust_pkg.cgi b/httemplate/edit/process/REAL_cust_pkg.cgi
index 6bed85c19..2e0352c76 100755
--- a/httemplate/edit/process/REAL_cust_pkg.cgi
+++ b/httemplate/edit/process/REAL_cust_pkg.cgi
@@ -5,6 +5,7 @@ my $old = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
my %hash = $old->hash;
$hash{'setup'} = $cgi->param('setup') ? str2time($cgi->param('setup')) : '';
$hash{'bill'} = $cgi->param('bill') ? str2time($cgi->param('bill')) : '';
+$hash{'expire'} = $cgi->param('expire') ? str2time($cgi->param('expire')) : '';
my $new = new FS::cust_pkg \%hash;
my $error = $new->replace($old);
diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi
index 4049ade80..e224bf634 100755
--- a/httemplate/edit/process/part_bill_event.cgi
+++ b/httemplate/edit/process/part_bill_event.cgi
@@ -12,7 +12,7 @@ if ( ! $cgi->param('plan_weight_eventcode') ) {
$error = "Must select an action";
} else {
- $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/
+ $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s
or die "illegal plan_weight_eventcode:".
$cgi->param('plan_weight_eventcode');
$cgi->param('plan', $1);
diff --git a/httemplate/edit/process/quick-charge.cgi b/httemplate/edit/process/quick-charge.cgi
index 49175d848..477f58508 100644
--- a/httemplate/edit/process/quick-charge.cgi
+++ b/httemplate/edit/process/quick-charge.cgi
@@ -12,7 +12,12 @@ 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') );
+my $error = $cust_main->charge(
+ $amount,
+ $cgi->param('pkg'),
+ '$'. sprintf("%.2f",$amount),
+ $cgi->param('taxclass')
+);
if ($error) {
%>
diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi
index eca0a31cf..90b26324a 100755
--- a/httemplate/edit/svc_acct.cgi
+++ b/httemplate/edit/svc_acct.cgi
@@ -12,8 +12,8 @@ if ( $cgi->param('error') ) {
$svcnum = $svc_acct->svcnum;
$pkgnum = $cgi->param('pkgnum');
$svcpart = $cgi->param('svcpart');
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
- die "No part_svc entry!" unless $part_svc;
+ $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
+ die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
@groups = $cgi->param('radius_usergroup');
} else {
my($query) = $cgi->keywords;
@@ -28,8 +28,8 @@ if ( $cgi->param('error') ) {
$pkgnum=$cust_svc->pkgnum;
$svcpart=$cust_svc->svcpart;
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
- die "No part_svc entry!" unless $part_svc;
+ $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
+ die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
@groups = $svc_acct->radius_groups;
@@ -41,8 +41,8 @@ if ( $cgi->param('error') ) {
$pkgnum=$1 if /^pkgnum(\d+)$/;
$svcpart=$1 if /^svcpart(\d+)$/;
}
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
- die "No part_svc entry!" unless $part_svc;
+ $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
+ die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
$svcnum='';
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/index.html b/httemplate/index.html
index 29dd3b471..dce020b1b 100644
--- a/httemplate/index.html
+++ b/httemplate/index.html
@@ -11,7 +11,7 @@
</td><td>
<font color="#ff0000" size=7>freeside main menu</font>
</td><td align=right valign=bottom>
- version 1.4.0
+ version %%%VERSION%%%
<BR><A HREF="http://www.sisd.com/freeside">Freeside home page</A>
<BR><A HREF="docs/">Documentation</A>
</td></tr>
@@ -166,6 +166,8 @@
<BR>
<A HREF="browse/nas.cgi">View active NAS ports</A>
<BR><A HREF="browse/queue.cgi">View pending job queue</A>
+ <BR><A HREF="misc/cust_main-import.cgi">Batch import customers from CSV file</A>
+ <BR><A HREF="misc/cust_main-import_charges.cgi">Batch import charges from CSV file</A>
<BR><BR><CENTER><HR WIDTH="94%" NOSHADE></CENTER><BR>
<A NAME="config" HREF="config/config-view.cgi">Configuration</a><!-- - <font size="+2" color="#ff0000">start here</font> -->
<BR><BR><A NAME="admin">Administration</a>
diff --git a/httemplate/misc/cancel-unaudited.cgi b/httemplate/misc/cancel-unaudited.cgi
index f1fb15341..11cde968d 100755
--- a/httemplate/misc/cancel-unaudited.cgi
+++ b/httemplate/misc/cancel-unaudited.cgi
@@ -17,30 +17,14 @@ die "Unknown svcnum!" unless $cust_svc;
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';
-local $SIG{TERM} = 'IGNORE';
-local $SIG{TSTP} = 'IGNORE';
-
-local $FS::UID::AutoCommit = 0;
-
-my $error = $svc_x->cancel;
-$error ||= $svc_x->delete;
-$error ||= $cust_svc->delete;
+my $error = $cust_svc->cancel;
if ( $error ) {
- $dbh->rollback;
%>
<!-- mason kludge -->
<%
&eidiot($error);
} else {
-
- $dbh->commit or die $dbh->errstr;
-
print $cgi->redirect(popurl(2));
}
diff --git a/httemplate/misc/cust_main-import.cgi b/httemplate/misc/cust_main-import.cgi
new file mode 100644
index 000000000..6b36f478d
--- /dev/null
+++ b/httemplate/misc/cust_main-import.cgi
@@ -0,0 +1,51 @@
+<!-- mason kludge -->
+<%= header('Batch Customer Import') %>
+<FORM ACTION="process/cust_main-import.cgi" METHOD="post" ENCTYPE="multipart/form-data">
+Import a CSV file containing customer records.<BR><BR>
+Default file format is CSV, with the following field order: <i>cust_pkg.setup, dayphone, first, last, address1, address2, city, state, zip, comments</i><BR><BR>
+
+<%
+ #false laziness with edit/cust_main.cgi
+ my @agents = qsearch( 'agent', {} );
+ die "No agents created!" unless @agents;
+ my $agentnum = $agents[0]->agentnum; #default to first
+
+ if ( scalar(@agents) == 1 ) {
+%>
+ <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
+<% } else { %>
+ <BR><BR>Agent <SELECT NAME="agentnum" SIZE="1">
+ <% foreach my $agent (sort { $a->agent cmp $b->agent } @agents) { %>
+ <OPTION VALUE="<%= $agent->agentnum %>" <%= " SELECTED"x($agent->agentnum==$agentnum) %>><%= $agent->agent %></OPTION>
+ <% } %>
+ </SELECT><BR><BR>
+<% } %>
+
+<%
+ my @referrals = qsearch('part_referral',{});
+ die "No advertising sources created!" unless @referrals;
+ my $refnum = $referrals[0]->refnum; #default to first
+
+ if ( scalar(@referrals) == 1 ) {
+%>
+ <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
+<% } else { %>
+ <BR><BR>Advertising source <SELECT NAME="refnum" SIZE="1">
+ <% foreach my $referral ( sort { $a->referral <=> $b->referral } @referrals) { %>
+ <OPTION VALUE="<%= $referral->refnum %>" <%= " SELECTED"x($referral->refnum==$refnum) %>><%= $referral->refnum %>: <%= $referral->referral %></OPTION>
+ <% } %>
+ </SELECT><BR><BR>
+<% } %>
+
+ First package: <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION>
+<% foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { %>
+ <OPTION VALUE="<%= $part_pkg->pkgpart %>"><%= $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION>
+<% } %>
+</SELECT><BR><BR>
+
+ CSV Filename: <INPUT TYPE="file" NAME="csvfile"><BR><BR>
+ <INPUT TYPE="submit" VALUE="Import">
+ </FORM>
+ </BODY>
+<HTML>
+
diff --git a/httemplate/misc/cust_main-import_charges.cgi b/httemplate/misc/cust_main-import_charges.cgi
new file mode 100644
index 000000000..0822b9eb6
--- /dev/null
+++ b/httemplate/misc/cust_main-import_charges.cgi
@@ -0,0 +1,14 @@
+<!-- mason kludge -->
+<%= header('Batch Customer Charge') %>
+<FORM ACTION="process/cust_main-import_charges.cgi" METHOD="post" ENCTYPE="multipart/form-data">
+Import a CSV file containing customer charges.<BR><BR>
+Default file format is CSV, with the following field order: <i>custnum, amount, description</i><BR><BR>
+If <i>amount</i> is negative, a credit will be applied instead.<BR><BR>
+<BR><BR>
+
+ CSV Filename: <INPUT TYPE="file" NAME="csvfile"><BR><BR>
+ <INPUT TYPE="submit" VALUE="Import">
+ </FORM>
+ </BODY>
+<HTML>
+
diff --git a/httemplate/misc/process/cust_main-import.cgi b/httemplate/misc/process/cust_main-import.cgi
new file mode 100644
index 000000000..9e1adce54
--- /dev/null
+++ b/httemplate/misc/process/cust_main-import.cgi
@@ -0,0 +1,30 @@
+<%
+
+ my $fh = $cgi->upload('csvfile');
+ #warn $cgi;
+ #warn $fh;
+
+ my $error = defined($fh)
+ ? FS::cust_main::batch_import( {
+ filehandle => $fh,
+ agentnum => scalar($cgi->param('agentnum')),
+ refnum => scalar($cgi->param('refnum')),
+ pkgpart => scalar($cgi->param('pkgpart')),
+ 'fields' => [qw( cust_pkg.setup dayphone first last address1 address2
+ city state zip comments )],
+ } )
+ : 'No file';
+
+ if ( $error ) {
+ %>
+ <!-- mason kludge -->
+ <%
+ eidiot($error);
+# $cgi->param('error', $error);
+# print $cgi->redirect( "${p}cust_main-import.cgi
+ } else {
+ %>
+ <!-- mason kludge -->
+ <%= header('Import sucessful') %> <%
+ }
+%>
diff --git a/httemplate/misc/process/cust_main-import_charges.cgi b/httemplate/misc/process/cust_main-import_charges.cgi
new file mode 100644
index 000000000..14df1bd8d
--- /dev/null
+++ b/httemplate/misc/process/cust_main-import_charges.cgi
@@ -0,0 +1,26 @@
+<%
+
+ my $fh = $cgi->upload('csvfile');
+ #warn $cgi;
+ #warn $fh;
+
+ my $error = defined($fh)
+ ? FS::cust_main::batch_charge( {
+ filehandle => $fh,
+ 'fields' => [qw( custnum amount pkg )],
+ } )
+ : 'No file';
+
+ if ( $error ) {
+ %>
+ <!-- mason kludge -->
+ <%
+ eidiot($error);
+# $cgi->param('error', $error);
+# print $cgi->redirect( "${p}cust_main-import_charges.cgi
+ } else {
+ %>
+ <!-- mason kludge -->
+ <%= header('Import sucessful') %> <%
+ }
+%>
diff --git a/httemplate/misc/unprovision.cgi b/httemplate/misc/unprovision.cgi
new file mode 100755
index 000000000..8f2a7d13d
--- /dev/null
+++ b/httemplate/misc/unprovision.cgi
@@ -0,0 +1,33 @@
+<%
+
+my $dbh = dbh;
+
+#untaint svcnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $svcnum = $1;
+
+#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 $custnum = $cust_svc->cust_pkg->custnum;
+
+my $error = $cust_svc->cancel;
+
+if ( $error ) {
+ %>
+<!-- mason kludge -->
+<%
+ &eidiot($error);
+} else {
+ print $cgi->redirect(popurl(2)."view/cust_main.cgi?$custnum");
+}
+
+%>
diff --git a/httemplate/search/cust_bill.cgi b/httemplate/search/cust_bill.cgi
index d83851804..586399a41 100755
--- a/httemplate/search/cust_bill.cgi
+++ b/httemplate/search/cust_bill.cgi
@@ -1,52 +1,60 @@
<%
-my(@cust_bill, $sortby);
+my $conf = new FS::Conf;
+my $maxrecords = $conf->config('maxsearchrecordsperpage');
+
+my $orderby = ''; #removeme
+
+my $limit = '';
+$limit .= "LIMIT $maxrecords" if $maxrecords;
+
+my $offset = $cgi->param('offset') || 0;
+$limit .= " OFFSET $offset" if $offset;
+
+my $total;
+
+my(@cust_bill);
if ( $cgi->keywords ) {
my($query) = $cgi->keywords;
- if ( $query eq 'invnum' ) {
- $sortby = \*invnum_sort;
- @cust_bill = qsearch('cust_bill', {} );
- } elsif ( $query eq 'date' ) {
- $sortby = \*date_sort;
- @cust_bill = qsearch('cust_bill', {} );
- } elsif ( $query eq 'custnum' ) {
- $sortby = \*custnum_sort;
- @cust_bill = qsearch('cust_bill', {} );
- } elsif ( $query eq 'OPEN_invnum' ) {
- $sortby = \*invnum_sort;
- @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
- } elsif ( $query eq 'OPEN_date' ) {
- $sortby = \*date_sort;
- @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
- } elsif ( $query eq 'OPEN_custnum' ) {
- $sortby = \*custnum_sort;
- @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
- } elsif ( $query =~ /^OPEN(\d+)_invnum$/ ) {
- my $open = $1 * 86400;
- $sortby = \*invnum_sort;
- @cust_bill =
- grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
- } elsif ( $query =~ /^OPEN(\d+)_date$/ ) {
- my $open = $1 * 86400;
- $sortby = \*date_sort;
- @cust_bill =
- grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
- } elsif ( $query =~ /^OPEN(\d+)_custnum$/ ) {
- my $open = $1 * 86400;
- $sortby = \*custnum_sort;
- @cust_bill =
- grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+ my $owed = "charged - ( select coalesce(sum(amount),0) from cust_bill_pay
+ where cust_bill_pay.invnum = cust_bill.invnum )
+ - ( select coalesce(sum(amount),0) from cust_credit_bill
+ where cust_credit_bill.invnum = cust_bill.invnum )";
+ my @where;
+ if ( $query =~ /^(OPEN(\d*)_)?(invnum|date|custnum)$/ ) {
+ my($open, $days, $field) = ($1, $2, $3);
+ $field = "_date" if $field eq 'date';
+ $orderby = "ORDER BY cust_bill.$field";
+ push @where, "0 != $owed" if $open;
+ push @where, "cust_bill._date < ". (time-86400*$days) if $days;
} else {
die "unknown query string $query";
}
+
+ my $extra_sql = scalar(@where) ? 'WHERE '. join(' AND ', @where) : '';
+
+ my $statement = "SELECT COUNT(*), sum(charged), sum($owed)
+ FROM cust_bill $extra_sql";
+ my $sth = dbh->prepare($statement) or die dbh->errstr. " doing $statement";
+ $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
+
+ ( $total, $tot_amount, $tot_balance ) = @{$sth->fetchrow_arrayref};
+
+ @cust_bill = qsearch(
+ 'cust_bill',
+ {},
+ "cust_bill.*, $owed as owed",
+ "$extra_sql $orderby $limit"
+ );
} else {
$cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/;
my $invnum = $2;
@cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum } );
- $sortby = \*invnum_sort;
+ $total = scalar(@cust_bill);
}
-if ( scalar(@cust_bill) == 1 ) {
+#if ( scalar(@cust_bill) == 1 ) {
+if ( $total == 1 ) {
my $invnum = $cust_bill[0]->invnum;
print $cgi->redirect(popurl(2). "view/cust_bill.cgi?$invnum"); #redirect
} elsif ( scalar(@cust_bill) == 0 ) {
@@ -58,10 +66,41 @@ if ( scalar(@cust_bill) == 1 ) {
%>
<!-- mason kludge -->
<%
- my $total = scalar(@cust_bill);
+
+ #begin pager
+ my $pager = '';
+ if ( $total != scalar(@cust_bill) && $maxrecords ) {
+ unless ( $offset == 0 ) {
+ $cgi->param('offset', $offset - $maxrecords);
+ $pager .= '<A HREF="'. $cgi->self_url.
+ '"><B><FONT SIZE="+1">Previous</FONT></B></A> ';
+ }
+ my $poff;
+ my $page;
+ for ( $poff = 0; $poff < $total; $poff += $maxrecords ) {
+ $page++;
+ if ( $offset == $poff ) {
+ $pager .= qq!<FONT SIZE="+2">$page</FONT> !;
+ } else {
+ $cgi->param('offset', $poff);
+ $pager .= qq!<A HREF="!. $cgi->self_url. qq!">$page</A> !;
+ }
+ }
+ unless ( $offset + $maxrecords > $total ) {
+ $cgi->param('offset', $offset + $maxrecords);
+ $pager .= '<A HREF="'. $cgi->self_url.
+ '"><B><FONT SIZE="+1">Next</FONT></B></A> ';
+ }
+ }
+ #end pager
+
print header("Invoice Search Results", menubar(
'Main Menu', popurl(2)
- )), "$total matching invoices found<BR>", &table(), <<END;
+ )).
+ "$total matching invoices found<BR>".
+ "\$$tot_balance total balance<BR>".
+ "\$$tot_amount total amount<BR>".
+ "<BR>$pager". table(). <<END;
<TR>
<TH></TH>
<TH>Balance</TH>
@@ -72,22 +111,15 @@ if ( scalar(@cust_bill) == 1 ) {
</TR>
END
- my(%saw, $cust_bill);
- my($tot_balance, $tot_amount) = (0, 0);
- foreach $cust_bill (
- sort $sortby grep(!$saw{$_->invnum}++, @cust_bill)
- ) {
+ foreach my $cust_bill ( @cust_bill ) {
my($invnum, $owed, $charged, $date ) = (
$cust_bill->invnum,
- sprintf("%.2f", $cust_bill->owed),
+ sprintf("%.2f", $cust_bill->getfield('owed')),
sprintf("%.2f", $cust_bill->charged),
$cust_bill->_date,
);
my $pdate = time2str("%b %d %Y", $date);
- $tot_balance += $owed;
- $tot_amount += $charged;
-
my $rowspan = 1;
my $view = popurl(2). "view/cust_bill.cgi?$invnum";
@@ -120,8 +152,8 @@ END
}
$tot_balance = sprintf("%.2f", $tot_balance);
$tot_amount = sprintf("%.2f", $tot_amount);
- print <<END;
- <TR><TD></TD><TH><FONT SIZE=-1>Total</FONT></TH><TH><FONT SIZE=-1>Total</FONT></TH></TR>
+ print "</TABLE>$pager<BR>". table(). <<END;
+ <TR><TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD><TH><FONT SIZE=-1>Total<BR>Balance</FONT></TH><TH><FONT SIZE=-1>Total<BR>Amount</FONT></TH></TR>
<TR><TD></TD><TD ALIGN="right"><FONT SIZE=-1>\$$tot_balance</FONT></TD><TD ALIGN="right"><FONT SIZE=-1>\$$tot_amount</FONT></TD></TD></TR>
</TABLE>
</BODY>
@@ -130,17 +162,4 @@ END
}
-#
-
-sub invnum_sort {
- $a->invnum <=> $b->invnum;
-}
-
-sub custnum_sort {
- $a->custnum <=> $b->custnum || $a->invnum <=> $b->invnum;
-}
-
-sub date_sort {
- $a->_date <=> $b->_date || $a->invnum <=> $b->invnum;
-}
%>
diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi
index abf6eee4c..5f0782b8c 100755
--- a/httemplate/search/cust_pkg.cgi
+++ b/httemplate/search/cust_pkg.cgi
@@ -263,11 +263,11 @@ END
my $p = popurl(2);
print $n1, <<END;
<TD ROWSPAN=$rowspan><A HREF="${p}view/cust_pkg.cgi?$pkgnum"><FONT SIZE=-1>$pkgnum - $pkg</FONT></A></TD>
- <TD>$setup</TD>
- <TD>$bill</TD>
- <TD>$susp</TD>
- <TD>$expire</TD>
- <TD>$cancel</TD>
+ <TD ROWSPAN=$rowspan>$setup</TD>
+ <TD ROWSPAN=$rowspan>$bill</TD>
+ <TD ROWSPAN=$rowspan>$susp</TD>
+ <TD ROWSPAN=$rowspan>$expire</TD>
+ <TD ROWSPAN=$rowspan>$cancel</TD>
END
if ( $cust_main ) {
print <<END;
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 479648183..0610bc324 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -241,9 +241,10 @@ print '</TD></TR></TABLE>';
if ( defined $cust_main->dbdef_table->column('comments')
&& $cust_main->comments )
{
- print "<BR>Comments", &ntable("#cccccc"), "<TR><TD>",
- &ntable("#cccccc",2),
- '<TR><TD BGCOLOR="#ffffff"><PRE>', $cust_main->comments,
+ print "<BR>Comments". &ntable("#cccccc"). "<TR><TD>".
+ &ntable("#cccccc",2).
+ '<TR><TD BGCOLOR="#ffffff"><PRE>'.
+ encode_entities($cust_main->comments).
'</PRE></TD></TR></TABLE></TABLE>';
}
@@ -271,13 +272,35 @@ 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!&nbsp;<INPUT TYPE="submit" VALUE="One-time charge"></FORM><BR>!;
+ qq!&nbsp;Amount:<INPUT TYPE="text" NAME="amount" SIZE=6>!.
+ qq!&nbsp;!;
+
+#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;
+}
+function svc_areyousure(href) {
+ if (confirm("Permanently unprovision and delete this service?") == true)
window.location.href = href;
}
</SCRIPT>
@@ -382,6 +405,7 @@ foreach my $package (@packages) {
#foreach my $cust_svc ( @cust_svc ) {
foreach my $svcpart ( sort { $a<=>$b } keys %pkg_svc ) {
my $svc = qsearchs('part_svc',{'svcpart'=>$svcpart})->getfield('svc');
+ $svc =~ s/ /&nbsp;/g;
my(@cust_svc)=qsearch('cust_svc',{'pkgnum'=>$pkgnum,
'svcpart'=>$svcpart,
});
@@ -392,13 +416,13 @@ foreach my $package (@packages) {
my($svcnum) = $cust_svc->svcnum;
my($sview) = popurl(2). "view";
print $n2,qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
- qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
+ qq!<TD><FONT SIZE=-1><A HREF="$sview/$svcdb.cgi?$svcnum">$value</A><BR>(&nbsp;<A HREF="javascript:svc_areyousure('${p}misc/unprovision.cgi?$svcnum')">Unprovision</A>&nbsp;)</FONT></TD>!;
} else {
print $n2, qq!<TD COLSPAN=2><A HREF="$uiadd{$svcpart}?pkgnum$pkgnum-svcpart$svcpart"><b><font size="+1" color="#ff0000">!.
- qq!Provision $svc</A></b></font>!;
+ qq!Provision&nbsp;$svc</A></b></font>!;
print qq!<BR><A HREF="../misc/link.cgi?pkgnum$pkgnum-svcpart$svcpart">!.
- qq!<b><font size="+1" color="#ff0000">Link to legacy $svc</A></b></font>!
+ qq!<b><font size="+1" color="#ff0000">Link&nbsp;to&nbsp;legacy&nbsp;$svc</A></b></font>!
if $conf->exists('legacy_link');
print '</TD>';
@@ -604,10 +628,10 @@ foreach my $item (sort keyfield_numerically @history) {
( $charge ? "\$".sprintf("%.2f",$charge) : '' ),
"</FONT></TD>",
"<TD><FONT SIZE=-1>",
- ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ),
+ ( $payment ? "-&nbsp;\$".sprintf("%.2f",$payment) : '' ),
"</FONT></TD>",
"<TD><FONT SIZE=-1>",
- ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ),
+ ( $credit ? "-&nbsp;\$".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..19953bafd 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>!;
@@ -72,7 +83,7 @@ if ( $password =~ /^\*\w+\* (.*)$/ ) {
print "<I>(login disabled)</I> ";
}
if ( $conf->exists('showpasswords') ) {
- print "$password";
+ print '<PRE>'. encode_entities($password). '</PRE>';
} else {
print "<I>(hidden)</I>";
}
diff --git a/httemplate/view/svc_domain.cgi b/httemplate/view/svc_domain.cgi
index b70ac8f90..cc3cdb6bf 100755
--- a/httemplate/view/svc_domain.cgi
+++ b/httemplate/view/svc_domain.cgi
@@ -46,7 +46,7 @@ my $domain = $svc_domain->domain;
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>:
+<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>
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>'
;