summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/browse/access_user.html87
-rwxr-xr-xhttemplate/browse/agent.cgi114
-rwxr-xr-xhttemplate/browse/part_pkg.cgi2
-rwxr-xr-xhttemplate/browse/part_referral.html (renamed from httemplate/browse/part_referral.cgi)75
-rw-r--r--httemplate/config/config.cgi2
-rw-r--r--httemplate/docs/index.html6
-rw-r--r--httemplate/docs/install-rt.html78
-rw-r--r--httemplate/docs/install.html173
-rwxr-xr-xhttemplate/docs/trouble.html26
-rw-r--r--httemplate/docs/upgrade-1.4.2.html27
-rw-r--r--httemplate/docs/upgrade10.html115
-rw-r--r--httemplate/docs/upgrade9.html28
-rw-r--r--httemplate/edit/access_user.html2
-rwxr-xr-xhttemplate/edit/cust_credit.cgi4
-rwxr-xr-xhttemplate/edit/cust_main.cgi88
-rwxr-xr-xhttemplate/edit/cust_pay.cgi20
-rw-r--r--httemplate/edit/elements/edit.html15
-rwxr-xr-xhttemplate/edit/part_referral.cgi44
-rwxr-xr-xhttemplate/edit/part_referral.html9
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi2
-rwxr-xr-xhttemplate/edit/process/cust_pay.cgi30
-rwxr-xr-xhttemplate/edit/process/part_referral.cgi28
-rwxr-xr-xhttemplate/edit/process/part_referral.html5
-rwxr-xr-xhttemplate/edit/svc_acct.cgi15
-rw-r--r--httemplate/elements/header.html94
-rw-r--r--httemplate/elements/menu.html52
-rw-r--r--httemplate/elements/search-cust_main.html163
-rw-r--r--httemplate/elements/select-agent.html8
-rw-r--r--httemplate/elements/select-part_referral.html17
-rw-r--r--httemplate/elements/table-grid.html6
-rw-r--r--httemplate/elements/tr-select-agent.html10
-rw-r--r--httemplate/elements/tr-select-part_referral.html30
-rw-r--r--httemplate/misc/batch-cust_pay.html2
-rw-r--r--httemplate/misc/cust_main-import.cgi102
-rw-r--r--httemplate/misc/download-batch.cgi2
-rw-r--r--httemplate/misc/process/cust_main-import.cgi5
-rwxr-xr-xhttemplate/search/cust_main.cgi111
-rwxr-xr-xhttemplate/search/cust_pkg.cgi13
-rw-r--r--httemplate/search/elements/search.html9
-rwxr-xr-xhttemplate/search/report_receivables.cgi80
-rwxr-xr-xhttemplate/view/cust_main.cgi19
-rw-r--r--httemplate/view/cust_main/billing.html14
-rw-r--r--httemplate/view/cust_main/misc.html30
-rwxr-xr-xhttemplate/view/cust_main/packages.html100
-rw-r--r--httemplate/view/cust_main/payment_history.html178
-rw-r--r--httemplate/view/cust_main/tickets.html46
46 files changed, 1097 insertions, 989 deletions
diff --git a/httemplate/browse/access_user.html b/httemplate/browse/access_user.html
index be11bf82a..5b787977d 100644
--- a/httemplate/browse/access_user.html
+++ b/httemplate/browse/access_user.html
@@ -4,6 +4,14 @@ my $html_init =
"Internal users have access to the back-office interface. Typically, this is your employees and contractors, but in a VISP setup, you can also add accounts for your reseller's employees. It is <B>highly recommended</B> to add a <B>separate account for each person</B> rather than using role accounts.<BR><BR>".
qq!<A HREF="${p}edit/access_user.html"><I>Add an internal user</I></A><BR><BR>!;
+#false laziness w/part_pkg.cgi
+my %search = ();
+my $search = '';
+unless ( $cgi->param('showdisabled') ) {
+ %search = ( 'disabled' => '' );
+ $search = "( disabled = '' OR disabled IS NULL )";
+}
+
#false laziness w/access_group.html & agent_type.cgi
my $groups_sub = sub {
my $access_user = shift;
@@ -28,36 +36,63 @@ my $groups_sub = sub {
};
+my $posttotal;
+if ( $cgi->param('showdisabled') ) {
+ $cgi->param('showdisabled', 0);
+ $posttotal = '( <a href="'. $cgi->self_url. '">hide disabled users</a> )';
+ $cgi->param('showdisabled', 1);
+} else {
+ $cgi->param('showdisabled', 1);
+ $posttotal = '( <a href="'. $cgi->self_url. '">show disabled users</a> )';
+ $cgi->param('showdisabled', 0);
+}
+
my $count_query = 'SELECT COUNT(*) FROM access_user';
+$count_query .= " WHERE $search"
+ if $search;
my $link = [ $p.'edit/access_user.html?', 'usernum' ];
+my @header = ( '#', 'Username' );
+my @fields = ( 'usernum', 'username' );
+my $align = 'rl';
+my @links = ( $link, $link );
+my @style = ( '', '' );
+
+#false laziness w/part_pkg.cgi
+#unless ( $cgi->param('showdisabled') ) { #its been reversed already
+if ( $cgi->param('showdisabled') ) { #its been reversed already
+ push @header, 'Status';
+ push @fields, sub { shift->disabled
+ ? '<FONT COLOR="#FF0000">DISABLED</FONT>'
+ : '<FONT COLOR="#00CC00">Active</FONT>'
+ };
+ push @links, '';
+ $align .= 'c';
+ push @style, 'b';
+}
+
+push @header, 'Full name', 'Groups';
+push @fields, 'name', $groups_sub;
+push @links, $link, '';
+$align .= 'll';
+
%><%= include( 'elements/browse.html',
- 'title' => 'Internal Users',
- 'menubar' => [ #'Main menu' => $p,
- 'Internal access groups' => $p.'browse/access_group.html',
- ],
- 'html_init' => $html_init,
- 'name' => 'internal users',
- 'query' => { 'table' => 'access_user',
- 'hashref' => {},
- 'extra_sql' => 'ORDER BY last, first',
- },
- 'count_query' => $count_query,
- 'header' => [ '#',
- 'Username',
- 'Full name',
- 'Groups'
- ],
- 'fields' => [ 'usernum',
- 'username',
- 'name', # sub { shift->name },
- $groups_sub,
- ],
- 'links' => [ $link,
- $link,
- $link,
- ''
- ],
+ 'title' => 'Internal Users',
+ 'menubar' => [ #'Main menu' => $p,
+ 'Internal access groups' => $p.'browse/access_group.html',
+ ],
+ 'html_init' => $html_init,
+ 'html_posttotal' => $posttotal,
+ 'name' => 'internal users',
+ 'query' => { 'table' => 'access_user',
+ 'hashref' => \%search,
+ 'extra_sql' => 'ORDER BY last, first',
+ },
+ 'count_query' => $count_query,
+ 'header' => \@header,
+ 'fields' => \@fields,
+ 'links' => \@links,
+ 'style' => \@style,
)
%>
diff --git a/httemplate/browse/agent.cgi b/httemplate/browse/agent.cgi
index 17cc8bd40..f5157d9b7 100755
--- a/httemplate/browse/agent.cgi
+++ b/httemplate/browse/agent.cgi
@@ -29,21 +29,27 @@ full offerings (via their type).<BR><BR>
%>
<% } %>
-<%= table() %>
+<%= include('/elements/table-grid.html') %>
+
+<% my $bgcolor1 = '#eeeeee';
+ my $bgcolor2 = '#ffffff';
+ my $bgcolor = '';
+%>
+
<TR>
- <TH COLSPAN=<%= ( $cgi->param('showdisabled') || !dbdef->table('agent')->column('disabled') ) ? 2 : 3 %>>Agent</TH>
- <TH>Type</TH>
- <TH>Customers</TH>
- <TH><FONT SIZE=-1>Customer<BR>packages</FONT></TH>
- <TH>Reports</TH>
- <TH>Registration codes</TH>
- <TH>Prepaid cards</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=<%= ( $cgi->param('showdisabled') || !dbdef->table('agent')->column('disabled') ) ? 2 : 3 %>>Agent</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Type</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Customers</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Customer<BR>packages</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Reports</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Registration codes</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Prepaid cards</TH>
<% if ( $conf->config('ticket_system') ) { %>
- <TH>Ticketing</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Ticketing</TH>
<% } %>
- <TH><FONT SIZE=-1>Payment Gateway Overrides</FONT></TH>
- <TH><FONT SIZE=-1>Freq.</FONT></TH>
- <TH><FONT SIZE=-1>Prog.</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Payment Gateway Overrides</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Freq.</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Prog.</FONT></TH>
</TR>
<%
# <TH><FONT SIZE=-1>Agent #</FONT></TH>
@@ -58,107 +64,157 @@ foreach my $agent ( sort {
'agentnum='. $agent->agentnum;
my $cust_pkg_link = $p. 'search/cust_pkg.cgi?agentnum='. $agent->agentnum;
+
+ if ( $bgcolor eq $bgcolor1 ) {
+ $bgcolor = $bgcolor2;
+ } else {
+ $bgcolor = $bgcolor1;
+ }
%>
<TR>
- <TD><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
<%= $agent->agentnum %></A></TD>
<% if ( dbdef->table('agent')->column('disabled')
&& !$cgi->param('showdisabled') ) { %>
- <TD><%= $agent->disabled ? 'DISABLED' : '' %></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $agent->disabled ? 'DISABLED' : '' %></TD>
<% } %>
- <TD><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
<%= $agent->agent %></A></TD>
- <TD><A HREF="<%=$p%>edit/agent_type.cgi?<%= $agent->typenum %>"><%= $agent->agent_type->atype %></A></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF="<%=$p%>edit/agent_type.cgi?<%= $agent->typenum %>"><%= $agent->agent_type->atype %></A></TD>
+
+ <TD CLASS="inv" BGCOLOR="<%= $bgcolor %>">
+ <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0>
- <TD>
- <TABLE CELLSPACING=0 CELLPADDING=0>
<TR>
<TH ALIGN="right" WIDTH="40%">
- <%= my $num_prospect = $agent->num_prospect_cust_main %>&nbsp;
+ <FONT COLOR="#7e0079">
+ <%= my $num_prospect = $agent->num_prospect_cust_main %>&nbsp;
+ </FONT>
</TH>
+
<TD>
<% if ( $num_prospect ) { %>
<A HREF="<%= $cust_main_link %>&prospect=1"><% } %>prospects<% if ($num_prospect ) { %></A><% } %>
<TD>
</TR>
+
+ <TR>
+ <TH ALIGN="right" WIDTH="40%">
+ <FONT COLOR="#0000CC">
+ <%= my $num_inactive = $agent->num_inactive_cust_main %>&nbsp;
+ </FONT>
+ </TH>
+
+ <TD>
+ <% if ( $num_inactive ) { %>
+ <A HREF="<%= $cust_main_link %>&inactive=1"><% } %>inactive<% if ( $num_inactive ) { %></A><% } %>
+ </TD>
+ </TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#00CC00">
<%= my $num_active = $agent->num_active_cust_main %>&nbsp;
</FONT>
</TH>
+
<TD>
<% if ( $num_active ) { %>
<A HREF="<%= $cust_main_link %>&active=1"><% } %>active<% if ( $num_active ) { %></A><% } %>
</TD>
</TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#FF9900">
<%= my $num_susp = $agent->num_susp_cust_main %>&nbsp;
</FONT>
</TH>
+
<TD>
<% if ( $num_susp ) { %>
<A HREF="<%= $cust_main_link %>&suspended=1"><% } %>suspended<% if ( $num_susp ) { %></A><% } %>
</TD>
</TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#FF0000">
<%= my $num_cancel = $agent->num_cancel_cust_main %>&nbsp;
</FONT>
</TH>
+
<TD>
<% if ( $num_cancel ) { %>
<A HREF="<%= $cust_main_link %>&showcancelledcustomers=1&cancelled=1"><% } %>cancelled<% if ( $num_cancel ) { %></A><% } %>
</TD>
</TR>
+
</TABLE>
</TD>
- <TD>
- <TABLE CELLSPACING=0 CELLPADDING=0>
+ <TD CLASS="inv" BGCOLOR="<%= $bgcolor %>" VALIGN="bottom">
+ <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0>
+
+ <TR>
+ <TH ALIGN="right" WIDTH="40%">
+ <FONT COLOR="#0000CC">
+ <%= my $num_inactive_pkg = $agent->num_inactive_cust_pkg %>&nbsp;
+ </FONT>
+ </TH>
+
+ <TD>
+ <% if ( $num_inactive_pkg ) { %>
+ <A HREF="<%= $cust_pkg_link %>&magic=inactive"><% } %>inactive<% if ( $num_inactive_pkg ) { %></A><% } %>
+ </TD>
+ </TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#00CC00">
<%= my $num_active_pkg = $agent->num_active_cust_pkg %>&nbsp;
</FONT>
</TH>
+
<TD>
<% if ( $num_active_pkg ) { %>
<A HREF="<%= $cust_pkg_link %>&magic=active"><% } %>active<% if ( $num_active_pkg ) { %></A><% } %>
</TD>
</TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#FF9900">
<%= my $num_susp_pkg = $agent->num_susp_cust_pkg %>&nbsp;
</FONT>
+
</TH>
<TD>
<% if ( $num_susp_pkg ) { %>
<A HREF="<%= $cust_pkg_link %>&magic=suspended"><% } %>suspended<% if ( $num_susp_pkg ) { %></A><% } %>
</TD>
</TR>
+
<TR>
<TH ALIGN="right" WIDTH="40%">
<FONT COLOR="#FF0000">
<%= my $num_cancel_pkg = $agent->num_cancel_cust_pkg %>&nbsp;
</FONT>
</TH>
+
<TD>
<% if ( $num_cancel_pkg ) { %>
<A HREF="<%= $cust_pkg_link %>&magic=cancelled"><% } %>cancelled<% if ( $num_cancel_pkg ) { %></A><% } %>
</TD>
</TR>
+
</TABLE>
</TD>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<A HREF="<%= $p %>search/report_cust_pay.html?agentnum=<%= $agent->agentnum %>">Payments</A>
<BR><A HREF="<%= $p %>search/report_cust_credit.html?agentnum=<%= $agent->agentnum %>">Credits</A>
<BR><A HREF="<%= $p %>search/report_receivables.cgi?agentnum=<%= $agent->agentnum %>">A/R Aging</A>
@@ -166,14 +222,14 @@ foreach my $agent ( sort {
</TD>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<%= my $num_reg_code = $agent->num_reg_code %>
<% if ( $num_reg_code ) { %>
<A HREF="<%=$p%>search/reg_code.html?agentnum=<%= $agent->agentnum %>"><% } %>Unused<% if ( $num_reg_code ) { %></A><% } %>
<BR><A HREF="<%=$p%>edit/reg_code.cgi?agentnum=<%= $agent->agentnum %>">Generate codes</A>
</TD>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<%= my $num_prepay_credit = $agent->num_prepay_credit %>
<% if ( $num_prepay_credit ) { %>
<A HREF="<%=$p%>search/prepay_credit.html?agentnum=<%= $agent->agentnum %>"><% } %>Unused<% if ( $num_prepay_credit ) { %></A><% } %>
@@ -182,7 +238,7 @@ foreach my $agent ( sort {
<% if ( $conf->config('ticket_system') ) { %>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<% if ( $agent->ticketing_queueid ) { %>
Queue: <%= $agent->ticketing_queueid %>: <%= $agent->ticketing_queue %><BR>
<% } %>
@@ -190,7 +246,7 @@ foreach my $agent ( sort {
<% } %>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<TABLE CELLSPACING=0 CELLPADDING=0>
<% foreach my $override (
# sort { } want taxclass-full stuff first? and default cards (empty cardtype)
@@ -214,8 +270,10 @@ foreach my $agent ( sort {
</TABLE>
</TD>
- <TD><%= $agent->freq %></TD>
- <TD><%= $agent->prog %></TD>
+<!--
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $agent->freq %></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $agent->prog %></TD>
+-->
</TR>
diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi
index b67a5e55f..a5e212d17 100755
--- a/httemplate/browse/part_pkg.cgi
+++ b/httemplate/browse/part_pkg.cgi
@@ -1,5 +1,6 @@
<%
+#false laziness w/access_user.html
my %search = ();
my $search = '';
unless ( $cgi->param('showdisabled') ) {
@@ -71,6 +72,7 @@ my $align = 'rll';
my @links = ( $link, $link, '' );
my @style = ( '', '', '' );
+#false laziness w/access_user.html
#unless ( $cgi->param('showdisabled') ) { #its been reversed already
if ( $cgi->param('showdisabled') ) { #its been reversed already
push @header, 'Status';
diff --git a/httemplate/browse/part_referral.cgi b/httemplate/browse/part_referral.html
index 238ddace7..c50a406ed 100755
--- a/httemplate/browse/part_referral.cgi
+++ b/httemplate/browse/part_referral.html
@@ -1,11 +1,9 @@
-<!-- mason kludge -->
-<%= include("/elements/header.html","Advertising source Listing", menubar(
- 'Main Menu' => $p,
-# 'Add new referral' => "../edit/part_referral.cgi",
-)) %>
+<%= include("/elements/header.html","Advertising source Listing" ) %>
+
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>
+
+<A HREF="<%= $p %>edit/part_referral.html"><I>Add a new advertising source</I></A>
<BR><BR>
<%
@@ -34,36 +32,71 @@ Where a customer heard about your service. Tracked for informational purposes.
'Total' => 86400, # 60sec * 60min * 24hrs
);
+ my $curuser = $FS::CurrentUser::CurrentUser;
+
my $statement = "SELECT COUNT(*) FROM h_cust_main
WHERE history_action = 'insert'
AND refnum = ?
AND history_date >= ?
AND history_date < ?
- ";
+ AND ". $curuser->agentnums_sql;
my $sth = dbh->prepare($statement)
or die dbh->errstr;
+
+ my $show_agentnums = scalar($curuser->agentnums);
+
+%>
+
+<%= include('/elements/table-grid.html') %>
+
+<% my $bgcolor1 = '#eeeeee';
+ my $bgcolor2 = '#ffffff';
+ my $bgcolor = '';
%>
-<%= table() %>
<TR>
- <TH COLSPAN=2 ROWSPAN=2>Advertising source</TH>
- <TH COLSPAN=<%= scalar(keys %after) %>>Customers</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=2 ROWSPAN=2>Advertising source</TH>
+ <% if ( $show_agentnums ) { %>
+ <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2>Agent</TH>
+ <% } %>
+ <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=<%= scalar(keys %after) %>>Customers</TH>
</TR>
<% for my $period ( keys %after ) { %>
- <TH><FONT SIZE=-1><%= $period %></FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1><%= $period %></FONT></TH>
<% } %>
</TR>
<%
-foreach my $part_referral ( sort {
- $a->getfield('refnum') <=> $b->getfield('refnum')
-} qsearch('part_referral',{}) ) {
+foreach my $part_referral ( FS::part_referral->all_part_referral(1) ) {
+
+ if ( $bgcolor eq $bgcolor1 ) {
+ $bgcolor = $bgcolor2;
+ } else {
+ $bgcolor = $bgcolor1;
+ }
+
+ $a = 0;
+
%>
<TR>
- <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
- <%= $part_referral->refnum %></A></TD>
- <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
- <%= $part_referral->referral %></A></TD>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <% if ( $part_referral->agentnum || $curuser->access_right('Edit global advertising sources') ) {
+ $a++;
+ %>
+ <A HREF="<%= $p %>edit/part_referral.html?<%= $part_referral->refnum %>">
+ <% } %>
+ <%= $part_referral->refnum %><%= $a ? '</A>' : '' %></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <% if ( $a ) { %>
+ <A HREF="<%= $p %>edit/part_referral.html?<%= $part_referral->refnum %>">
+ <% } %>
+ <%= $part_referral->referral %><%= $a ? '</A>' : '' %></TD>
+
+ <% if ( $show_agentnums ) { %>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $part_referral->agentnum ? $part_referral->agent->agent : '(global)' %></TD>
+ <% } %>
+
<% for my $period ( keys %after ) {
$sth->execute( $part_referral->refnum,
$today-$after{$period},
@@ -71,7 +104,7 @@ foreach my $part_referral ( sort {
) or die $sth->errstr;
my $number = $sth->fetchrow_arrayref->[0];
%>
- <TD ALIGN="right"><%= $number %></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"><%= $number %></TD>
<% } %>
</TR>
<% } %>
@@ -82,14 +115,14 @@ foreach my $part_referral ( sort {
or die dbh->errstr;
%>
<TR>
- <TH COLSPAN=2>Total</TH>
+ <TD BGCOLOR="#dddddd" ALIGN="center" COLSPAN=3><B>Total</B></TD>
<% for my $period ( keys %after ) {
$sth->execute( $today-$after{$period},
$today+$before{$period},
) or die $sth->errstr;
my $number = $sth->fetchrow_arrayref->[0];
%>
- <TD ALIGN="right"><%= $number %></TD>
+ <TD BGCOLOR="#dddddd" ALIGN="right"><B><%= $number %><B></TD>
<% } %>
</TR>
</TABLE>
diff --git a/httemplate/config/config.cgi b/httemplate/config/config.cgi
index 6008c0e42..cf228dba5 100644
--- a/httemplate/config/config.cgi
+++ b/httemplate/config/config.cgi
@@ -102,7 +102,7 @@ function SafeOnsubmit() {
<% my $curvalue = $conf->config($i->key);
if ( $conf->exists($i->key) && $curvalue
- && ! grep { $curvalue eq $_ } @{$i->select_enum}
+ && ! $hash{$curvalue}
) {
%>
diff --git a/httemplate/docs/index.html b/httemplate/docs/index.html
index 1693b6d9b..d7b464346 100644
--- a/httemplate/docs/index.html
+++ b/httemplate/docs/index.html
@@ -7,10 +7,8 @@
<h3>Installation and upgrades</h3>
<ul>
<li><a href="http://www.sisd.com/mediawiki/index.php/Freeside:1.7:Documentation:Installation">New Installation</a>
- <li><a href="install-rt.html">Installing integrated RT ticketing</a>
- <li><a href="upgrade9.html">Upgrading from 1.4.0 to 1.4.1</a>
- <li><a href="upgrade-1.4.2.html">Upgrading from 1.4.1 to 1.4.2</a>
- <li><a href="upgrade10.html">Upgrading from 1.4.1 (or 1.4.2) to 1.5.8</a>
+ <li><a href="http://www.sisd.com/mediawiki/index.php/Freeside:1.7:Documentation:RT_Installation">Installing integrated RT ticketing</a>
+ <li><a href="http://www.sisd.com/mediawiki/index.php/Freeside:1.7:Documentation:Upgrading">Upgrading from 1.5.8 or 1.6.X</a>
</ul>
<h3>Configuration and setup</h3>
<ul>
diff --git a/httemplate/docs/install-rt.html b/httemplate/docs/install-rt.html
deleted file mode 100644
index da0941a09..000000000
--- a/httemplate/docs/install-rt.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<head>
- <title>Installing integrated RT ticketing</title>
-</head>
-<body>
-<h1>Installing integrated RT ticketing</h1>
-
-<p><i>Integrated ticketing is an new feature and these instructions are preliminary. Documentation contributions are welcome.</i>
-
-<p><i>There is also support for running this integration against an external RT installation, but it is not (yet) documented.</i>
-
-<p>Perl minimum version 5.8.3 is required. HTML::Mason is required.
-
-<p>Install the following perl modules:
- <ul>
- <li><a href="http://search.cpan.org/search?dist=Apache-Session">Apache::Session</a>
- <li><a href="http://search.cpan.org/search?dist=HTML-Tree">HTML::TreeBuilder (HTML-Tree)</a>
- <li><a href="http://search.cpan.org/search?dist=HTML-Format">HTML::FormatText (HTML-Format)</a>
- <li><a href="http://search.cpan.org/search?dist=Test-Inline">Test::Inline</a>
- <li><a href="http://search.cpan.org/search?dist=Class-ReturnValue">Class::ReturnValue</a>
- <li><a href="http://search.cpan.org/search?dist=DBIx-SearchBuilder">DBIx::SearchBuilder</a>
- <li><a href="http://search.cpan.org/search?dist=Log-Dispatch">Log::Dispatch</a>
- <li><a href="http://search.cpan.org/search?dist=Locale-Maketext-Lexicon">Locale::Maketext::Lexicon</a>
- <li><a href="http://search.cpan.org/search?dist=Locale-Maketext-Fuzzy">Locale::Maketext::Fuzzy</a>
- <li><a href="http://search.cpan.org/search?dist=Text-Wrapper">Text::Wrapper</a>
- <li><a href="http://search.cpan.org/search?dist=Time-modules">Time::ParseDate (Time-modules)</a>
- <li><a href="http://search.cpan.org/search?dist=TermReadKey">Term::ReadKey (TermReadKey)</a>
- <li><a href="http://search.cpan.org/search?dist=Text-Autoformat">Text::Autoformat</a>
- <li><a href="http://search.cpan.org/search?dist=Text-Quoted">Text::Quoted</a>
- <li><a href="http://search.cpan.org/search?dist=Regexp-Common">Regexp::Common</a>
- <li><a href="http://search.cpan.org/search?dist=HTML-Scrubber">HTML::Scrubber</a>
- <li><a href="http://search.cpan.org/search?dist=Tree-Simple">Tree::Simple</a>
- </ul>
-
-<p>Create a new Unix group called 'rt'
-
-<p>Edit the top-level Makefile, set RT_ENABLED to 1 and set the RT_DOMAIN, RT_TIMEZONE, and FREESIDE_URL variables.
-
-<p><pre>make configure-rt
-make create-rt
-make install-rt
-</pre>
-
-<p>Add the following to your httpd.conf:
-<pre>
-# replace /var/www/freeside with your freeside document root
-&lt;DirectoryMatch "^/var/www/freeside/rt/.*NoAuth"&gt;
-&lt;Limit GET POST&gt;
-allow from all
-Satisfy any
-SetHandler perl-script
-PerlHandler HTML::Mason
-&lt;/Limit&gt;
-&lt;/DirectoryMatch&gt;
-# replace /var/www/freeside with your freeside document root
-&lt;DirectoryMatch "^/var/www/freeside/rt/.*NoAuth/images"&gt;
-SetHandler None
-&lt;/DirectoryMatch&gt;
-# replace /var/www/freeside with your freeside document root
-&lt;Directory /var/www/freeside/rt/Ticket/Attachment&gt;
-SetHandler perl-script
-PerlHandler HTML::Mason
-&lt;/Directory&gt;
-</pre>
-
-<p>Set the <b>ticket_system</b> configuration value to <b>RT_Internal</b>. You may also wish to set <b>ticket_system-default_queueid</b> once you have RT configured.
-
-<p>Bootstrap RT's permissions:
- <ul>
- <li>Click on "Ticketing Main" on the Freeside main menu to auto-create an RT login for your username
- <li>Run <code>freeside-adduser -h /usr/local/etc/freeside/htpasswd root</code> and set a (temporary) password
- <li>Log into your Freeside installation as the "root" user you just created, by closing your browser or using <code>https://root@yourmachone/freeside/</code> syntax.
- <li>Click on "Ticketing Main" on the Freeside main menu. Click on "Configuration", then "Global", and then "User Rights". Grant the "SuperUser" right to your RT login.
- <li>Remove the temporary "root" user from /usr/local/etc/freeside/mapsecrets and /usr/local/etc/freeside/htpasswd
- </ul>
-
-<p>Follow the <A HREF="http://wiki.bestpractical.com/">regular RT documentation</A> to configure RT, setup the mailgate, etc.
-
-</body>
diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html
deleted file mode 100644
index 78172e8e4..000000000
--- a/httemplate/docs/install.html
+++ /dev/null
@@ -1,173 +0,0 @@
-<head>
- <title>Installation</title>
-</head>
-<body>
-<h1>Installation</h1>
-<i>Note: Install Freeside on a firewalled, private server, not a public (web, RADIUS, etc.) server.</i><br><br>
-Before installing, you need:
-<ul>
- <li><a href="http://www.perl.com/">Perl</a>, minimum version 5.005_03. (5.8.3 for the integrated RT ticketing)
- <li><a href="http://www.apache.org">Apache</a> (<a href="http://www.modssl.org/">mod_ssl</a> or <a href="http://www.apache-ssl.org">Apache-SSL</a> highly recommended)
- <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>Optional, enables typeset invoices: teTeX and Ghostscript (included with most distributions).
- <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> is recommended (v7.2 or later, 7.4 or later recommended).
- <li> <a href="http://www.mysql.com/">MySQL</a> is <b>not currently supported</b>. <FONT SIZE="-1"><i>Developers intersted in maintaining MySQL support are welcome to ask on the -devel mailing list; many things work, but MySQL support needs a maintainer to update it for recent (and future) changes.</i></FONT>
- <!-- <li><a href="http://www.mysql.com/">MySQL</a> <b>MINIMUM VERSION 4.1</b> is untested but may work. Versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>.
-<!-- <li>MySQL has been reported to work.
- 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. 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/I/n/InnoDB.html">InnoDB</a>. Set it as the default table type using the <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=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>
- <i>Note: the above only applies to the database used by the Freeside software itself. Freeside can integrate with RADIUS and other servers running MySQL <!--(any version)--> or any other DBI-supported database.</i>
- <li>Perl modules (<a href="http://search.cpan.org/~andk/CPAN/lib/CPAN.pm">CPAN</a> will query, download and build perl modules automatically)
- <ul>
-<!-- <li><a href="http://search.cpan.org/dist/Array-PrintCols">Array-PrintCols</a>
- <li><a href="http://search.cpan.org/dist/Term-Query">Term-Query</a> (make test broken; install manually) -->
- <li><a href="http://search.cpan.org/dist/MIME-Base64">MIME-Base64</a>
- <li><a href="http://search.cpan.org/dist/Digest-MD5">Digest-MD5</a>
-<!-- <li><a href="http://search.cpan.org/dist/MD5">MD5</a> -->
- <li><a href="http://search.cpan.org/dist/URI">URI</a>
- <li><a href="http://search.cpan.org/dist/HTML-Tagset">HTML-Tagset</a>
- <li><a href="http://search.cpan.org/dist/HTML-Parser">HTML-Parser</a>
- <li><a href="http://search.cpan.org/dist/libnet">libnet</a>
- <li><a href="http://search.cpan.org/dist/Locale-Codes">Locale-Codes</a>
- <li><a href="http://search.cpan.org/dist/Net-Whois-Raw">Net-Whois-Raw</a>
- <li><a href="http://search.cpan.org/dist/libwww-perl">libwww-perl</a>
- <li><a href="http://search.cpan.org/dist/Business-CreditCard">Business-CreditCard</a>
-<!-- <li><a href="http://search.cpan.org/dist/Data-ShowTable">Data-ShowTable</a> -->
- <li><a href="http://search.cpan.org/dist/MailTools">MailTools</a>
- <li><a href="http://search.cpan.org/dist/TimeDate">TimeDate</a>
- <li><a href="http://search.cpan.org/dist/DateManip">DateManip</a>
- <li><a href="http://search.cpan.org/dist/File-CounterFile">File-CounterFile</a>
- <li><a href="http://search.cpan.org/dist/FreezeThaw">FreezeThaw</a>
- <li><a href="http://search.cpan.org/dist/String-Approx">String-Approx</a>
- <li><a href="http://search.cpan.org/dist/Text-Template">Text-Template</a>
- <li><a href="http://search.cpan.org/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/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/dist/DBIx-DataSource">DBIx-DataSource</a> -->
- <li><a href="http://search.cpan.org/dist/DBIx-DBSchema">DBIx-DBSchema</a>
- <li><a href="http://search.cpan.org/dist/Net-SSH">Net-SSH</a>
- <li><a href="http://search.cpan.org/dist/String-ShellQuote">String-ShellQuote</a>
- <li><a href="http://search.cpan.org/dist/Net-SCP">Net-SCP</a>
- <li><a href="http://www.masonhq.com/">HTML::Mason</a>
- <li><a href="http://search.cpan.org/dist/Tie-IxHash">Tie-IxHash</a>
- <li><a href="http://search.cpan.org/dist/Time-Duration">Time-Duration</a>
- <li><a href="http://search.cpan.org/dist/HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>
- <li><a href="http://search.cpan.org/dist/Storable">Storable</a>
- <li><a href="http://search.cpan.org/dist/Cache-Cache">Cache::Cache</a>
- <li><a href="http://search.cpan.org/dist/NetAddr-IP">NetAddr-IP</a>
- <li><a href="http://search.cpan.org/dist/Chart">Chart</a>
- <li><a href="http://search.cpan.org/dist/Crypt-PasswdMD5">Crypt::PasswdMD5</a>
- <li><a href="http://search.cpan.org/dist/Locale-SubCountry">Locale::SubCountry</a>
- <li><a href="http://search.cpan.org/dist/Frontier-RPC">Frontier::RPC</a>
- <li><a href="http://search.cpan.org/dist/Text-CSV_XS">Text::CSV_XS</a>
- <li><a href="http://search.cpan.org/dist/Spreadsheet-WriteExcel">Spreadsheet::WriteExcel</a>
- <li><a href="http://search.cpan.org/dist/IO-stringy">IO-stringy (IO::Scalar)</a>
- <li><a href="http://search.cpan.org/dist/Frontier-RPC">Frontier::RPC (Frontier::RPC2)</a>
- <li><a href="http://search.cpan.org/dist/MIME-tools">MIME::Entity (MIME-tools)</a>
- <li><a href="http://search.cpan.org/dist/IPC-Run3">IPC::Run3</a>
- <li><a href="http://search.cpan.org/dist/Term-ReadKey">Term::ReadKey</a>
-<!-- <li><a href="http://search.cpan.org/dist/Crypt-YAPassGen">Crypt::YAPassGen</a> -->
- <li><a href="http://search.cpan.org/dist/JSON">JSON</a>
- <li><a href="http://search.cpan.org/search?mode=module&query=MIME::Entity">Fax::Hylafax::Client</a> <i>(Required if using FAX invoice destinations)</i>
- <li><a href="http://search.cpan.org/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 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>:
- <pre>
-$ su postgres (pgsql on some distributions)
-$ createuser -P freeside
-Enter password for user "freeside":
-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>:
- <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: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:
- <ul>
- <li>with Postgres:
- <pre>
-$ su freeside
-$ createdb -E sql_ascii freeside</pre>
- <li>with MySQL:
- <pre>
-$ mysqladmin -u freeside -p create freeside </pre>
- </ul>
- <li>Build and install the Perl modules:
- <pre>
-$ make perl-modules
-$ su
-# make install-perl-modules</pre>
- <li>Create the necessary configuration files:<pre>
-$ su
-# make create-config
-</pre>
- <li>Run a <b>separate</b> iteration of Apache[-SSL] with mod_perl enabled <b>as the freeside user</b>.
- <li>Edit the <tt>Makefile</tt> and set <tt>TEMPLATE</tt> to <tt>asp</tt> or <tt>mason</tt>. Also set <tt>FREESIDE_DOCUMENT_ROOT</tt>.
- <li>Run <tt> make install-docs</tt>.
-<li>Configure Apache:
-<font size="-1"><pre>
-PerlModule HTML::Mason
-# your freeside docuemnt root
-&lt;Directory&nbsp;/var/www/freeside&gt;
-&lt;Files ~ (\.cgi|\.html)&gt;
-AddHandler perl-script .cgi .html
-PerlHandler HTML::Mason
-&lt;/Files&gt;
-&lt;Perl&gt;
-require&nbsp;"/usr/local/etc/freeside/handler.pl";
-&lt;/Perl&gt;
-&lt;/Directory&gt;
-</pre></font>
-<li>Restrict access to this web interface - see the <a href="http://httpd.apache.org/docs/misc/FAQ.html#user-authentication">Apache documentation on user authentication</a>. For example, to configure user authentication with <a href="http://httpd.apache.org/docs/mod/mod_auth.html">mod_auth</a> (flat files), add something like the following to your Apache httpd.conf file, adjusting for your actual paths:
-<pre>
-#your freeside document root
-&lt;Directory /var/www/freeside&gt;
-AuthName Freeside
-AuthType Basic
-AuthUserFile /usr/local/etc/freeside/htpasswd
-require valid-user
-&lt;/Directory&gt;
-</pre>
- <li>Create one or more Freeside users (your internal sales/tech folks, not customer accounts). These users are setup using using Apache authentication, not UNIX user accounts. For example, using <a href="http://httpd.apache.org/docs/mod/mod_auth.html">mod_auth</a> (flat files):
- <ul>
- <li>First user:<font size="-1">
-<pre>$ su
-# <a href="man/bin/freeside-adduser.html">freeside-adduser</a> -c -h /usr/local/etc/freeside/htpasswd <i>username</i></pre></font>
- <li>Additional users:<font size="-1">
-<pre>$ su
-# <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>Create the Freeside system users:
-<pre>$ su
-# <a href="man/bin/freeside-adduser.html">freeside-adduser</a> fs_queue
-# <a href="man/bin/freeside-adduser.html">freeside-adduser</a> fs_selfservice</pre>
- <li>As the freeside UNIX user, run <tt>freeside-setup -d <b>domain.name</b> <b>username</b></tt> to create the database tables and initial data, passing the username of a Freeside user you created above:
-<pre>
-$ su freeside
-$ freeside-setup -d </b>example.com</b> <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 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/trouble.html b/httemplate/docs/trouble.html
deleted file mode 100755
index fce743928..000000000
--- a/httemplate/docs/trouble.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<head>
- <title>Troubleshooting</title>
-</head>
-<body>
- <h1>Troubleshooting</h1>
- <ul>
- <li>When troubleshooting the web interface, helpful information is often in your web server's error log.
- <li>If bin/svc_acct.import fails with an "Out of memory!" error using MySQL, upgrede MySQL and recompile the Perl DBD. There was a memory leak in some older versions of MySQL.
- <li>If you get tons of errors in your web server's error log like this:
-<pre>
-Ambiguous use of value => resolved to "value" =>
-at /usr/lib/perl5/site_perl/File/CounterFile.pm line 132.
-</pre>
- This clutters up your log files but is otherwise harmless. Upgrade to the latest File::CounterFile.
- <li>If you get errors like this:
-<pre>
-UID.pm: Can't open /var/spool/freeside/conf/secrets: Permission denied
-at <i>/your/path</i>/site_perl/FS/UID.pm line 26.
-BEGIN failed--compilation aborted at
-<i>/your/path</i>/edit/process/part_svc.cgi line 15.
-</pre>
- Then the scripts are not running as the freeside freeside user. See
-the <a href="install.html">New Installation</a> section of the documentation.
- <li>If you receive `can not connect to server' errors using MySQL on a system that doesn't support native threading, you may need to specify the full hostname in your DBI datasource. See the <a href="http://www.mysql.com/Manual_chapter/manual_Problems.html#Can_not_connect_to_server">MySQL documentation</a>, DBI manpage and the DBD::mysql manpage for details.
- </ul>
-</body>
diff --git a/httemplate/docs/upgrade-1.4.2.html b/httemplate/docs/upgrade-1.4.2.html
deleted file mode 100644
index a24661142..000000000
--- a/httemplate/docs/upgrade-1.4.2.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<head>
- <title>Upgrading to 1.4.2</title>
-</head>
-<body>
-<h1>Upgrading to 1.4.2 from 1.4.1</h1>
-<ul>
- <li>If migrating from less than 1.4.1, see these <a href="upgrade9.html">instructions</a> first.
- <li>Back up your data and current Freeside installation.
- <li>Install <a href="http://search.cpan.org/search?dist=Locale-SubCountry">Locale::SubCountry</a>
- <li>Install <a href="http://search.cpan.org/search?dist=IPC-ShareLite">IPC::ShareLite</a>
- <li>Install <a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML::Widgets::SelectLayers</a> 0.04.
- <li>Install <a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx::DBSchema</a> 0.23.
- <li>Install <a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> 1.32.
- <li>Install <a href="http://search.cpan.org/search?dist=Cache-Cache">Cache::Cache</a>.
- <li>Install <a href="http://search.cpan.org/search?dist=Net-SSH">Net::SSH</a> 0.08.
- <li>Install <a href="http://search.cpan.org/search?dist=Crypt-PasswdMD5">Crypt::PasswdMD5</a>
- <li>Install <a href="http://search.cpan.org/search?dist=Net-Whois-Raw">Net::Whois::Raw</a>
- <li>CGI.pm minimum version 2.47 is required. You will probably need to install a current CGI.pm from CPAN if you are using Perl 5.005 or earlier.
- <li>File::Temp minimum version 0.14 is required. You will probably need to install a currrent File::Temp from CPAN if you are using Perl 5.6 or earlier.
- <li>If using Apache::ASP, add <code>PerlSetVar RequestBinaryRead Off</code> to your Apache configuration and make sure you are using Apache::ASP minimum version 2.55.
- <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>The signup server and password server are deprecated in 1.4.2. Their functionality has been incorperated into the self-service server. Edit or reinstall your init script, and set the "signup_server-default_agentnum" and "signup_server-default_refnum" configuration options. The FS::SignupClient interface is still available as a compatibility wrapper, so you should be able to continue to use your current signup.cgi.
- <li>Optional: To use typeset invoices, install tetex and ghostscript, and copy conf/invoice_latex, conf/invoice_latexnotes, and conf/invoice_latexfooter to /usr/local/etc/freeside/conf.<datasrc>/
- <li>Restart Apache and freeside-queued.
-</body>
diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html
deleted file mode 100644
index 2a4b0d975..000000000
--- a/httemplate/docs/upgrade10.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<head>
- <title>Upgrading to 1.5.8</title>
-</head>
-<body>
-<h1>Upgrading to 1.5.8 from 1.4.1 or 1.4.2</h1
-
-<table bgcolor="#dddddd">
-<tr><td>
-<i><b>Note:</b> Version numbering has been simplified. 1.5.7 and 1.5.8 are the
-versions following 1.5.0pre6. They are still development versions - releases
-with odd numbered middle parts (NN in x.NN.x) are development versions, like
-Perl or Linux.
-</td></tr>
-</table>
-<br>
-
-<ul>
- <li>If migrating from 1.5.0pre6, see README.1.5.7 instead
- <li>If migrating from 1.5.7, see README.1.5.8 instead
- <li> install DBD::Pg 1.32, 1.41 or later (not 1.40) (or, if you're using a Perl version before 5.6, you could try installing DBD::Pg 1.22 with <a href="http://420.am/~ivan/DBD-Pg-1.22-fixvercmp.patch">this patch</a> and commenting out the "use DBD::Pg 1.32" at the top of DBIx/DBSchema/DBD/Pg.pm)
- <li> install DBIx::DBSchema 0.27 (or later) (if you are running Pg version 7.2.x or earlier, install at least DBIx::DBSchema 0.29)
- <li> install Net::SSH 0.08 or later
- <li> install HTML::Widgets::SelectLayers 0.05 or later
- <li> install Business::CreditCard 0.28 or later
-
- <li>If using Apache::ASP, add PerlSetVar RequestBinaryRead Off and PerlSetVar IncludesDir /your/freeside/document/root/ to your Apache configuration and make sure you are using Apache::ASP minimum version 2.55.
- <ul>
- <li>In httpd.conf, change &lt;Files ~ \.cgi&gt; to &lt;Files ~ (\.cgi|\.html)&gt;
- <li>In httpd.conf, change <b>AddHandler perl-script .cgi</b> or <b>SetHandler perl-script</b> to <b>AddHandler perl-script .cgi .html</b>
- </ul>
- <li>install NetAddr::IP, Chart::Base, Locale::SubCountry, Text::CSV_XS,
-Spreadsheet::WriteExcel, IO-stringy (IO::Scalar), Frontier::RPC
-(Frontier::RPC2), MIME::Entity (MIME-tools), IPC::Run3, Net::Whois::Raw,
-JSON, Term::ReadKey and Color::Scheme
-<!-- and Crypt::YAPassGen-->
-
- <li>Apply the following changes to your database:
-<pre>
-INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 20, 'svc_external-id', 'en_US', 'External ID' );
-INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 21, 'svc_external-title', 'en_US', 'Title' );
-
-DROP INDEX cust_bill_pkg1;
-</pre>
-
- <li>On recent Pg versions:
-<pre>
-ALTER TABLE cust_main ALTER COLUMN payinfo varchar(512) NULL;
-ALTER TABLE h_cust_main ALTER COLUMN payinfo varchar(512) NULL;
-ALTER TABLE cust_pay_batch ADD COLUMN batchnum int NOT NULL;
-ALTER TABLE cust_pay_batch ALTER COLUMN batchnum SET NOT NULL;
-ALTER TABLE cust_pay_batch ADD COLUMN payinfo varchar(512) NULL;
-UPDATE cust_pay_batch SET payinfo = cardnum;
-ALTER TABLE cust_pay_batch DROP COLUMN cardnum;
-ALTER TABLE h_cust_pay_batch ADD COLUMN payinfo varchar(512) NULL;
-UPDATE h_cust_pay_batch SET payinfo = cardnum;
-ALTER TABLE h_cust_pay_batch DROP COLUMN cardnum;
-</pre>
-On older Pg versions that don't support altering columns directly, you will need to dump the database, edit the schema definitions in the dump file, and reload.
-
- <li>On recent Pg versions:
-<pre>
-ALTER TABLE svc_forward ALTER COLUMN srcsvc DROP NOT NULL;
-ALTER TABLE h_svc_forward ALTER COLUMN srcsvc DROP NOT NULL;
-ALTER TABLE svc_forward ALTER COLUMN dstsvc DROP NOT NULL;
-ALTER TABLE h_svc_forward ALTER COLUMN dstsvc DROP NOT NULL;
-ALTER TABLE cust_main ALTER COLUMN zip DROP NOT NULL;
-ALTER TABLE h_cust_main ALTER COLUMN zip DROP NOT NULL;
-</pre>
-Or on Pg versions that don't support DROP NOT NULL (tested on 7.1 and 7.2 so far):
-<pre>
-UPDATE pg_attribute SET attnotnull = FALSE WHERE ( attname = 'srcsvc' OR attname = 'dstsvc' ) AND ( attrelid = ( SELECT oid FROM pg_class WHERE relname = 'svc_forward' ) OR attrelid = ( SELECT oid FROM pg_class WHERE relname = 'h_svc_forward' ) );
-UPDATE pg_attribute SET attnotnull = FALSE WHERE ( attname = 'zip' ) AND ( attrelid = ( SELECT oid FROM pg_class WHERE relname = 'cust_main' ) OR attrelid = ( SELECT oid FROM pg_class WHERE relname = 'h_cust_main' ) );
-</pre>
-
- <li> If you created your database with a version before 1.4.2, dump database, edit the following, then reload:
- <ul>
- <li>cust_main and h_cust_main: increase otaker from 8 to 32
- <li>cust_main and h_cust_main: change ss from char(11) to varchar(11) ( "character(11)" to "character varying(11)" )
- <li>cust_credit and h_cust_credit: increase otaker from 8 to 32
- <li>cust_pkg and h_cust_pkg: increase otaker from 8 to 32
- <li>cust_refund and h_cust_refund: increase otaker from 8 to 32
- <li>domain_record and h_domain_record: increase reczone from 80 to 255
- <li>domain_record and h_domain_record: change rectype from char to varchar ( "character(5)" to "character varying(5)" )
- <li>domain_record and h_domain_record: increase recdata from 80 to 255
- </ul>
-
-<li>make install-perl-modules to install the new libraries and CLI utilities
-<li>run "freeside-upgrade username" to create the remaining new tables and columns
-
-<li>optionally:
-<pre>
-CREATE INDEX cust_main4 ON cust_main ( daytime );
-CREATE INDEX cust_main5 ON cust_main ( night );
-CREATE INDEX cust_main6 ON cust_main ( fax );
-CREATE INDEX cust_main7 ON cust_main ( refnum );
-CREATE INDEX cust_main8 ON cust_main ( county );
-CREATE INDEX cust_main9 ON cust_main ( state );
-CREATE INDEX cust_main10 ON cust_main ( country );
-CREATE INDEX cust_main11 ON cust_main ( ship_last );
-CREATE INDEX cust_main12 ON cust_main ( ship_company );
-CREATE INDEX cust_main13 ON cust_main ( ship_daytime );
-CREATE INDEX cust_main14 ON cust_main ( ship_night );
-CREATE INDEX cust_main15 ON cust_main ( ship_fax );
-CREATE INDEX agent2 ON agent ( disabled );
-CREATE INDEX part_bill_event2 ON part_bill_event ( disabled );
-CREATE INDEX cust_pay4 ON cust_pay (_date);
-CREATE INDEX part_referral1 ON part_referral ( disabled );
-CREATE INDEX part_pkg2 ON part_pkg ( promo_code );
-CREATE INDEX h_part_pkg2 ON h_part_pkg ( promo_code );
-</pre>
-
-</ul>
-
-</body>
-</html>
diff --git a/httemplate/docs/upgrade9.html b/httemplate/docs/upgrade9.html
deleted file mode 100644
index 6a8fd965d..000000000
--- a/httemplate/docs/upgrade9.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<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>Install <a href="http://search.cpan.org/search?dist=Net-SSH">Net::SSH</a> minimum version 0.07
- <li>Apply the following changes to your database:
-<pre>
-INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 18, 'daytime', 'en_US', 'Day Phone' );
-INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 19, 'night', 'en_US', 'Night Phone' );
-</pre>
- <li>Optionally, apply the following changes to your database (performance improvements):
-<pre>
-CREATE INDEX part_pkg1 ON part_pkg ( disabled );
-CREATE INDEX part_svc1 ON part_svc ( disabled );
-CREATE INDEX cust_bill2 ON cust_bill ( _date );
-</pre>
- <li>If you want to use ACH (electronic checks), you will need to make changes to your database. The easiest way to make these changes is to dump your database (with pg_dump), change the payinfo field in the cust_pay, cust_refund, h_cust_pay and h_cust_refund tables from varchar(16) to varchar(80), reload the database from the dump.
- <li>If you will be doing bind exports you should make additional changes to your database. Follow the directions above to dump the database and change the reczone and recdata fields in the domain_record and h_domain_record tables from varchar(80) to varchar(255).
- <li>If you made changes to your db schema from a dump as listed above run dbdef-create.
- <li>Restart Apache and freeside-queued.
-</body>
diff --git a/httemplate/edit/access_user.html b/httemplate/edit/access_user.html
index 2b19dbf7b..fb2a97196 100644
--- a/httemplate/edit/access_user.html
+++ b/httemplate/edit/access_user.html
@@ -6,6 +6,7 @@
{ field=>'_password', type=>'password' },
'last',
'first',
+ { field=>'disabled', type=>'checkbox', value=>'Y' },
],
'labels' => {
'usernum' => 'User number',
@@ -13,6 +14,7 @@
'_password' => 'Password',
'last' => 'Last name',
'first' => 'First name',
+ 'disabled' => 'Disable employee',
},
'viewall_dir' => 'browse',
'html_bottom' =>
diff --git a/httemplate/edit/cust_credit.cgi b/httemplate/edit/cust_credit.cgi
index d19f0e4b3..8de627d20 100755
--- a/httemplate/edit/cust_credit.cgi
+++ b/httemplate/edit/cust_credit.cgi
@@ -24,7 +24,7 @@ my $otaker = getotaker;
my $p1 = popurl(1);
-%><%= include('/elements/header-popup.html', 'Post Credit') %>
+%><%= include('/elements/header-popup.html', 'Enter Credit') %>
<% if ( $cgi->param('error') ) { %>
<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
@@ -72,7 +72,7 @@ Credit
</TABLE>
<BR>
-<CENTER><INPUT TYPE="submit" VALUE="Post credit"></CENTER>
+<CENTER><INPUT TYPE="submit" VALUE="Enter credit"></CENTER>
</FORM>
</BODY>
</HTML>
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
index bb2a8618e..c3d1804bc 100755
--- a/httemplate/edit/cust_main.cgi
+++ b/httemplate/edit/cust_main.cgi
@@ -64,7 +64,11 @@ if ( $cgi->param('error') ) {
@invoicing_list = ();
}
$cgi->delete_all();
+
my $action = $custnum ? 'Edit' : 'Add';
+$action .= ": ". $cust_main->name if $custnum;
+
+my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
%>
@@ -77,38 +81,29 @@ my $action = $custnum ? 'Edit' : 'Add';
) %>
<% if ( $error ) { %>
-<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $error %></FONT>
+<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $error %></FONT><BR><BR>
<% } %>
<FORM NAME="topform" STYLE="margin-bottom: 0">
<INPUT TYPE="hidden" NAME="custnum" VALUE="<%= $custnum %>">
-Customer # <%= $custnum ? "<B>$custnum</B>" : " (NEW)" %>
-
-<!-- agent -->
-
-<%
+<% if ( $custnum ) { %>
+ Customer #<B><%= $custnum %></B> -
+ <B><FONT COLOR="<%= $cust_main->statuscolor %>">
+ <%= ucfirst($cust_main->status) %>
+ </FONT></B>
+ <BR><BR>
+<% } %>
-my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
+<%= &ntable("#cccccc") %>
-my %agent_search = dbdef->table('agent')->column('disabled')
- ? ( 'disabled' => '' ) : ();
-my @agents = qsearch( 'agent', \%agent_search );
-#die "No agents created!" unless @agents;
-eidiot "You have not created any agents (or all agents are disabled). 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
+<!-- agent -->
+<%= include('/elements/tr-select-agent.html', $cust_main->agentnum,
+ 'label' => "<B>${r}Agent</B>",
+ 'empty_label' => 'Select agent',
+ )
%>
-<% if ( scalar(@agents) == 1 ) { %>
- <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
-<% } else { %>
- <BR><BR><%=$r%>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 %>
- <% } %>
- </SELECT>
-<% } %>
-
<!-- referral (advertising source) -->
<%
@@ -118,28 +113,9 @@ if ( $custnum && ! $conf->exists('editreferrals') ) {
<INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
-<%
- } else {
-
- my(@referrals) = qsearch('part_referral',{});
- if ( scalar(@referrals) == 0 ) {
- 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;
-%>
-
- <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
-
<% } else { %>
- <BR><BR><%=$r%>Advertising source
- <SELECT NAME="refnum" SIZE="1">
- <%= $refnum ? '' : '<OPTION VALUE="">' %>
- <% foreach my $referral (sort { $a->refnum <=> $b->refnum } @referrals) { %>
- <OPTION VALUE="<%= $referral->refnum %>" <%= $referral->refnum == $refnum ? 'SELECTED' : '' %>><%= $referral->refnum %>: <%= $referral->referral %>
- <% } %>
- </SELECT>
-<% } %>
+ <%= include('/elements/tr-select-part_referral.html') %>
<% } %>
@@ -153,14 +129,26 @@ if ( $cust_main->referral_custnum
) {
%>
- <BR><BR>Referring Customer:
- <A HREF="<%= popurl(1) %>/cust_main.cgi?<%= $cust_main->referral_custnum %>"><%= $cust_main->referral_custnum %>: <%= $referring_cust_main->name %></A>
+ <TR>
+ <TD ALIGN="right">Referring customer</TD>
+ <TD>
+ <A HREF="<%= popurl(1) %>/cust_main.cgi?<%= $cust_main->referral_custnum %>"><%= $cust_main->referral_custnum %>: <%= $referring_cust_main->name %></A>
+ </TD>
+ </TR>
<INPUT TYPE="hidden" NAME="referral_custnum" VALUE="<%= $cust_main->referral_custnum %>">
<% } elsif ( ! $conf->exists('disable_customer_referrals') ) { %>
- <BR><BR>Referring customer number:
- <INPUT TYPE="text" NAME="referral_custnum" VALUE="">
+ <TR>
+ <TD ALIGN="right">Referring customer</TD>
+ <TD>
+ <!-- <INPUT TYPE="text" NAME="referral_custnum" VALUE=""> -->
+ <%= include('/elements/search-cust_main.html',
+ 'field_name' => 'referral_custnum',
+ )
+ %>
+ </TD>
+ </TR>
<% } else { %>
@@ -168,6 +156,8 @@ if ( $cust_main->referral_custnum
<% } %>
+</TABLE>
+
<!-- contact info -->
<BR><BR>
@@ -377,10 +367,10 @@ unless ( $custnum ) {
#false laziness, copied from FS::cust_pkg::order
my $pkgpart;
+ my @agents = $FS::CurrentUser::CurrentUser->agents;
if ( scalar(@agents) == 1 ) {
# $pkgpart->{PKGPART} is true iff $custnum may purchase PKGPART
- my($agent)=qsearchs('agent',{'agentnum'=> $agentnum });
- $pkgpart = $agent->pkgpart_hashref;
+ $pkgpart = $agents[0]->pkgpart_hashref;
} else {
#can't know (agent not chosen), so, allow all
my %typenum;
diff --git a/httemplate/edit/cust_pay.cgi b/httemplate/edit/cust_pay.cgi
index a03a245eb..e7734c1fc 100755
--- a/httemplate/edit/cust_pay.cgi
+++ b/httemplate/edit/cust_pay.cgi
@@ -9,22 +9,20 @@ my %payby = (
'MCRD' => 'Manual credit card',
);
-my($link, $linknum, $paid, $payby, $payinfo, $quickpay, $_date);
+my($link, $linknum, $paid, $payby, $payinfo, $_date);
if ( $cgi->param('error') ) {
$link = $cgi->param('link');
$linknum = $cgi->param('linknum');
$paid = $cgi->param('paid');
$payby = $cgi->param('payby');
$payinfo = $cgi->param('payinfo');
- $quickpay = $cgi->param('quickpay');
$_date = $cgi->param('_date') ? str2time($cgi->param('_date')) : time;
} elsif ( $cgi->param('custnum') =~ /^(\d+)$/ ) {
- $link = 'custnum';
+ $link = $cgi->param('popup') ? 'popup' : 'custnum';
$linknum = $1;
$paid = '';
$payby = $cgi->param('payby') || 'BILL';
$payinfo = '';
- $quickpay = $cgi->param('quickpay');
$_date = time;
} elsif ( $cgi->param('invnum') =~ /^(\d+)$/ ) {
$link = 'invnum';
@@ -32,7 +30,6 @@ if ( $cgi->param('error') ) {
$paid = '';
$payby = $cgi->param('payby') || 'BILL';
$payinfo = "";
- $quickpay = '';
$_date = time;
} else {
die "illegal query ". $cgi->keywords;
@@ -43,9 +40,15 @@ my $paybatch = "webui-$_date-$$-". rand() * 2**32;
my $title = 'Post '. $payby{$payby}. ' payment';
$title .= " against Invoice #$linknum" if $link eq 'invnum';
-%>
+if ( $link eq 'popup' ) {
+
+%><%= include('/elements/header-popup.html', $title ) %>
+
+<% } else { %>
-<%= include("/elements/header.html",$title, '') %>
+<%= include("/elements/header.html", $title, '') %>
+
+<% } %>
<% if ( $cgi->param('error') ) { %>
<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
@@ -60,7 +63,6 @@ $title .= " against Invoice #$linknum" if $link eq 'invnum';
<FORM ACTION="<%= popurl(1) %>process/cust_pay.cgi" METHOD=POST>
<INPUT TYPE="hidden" NAME="link" VALUE="<%= $link %>">
<INPUT TYPE="hidden" NAME="linknum" VALUE="<%= $linknum %>">
-<INPUT TYPE="hidden" NAME="quickpay" VALUE="<%= $quickpay %>">
<%
my $money_char = $conf->config('money_char') || '$';
@@ -74,7 +76,9 @@ if ( $link eq 'invnum' ) {
}
%>
+<% unless ( $link eq 'popup' ) { %>
<%= small_custview($custnum, $conf->config('countrydefault')) %>
+<% } %>
<INPUT TYPE="hidden" NAME="payby" VALUE="<%= $payby %>">
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index f79cc0b24..c40a00492 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -15,7 +15,9 @@
# 'fields' => [
# 'columname',
# { 'field' => 'another_columname',
- # 'type' => 'text', #text, fixed, hidden
+ # 'type' => 'text', #text, fixed, hidden, checkbox
+ # #eventually more for <SELECT>, etc.
+ # 'value' => 'Y', #only for checkbox
# },
# ]
#
@@ -150,14 +152,17 @@
%>
</TD>
- <%
- #eventually more options for <SELECT>, etc. fields
- if ( $type eq 'fixed' ) {
- %>
+ <% if ( $type eq 'fixed' ) { %>
<TD BGCOLOR="#dddddd"><%= $f->{'value'} %></TD>
<INPUT TYPE="hidden" NAME="<%= $field %>" VALUE="<%= $f->{'value'} %>">
+ <% } elsif ( $type eq 'checkbox' ) { %>
+
+ <TD>
+ <INPUT TYPE="checkbox" NAME="<%= $field %>" VALUE="<%= $f->{'value'} %>" <%= $object->$field() eq $f->{'value'} ? ' CHECKED' : '' %>>
+ </TD>
+
<% } else { %>
<TD>
diff --git a/httemplate/edit/part_referral.cgi b/httemplate/edit/part_referral.cgi
deleted file mode 100755
index dce1e6394..000000000
--- a/httemplate/edit/part_referral.cgi
+++ /dev/null
@@ -1,44 +0,0 @@
-<%
-
-my $part_referral;
-if ( $cgi->param('error') ) {
- $part_referral = new FS::part_referral ( {
- map { $_, scalar($cgi->param($_)) } fields('part_referral')
- } );
-} elsif ( $cgi->keywords ) {
- my($query) = $cgi->keywords;
- $query =~ /^(\d+)$/;
- $part_referral = qsearchs( 'part_referral', { 'refnum' => $1 } );
-} else { #adding
- $part_referral = new FS::part_referral {};
-}
-my $action = $part_referral->refnum ? 'Edit' : 'Add';
-my $hashref = $part_referral->hashref;
-
-my $p1 = popurl(1);
-
-%><%= include('/elements/header.html', "$action Advertising source", menubar(
- 'Main Menu' => popurl(2),
- 'View all advertising sources' => popurl(2). "browse/part_referral.cgi",
-)) %>
-
-<% if ( $cgi->param('error') ) { %>
- <FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
-<% } %>
-
-<FORM ACTION="<%= $p1 %>process/part_referral.cgi" METHOD=POST>
-
-<INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $hashref->{refnum} %>">
-
-<%
-#print "Referral #", $hashref->{refnum} ? $hashref->{refnum} : "(NEW)";
-%>
-
-Advertising source <INPUT TYPE="text" NAME="referral" SIZE=32 VALUE="<%= $hashref->{referral} %>">
-
-<BR>
-<INPUT TYPE="submit" VALUE="<%= $hashref->{refnum} ? "Apply changes" : "Add advertising source" %>">
-
-</FORM>
-
-<%= include('/elements/footer.html') %>
diff --git a/httemplate/edit/part_referral.html b/httemplate/edit/part_referral.html
new file mode 100755
index 000000000..ec0f32f58
--- /dev/null
+++ b/httemplate/edit/part_referral.html
@@ -0,0 +1,9 @@
+<%= include( 'elements/edit.html',
+ 'name' => 'Advertising source',
+ 'table' => 'part_referral',
+ 'fields' => [ 'referral' ],
+ 'labels' => { 'referral' => 'Advertising source' },
+ 'viewall_dir' => 'browse',
+ 'html_table_bottom' => include('/elements/tr-select-agent.html'),
+ )
+%>
diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi
index 09a42544c..4ba30c435 100755
--- a/httemplate/edit/process/cust_main.cgi
+++ b/httemplate/edit/process/cust_main.cgi
@@ -103,8 +103,6 @@ if ( $new->custnum eq '' ) {
'popnum' => $cgi->param('popnum'),
} );
- my $y = $svc_acct->setdefault; # arguably should be in new method
- $error ||= $y unless ref($y);
#and just in case you were silly
$svc_acct->svcpart($svcpart);
$svc_acct->username($cgi->param('username'));
diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi
index 87d6011e7..cecccb59e 100755
--- a/httemplate/edit/process/cust_pay.cgi
+++ b/httemplate/edit/process/cust_pay.cgi
@@ -4,15 +4,16 @@ $cgi->param('linknum') =~ /^(\d+)$/
or die "Illegal linknum: ". $cgi->param('linknum');
my $linknum = $1;
-$cgi->param('link') =~ /^(custnum|invnum)$/
+$cgi->param('link') =~ /^(custnum|invnum|popup)$/
or die "Illegal link: ". $cgi->param('link');
-my $link = $1;
+my $field = my $link = $1;
+$field = 'custnum' if $field eq 'popup';
my $_date = str2time($cgi->param('_date'));
my $new = new FS::cust_pay ( {
- $link => $linknum,
- _date => $_date,
+ $field => $linknum,
+ _date => $_date,
map {
$_, scalar($cgi->param($_));
} qw(paid payby payinfo paybatch)
@@ -24,19 +25,30 @@ my $error = $new->insert;
if ($error) {
$cgi->param('error', $error);
print $cgi->redirect(popurl(2). 'cust_pay.cgi?'. $cgi->query_string );
-} elsif ( $link eq 'invnum' ) {
+} elsif ( $field eq 'invnum' ) {
print $cgi->redirect(popurl(3). "view/cust_bill.cgi?$linknum");
-} elsif ( $link eq 'custnum' ) {
+} elsif ( $field eq 'custnum' ) {
if ( $cgi->param('apply') eq 'yes' ) {
my $cust_main = qsearchs('cust_main', { 'custnum' => $linknum })
or die "unknown custnum $linknum";
$cust_main->apply_payments;
}
- if ( $cgi->param('quickpay') eq 'yes' ) {
- print $cgi->redirect(popurl(3). "search/cust_main-quickpay.html");
- } else {
+ if ( $link eq 'popup' ) {
+
+ %><%= header('Payment entered') %>
+ <SCRIPT TYPE="text/javascript">
+ window.top.location.reload();
+ </SCRIPT>
+
+ </BODY></HTML>
+ <%
+
+ } elsif ( $link eq 'custnum' ) {
print $cgi->redirect(popurl(3). "view/cust_main.cgi?$linknum");
+ } else {
+ die "unknown link $link";
}
+
}
%>
diff --git a/httemplate/edit/process/part_referral.cgi b/httemplate/edit/process/part_referral.cgi
deleted file mode 100755
index fd2c01506..000000000
--- a/httemplate/edit/process/part_referral.cgi
+++ /dev/null
@@ -1,28 +0,0 @@
-<%
-
-my $refnum = $cgi->param('refnum');
-
-my $new = new FS::part_referral ( {
- map {
- $_, scalar($cgi->param($_));
- } fields('part_referral')
-} );
-
-my $error;
-if ( $refnum ) {
- my $old = qsearchs( 'part_referral', { 'refnum' =>$ refnum } );
- die "(Old) Record not found!" unless $old;
- $error = $new->replace($old);
-} else {
- $error = $new->insert;
-}
-$refnum=$new->refnum;
-
-if ( $error ) {
- $cgi->param('error', $error);
- print $cgi->redirect(popurl(2). "part_referral.cgi?". $cgi->query_string );
-} else {
- print $cgi->redirect(popurl(3). "browse/part_referral.cgi");
-}
-
-%>
diff --git a/httemplate/edit/process/part_referral.html b/httemplate/edit/process/part_referral.html
new file mode 100755
index 000000000..0b5d959a0
--- /dev/null
+++ b/httemplate/edit/process/part_referral.html
@@ -0,0 +1,5 @@
+<%= include( 'elements/process.html',
+ 'table' => 'part_referral',
+ 'viewall_dir' => 'browse',
+ )
+%>
diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi
index 4b324a501..71b324d99 100755
--- a/httemplate/edit/svc_acct.cgi
+++ b/httemplate/edit/svc_acct.cgi
@@ -69,7 +69,20 @@ unless ( $svcnum || $cgi->param('error') ) { #adding
}
$svc_acct->set_default_and_fixed( {
- 'usergroup' => sub { @groups = split(',', shift ); },
+ #false laziness w/svc-acct::_fieldhandlers
+ 'usergroup' => sub {
+ my( $self, $groups ) = @_;
+ if ( ref($groups) eq 'ARRAY' ) {
+ @groups = @$groups;
+ $groups;
+ } elsif ( length($groups) ) {
+ @groups = split(/\s*,\s*/, $groups);
+ [ @groups ];
+ } else {
+ @groups = ();
+ [];
+ }
+ }
} );
}
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
index 3aa81be3b..ea8c418c3 100644
--- a/httemplate/elements/header.html
+++ b/httemplate/elements/header.html
@@ -3,6 +3,7 @@
my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc.
my $head = @_ ? shift : ''; #$head is for things that go in the <HEAD> section
my $conf = new FS::Conf;
+
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
@@ -18,17 +19,22 @@
<SCRIPT TYPE="text/javascript">
function clearhint_search_cust (what) {
- if ( what.value = '(cust #, name or company)' )
+ if ( what.value == '(cust #, name, company or phone)' )
+ what.value = '';
+ }
+
+ function clearhint_search_invoice (what) {
+ if ( what.value == '(inv #)' )
what.value = '';
}
function clearhint_search_svc (what) {
- if ( what.value = '(user, user@domain or domain)' )
+ if ( what.value == '(user, user@domain or domain)' )
what.value = '';
}
function clearhint_search_ticket (what) {
- if ( what.value = '(ticket # or subject string)' )
+ if ( what.value == '(ticket # or subject string)' )
what.value = '';
}
</SCRIPT>
@@ -39,13 +45,11 @@
<BODY BACKGROUND="<%=$fsurl%>images/background-cheat.png" <%= $etc %> STYLE="margin-top:0; margin-bottom:0; margin-left:0; margin-right:0">
<table width="100%" CELLPADDING=0 CELLSPACING=0 STYLE="padding-left:0; padding-right:4">
<tr>
- <td rowspan=2 BGCOLOR="#ffffff">
- <IMG BORDER=0 ALT="freeside" SRC="<%=$fsurl%>images/small-logo.png">
- </td>
+ <td rowspan=2 BGCOLOR="#ffffff"><IMG BORDER=0 ALT="freeside" SRC="<%=$fsurl%>images/small-logo.png"></td>
<td align=left rowspan=2 BGCOLOR="#ffffff"> <!-- valign="top" -->
<font size=6><%= $conf->config('company_name') || 'ExampleCo' %></font>
</td>
- <td align=right valign=top BGCOLOR="#ffffff">Logged in as <b><%= getotaker %>&nbsp</b><br><FONT SIZE="-2"><a href="<%=$fsurl%>pref/XXXwritethis">Preferences</a>&nbsp;<BR><BR></FONT>
+ <td align=right valign=top BGCOLOR="#ffffff"><FONT SIZE="-1">Logged in as <b><%= getotaker %>&nbsp</b><br></FONT><FONT SIZE="-2"><a href="<%=$fsurl%>pref/XXXwritethis">Preferences</a>&nbsp;<BR></FONT>
</td>
</tr>
<tr>
@@ -77,34 +81,88 @@
</tr>
</table>
- <TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=4>
+<style type="text/css">
+input.fsblackbutton {
+ background-color:#333333;
+ color: #ffffff;
+ border:1px solid;
+ border-top-color:#cccccc;
+ border-left-color:#cccccc;
+ border-right-color:#aaaaaa;
+ border-bottom-color:#aaaaaa;
+ font-weight:bold;
+ padding-left:12px;
+ padding-right:12px;
+ overflow:visible;
+ filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff333333',EndColorStr='#ff666666')
+}
+
+input.fsblackbuttonselected {
+ background-color:#7e0079;
+ color: #ffffff;
+ border:1px solid;
+ border-top-color:#cccccc;
+ border-left-color:#cccccc;
+ border-right-color:#aaaaaa;
+ border-bottom-color:#aaaaaa;
+ font-weight:bold;
+ padding-left:12px;
+ padding-right:12px;
+ overflow:visible;
+ filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff330033',EndColorStr='#ff7e0079')
+}
+</style>
+
+ <TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=0>
<TR>
- <TD COLSPAN=4 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%=$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
+ <TD COLSPAN=5 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%=$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
</TR>
+
<TR>
- <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" WIDTH="15%">
+
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
<FORM ACTION="<%=$fsurl%>edit/cust_main.cgi" METHOD="GET" STYLE="margin:0">
- <INPUT TYPE="submit" VALUE="New customer">
+ <INPUT TYPE="submit" VALUE="New customer" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="vertical-align:bottom">
</FORM>
</TD>
+
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
<FORM ACTION="<%=$fsurl%>search/cust_main.cgi" METHOD="GET" STYLE="margin:0">
- <INPUT NAME="search_cust" TYPE="text" VALUE="(cust #, name or company)" SIZE="22" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" STYLE="text-align:right">
- <INPUT TYPE="submit" VALUE="Search customers">
+ <INPUT NAME="search_cust" TYPE="text" VALUE="(cust #, name, company or phone)" SIZE="28" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" STYLE="vertical-align:bottom;text-align:right"><BR>
+ <A HREF="<%=$fsurl%>search/cust_main.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
+ <INPUT TYPE="submit" VALUE="Search customers" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
</FORM>
</TD>
+
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
+ <% if ( $FS::CurrentUser::CurrentUser->access_right('View invoices') ) { %>
+ <FORM ACTION="<%=$fsurl%>search/cust_bill.html" METHOD="GET" STYLE="margin:0;display:inline">
+ <INPUT NAME="invnum" TYPE="text" VALUE="(inv #)" SIZE="4" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" STYLE="vertical-align:bottom;text-align:right;margin-bottom:1px">
+ <% if ( $FS::CurrentUser::CurrentUser->access_right('List invoices') ) { %>
+ <A HREF="<%=$fsurl%>search/report_cust_bill.html" STYLE="color: #ffffff; font-size: 70%">Advanced</A>
+ <% } %>
+ <BR>
+ <INPUT TYPE="submit" VALUE="Search invoices" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
+ </FORM>
+ <% } %>
+ </TD>
+
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
<FORM ACTION="<%=$fsurl%>search/svc_Smart.html" METHOD="GET" STYLE="margin:0">
- <INPUT NAME="search_svc" TYPE="text" VALUE="(user, user@domain or domain)" SIZE="26" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" STYLE="text-align:right">
- <INPUT TYPE="submit" VALUE="Search services">
+ <INPUT NAME="search_svc" TYPE="text" VALUE="(user, user@domain or domain)" SIZE="26" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" STYLE="vertical-align:bottom;text-align:right"><BR>
+ <A HREF="<%=$fsurl%>search/svc_Smarter.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
+ <INPUT TYPE="submit" VALUE="Search services"CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
</FORM>
</TD>
- <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
+
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-right:4px">
<FORM ACTION="<%=$fsurl%>rt/index.html" METHOD="GET" STYLE="margin:0">
- <INPUT NAME="q" TYPE="text" VALUE="(ticket # or subject string)" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" STYLE="text-align:right">
- <INPUT TYPE="submit" VALUE="Search tickets">
+ <INPUT NAME="q" TYPE="text" VALUE="(ticket # or subject string)" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" STYLE="vertical-align:bottom;text-align:right"><BR>
+ <A HREF="<%=$fsurl%>rt/Search/Build.html" STYLE="color: #ffffff; font-size: 70%">Advanced</A>
+ <INPUT TYPE="submit" VALUE="Search tickets" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%;padding-left:2px;padding-right:2px">
</FORM>
</TD>
+
</TR>
</TABLE>
<TABLE WIDTH="100%" HEIGHT="100%" CELLSPACING=0 CELLPADDING=4>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 8c62d9778..a5b41aefd 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -189,26 +189,36 @@
'View/Edit address blocks' => [ $fsurl.'browse/addr_block.cgi', 'Manage address blocks and block assignments to broadband routers' ],
;
- tie my %config_misc, 'Tie::IxHash',
- 'View/Edit advertising sources' => [ $fsurl.'browse/part_referral.cgi', 'Where a customer heard about your service. Tracked for informational purposes' ],
- 'View/Edit virtual fields' => [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ],
- 'View/Edit message catalog' => [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ],
- 'View/Edit inventory classes and inventory' => [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ],
- ;
+ tie my %config_misc, 'Tie::IxHash';
+ $config_misc{'View/Edit advertising sources'} = [ $fsurl.'browse/part_referral.html', 'Where a customer heard about your service. Tracked for informational purposes' ]
+ if $curuser->access_right('Configuration')
+ || $curuser->access_right('Edit advertising sources')
+ || $curuser->access_right('Edit global advertising sources');
+ if ( $curuser->access_right('Configuration') ) {
+ $config_misc{'View/Edit virtual fields'} = [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ];
+ $config_misc{'View/Edit message catalog'} = [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ];
+ $config_misc{'View/Edit inventory classes and inventory'} = [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ];
+ }
- tie my %config_menu, 'Tie::IxHash',
- 'Settings' => [ $fsurl.'config/config-view.cgi', '' ],
- 'separator' => '', #its a separator!
- 'Employees' => [ \%config_employees, '' ],
- 'Provisioning, services and packages'
- => [ \%config_export_svc_pkg, '' ],
- 'Resellers' => [ \%config_agent, '' ],
- 'Billing' => [ \%config_billing, '' ],
- 'Dialup' => [ \%config_dialup, '' ],
- 'Fixed (username-less) broadband'
- => [ \%config_broadband, '' ],
- 'Miscellaneous' => [ \%config_misc, '' ],
- ;
+ tie my %config_menu, 'Tie::IxHash';
+ if ( $curuser->access_right('Configuration' ) ) {
+ %config_menu = (
+ 'Settings' => [ $fsurl.'config/config-view.cgi', '' ],
+ 'separator' => '', #its a separator!
+ 'Employees' => [ \%config_employees, '' ],
+ 'Provisioning, services and packages'
+ => [ \%config_export_svc_pkg, '' ],
+ 'Resellers' => [ \%config_agent, '' ],
+ 'Billing' => [ \%config_billing, '' ],
+ 'Dialup' => [ \%config_dialup, '' ],
+ 'Fixed (username-less) broadband'
+ => [ \%config_broadband, '' ],
+ );
+ }
+ $config_menu{'Miscellaneous'} = [ \%config_misc, '' ]
+ if $curuser->access_right('Configuration')
+ || $curuser->access_right('Edit advertising sources')
+ || $curuser->access_right('Edit global advertising sources');
tie my %menu, 'Tie::IxHash',
'Billing Main' => [ $fsurl, 'Billing start page', ],
@@ -225,7 +235,9 @@
$menu{'Tools'} = [ \%tools_menu, 'Tools' ]
if keys %tools_menu;
$menu{'Configuration'} = [ \%config_menu, 'Configuraiton and setup' ]
- if $curuser->access_right('Configuration');
+ if $curuser->access_right('Configuration')
+ || $curuser->access_right('Edit advertising sources')
+ || $curuser->access_right('Edit global advertising sources');
use vars qw($gmenunum);
$gmenunum = 0;
diff --git a/httemplate/elements/search-cust_main.html b/httemplate/elements/search-cust_main.html
new file mode 100644
index 000000000..ca91b4027
--- /dev/null
+++ b/httemplate/elements/search-cust_main.html
@@ -0,0 +1,163 @@
+<%
+ my( %opt ) = @_;
+ $opt{'field_name'} ||= 'custnum';
+
+ my $cust_main = '';
+ if ( $opt{'value'} ) {
+ $cust_main = qsearchs(
+ 'table' => 'cust_main',
+ 'hashref' => { 'custnum' => $opt{'value'} },
+ 'extra_sql' => " AND ". $FS::CurrentUser::CurrentUser->agentnums_sql,
+ );
+ }
+%>
+
+<INPUT TYPE="hidden" NAME="<%= $opt{'field_name'} %>" VALUE="<%= $opt{'value'} %>">
+
+<!-- some false laziness w/ misc/batch-cust_pay.html, though not as bad as i'd thought at first... -->
+
+<INPUT TYPE="text" NAME="<%= $opt{'field_name'} %>_search" ID="<%= $opt{'field_name'} %>_search" SIZE="32" VALUE="<%= $cust_main ? $cust_main->name : '(cust #, name or company)' %>" onFocus="clearhint_<%= $opt{'field_name'} %>_search(this);" onClick="clearhint_<%= $opt{'field_name'} %>_search(this);" onChange="smart_<%= $opt{'field_name'} %>_search(this);">
+
+<SELECT NAME="<%= $opt{'field_name'} %>_select" ID="<%= $opt{'field_name'} %>_select" STYLE="color:#ff0000; display:none" onChange="select_<%= $opt{'field_name'} %>(this);">
+</SELECT>
+
+<%= include('/elements/xmlhttp.html',
+ 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi',
+ 'subs' => [ 'smart_search' ],
+ )
+%>
+
+<SCRIPT TYPE="text/javascript">
+
+ function clearhint_<%= $opt{'field_name'} %>_search (what) {
+
+ what.style.color = '#000000';
+
+ if ( what.value == '(cust #, name or company)' )
+ what.value = '';
+
+ if ( what.value.indexOf('Customer not found: ') == 0 )
+ what.value = what.value.substr(20);
+
+ }
+
+ function smart_<%= $opt{'field_name'} %>_search(what) {
+
+ var customer = what.value;
+
+ if ( customer == 'searching...' || customer == ''
+ || customer.indexOf('Customer not found: ') == 0 )
+ return;
+
+ if ( what.getAttribute('magic') == 'nosearch' ) {
+ what.setAttribute('magic', '');
+ return;
+ }
+
+ //what.value = 'searching...'
+ what.disabled = true;
+ what.style.color= '#000000';
+ what.style.backgroundColor = '#dddddd';
+
+ var customer_select = document.getElementById('<%= $opt{'field_name'} %>_select');
+
+ //alert("search for customer " + customer);
+
+ function <%= $opt{'field_name'} %>_search_update(customers) {
+
+ //alert('customers returned: ' + customers);
+
+ var customerArray = eval('(' + customers + ')');
+
+ what.disabled = false;
+ what.style.backgroundColor = '#ffffff';
+
+ if ( customerArray.length == 0 ) {
+
+ what.form.<%= $opt{'field_name'} %>.value = '';
+
+ what.value = 'Customer not found: ' + what.value;
+ what.style.color = '#ff0000';
+
+ what.style.display = '';
+ customer_select.style.display = 'none';
+
+ } else if ( customerArray.length == 1 ) {
+
+ //alert('one customer found: ' + customerArray[0]);
+
+ what.form.<%= $opt{'field_name'} %>.value = customerArray[0][0];
+ what.value = customerArray[0][1];
+
+ what.style.display = '';
+ customer_select.style.display = 'none';
+
+ } else {
+
+ //alert('multiple customers found, have to create select dropdown');
+
+ //blank the current list
+ for ( var i = customer_select.length; i >= 0; i-- )
+ customer_select.options[i] = null;
+
+ opt(customer_select, '', 'Multiple customers match "' + customer + '" - select one', '#ff0000');
+
+ //add the multiple customers
+ for ( var s = 0; s < customerArray.length; s++ )
+ opt(customer_select, customerArray[s][0], customerArray[s][1], '#000000');
+
+ opt(customer_select, 'cancel', '(Edit search string)', '#000000');
+
+ what.style.display = 'none';
+ customer_select.style.display = '';
+
+ }
+
+ }
+
+ smart_search( customer, <%= $opt{'field_name'} %>_search_update );
+
+
+ }
+
+ function select_<%= $opt{'field_name'} %> (what) {
+
+ var custnum = what.options[what.selectedIndex].value;
+ var customer = what.options[what.selectedIndex].text;
+
+ var customer_obj = document.getElementById('<%= $opt{'field_name'} %>_search');
+
+ if ( custnum == '' ) {
+ //what.style.color = '#ff0000';
+
+ } else if ( custnum == 'cancel' ) {
+
+ customer_obj.style.color = '#000000';
+
+ what.style.display = 'none';
+ customer_obj.style.display = '';
+ customer_obj.focus();
+
+ } else {
+
+ what.form.<%= $opt{'field_name'} %>.value = custnum;
+
+ customer_obj.value = customer;
+ customer_obj.style.color = '#000000';
+
+ what.style.display = 'none';
+ customer_obj.style.display = '';
+
+ }
+
+ }
+
+ function opt(what,value,text,color) {
+ var optionName = new Option(text, value, false, false);
+ optionName.style.color = color;
+ var length = what.length;
+ what.options[length] = optionName;
+ }
+
+</SCRIPT>
+
diff --git a/httemplate/elements/select-agent.html b/httemplate/elements/select-agent.html
index 78ec25f82..009cc6e06 100644
--- a/httemplate/elements/select-agent.html
+++ b/httemplate/elements/select-agent.html
@@ -1,8 +1,7 @@
<%
my( $agentnum, %opt ) = @_;
- my %select_opt = ();
- $select_opt{'records'} = $opt{'agents'}
+ $opt{'records'} = delete $opt{'agents'}
if $opt{'agents'};
%><%= include( '/elements/select-table.html',
@@ -12,7 +11,8 @@
'empty_label' => 'all',
'hashref' => { 'disabled' => '' },
'extra_sql' => ' AND '.
- $FS::CurrentUser::CurrentUser->agentnums_sql,
- %select_opt,
+ $FS::CurrentUser::CurrentUser->agentnums_sql.
+ ' ORDER BY agent',
+ %opt,
)
%>
diff --git a/httemplate/elements/select-part_referral.html b/httemplate/elements/select-part_referral.html
new file mode 100644
index 000000000..deb87bd3b
--- /dev/null
+++ b/httemplate/elements/select-part_referral.html
@@ -0,0 +1,17 @@
+<%
+ my( $refnum, %opt ) = @_;
+
+ $opt{'records'} = delete $opt{'part_referrals'}
+ if $opt{'part_referrals'};
+
+%><%= include( '/elements/select-table.html',
+ 'table' => 'part_referral',
+ 'name_col' => 'referral',
+ 'value' => $refnum,
+ 'empty_label' => 'Select advertising source',
+ 'hashref' => { 'disabled' => '' },
+ 'extra_sql' => ' AND '.
+ FS::part_referral->all_part_referral(1),
+ %opt,
+ )
+%>
diff --git a/httemplate/elements/table-grid.html b/httemplate/elements/table-grid.html
index 17eafdf1a..fd1cb9113 100644
--- a/httemplate/elements/table-grid.html
+++ b/httemplate/elements/table-grid.html
@@ -5,9 +5,15 @@
%>
<STYLE TYPE="text/css">
+
.grid table { border: solid; empty-cells: show }
.grid TH { padding-left: 3px; padding-right: 3px; border: 1px solid #dddddd; border-bottom: dashed 1px black; border-right: none }
.grid TD { padding-left: 3px; padding-right: 3px; empty-cells: show; border: 1px solid #cccccc; border-bottom: none; border-right: none }
+
+.inv table { border: none }
+.inv TH { border: none }
+.inv TD { border: none }
+
</STYLE>
<TABLE CLASS="grid" CELLSPACING=<%= $opt{cellspacing} %> CELLPADDING=<%= $opt{cellpadding} %> BORDER=1 BORDERCOLOR="#000000" STYLE="border: solid 1px black; empty-cells: show">
diff --git a/httemplate/elements/tr-select-agent.html b/httemplate/elements/tr-select-agent.html
index 83c8d1758..6158f6f47 100644
--- a/httemplate/elements/tr-select-agent.html
+++ b/httemplate/elements/tr-select-agent.html
@@ -7,12 +7,9 @@
#here is the agent virtualization
my $agentnums_href = $FS::CurrentUser::CurrentUser->agentnums_href;
@agents = grep $agentnums_href->{$_->agentnum}, @{ $opt{'agents'} };
+ delete $opt{'agents'};
} else {
- @agents = qsearch( {
- 'table' => 'agent',
- 'hashref' => { disabled=>'' },
- 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
- });
+ @agents = $FS::CurrentUser::CurrentUser->agents;
}
%>
@@ -24,10 +21,11 @@
<% } else { %>
<TR>
- <TD ALIGN="right"><%= $opt{'label'} || 'Agent: ' %></TD>
+ <TD ALIGN="right"><%= $opt{'label'} || 'Agent' %></TD>
<TD>
<%= include( '/elements/select-agent.html', $agentnum,
'agents' => \@agents,
+ %opt,
)
%>
</TD>
diff --git a/httemplate/elements/tr-select-part_referral.html b/httemplate/elements/tr-select-part_referral.html
new file mode 100644
index 000000000..0108388bc
--- /dev/null
+++ b/httemplate/elements/tr-select-part_referral.html
@@ -0,0 +1,30 @@
+<%
+ my( $refnum, %opt ) = @_;
+
+ $opt{'part_referrals'} ||=
+ [ FS::part_referral->all_part_referral( 1 ) ]; #1: include global
+
+ my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
+
+%>
+
+<% if ( scalar( @{$opt{'part_referrals'}} ) == 0 ) {
+ 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.html and create one or more advertising sources.";
+ } elsif ( scalar( @{$opt{'part_referrals'}} ) == 1 ) {
+%>
+
+ <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $opt{'part_referrals'}->[0]->refnum %>">
+
+<% } else { %>
+
+ <TR>
+ <TH ALIGN="right"><%=$r%>Advertising source</TH>
+ <TD>
+ <%= include( '/elements/select-part_referral.html', $refnum,
+ 'part_referrals' => $opt{'part_referrals'},
+ )
+ %>
+ </TD>
+ </TR>
+
+<% } %>
diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html
index 41537ee7e..ed093ac08 100644
--- a/httemplate/misc/batch-cust_pay.html
+++ b/httemplate/misc/batch-cust_pay.html
@@ -264,7 +264,7 @@
customer_input<%= $row %>.onclick = clearhint_customer;
customer_input<%= $row %>.onchange = search_customer;
</SCRIPT>
- <SELECT NAME="cust_select<%= $row %>" ID="cust_select<%= $row %>" rownum="<%= $row %>" STYLE="color:#ff0000; display:none"">
+ <SELECT NAME="cust_select<%= $row %>" ID="cust_select<%= $row %>" rownum="<%= $row %>" STYLE="color:#ff0000; display:none">
</SELECT>
<SCRIPT TYPE="text/javascript">
var customer_select<%= $row %> = document.getElementById("cust_select<%= $row %>");
diff --git a/httemplate/misc/cust_main-import.cgi b/httemplate/misc/cust_main-import.cgi
index 484855005..2ad4d95b4 100644
--- a/httemplate/misc/cust_main-import.cgi
+++ b/httemplate/misc/cust_main-import.cgi
@@ -1,51 +1,65 @@
-<!-- mason kludge -->
<%= include("/elements/header.html",'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
+Import a CSV file containing customer records.
+<BR><BR>
+
+<!-- Simple 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> -->
+
+Extended file format is CSV, with the following field order: <i>agent_custid, refnum[1], last, first, address1, address2, city, state, zip, country, daytime, night, ship_last, ship_first, ship_address1, ship_address2, ship_city, ship_state, ship_zip, ship_country, payinfo, paycvv, paydate, invoicing_list, pkgpart, username, _password</i>
+<BR><BR>
- if ( scalar(@agents) == 1 ) {
+[1] This field has special treatment upon import: If a string is passed instead
+of an integer, the string is searched for and if necessary auto-created in the
+target table.
+<BR><BR>
+
+<%= &ntable("#cccccc") %>
+
+<%= include('/elements/tr-select-agent.html', '', #$agentnum,
+ 'label' => "<B>Agent</B>",
+ 'empty_label' => 'Select agent',
+ )
%>
- <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 ) {
+
+<TR>
+ <TH ALIGN="right">Format</TH>
+ <TD>
+ <SELECT NAME="format">
+<!-- <OPTION VALUE="simple">Simple -->
+ <OPTION VALUE="extended" SELECTED>Extended
+ </SELECT>
+ </TD>
+</TR>
+
+<TR>
+ <TH ALIGN="right">CSV filename</TH>
+ <TD><INPUT TYPE="file" NAME="csvfile"></TD>
+</TR>
+
+<% #include('/elements/tr-select-part_referral.html')
%>
- <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>
+
+<!--
+<TR>
+ <TH>First package</TH>
+ <TD>
+ <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>
+ </TD>
+</TR>
+-->
+
+</TABLE>
+<BR><BR>
+
+<INPUT TYPE="submit" VALUE="Import">
+</FORM>
+
+<%= include('/elements/footer.html') %>
diff --git a/httemplate/misc/download-batch.cgi b/httemplate/misc/download-batch.cgi
index 6172b1335..2d6f8a286 100644
--- a/httemplate/misc/download-batch.cgi
+++ b/httemplate/misc/download-batch.cgi
@@ -16,7 +16,7 @@ my $oldAutoCommit = $FS::UID::AutoCommit;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
-my $pay_batch = qsearchs('pay_batch', {'status'=>'O'} );
+my $pay_batch = qsearchs('pay_batch', {'status'=>''} );
die "No pending batch. \n" unless $pay_batch;
my %batchhash = $pay_batch->hash;
diff --git a/httemplate/misc/process/cust_main-import.cgi b/httemplate/misc/process/cust_main-import.cgi
index 371929a5e..aff6b39ef 100644
--- a/httemplate/misc/process/cust_main-import.cgi
+++ b/httemplate/misc/process/cust_main-import.cgi
@@ -10,8 +10,9 @@
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 )],
+ #'fields' => [qw( cust_pkg.setup dayphone first last address1 address2
+ # city state zip comments )],
+ 'format' => scalar($cgi->param('format')),
} )
: 'No file';
diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi
index 7d5941a16..f6841a099 100755
--- a/httemplate/search/cust_main.cgi
+++ b/httemplate/search/cust_main.cgi
@@ -109,6 +109,7 @@ if ( $cgi->param('browse')
push @qual, FS::cust_main->cancel_sql if $cgi->param('cancelled');
push @qual, FS::cust_main->prospect_sql if $cgi->param('prospect');
push @qual, FS::cust_main->active_sql if $cgi->param('active');
+ push @qual, FS::cust_main->inactive_sql if $cgi->param('inactive');
push @qual, FS::cust_main->susp_sql if $cgi->param('suspended');
#EWWWWWW
@@ -415,48 +416,78 @@ END
foreach my $addl_col ( @addl_cols ) { %>
- <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
-
- <% if ( $addl_col eq 'tickets' ) {
- if ( @custom_priorities ) {
- print &itable('', 0);
- foreach my $priority ( @custom_priorities, '' ) {
-
- my $num =
- FS::TicketSystem->num_customer_tickets($custnum,$priority);
- my $ahref = '';
- $ahref= '<A HREF="'.
- FS::TicketSystem->href_customer_tickets($custnum,$priority).
- '">'
- if $num;
-
- print '<TR>'.
- " <TD ALIGN=right><FONT SIZE=-1>$ahref$num</A></FONT></TD>".
- "<TD ALIGN=left><FONT SIZE=-1>$ahref".
- ( $priority || '<i>(none)</i>' ).
- "</A></FONT></TD></TR>";
-
- }
- print '<TR><TD BGCOLOR="#000000" COLSPAN=2></TD></TR>'.
- '<TR><TD ALIGN=right><FONT SIZE=-1>';
- }
-
- my $ahref = '';
- $ahref = '<A HREF="'.
- FS::TicketSystem->href_customer_tickets($custnum).
- '">'
- if $cust_main->get($addl_col);
-
- print $ahref. $cust_main->get($addl_col). '</A>';
- print "</FONT></TD><TD ALIGN=left>".
- "<FONT SIZE=-1>${ahref}Total</A><FONT>".
- "</TD></TR></TABLE>"
- if @custom_priorities;
+ <% if ( $addl_col eq 'tickets' ) { %>
- } else {
- print $cust_main->get($addl_col);
+ <% if ( @custom_priorities ) { %>
+
+ <TD CLASS="inv" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+
+ <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0>
+
+ <% foreach my $priority ( @custom_priorities, '' ) { %>
+
+ <%
+ my $num =
+ FS::TicketSystem->num_customer_tickets($custnum,$priority);
+ my $ahref = '';
+ $ahref= '<A HREF="'.
+ FS::TicketSystem->href_customer_tickets($custnum,$priority).
+ '">'
+ if $num;
+ %>
+
+ <TR>
+ <TD ALIGN=right>
+ <FONT SIZE=-1><%= $ahref.$num %></A></FONT>
+ </TD>
+ <TD ALIGN=left>
+ <FONT SIZE=-1><%= $ahref %><%= $priority || '<i>(none)</i>' %></A></FONT>
+ </TD>
+ </TR>
+
+ <% } %>
+
+ <TR>
+ <TH ALIGN=right STYLE="border-top: dashed 1px black">
+ <FONT SIZE=-1>
+
+ <% } else { %>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+
+ <% } %>
+
+ <%
+ my $ahref = '';
+ $ahref = '<A HREF="'.
+ FS::TicketSystem->href_customer_tickets($custnum).
+ '">'
+ if $cust_main->get($addl_col);
+ %>
+
+ <%= $ahref %><%= $cust_main->get($addl_col) %></A>
+
+ <% if ( @custom_priorities ) { %>
+
+ </FONT></TH>
+ <TH ALIGN=left STYLE="border-top: dashed 1px black">
+ <FONT SIZE=-1><%= ${ahref} %>Total</A><FONT>
+ </TH>
+ </TR>
+ </TABLE>
+
+ <% } %>
+
+ </FONT></TD>
+
+ <% } else { %>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+ <%= $cust_main->get($addl_col) %>
+ </FONT></TD>
+
+<%
}
- print "</FONT></TD>";
}
my($n1)='';
diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi
index e8b3f490d..614e9b509 100755
--- a/httemplate/search/cust_pkg.cgi
+++ b/httemplate/search/cust_pkg.cgi
@@ -24,6 +24,12 @@ if ( $cgi->param('magic') eq 'active'
push @where, FS::cust_pkg->active_sql();
+} elsif ( $cgi->param('magic') eq 'inactive'
+ || $cgi->param('status') eq 'inactive' ) {
+
+ push @where, FS::cust_pkg->inactive_sql();
+
+
} elsif ( $cgi->param('magic') eq 'suspended'
|| $cgi->param('status') eq 'suspended' ) {
@@ -47,7 +53,10 @@ if ( $cgi->param('magic') eq 'active'
#false lazinessish w/graph/cust_bill_pkg.cgi
my $classnum = 0;
my @pkg_class = ();
-if ( $cgi->param('classnum') =~ /^(\d*)$/ ) {
+if ( exists($cgi->Vars->{'classnum'})
+ && $cgi->param('classnum') =~ /^(\d*)$/
+ )
+{
$classnum = $1;
if ( $classnum ) { #a specific class
push @where, "classnum = $classnum";
@@ -90,7 +99,7 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
} else {
if ( $cgi->param('magic') &&
- $cgi->param('magic') =~ /^(active|suspended|cancell?ed)$/
+ $cgi->param('magic') =~ /^(active|inactive|suspended|cancell?ed)$/
) {
$orderby = 'ORDER BY pkgnum';
diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html
index 6cf574164..3e689eba1 100644
--- a/httemplate/search/elements/search.html
+++ b/httemplate/search/elements/search.html
@@ -380,8 +380,7 @@
my $tableref = $_;
- '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0'.
- ' STYLE="border:none">'.
+ '<TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0>'.
join('', map {
@@ -393,7 +392,7 @@
my $element = $_;
- '<TD STYLE="border:none"'.
+ '<TD'.
( $element->{'align'}
? ' ALIGN="'. $element->{'align'}. '"'
: ''
@@ -432,6 +431,8 @@
) {
+ my $class = ( $field =~ /^<TABLE/i ) ? 'inv' : 'grid';
+
my $align = $aligns ? shift @$aligns : '';
$align = " ALIGN=$align" if $align;
@@ -471,7 +472,7 @@
}
%>
- <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"<%= $align %>><%= $font %><%= $a %><%= $s %><%= $field %><%= $es %><%= $a ? '</A>' : '' %><%= $font ? '</FONT>' : '' %></TD>
+ <TD CLASS="<%= $class %>" BGCOLOR="<%= $bgcolor %>"<%= $align %>><%= $font %><%= $a %><%= $s %><%= $field %><%= $es %><%= $a ? '</A>' : '' %><%= $font ? '</FONT>' : '' %></TD>
<% } %>
<% } else { %>
<% foreach ( @$row ) { %>
diff --git a/httemplate/search/report_receivables.cgi b/httemplate/search/report_receivables.cgi
index c1a239fd2..3052ea93c 100755
--- a/httemplate/search/report_receivables.cgi
+++ b/httemplate/search/report_receivables.cgi
@@ -62,26 +62,19 @@ END
my $owed_cols = join(',', map owed( @$_, 'cust'=>1 ), @ranges );
- my $recurring = <<END;
- '0' != ( select freq from part_pkg
- where cust_pkg.pkgpart = part_pkg.pkgpart )
-END
-
- my $packages_cols = <<END;
+ my $select_count_pkgs = FS::cust_main->select_count_pkgs_sql;
- ( select count(*) from cust_pkg
- where cust_main.custnum = cust_pkg.custnum
- and $recurring
- and ( cancel = 0 or cancel is null )
- ) as uncancelled_pkgs,
-
- ( select count(*) from cust_pkg
- where cust_main.custnum = cust_pkg.custnum
- and $recurring
- and ( cancel = 0 or cancel is null )
- and ( susp = 0 or susp is null )
- ) as active_pkgs
+ my $active_sql = FS::cust_pkg->active_sql;
+ my $inactive_sql = FS::cust_pkg->inactive_sql;
+ my $suspended_sql = FS::cust_pkg->inactive_sql;
+ my $cancelled_sql = FS::cust_pkg->inactive_sql;
+ my $packages_cols = <<END;
+ ( $select_count_pkgs ) AS num_pkgs_sql,
+ ( $select_count_pkgs AND $active_sql ) AS active_pkgs,
+ ( $select_count_pkgs AND $inactive_sql ) AS inactive_pkgs,
+ ( $select_count_pkgs AND $suspended_sql ) AS suspended_pkgs,
+ ( $select_count_pkgs AND $cancelled_sql ) AS cancelled_pkgs
END
my $where = "where ". owed(0, 0, 'cust'=>1, 'noas'=>1). " > 0";
@@ -119,6 +112,27 @@ END
my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ];
+ my $status_statuscol = sub {
+ #conceptual false laziness with cust_main::status...
+ my $row = shift;
+
+ my $status = 'unknown';
+ if ( $row->num_pkgs_sql == 0 ) {
+ $status = 'prospect';
+ } elsif ( $row->active_pkgs > 0 ) {
+ $status = 'active';
+ } elsif ( $row->inactive_pkgs > 0 ) {
+ $status = 'inactive';
+ } elsif ( $row->suspended_pkgs > 0 ) {
+ $status = 'suspended';
+ } elsif ( $row->cancelled_pkgs > 0 ) {
+ $status = 'cancelled'
+ }
+
+ ( ucfirst($status), $FS::cust_main::statuscolor{$status} );
+ };
+
+
%><%= include( 'elements/search.html',
'title' => 'Accounts Receivable Aging Summary',
'name' => 'customers',
@@ -156,20 +170,7 @@ END
],
'fields' => [
\&FS::UI::Web::cust_fields,
- sub {
- my $row = shift;
- my $status = 'Cancelled';
- my $statuscol = 'FF0000';
- if ( $row->uncancelled_pkgs ) {
- $status = 'Suspended';
- $statuscol = 'FF9900';
- if ( $row->active_pkgs ) {
- $status = 'Active';
- $statuscol = '00CC00';
- }
- }
- $status;
- },
+ sub { ( &{$status_statuscol}(shift) )[0] },
#sub { ucfirst(shift->status) },
sub { sprintf( $money_char.'%.2f',
shift->get('owed_0_30') ) },
@@ -202,20 +203,7 @@ END
'b', '', '', '', '', 'b', ],
'color' => [
( map '', FS::UI::Web::cust_header() ),
- sub {
- my $row = shift;
- my $status = 'Cancelled';
- my $statuscol = 'FF0000';
- if ( $row->uncancelled_pkgs ) {
- $status = 'Suspended';
- $statuscol = 'FF9900';
- if ( $row->active_pkgs ) {
- $status = 'Active';
- $statuscol = '00CC00';
- }
- }
- $statuscol;
- },
+ sub { ( &{$status_statuscol}(shift) )[1] },
#sub { shift->statuscolor; },
'',
'',
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 89ddc38f2..8267fea51 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -2,24 +2,6 @@
my $conf = new FS::Conf;
-my %uiview = ();
-my %uiadd = ();
-foreach my $part_svc ( qsearch('part_svc',{}) ) {
- $uiview{$part_svc->svcpart} = $p. "view/". $part_svc->svcdb . ".cgi";
- $uiadd{$part_svc->svcpart}= $p. "edit/". $part_svc->svcdb . ".cgi";
-}
-
-%>
-
-
-<%= include("/elements/header.html","Customer View",
- include("/elements/menubar.html",
- 'Main Menu' => $p,
-)) %>
-
-
-<%
-
my $curuser = $FS::CurrentUser::CurrentUser;
die "No customer specified (bad URL)!" unless $cgi->keywords;
@@ -31,6 +13,7 @@ die "Customer not found!" unless $cust_main;
%>
+<%= include("/elements/header.html","Customer View: ". $cust_main->name ) %>
<% if ( $curuser->access_right('Edit customer') ) { %>
<A HREF="<%= $p %>edit/cust_main.cgi?<%= $custnum %>">Edit this customer</A> |
diff --git a/httemplate/view/cust_main/billing.html b/httemplate/view/cust_main/billing.html
index 895814cc2..191d3092f 100644
--- a/httemplate/view/cust_main/billing.html
+++ b/httemplate/view/cust_main/billing.html
@@ -1,12 +1,24 @@
<%
my( $cust_main ) = @_;
my @invoicing_list = $cust_main->invoicing_list;
+ my $conf = new FS::Conf;
+ my $money_char = $conf->config('money_char') || '$';
%>
Billing information
(<A HREF="<%= $p %>misc/bill.cgi?<%= $cust_main->custnum %>">Bill now</A>)
<%= ntable("#cccccc") %><TR><TD><%= ntable("#cccccc",2) %>
+<%
+( my $balance = $cust_main->balance )
+ =~ s/^(\-?)(.*)$/<FONT SIZE=+1>$1<\/FONT>$money_char$2/;
+%>
+
+<TR>
+ <TD ALIGN="right">Balance due</TD>
+ <TD BGCOLOR="#ffffff"><B><%= $balance %></B></TD>
+</TR>
+
<TR>
<TD ALIGN="right">Billing&nbsp;type</TD>
<TD BGCOLOR="#ffffff">
@@ -159,7 +171,7 @@ if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format
<%= join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || 'no' %>
</TD>
</TR>
-<% my $conf = new FS::Conf; if ( $conf->exists('voip-cust_cdr_spools') ) { %>
+<% if ( $conf->exists('voip-cust_cdr_spools') ) { %>
<TR>
<TD ALIGN="right">Spool&nbsp;CDRs</TD>
<TD BGCOLOR="#ffffff"><%= $cust_main->spool_cdr ? 'yes' : 'no' %></TD>
diff --git a/httemplate/view/cust_main/misc.html b/httemplate/view/cust_main/misc.html
index 69e120573..f06a4fbd2 100644
--- a/httemplate/view/cust_main/misc.html
+++ b/httemplate/view/cust_main/misc.html
@@ -1,13 +1,20 @@
<%
my( $cust_main ) = @_;
+ my $conf = new FS::Conf;
%>
<%= ntable("#cccccc") %><TR><TD><%= &ntable("#cccccc",2) %>
+
<TR>
<TD ALIGN="right">Customer&nbsp;number</TD>
<TD BGCOLOR="#ffffff"><%= $cust_main->custnum %></TD>
</TR>
+<TR>
+ <TD ALIGN="right">Status</TD>
+ <TD BGCOLOR="#ffffff"><FONT COLOR="#<%= $cust_main->statuscolor %>"><B><%= ucfirst($cust_main->status) %></B></FONT></TD>
+</TR>
+
<%
my @agents = qsearch( 'agent', {} );
my $agent;
@@ -25,8 +32,18 @@
$agent = $agents[0];
}
- my @referrals = qsearch( 'part_referral', {} );
- unless ( scalar(@referrals) == 1 ) {
+ if ( $cust_main->agent_custid ) {
+%>
+
+<TR>
+ <TD ALIGN="right">Agent customer ref#</TD>
+ <TD BGCOLOR="#ffffff"><%= $cust_main->agent_custid %></TD>
+</TR>
+
+<%
+ }
+
+ unless ( FS::part_referral->num_part_referral == 1 ) {
my $referral = qsearchs('part_referral', {
'refnum' => $cust_main->refnum
} );
@@ -40,10 +57,6 @@
<% } %>
<TR>
- <TD ALIGN="right">Order taker</TD>
- <TD BGCOLOR="#ffffff"><%= $cust_main->otaker %></TD>
-</TR>
-<TR>
<TD ALIGN="right">Referring&nbsp;Customer</TD>
<TD BGCOLOR="#ffffff">
@@ -71,5 +84,10 @@
</TD>
</TR>
+<TR>
+ <TD ALIGN="right">Order taker</TD>
+ <TD BGCOLOR="#ffffff"><%= $cust_main->otaker %></TD>
+</TR>
+
</TABLE></TD></TR></TABLE>
diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html
index beb67f325..9cd1e284f 100755
--- a/httemplate/view/cust_main/packages.html
+++ b/httemplate/view/cust_main/packages.html
@@ -7,10 +7,6 @@
my $packages = get_packages($cust_main, $conf);
%>
-<STYLE TYPE="text/css">
-.package .provision { font-weight: bold }
-</STYLE>
-
<A NAME="cust_pkg"><FONT SIZE="+2">Packages</FONT></A>
<% if ( $curuser->access_right('Order customer package') ) { %>
@@ -54,30 +50,33 @@ Current packages
<% if ( @$packages ) { %>
-<TABLE CLASS="package" BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">
+<%= include('/elements/table-grid.html') %>
+
+<% my $bgcolor1 = '#eeeeee';
+ my $bgcolor2 = '#ffffff';
+ my $bgcolor = '';
+%>
+
<TR>
- <TH>Package</TH>
- <TH>Status</TH>
- <TH COLSPAN=2>Services</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Package</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Services</TH>
</TR>
<%
foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
- my $rowspan = 0;
- if ($pkg->{cancel}) {
- $rowspan = 0;
+ if ( $bgcolor eq $bgcolor1 ) {
+ $bgcolor = $bgcolor2;
} else {
- foreach my $svcpart (@{$pkg->{svcparts}}) {
- $rowspan += $svcpart->{count};
- $rowspan++ if ($svcpart->{count} < $svcpart->{quantity});
- }
- }
+ $bgcolor = $bgcolor1;
+ }
+
%>
<!--pkgnum: <%=$pkg->{pkgnum}%>-->
<TR>
- <TD ROWSPAN=<%= $rowspan || 1 %>>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<A NAME="cust_pkg<%=$pkg->{pkgnum}%>"><%=$pkg->{pkgnum}%></A>:
<%=$pkg->{pkg}%> - <%=$pkg->{comment}%><BR>
<FONT SIZE=-1>
@@ -94,8 +93,8 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
<% } %>
</FONT>
</TD>
- <TD ROWSPAN=<%= $rowspan || 1 %>>
- <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
+ <TD CLASS="inv" BGCOLOR="<%= $bgcolor %>">
+ <TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
<%
sub myfreq {
@@ -315,42 +314,51 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
</TABLE>
</TD>
-<%
- if ($rowspan == 0) { print qq!</TR>\n!; next; }
+<TD CLASS="inv" BGCOLOR="<%= $bgcolor %>">
+ <TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
- my $cnt = 0;
+
+<%
foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
foreach my $service (@{$svcpart->{services}}) {
- print '<TR>' if ($cnt > 0);
%>
- <TD><%=svc_link($svcpart,$service)%></TD>
- <TD><%=svc_label_link($svcpart,$service)%>
- <% if ( $curuser->access_right('Unprovision customer service') ) { %>
- <BR>(&nbsp;<%=svc_unprovision_link($service)%>&nbsp;)
+ <TR>
+ <TD ALIGN="right" VALIGN="top" ROWSPAN=2><%=svc_link($svcpart,$service)%></TD>
+ <TD STYLE="padding-bottom:0px"><B><%=svc_label_link($svcpart,$service)%></B></TD>
+ </TR>
+
+ <% if ( $curuser->access_right('Unprovision customer service') ) { %>
+ <TR>
+ <TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">(&nbsp;<%=svc_unprovision_link($service)%>&nbsp;)</FONT></TD>
+ </TR>
+ <% } %>
+
<% } %>
- </TD>
-</TR>
-<%
- $cnt++;
- }
- if ( $svcpart->{count} < $svcpart->{quantity} ) {
- print '<TR>' if ($cnt > 0);
- if ( $curuser->access_right('Provision customer service') ) {
- print '<TD COLSPAN=2>'.
- svc_provision_link($pkg, $svcpart, $conf, $curuser).
- '</TD></TR>';
- } else {
- #print '<TD COLSPAN=2>&nbsp;</TD></TR>';
- print '<TD COLSPAN=2></TD></TR>';
- }
- }
- }
-}
-#end display packages
+ <% if ( $curuser->access_right('Provision customer service')
+ && $svcpart->{count} < $svcpart->{quantity}
+ )
+ {
+ %>
+
+ <TR>
+ <TD COLSPAN=2 ALIGN="center" STYLE="padding-bottom:4px;padding-top:0px">
+ <B><%= svc_provision_link($pkg, $svcpart, $conf, $curuser) %></B>
+ </TD>
+ </TR>
+
+ <% } %>
+
+<% } %>
+
+</TABLE>
+</TD>
+
+<% } #end display packages
%>
</TABLE>
+
<% } else { %>
<BR>
<% } %>
diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html
index 5c2aa24c9..aef5fb8f8 100644
--- a/httemplate/view/cust_main/payment_history.html
+++ b/httemplate/view/cust_main/payment_history.html
@@ -21,21 +21,21 @@
<% if ( $payby{'BILL'} && $curuser->access_right('Post payment') ) { %>
<%= $s++ ? ' | ' : '' %>
- <A HREF="<%= $p %>edit/cust_pay.cgi?payby=BILL;custnum=<%= $custnum %>">Post check payment</A>
+ <A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('<%= $p %>edit/cust_pay.cgi?popup=1;payby=BILL;custnum=<%= $custnum %>', 392, 336, 'cust_pay_popup' ), CAPTION, 'Enter check payment', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Enter check payment</A>
<% } %>
<% if ( $payby{'CASH'} && $curuser->access_right('Post payment') ) { %>
<%= $s++ ? ' | ' : '' %>
- <A HREF="<%= $p %>edit/cust_pay.cgi?payby=CASH;custnum=<%= $custnum %>">Post cash payment</A>
+ <A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('<%= $p %>edit/cust_pay.cgi?popup=1;payby=CASH;custnum=<%= $custnum %>', 392, 336, 'cust_pay_popup' ), CAPTION, 'Enter cash payment', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Enter cash payment</A>
<% } %>
<% if ( $payby{'WEST'} && $curuser->access_right('Post payment') ) { %>
<%= $s++ ? ' | ' : '' %>
- <A HREF="<%= $p %>edit/cust_pay.cgi?payby=WEST;custnum=<%= $custnum %>">Post Western Union payment</A>
+ <A HREF="<%= $p %>edit/cust_pay.cgi?payby=WEST;custnum=<%= $custnum %>">Enter Western Union payment</A>
<% } %>
@@ -62,7 +62,7 @@
<% if ( $payby{'MCRD'} && $curuser->access_right('Post payment') ) { %>
<%= $s++ ? ' | ' : '' %>
- <A HREF="<%= $p %>edit/cust_pay.cgi?payby=MCRD;custnum=<%= $custnum %>">Post manual credit card payment</A>
+ <A HREF="<%= $p %>edit/cust_pay.cgi?payby=MCRD;custnum=<%= $custnum %>">Post manual (offline) credit card payment</A>
<% } %>
@@ -70,7 +70,7 @@
<% if ( $curuser->access_right('Post credit') ) { %>
- <A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('<%= $p %>edit/cust_credit.cgi?<%= $custnum %>', 392, 336, 'cust_credit_popup' ), CAPTION, 'Post credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Post credit</A>
+ <A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('<%= $p %>edit/cust_credit.cgi?<%= $custnum %>', 392, 336, 'cust_credit_popup' ), CAPTION, 'Enter credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Enter credit</A>
<BR>
@@ -135,7 +135,7 @@ foreach my $cust_pay ($cust_main->cust_pay) {
$post = '</FONT></B>';
$apply = qq! (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}edit/cust_bill_pay.cgi?!.
$cust_pay->paynum.
- qq!', 392, 336, 'cust_credit_popup' ), CAPTION, 'Post credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!;
+ qq!', 392, 336, 'cust_bill_pay_popup' ), CAPTION, 'Apply payment', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!;
} elsif ( scalar(@cust_bill_pay) == 1
&& scalar(@cust_pay_refund) == 0
@@ -161,7 +161,7 @@ foreach my $cust_pay ($cust_main->cust_pay) {
} elsif ( $app->isa('FS::cust_pay_refund') ) {
$desc .= '&nbsp;&nbsp;'.
'$'. $app->amount.
- ' refunded on'. time2str("%D", $app->_date).
+ ' refunded on '. time2str("%D", $app->_date).
'<BR>';
} else {
die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
@@ -173,7 +173,7 @@ foreach my $cust_pay ($cust_main->cust_pay) {
$cust_pay->unapplied. ' unapplied</FONT></B>'.
qq! (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}edit/cust_bill_pay.cgi?!.
$cust_pay->paynum.
- qq!', 392, 336, 'cust_credit_popup' ), CAPTION, 'Post credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!.
+ qq!', 392, 336, 'cust_bill_pay_popup' ), CAPTION, 'Apply payment', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!.
'<BR>';
}
}
@@ -195,13 +195,14 @@ foreach my $cust_pay ($cust_main->cust_pay) {
my $void = '';
if ( $cust_pay->closed !~ /^Y/i
&& ( ( $cust_pay->payby eq 'CARD'
- && $conf->exists('cc-void')
- && $curuser->acccess_right('Credit card void')
+ && $curuser->access_right('Credit card void')
)
|| ( $cust_pay->payby eq 'CHEK'
- && $conf->exists('echeck-void')
- && $curuser->acccess_right('Echeck void')
- )
+ && $curuser->access_right('Echeck void')
+ )
+ || ( $cust_pay->payby !~ /^(CARD|CHEK)$/
+ && $curuser->access_right('Regular void')
+ )
)
)
{
@@ -231,7 +232,6 @@ foreach my $cust_pay ($cust_main->cust_pay) {
my $unapply = '';
if ( $cust_pay->closed !~ /^Y/i
- && $conf->exists('unapplypayments')
&& scalar(@cust_bill_pay)
&& $curuser->access_right('Unapply payment')
)
@@ -268,7 +268,6 @@ foreach my $cust_pay_void ($cust_main->cust_pay_void) {
my $unvoid = '';
if ( $cust_pay_void->closed !~ /^Y/i
- && $conf->exists('unvoid')
&& $curuser->access_right('Unvoid')
)
{
@@ -307,7 +306,7 @@ foreach my $cust_credit ($cust_main->cust_credit) {
$post = '</FONT></B>';
$apply = qq! (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}edit/cust_credit_bill.cgi?!.
$cust_credit->crednum.
- qq!', 392, 336, 'cust_credit_popup' ), CAPTION, 'Post credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!;
+ qq!', 392, 336, 'cust_credit_bill_popup' ), CAPTION, 'Apply credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!;
} elsif ( scalar(@cust_credit_bill) == 1
&& scalar(@cust_credit_refund) == 0
&& $cust_credit->credited == 0 ) {
@@ -332,7 +331,7 @@ foreach my $cust_credit ($cust_main->cust_credit) {
} elsif ( $app->isa('FS::cust_credit_refund') ) {
$desc .= '&nbsp;&nbsp;'.
'$'. $app->amount.
- ' refunded on'. time2str("%D", $app->_date).
+ ' refunded on '. time2str("%D", $app->_date).
'<BR>';
} else {
die "$app is not a FS::cust_credit_bill or a FS::cust_credit_refund";
@@ -343,14 +342,18 @@ foreach my $cust_credit ($cust_main->cust_credit) {
$cust_credit->credited. ' unapplied</FONT></B>'.
qq! (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}edit/cust_credit_bill.cgi?!.
$cust_credit->crednum.
- qq!', 392, 336, 'cust_credit_popup' ), CAPTION, 'Post credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!.
+ qq!', 392, 336, 'cust_credit_bill_popup' ), CAPTION, 'Apply credit', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">apply</A>)!.
'<BR>';
}
}
#
my $delete = '';
if ( $cust_credit->closed !~ /^Y/i
- && $conf->exists('deletecredits')
+
+ #s'pose deleting a credit isn't bad like deleting a payment
+ # and this needs to be generally available until we have credit voiding..
+ #&& $conf->exists('deletecredits')
+
&& $curuser->access_right('Delete credit')
)
{
@@ -362,7 +365,6 @@ foreach my $cust_credit ($cust_main->cust_credit) {
my $unapply = '';
if ( $cust_credit->closed !~ /^Y/i
- && $conf->exists('unapplycredits')
&& scalar(@cust_credit_bill)
&& $curuser->access_right('Unapply credit')
)
@@ -408,37 +410,98 @@ foreach my $cust_refund ($cust_main->cust_refund) {
%>
-<%= include("/elements/table.html") %>
+<%= include("/elements/table-grid.html") %>
+
+<% my $bgcolor1 = '#eeeeee';
+ my $bgcolor2 = '#ffffff';
+ my $bgcolor = '';
+%>
+
<TR>
- <TH>Date</TH>
- <TH>Description</TH>
- <TH><FONT SIZE=-1>Charge</FONT></TH>
- <TH><FONT SIZE=-1>Payment</FONT></TH>
- <TH><FONT SIZE=-1>In-house<BR>Credit</FONT></TH>
- <TH><FONT SIZE=-1>Refund</FONT></TH>
- <TH><FONT SIZE=-1>Balance</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Date</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Description</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Charge</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Payment</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>In-house<BR>Credit</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Refund</FONT></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Balance</FONT></TH>
</TR>
<%
#display payment history
-my %target;
my $balance = 0;
+my %target = ();
+my $money_char = $conf->config('money_char') || '$';
+
+my $years = $conf->config('payment_history-years') || 2;
+my $older_than = time - $years * 31556736; #60*60*24*365.24
+my $hidden = 0;
+my $seen = 0;
+my $old_history = 0;
+
foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) {
+ my $display;
+ if ( $item->{'date'} < $older_than ) {
+ $display = ' STYLE="display:none" ';
+ $hidden = 1;
+ } else {
+
+ $display = '';
+
+ if ( $hidden && ! $seen++ ) {
+ ( my $balance_forward = $money_char. $balance ) =~ s/^\$\-/-&nbsp;\$/;
+ %>
+
+ <TR ID="balance_forward_row">
+ <TD CLASS="grid" BGCOLOR="#dddddd">
+ <%= time2str("%D",$item->{'date'}) %>
+ </TD>
+
+ <TD CLASS="grid" BGCOLOR="#dddddd">
+ <I>Starting balance on <%= time2str("%D",$item->{'date'}) %></I>
+ (<A HREF="javascript:void(0);" onClick="show_history();">show prior history</A>)
+ </TD>
+
+ <TD CLASS="grid" BGCOLOR="#dddddd"></TD>
+ <TD CLASS="grid" BGCOLOR="#dddddd"></TD>
+ <TD CLASS="grid" BGCOLOR="#dddddd"></TD>
+ <TD CLASS="grid" BGCOLOR="#dddddd"></TD>
+ <TD CLASS="grid" BGCOLOR="#dddddd"><I><%= $balance_forward %></I></TD>
+
+ </TR>
+
+ <%
+ }
+
+ }
+
+ if ( $bgcolor eq $bgcolor1 ) {
+ $bgcolor = $bgcolor2;
+ } else {
+ $bgcolor = $bgcolor1;
+ }
+
my $charge = exists($item->{'charge'})
- ? sprintf('$%.2f', $item->{'charge'})
+ ? sprintf("$money_char\%.2f", $item->{'charge'})
: '';
+
my $payment = exists($item->{'payment'})
- ? sprintf('-&nbsp;$%.2f', $item->{'payment'})
+ ? sprintf("-&nbsp;$money_char\%.2f", $item->{'payment'})
: '';
- $payment ||= sprintf('<DEL>-&nbsp;$%.2f</DEL>', $item->{'void_payment'})
+
+ $payment ||= sprintf( "<DEL>-&nbsp;$money_char\%.2f</DEL>",
+ $item->{'void_payment'}
+ )
if exists($item->{'void_payment'});
+
my $credit = exists($item->{'credit'})
- ? sprintf('-&nbsp;$%.2f', $item->{'credit'})
+ ? sprintf("-&nbsp;$money_char\%.2f", $item->{'credit'})
: '';
+
my $refund = exists($item->{'refund'})
- ? sprintf('$%.2f', $item->{'refund'})
+ ? sprintf("$money_char\%.2f", $item->{'refund'})
: '';
my $target = exists($item->{'target'}) ? $item->{'target'} : '';
@@ -449,12 +512,12 @@ foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) {
$balance += $item->{'refund'} if exists $item->{'refund'};
$balance = sprintf("%.2f", $balance);
$balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
- ( my $showbalance = '$'. $balance ) =~ s/^\$\-/-&nbsp;\$/;
+ ( my $showbalance = $money_char. $balance ) =~ s/^\$\-/-&nbsp;\$/;
%>
- <TR>
- <TD>
+ <TR <%= $display ? $display.' ID="old_history'.$old_history++.'"' : ''%>>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
<% unless ( !$target || $target{$target}++ ) { %>
<A NAME="<%= $target %>">
<% } %>
@@ -464,15 +527,44 @@ foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) {
<% } %>
</FONT>
</TD>
- <TD><%= $item->{'desc'} %></TD>
- <TD ALIGN="right"><%= $charge %></TD>
- <TD ALIGN="right"><%= $payment %></TD>
- <TD ALIGN="right"><%= $credit %></TD>
- <TD ALIGN="right"><%= $refund %></TD>
- <TD ALIGN="right"><%= $showbalance %></TD>
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $item->{'desc'} %>
+ </TD>
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $charge %>
+ </TD>
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $payment %>
+ </TD>
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $credit %>
+ </TD>
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $refund %>
+ </TD>
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>">
+ <%= $showbalance %>
+ </TD>
</TR>
<% } %>
</TABLE>
+<SCRIPT TYPE="text/javascript">
+
+function show_history () {
+ //alert('showing history!');
+
+ var balance_forward_row = document.getElementById('balance_forward_row');
+
+ balance_forward_row.style.display = 'none';
+ for ( var i = 0; i < <%= $old_history %>; i++ ) {
+ var oldRow = document.getElementById('old_history'+i);
+ oldRow.style.display = '';
+ }
+
+}
+
+</SCRIPT>
+
diff --git a/httemplate/view/cust_main/tickets.html b/httemplate/view/cust_main/tickets.html
index 5c1d94ee1..93cb51f25 100644
--- a/httemplate/view/cust_main/tickets.html
+++ b/httemplate/view/cust_main/tickets.html
@@ -2,7 +2,7 @@
my( $cust_main ) = @_;
my $conf = new FS::Conf;
- my $num = 10;
+ my $num = $conf->config('cust_main-max_tickets') || 10;
my @tickets = ();
unless ( $conf->config('ticket_system-custom_priority_field') ) {
@@ -31,24 +31,46 @@
Highest priority tickets
(<A HREF="<%= FS::TicketSystem->href_customer_tickets($cust_main->custnum) %>">View all tickets for this customer</A>)
(<A HREF="<%= FS::TicketSystem->href_new_ticket($cust_main, join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list ) ) %>">New ticket for this customer</A>)
-<%= include("/elements/table.html") %>
+
+<%= include("/elements/table-grid.html") %>
+
+<% my $bgcolor1 = '#eeeeee';
+ my $bgcolor2 = '#ffffff';
+ my $bgcolor = '';
+%>
+
<TR>
- <TH>#</TH>
- <TH>Subject</TH>
- <TH>Priority</TH>
- <TH>Queue</TH>
- <TH>Status</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">#</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Subject</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Priority</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Queue</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
</TR>
+
<% foreach my $ticket ( @tickets ) {
my $href = FS::TicketSystem->href_ticket($ticket->{id});
+ if ( $bgcolor eq $bgcolor1 ) {
+ $bgcolor = $bgcolor2;
+ } else {
+ $bgcolor = $bgcolor1;
+ }
%>
+
<TR>
- <TD><A HREF=<%=$href%>><%= $ticket->{id} %></A></TD>
- <TD><A HREF=<%=$href%>><%= $ticket->{subject} %></A></TD>
- <TD ALIGN="right"><%= $ticket->{content} || $ticket->{priority} %></TD>
- <TD><%= $ticket->{name} %></TD>
- <TD><%= $ticket->{status} %></TD>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF=<%=$href%>><%= $ticket->{id} %></A></TD>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF=<%=$href%>><%= $ticket->{subject} %></A></TD>
+
+ <TD ALIGN="right" CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $ticket->{content} || $ticket->{priority} %></TD>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $ticket->{name} %></TD>
+
+ <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $ticket->{status} %></TD>
+
</TR>
+
<% } %>
+
</TABLE>