diff options
Diffstat (limited to 'httemplate')
-rw-r--r-- | httemplate/edit/process/quick-charge.cgi | 108 | ||||
-rw-r--r-- | httemplate/edit/quick-charge.html | 114 | ||||
-rw-r--r-- | httemplate/elements/tr-input-beginning_ending.html | 4 | ||||
-rw-r--r-- | httemplate/graph/report_money_time_daily.html | 9 | ||||
-rw-r--r-- | httemplate/loginout/login.html | 2 | ||||
-rw-r--r-- | httemplate/search/cust_bill_pkg.cgi | 41 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg.cgi | 4 | ||||
-rwxr-xr-x | httemplate/search/report_cust_pkg.html | 60 | ||||
-rw-r--r-- | httemplate/search/report_sales_commission.html | 16 | ||||
-rw-r--r-- | httemplate/search/sales_commission.html | 72 | ||||
-rw-r--r-- | httemplate/search/sales_pkg_class.html | 56 | ||||
-rw-r--r-- | httemplate/view/cust_main/packages/package.html | 28 | ||||
-rw-r--r-- | httemplate/view/cust_main/payment_history.html | 14 | ||||
-rw-r--r-- | httemplate/view/cust_main/payment_history/voided_credit.html | 25 |
14 files changed, 389 insertions, 164 deletions
diff --git a/httemplate/edit/process/quick-charge.cgi b/httemplate/edit/process/quick-charge.cgi index 38f06e1e9..db41fb238 100644 --- a/httemplate/edit/process/quick-charge.cgi +++ b/httemplate/edit/process/quick-charge.cgi @@ -10,8 +10,9 @@ % } <%init> +my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('One-time charge'); + unless $curuser->access_right('One-time charge'); my $error = ''; my $conf = new FS::conf; @@ -27,49 +28,76 @@ $param->{"custnum"} =~ /^(\d+)$/ or $error .= "Illegal customer number " . $param->{"custnum"} . " "; my $custnum = $1; -$param->{"amount"} =~ /^\s*(\d*(?:\.?\d{1,2}))\s*$/ - or $error .= "Illegal amount " . $param->{"amount"} . " "; -my $amount = $1; +my $cust_main = FS::cust_main->by_key($custnum) + or die "custnum $custnum not found"; -my $quantity = 1; -if ( $cgi->param('quantity') =~ /^\s*(\d+)\s*$/ ) { - $quantity = $1; -} +exists($curuser->agentnums_href->{$cust_main->agentnum}) + or die "access denied"; -$param->{'tax_override'} =~ /^\s*([,\d]*)\s*$/ - or $error .= "Illegal tax override " . $param->{"tax_override"} . " "; -my $override = $1; +if ( $param->{'pkgnum'} =~ /^(\d+)$/ ) { + my $pkgnum = $1; + die "access denied" + unless $curuser->access_right('Modify one-time charge'); -if ( $param->{'taxclass'} eq '(select)' ) { - $error .= "Must select a tax class. " - unless ($conf->exists('enable_taxproducts') && - ( $override || $param->{taxproductnum} ) - ); - $cgi->param('taxclass', ''); -} + my $cust_pkg = FS::cust_pkg->by_key($1) + or die "pkgnum $pkgnum not found"; + + my $part_pkg = $cust_pkg->part_pkg; + die "pkgnum $pkgnum is not a one-time charge" unless $part_pkg->freq eq '0'; + + $error = $cust_pkg->modify_charge( + 'pkg' => scalar($cgi->param('pkg')), + 'classnum' => scalar($cgi->param('classnum')), + 'additional' => \@description, + 'adjust_commission' => ($cgi->param('adjust_commission') ? 1 : 0), + ); + +} else { + # the usual case: new one-time charge + $param->{"amount"} =~ /^\s*(\d*(?:\.?\d{1,2}))\s*$/ + or $error .= "Illegal amount " . $param->{"amount"} . " "; + my $amount = $1; + + my $quantity = 1; + if ( $cgi->param('quantity') =~ /^\s*(\d+)\s*$/ ) { + $quantity = $1; + } + + $param->{'tax_override'} =~ /^\s*([,\d]*)\s*$/ + or $error .= "Illegal tax override " . $param->{"tax_override"} . " "; + my $override = $1; + + if ( $param->{'taxclass'} eq '(select)' ) { + $error .= "Must select a tax class. " + unless ($conf->exists('enable_taxproducts') && + ( $override || $param->{taxproductnum} ) + ); + $cgi->param('taxclass', ''); + } + + unless ( $error ) { + my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or $error .= "Unknown customer number $custnum. "; -unless ( $error ) { - my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) - or $error .= "Unknown customer number $custnum. "; - - $error ||= $cust_main->charge( { - 'amount' => $amount, - 'quantity' => $quantity, - 'bill_now' => scalar($cgi->param('bill_now')), - 'invoice_terms' => scalar($cgi->param('invoice_terms')), - 'start_date' => ( scalar($cgi->param('start_date')) - ? parse_datetime($cgi->param('start_date')) - : '' - ), - 'no_auto' => scalar($cgi->param('no_auto')), - 'pkg' => scalar($cgi->param('pkg')), - 'setuptax' => scalar($cgi->param('setuptax')), - 'taxclass' => scalar($cgi->param('taxclass')), - 'taxproductnum' => scalar($cgi->param('taxproductnum')), - 'tax_override' => $override, - 'classnum' => scalar($cgi->param('classnum')), - 'additional' => \@description, - } ); + $error ||= $cust_main->charge( { + 'amount' => $amount, + 'quantity' => $quantity, + 'bill_now' => scalar($cgi->param('bill_now')), + 'invoice_terms' => scalar($cgi->param('invoice_terms')), + 'start_date' => ( scalar($cgi->param('start_date')) + ? parse_datetime($cgi->param('start_date')) + : '' + ), + 'no_auto' => scalar($cgi->param('no_auto')), + 'pkg' => scalar($cgi->param('pkg')), + 'setuptax' => scalar($cgi->param('setuptax')), + 'taxclass' => scalar($cgi->param('taxclass')), + 'taxproductnum' => scalar($cgi->param('taxproductnum')), + 'tax_override' => $override, + 'classnum' => scalar($cgi->param('classnum')), + 'additional' => \@description, + } ); + } } </%init> diff --git a/httemplate/edit/quick-charge.html b/httemplate/edit/quick-charge.html index 466091dfa..666ba82de 100644 --- a/httemplate/edit/quick-charge.html +++ b/httemplate/edit/quick-charge.html @@ -104,6 +104,49 @@ function bill_now_changed (what) { <TABLE ID="QuickChargeTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 STYLE="background-color: #cccccc"> +% if ( $cust_pkg ) { + +<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $cust_pkg->pkgnum %>"> +<& /elements/tr-fixed.html, + label => 'Amount', + field => 'amount', + value => $money_char . sprintf('%.2f',$part_pkg->option('setup_fee')), +&> + +% if ( $conf->exists('invoice-unitprice') ) { +<& /elements/tr-fixed.html, + label => 'Quantity', + field => 'quantity', + value => $cust_pkg->quantity +&> +% } + +<& /elements/tr-select-pkg_class.html, 'curr_value' => $classnum &> + +% # crudely estimate whether any agent commission credits might exist +% my @events = grep { $_->part_event->action =~ /credit/ } +% $cust_pkg->cust_event; +% if ( scalar @events ) { +<TR><TD></TD> + <TD><INPUT TYPE="checkbox" NAME="adjust_commission" VALUE="Y" CHECKED> +<% emt('Adjust commission credits if necessary') %> +</TD> +</TR> +% } + +% #display the future or past charge date, but don't allow changes +% # XXX we probably _could_ let as-yet unbilled charges be rescheduled, but +% # there's no compelling need yet +% if ( $cust_pkg->setup or $cust_pkg->start_date ) { +% my $label = $cust_pkg->setup ? emt('Billed on') : emt('Will be billed'); +% my $field = $cust_pkg->setup ? 'setup' : 'start_date'; + <& /elements/tr-fixed-date.html, + label => $label, + value => $cust_pkg->get($field) + &> +% } # else we don't show anything here +% } else { # new one-time charge + <TR> <TD ALIGN="right"><% mt('Amount') |h %> </TD> <TD> @@ -117,7 +160,7 @@ function bill_now_changed (what) { </TD> </TR> -% if ( $conf->exists('invoice-unitprice') ) { +% if ( $conf->exists('invoice-unitprice') ) { <TR> <TD ALIGN="right"><% mt('Quantity') |h %> </TD> <TD> @@ -128,9 +171,9 @@ function bill_now_changed (what) { onKeyPress = "return enable_quick_charge(event)"> </TD> </TR> -% } +% } -<& /elements/tr-select-pkg_class.html, 'curr_value' => $cgi->param('classnum') &> +<& /elements/tr-select-pkg_class.html, 'curr_value' => $classnum &> <TR> <TD ALIGN="right"><% mt('Invoice now') |h %></TD> @@ -206,6 +249,8 @@ function bill_now_changed (what) { <& /elements/tr-select-taxoverride.html, 'onclick' => 'parent.taxoverridemagic(this);', 'curr_value' => $cgi->param('tax_override') &> +% } # if !$cust_pkg + <TR> <TD ALIGN="right"><% mt('Description') |h %> </TD> <TD> @@ -226,11 +271,7 @@ function bill_now_changed (what) { </TR> % my $row = 0; -% if ( $cgi->param('error') || $cgi->param('magic') ) { -% my $param = $cgi->Vars; -% -% for ( $row = 0; exists($param->{"description$row"}); $row++ ) { - +% foreach (@description) { <TR> <TD></TD> <TD> @@ -238,21 +279,25 @@ function bill_now_changed (what) { NAME = "description<% $row %>" SIZE = "60" MAXLENGTH = "65" - VALUE = "<% $param->{"description$row"} |h %>" + VALUE = "<% $_ |h %>" rownum = "<% $row %>" onKeyPress = "return enable_quick_charge(event)" onKeyUp = "return possiblyAddRow(event)" > </TD> </TR> -% } +% $row++; % } </TABLE> <BR> -<INPUT TYPE="submit" ID="submit" NAME="submit" VALUE="<% mt('Add one-time charge') |h %>" <% $cgi->param('error') ? '' :' DISABLED' %>> +% my $label = $cust_pkg +% ? emt('Modify one-time charge') +% : emt('Add one-time charge'); +<INPUT TYPE="submit" ID="submit" NAME="submit" VALUE="<% $label %>" \ +<% ($cgi->param('error') || $cust_pkg) ? '' :' DISABLED' %>> </FORM> @@ -329,9 +374,25 @@ my $conf = new FS::Conf; my $date_format = $conf->config('date_format') || '%m/%d/%Y'; my $money_char = $conf->config('money_char') || '$'; -$cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum'; -my $custnum = $1; -my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ); #XXX agent-virt +my ($cust_main, $cust_pkg); +if ( $cgi->param('change_pkgnum') ) { + # change an existing one-time charge + die "access denied" + unless $curuser->access_right('Modify one-time charge'); + + $cgi->param('change_pkgnum') =~ /^(\d+)$/ or die "illegal pkgnum"; + $cust_pkg = FS::cust_pkg->by_key($1) or die "pkgnum $1 not found"; + $cust_main = $cust_pkg->cust_main; +} else { + $cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum'; + $cust_main = FS::cust_main->by_key($1) or die "custnum $1 not found"; +} + +my $custnum = $cust_main->custnum; +# agent-virt +if (!exists($curuser->agentnums_href->{$cust_main->agentnum})) { + die "custnum $custnum not found"; +} my $format = "%m/%d/%Y %T %z (%Z)"; #false laziness w/REAL_cust_pkg.cgi? my $start_date = $cust_main->next_bill_date; @@ -360,4 +421,29 @@ if ( $cust_main->invoice_terms ) { ); } +my @description; +my %param = $cgi->Vars; +for (my $i = 0; exists($param{"description$i"}); $i++) { + push @description, $param{"description$i"}; +} + +my $classnum; +if ( $cgi->param('classnum') =~ /^(\d+)$/ ) { + $classnum = $1; +} + +my $part_pkg; + +if ( $cust_pkg ) { # set defaults + $part_pkg = $cust_pkg->part_pkg; + $pkg ||= $part_pkg->pkg; + $classnum ||= $part_pkg->classnum; + if (!@description) { + for (my $i = 0; $i < ($part_pkg->option('additional_count',1) || 0); $i++) + { + push @description, $part_pkg->option("additional_info$i",1); + } + } +} + </%init> diff --git a/httemplate/elements/tr-input-beginning_ending.html b/httemplate/elements/tr-input-beginning_ending.html index ffc903875..91f55eb69 100644 --- a/httemplate/elements/tr-input-beginning_ending.html +++ b/httemplate/elements/tr-input-beginning_ending.html @@ -7,7 +7,7 @@ <TR> <TD ALIGN="right">From date: </TD> - <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>beginning" ID="<% $opt{prefix} %>beginning_text" VALUE="<% $from %>" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>beginning_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>beginning_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> + <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>beginning" ID="<% $opt{prefix} %>beginning_text" VALUE="<% time2str($date_format, $from) %>" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>beginning_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>beginning_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> <SCRIPT TYPE="text/javascript"> Calendar.setup({ inputField: "<% $opt{prefix} %>beginning_text", @@ -26,7 +26,7 @@ % } <TD ALIGN="right">To date: </TD> - <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>ending" ID="<% $opt{prefix} %>ending_text" VALUE="<% $to %>" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>ending_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>ending_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> + <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>ending" ID="<% $opt{prefix} %>ending_text" VALUE="<% time2str($date_format, $to) %>" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>ending_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>ending_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> <SCRIPT TYPE="text/javascript"> Calendar.setup({ inputField: "<% $opt{prefix} %>ending_text", diff --git a/httemplate/graph/report_money_time_daily.html b/httemplate/graph/report_money_time_daily.html index a436d0879..e80f5862c 100644 --- a/httemplate/graph/report_money_time_daily.html +++ b/httemplate/graph/report_money_time_daily.html @@ -4,12 +4,11 @@ <TABLE> -<% include( '/elements/tr-input-beginning_ending.html', +<& /elements/tr-input-beginning_ending.html, 'datesrequired' => 1, - 'from' => time2str('%m/%d/%Y',$from), - 'to' => time2str('%m/%d/%Y',time), - ) -%> + 'from' => $from, + 'to' => time, +&> <% include('/elements/tr-select-agent.html', 'label' => 'For agent: ', diff --git a/httemplate/loginout/login.html b/httemplate/loginout/login.html index d06d0a8fc..3c6e2ae9f 100644 --- a/httemplate/loginout/login.html +++ b/httemplate/loginout/login.html @@ -14,7 +14,7 @@ %# <FORM METHOD="POST" ACTION="<%$url_string%>loginout/login"> <FORM METHOD="POST" ACTION="/login"> - <INPUT TYPE="hidden" NAME="destination" VALUE="<% $r->prev->uri %>"> + <INPUT TYPE="hidden" NAME="destination" VALUE="<% $r->prev->unparsed_uri %>"> <TABLE CELLSPACING=0 CELLPADDING=4 BGCOLOR="#cccccc"> <TR> diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi index 4c5e90f6a..fc74b542e 100644 --- a/httemplate/search/cust_bill_pkg.cgi +++ b/httemplate/search/cust_bill_pkg.cgi @@ -283,24 +283,7 @@ if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { push @where, "cust_main.agentnum = $1"; } -# salesnum -if ( $cgi->param('salesnum') =~ /^(\d+)$/ ) { - - my $salesnum = $1; - - my $cmp_salesnum = $cgi->param('cust_main_sales') - ? ' COALESCE( cust_pkg.salesnum, cust_main.salesnum )' - : ' cust_pkg.salesnum '; - - push @where, "$cmp_salesnum = $salesnum"; - - #because currently we're called from sales_pkg_class.html for a specific - # class (or empty class) but not for all classes - #will have to do something to distinguish if someone wants the sales report - # (report_cust_bill_pkg.html) to have a sales person dropdown - $cgi->param('classnum', 0) unless $cgi->param('classnum'); -} - +# salesnum--see below # refnum if ( $cgi->param('refnum') =~ /^(\d+)$/ ) { push @where, "cust_main.refnum = $1"; @@ -704,6 +687,28 @@ if ( $cgi->param('credit') ) { push @select, 'cust_main.custnum', FS::UI::Web::cust_sql_fields(); +#salesnum +if ( $cgi->param('salesnum') =~ /^(\d+)$/ ) { + + my $salesnum = $1; + my $sales = FS::sales->by_key($salesnum) + or die "salesnum $salesnum not found"; + + my $subsearch = $sales->cust_bill_pkg_search('', '', + 'cust_main_sales' => ($cgi->param('cust_main_sales') ? 1 : 0), + 'paid' => ($cgi->param('paid') ? 1 : 0), + 'classnum' => scalar($cgi->param('classnum')) + ); + $join_pkg .= " JOIN sales_pkg_class ON ( COALESCE(sales_pkg_class.classnum, 0) = COALESCE( part_pkg.classnum, 0) )"; + + my $extra_sql = $subsearch->{extra_sql}; + $extra_sql =~ s/^WHERE//; + push @where, $extra_sql; + + $cgi->param('classnum', 0) unless $cgi->param('classnum'); +} + + my $where = join(' AND ', @where); $where &&= "WHERE $where"; diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi index 995779a46..54bfa00bf 100755 --- a/httemplate/search/cust_pkg.cgi +++ b/httemplate/search/cust_pkg.cgi @@ -175,6 +175,10 @@ for my $param (qw( censustract censustract2 )) { if grep { $_ eq $param } $cgi->param; } +#location flags (checkboxes) +my @loc = grep /^\w+$/, $cgi->param('loc'); +$search_hash{"location_$_"} = 1 foreach @loc; + my $report_option = $cgi->param('report_option'); $search_hash{report_option} = $report_option if $report_option; diff --git a/httemplate/search/report_cust_pkg.html b/httemplate/search/report_cust_pkg.html index f9aabfc7a..b3f2004b8 100755 --- a/httemplate/search/report_cust_pkg.html +++ b/httemplate/search/report_cust_pkg.html @@ -8,11 +8,7 @@ <TABLE BGCOLOR="#cccccc" CELLSPACING=0> - <TR> - <TH CLASS="background" COLSPAN=2 ALIGN="left"> - <FONT SIZE="+1">Customer search options</FONT> - </TH> - </TR> + <& /elements/tr-title.html, value => mt('Customer search options') &> <& /elements/tr-select-agent.html, 'curr_value' => scalar( $cgi->param('agentnum') ), @@ -56,11 +52,7 @@ <TABLE BGCOLOR="#cccccc" CELLSPACING=0> - <TR> - <TH CLASS="background" COLSPAN=2 ALIGN="left"> - <FONT SIZE="+1">Package search options</FONT> - </TH> - </TR> + <& /elements/tr-title.html, value => mt('Package search options') &> <& /elements/tr-select-sales.html, 'label' => 'Package sales person', @@ -70,11 +62,10 @@ 'disable_empty' => 1, &> - <% include( '/elements/tr-select-cust_pkg-status.html', + <& /elements/tr-select-cust_pkg-status.html, 'label' => 'Package status', 'onchange' => 'status_changed(this);', - ) - %> + &> <SCRIPT TYPE="text/javascript"> @@ -120,23 +111,21 @@ </SCRIPT> - <% include( '/elements/tr-select-pkg_class.html', + <& /elements/tr-select-pkg_class.html, 'pre_options' => [ '0' => 'all' ], 'empty_label' => '(empty class)', - ) - %> + &> % if ( scalar( qsearch( 'part_pkg_report_option', { 'disabled' => '' } ) ) ) { - <% include( '/elements/tr-select-table.html', + <& /elements/tr-select-table.html, 'label' => 'Report classes', 'table' => 'part_pkg_report_option', 'name_col' => 'name', 'hashref' => { 'disabled' => '' }, 'element_name' => 'report_option', 'multiple' => 'multiple', - ) - %> + &> % } <TR> @@ -189,24 +178,33 @@ </SCRIPT> - <% include( '/elements/tr-checkbox.html', + <& /elements/tr-checkbox.html, 'label' => 'Custom packages', 'field' => 'custom', 'value' => 1, 'onchange' => 'custom_changed(this);', - ) - %> - - <% include( '/elements/tr-selectmultiple-part_pkg.html' ) %> + &> + + <& /elements/tr-selectmultiple-part_pkg.html &> + + <& /elements/tr-title.html, value => mt('Location search options') &> + +% my @location_options = qw(cust nocust census nocensus); + <& /elements/tr-checkbox-multiple.html, + 'label' => 'Where package location:', + 'field' => 'loc', + 'options' => \@location_options, + 'labels' => { 'cust' => "is the customer's default location", + 'nocust' => "is not the customer's default location", + 'census' => "has a census tract", + 'nocensus' => "does not have a census tract", + }, + 'value' => { map { $_ => 1 } @location_options }, + &> - <TR> - <TH CLASS="background" COLSPAN=2> </TH> - </TR> + <& /elements/tr-title.html, value => mt('Display options') &> - <TR> - <TH CLASS="background" COLSPAN=2 ALIGN="left"><FONT SIZE="+1">Display options</FONT></TH> - </TR> - <% include( '/elements/tr-select-cust-fields.html' ) %> + <& /elements/tr-select-cust-fields.html &> </TABLE> diff --git a/httemplate/search/report_sales_commission.html b/httemplate/search/report_sales_commission.html index cc17e6bed..792c3353e 100644 --- a/httemplate/search/report_sales_commission.html +++ b/httemplate/search/report_sales_commission.html @@ -20,14 +20,22 @@ </SCRIPT> -<& /elements/tr-select-sales.html &> +<& /elements/tr-select-sales.html, + 'empty_label' => 'all', +&> <& /elements/tr-checkbox.html, - 'label' => 'Customer sales person if there is no package sales person', - 'field' => 'cust_main_sales', - 'value' => 'Y', + 'label' => 'Customer sales person if there is no package sales person', + 'field' => 'cust_main_sales', + 'value' => 'Y', &> +<& /elements/tr-checkbox.html, + 'label' => 'Show paid sales only', + 'field' => 'paid', + 'value' => 'Y', +&> + <& /elements/tr-input-beginning_ending.html &> </TABLE> diff --git a/httemplate/search/sales_commission.html b/httemplate/search/sales_commission.html index d7b7a88ad..e74f3792e 100644 --- a/httemplate/search/sales_commission.html +++ b/httemplate/search/sales_commission.html @@ -1,17 +1,22 @@ +% if ( $salesnum ) { +<% $cgi->redirect($sales_link->[0] . $salesnum) %> +% } else { <& elements/search.html, 'title' => $title, 'name_singular' => 'sales person', -# 'redirect' => sub { #my( $sales, $cgi ) = @); -# $saleslink; -# }, - 'header' => [ 'Sales person', 'Sales', 'Commission', ], - 'fields' => [ 'salesperson', $sales_sub, $commission_sub, ], - 'links' => [ '', $sales_link, $commission_link ], - 'align' => 'lrr', - 'query' => { 'table' => 'sales', }, - 'count_query' => 'SELECT COUNT(*) FROM sales', + 'header' => [ 'Sales person', 'One-Time Sales', 'Recurring Sales', 'Commission', ], + 'fields' => [ 'salesperson', + $sales_sub_maker->('setup'), + $sales_sub_maker->('recur'), + $commission_sub, + ], + 'links' => [ '', $sales_link, $sales_link, $commission_link ], + 'align' => 'lrrr', + 'query' => \%query, + 'count_query' => $count_query, 'disableable' => 1, &> +% } <%init> die "access denied" @@ -25,34 +30,49 @@ my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi, ''); my $date_format = $conf->config('date_format') || '%m/%d/%Y'; +my %query = ( 'table' => 'sales' ); +my $count_query = "SELECT COUNT(*) FROM sales"; + +my $salesnum; +if ( $cgi->param('salesnum') =~ /^(\d+)$/ ) { + $salesnum = $1; +} else { + $cgi->delete('salesnum'); +} + my $title = 'Sales person commission'; $title .= ': '. time2str($date_format, $beginning). ' to '. time2str($date_format, $ending) if $beginning; +my $paid = $cgi->param('paid') ? 1 : 0; +$title .= ' - paid sales only' if $paid; + my $cust_main_sales = $cgi->param('cust_main_sales') eq 'Y' ? 'Y' : ''; my $sales_link = [ 'sales_pkg_class.html?'. - "begin=$beginning;". - "end=$ending;". - "cust_main_sales=$cust_main_sales;". - "salesnum=", + # pass all of our parameters along + $cgi->query_string. ';salesnum=', 'salesnum' ]; -my $sales_sub = sub { - my $sales = shift; - - #efficiency improvement: ask the db for a sum instead of all the records - my $total_recur = 0; - my @cust_bill_pkg = $sales->cust_bill_pkg( - $beginning, - $ending, - 'cust_main_sales' => $cust_main_sales, - ); - $total_recur += $_->recur foreach @cust_bill_pkg; - - $money_char. sprintf('%.2f', $total_recur); +my $sales_sub_maker = sub { + my $field = shift; + sub { + my $sales = shift; + + #efficiency improvement: ask the db for a sum instead of all the records + my $total = 0; + my @cust_bill_pkg = $sales->cust_bill_pkg( + $beginning, + $ending, + 'cust_main_sales' => $cust_main_sales, + 'paid' => $paid, + ); + $total += $_->get($field) foreach @cust_bill_pkg; + + $money_char. sprintf('%.2f', $total); + }; }; my $commission_sub = sub { diff --git a/httemplate/search/sales_pkg_class.html b/httemplate/search/sales_pkg_class.html index c57aae66d..8bb6bde4c 100644 --- a/httemplate/search/sales_pkg_class.html +++ b/httemplate/search/sales_pkg_class.html @@ -1,10 +1,16 @@ <& elements/search.html, 'title' => $title, 'name_singular' => 'package class', - 'header' => [ 'Package class', 'Sales', 'Commission', ], - 'fields' => [ 'classname', $sales_sub, $commission_sub, ], - 'links' => [ '', $sales_link, $commission_link ], - 'align' => 'lrr', + 'header' => [ 'Package class', + 'One-Time Sales', + 'Recurring Sales', + 'Commission', ], + 'fields' => [ 'classname', + $sales_sub_maker->('setup'), + $sales_sub_maker->('recur'), + $commission_sub, ], + 'links' => [ '', $sales_link, $sales_link, $commission_link ], + 'align' => 'lrrr', 'query' => { 'table' => 'sales_pkg_class', 'hashref' => { 'salesnum' => $salesnum }, }, @@ -34,6 +40,9 @@ $title .= ': '. time2str($date_format, $beginning). ' to '. if $beginning; my $cust_main_sales = $cgi->param('cust_main_sales') eq 'Y' ? 'Y' : ''; +my $paid = $cgi->param('paid') ? 1 : 0; + +$title .= " - paid sales only" if $paid; my $sales_link = [ 'cust_bill_pkg.cgi?'. "begin=$beginning;". @@ -45,20 +54,22 @@ my $sales_link = [ 'cust_bill_pkg.cgi?'. 'classnum' ]; -my $sales_sub = sub { - my $sales_pkg_class = shift; - - #efficiency improvement: ask the db for a sum instead of all the records - my $total_recur = 0; - my @cust_bill_pkg = $sales->cust_bill_pkg( - $beginning, - $ending, - 'cust_main_sales' => $cust_main_sales, - 'classnum' => $sales_pkg_class->classnum, - ); - $total_recur += $_->recur foreach @cust_bill_pkg; - - $money_char. sprintf('%.2f', $total_recur); +my $sales_sub_maker = sub { + my $field = shift; + sub { + my $sales_pkg_class = shift; + # could be even more efficient but this is pretty good + my $search = $sales->cust_bill_pkg_search( + $beginning, + $ending, + 'cust_main_sales' => $cust_main_sales, + 'classnum' => $sales_pkg_class->classnum, + 'paid' => $paid, + ); + $search->{'select'} = "SUM(cust_bill_pkg.$field) AS total"; + my $result = qsearchs($search); + $money_char. sprintf('%.2f', $result ? $result->get('total') : 0); + }; }; my $commission_sub = sub { @@ -76,6 +87,15 @@ my $commission_sub = sub { $money_char. sprintf('%.2f', $total_credit); }; +my $sales_link = [ 'cust_bill_pkg.cgi?'. + "begin=$beginning;". + "end=$ending;". + "cust_main_sales=$cust_main_sales;". + "salesnum=$salesnum;". + "classnum=", + 'classnum' + ]; + my $commission_link = [ 'cust_credit.html?'. "begin=$beginning;". "end=$ending;". diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index 1c8db15f4..e97c141d2 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -21,17 +21,22 @@ <TD COLSPAN=2> <FONT SIZE=-1> -% unless ( $cust_pkg->get('cancel') || $opt{no_links} ) { +% if ( $part_pkg->freq eq '0' and !$opt{no_links} ) { +% # One-time charge. Nothing you can do with this, unless: +% if ( $curuser->access_right('Modify one-time charge') ) { + ( <%onetime_change_link($cust_pkg)%> ) + <BR> +% } +% +% } elsif ( !$cust_pkg->get('cancel') and !$opt{no_links} ) { % % if ( $change_from ) { % # This is the target package for a future change. % # Nothing you can do with it besides modify/cancel the % # future change, and that's on the current package. -% } elsif ( $supplemental or $part_pkg->freq eq '0' ) { +% } elsif ( $supplemental ) { % # Supplemental packages can't be changed independently. -% # One-time charges don't need to be changed. -% # For both of those, we only show "Add comments", -% # and "Add invoice details". +% # Show only "Add comments" and "Add invoice details". % } else { % # the usual case: links to change package definition, % # discount, and customization @@ -320,6 +325,19 @@ sub pkg_change_link { ); } +sub onetime_change_link { + my $cust_pkg = shift; + my $pkgnum = $cust_pkg->pkgnum; + include( '/elements/popup_link-cust_pkg.html', + 'action' => $p. "edit/quick-charge.html?change_pkgnum=$pkgnum", + 'label' => emt('Modify one-time charge'), + 'actionlabel' => emt('Modify'), + 'cust_pkg' => $cust_pkg, + 'width' => 690, + 'height' => 380, + ); +} + sub pkg_change_location_link { my $cust_pkg = shift; my $pkgpart = $cust_pkg->pkgpart; diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index c7bf3748c..73082ce96 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -270,6 +270,11 @@ % ? sprintf("- $money_char\%.2f", $item->{'credit'}) % : ''; % +% $credit ||= sprintf( "<DEL>- $money_char\%.2f</DEL>", +% $item->{'void_credit'} +% ) +% if exists($item->{'void_credit'}); +% % my $refund = exists($item->{'refund'}) % ? sprintf("$money_char\%.2f", $item->{'refund'}) % : ''; @@ -469,6 +474,15 @@ foreach my $cust_pay_void ($cust_main->cust_pay_void) { } +#voided credits +foreach my $cust_credit_void ($cust_main->cust_credit_void) { + push @history, { + 'date' => $cust_credit_void->_date, + 'desc' => include('payment_history/voided_credit.html', $cust_credit_void, %opt ), + 'void_credit' => $cust_credit_void->amount, + }; +} + #declined payments foreach my $cust_pay_pending ($cust_main->cust_pay_pending_attempt) { push @history, { diff --git a/httemplate/view/cust_main/payment_history/voided_credit.html b/httemplate/view/cust_main/payment_history/voided_credit.html new file mode 100644 index 000000000..0723a7282 --- /dev/null +++ b/httemplate/view/cust_main/payment_history/voided_credit.html @@ -0,0 +1,25 @@ +<DEL><% emt("Credit by [_1]", $cust_credit_void->otaker, $reason ) %>\ +<% $reason |h %></DEL> +<I> +<% emt("voided [_1]", time2str($date_format, $cust_credit_void->void_date) )%> +% my $void_user = $cust_credit_void->void_access_user; +% if ($void_user) { +<% emt('by [_1]', $void_user->username) %> +% } +<% $void_reason |h %> +</I> +<%init> + +my( $cust_credit_void, %opt ) = @_; + +my $date_format = $opt{'date_format'} || '%m/%d/%Y'; + +my $curuser = $FS::CurrentUser::CurrentUser; + +#my $unvoid = ''; # not yet available +my $reason = $cust_credit_void->reason; +$reason = " ($reason)" if $reason; + +my $void_reason = $cust_credit_void->void_reason; +$void_reason = " ($void_reason)" if $void_reason; +</%init> |