diff options
Diffstat (limited to 'httemplate')
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 %> + <FONT COLOR="#7e0079"> + <%= my $num_prospect = $agent->num_prospect_cust_main %> + </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 %> + </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 %> </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 %> </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 %> </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 %> + </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 %> </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 %> </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 %> </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 -<DirectoryMatch "^/var/www/freeside/rt/.*NoAuth"> -<Limit GET POST> -allow from all -Satisfy any -SetHandler perl-script -PerlHandler HTML::Mason -</Limit> -</DirectoryMatch> -# replace /var/www/freeside with your freeside document root -<DirectoryMatch "^/var/www/freeside/rt/.*NoAuth/images"> -SetHandler None -</DirectoryMatch> -# replace /var/www/freeside with your freeside document root -<Directory /var/www/freeside/rt/Ticket/Attachment> -SetHandler perl-script -PerlHandler HTML::Mason -</Directory> -</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 -<Directory /var/www/freeside> -<Files ~ (\.cgi|\.html)> -AddHandler perl-script .cgi .html -PerlHandler HTML::Mason -</Files> -<Perl> -require "/usr/local/etc/freeside/handler.pl"; -</Perl> -</Directory> -</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 -<Directory /var/www/freeside> -AuthName Freeside -AuthType Basic -AuthUserFile /usr/local/etc/freeside/htpasswd -require valid-user -</Directory> -</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 <Files ~ \.cgi> to <Files ~ (\.cgi|\.html)> - <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> !; %> @@ -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> !; +<%= &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 %> </b><br><FONT SIZE="-2"><a href="<%=$fsurl%>pref/XXXwritethis">Preferences</a> <BR><BR></FONT> + <td align=right valign=top BGCOLOR="#ffffff"><FONT SIZE="-1">Logged in as <b><%= getotaker %> </b><br></FONT><FONT SIZE="-2"><a href="<%=$fsurl%>pref/XXXwritethis">Preferences</a> <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> !; + +%> + +<% 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 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 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 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 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>( <%=svc_unprovision_link($service)%> ) + <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">( <%=svc_unprovision_link($service)%> )</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> </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 .= ' '. '$'. $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 .= ' '. '$'. $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/^\$\-/- \$/; + %> + + <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('- $%.2f', $item->{'payment'}) + ? sprintf("- $money_char\%.2f", $item->{'payment'}) : ''; - $payment ||= sprintf('<DEL>- $%.2f</DEL>', $item->{'void_payment'}) + + $payment ||= sprintf( "<DEL>- $money_char\%.2f</DEL>", + $item->{'void_payment'} + ) if exists($item->{'void_payment'}); + my $credit = exists($item->{'credit'}) - ? sprintf('- $%.2f', $item->{'credit'}) + ? sprintf("- $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/^\$\-/- \$/; + ( my $showbalance = $money_char. $balance ) =~ s/^\$\-/- \$/; %> - <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> |