summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/process/quick-charge.cgi108
-rw-r--r--httemplate/edit/quick-charge.html114
-rw-r--r--httemplate/elements/tr-input-beginning_ending.html4
-rw-r--r--httemplate/graph/report_money_time_daily.html9
-rw-r--r--httemplate/loginout/login.html2
-rw-r--r--httemplate/search/cust_bill_pkg.cgi41
-rwxr-xr-xhttemplate/search/cust_pkg.cgi4
-rwxr-xr-xhttemplate/search/report_cust_pkg.html60
-rw-r--r--httemplate/search/report_sales_commission.html16
-rw-r--r--httemplate/search/sales_commission.html72
-rw-r--r--httemplate/search/sales_pkg_class.html56
-rw-r--r--httemplate/view/cust_main/packages/package.html28
-rw-r--r--httemplate/view/cust_main/payment_history.html14
-rw-r--r--httemplate/view/cust_main/payment_history/voided_credit.html25
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>&nbsp;</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') ) {
+ (&nbsp;<%onetime_change_link($cust_pkg)%>&nbsp;)
+ <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("-&nbsp;$money_char\%.2f", $item->{'credit'})
% : '';
%
+% $credit ||= sprintf( "<DEL>-&nbsp;$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>