push @{$data{label}}, "$smonth/$syear"; # sprintf?
my $speriod = timelocal(0,0,0,1,$smonth-1,$syear);
- push @{$data{speriod}}, $speriod;
if ( ++$smonth == 13 ) { $syear++; $smonth=1; }
my $eperiod = timelocal(0,0,0,1,$smonth-1,$syear);
+ # 12-month mode: show results in a sliding window ending at $eperiod,
+ # but starting 12 months before.
+ if ( $self->{'12mo'}) {
+ $speriod = timelocal(0,0,0,1,$smonth-1,$syear-1);
+ }
+
+ push @{$data{speriod}}, $speriod;
push @{$data{eperiod}}, $eperiod;
my $col = 0; # a "column" here is the data corresponding to an item
use FS::cust_main;
use FS::access_user;
use FS::Conf;
+use charnames ':full';
=item search HASHREF
=over 4
-=item newest_percust
+=item newest_percust - only show the most recent invoice for each customer
+
+=item invoiced - show the invoiced amount (excluding discounts) instead of gross sales
=back
sub search {
my( $class, $params ) = @_;
- my( $count_query, $count_addl ) = ( '', '' );
+ my $count_query = '';
+ my @count_addl;
#some false laziness w/cust_bill::re_X
my $money = (FS::Conf->new->config('money_char') || '$') . '%.2f';
- $count_query = 'SELECT COUNT(*), '. join(', ',
- map "SUM($_)",
- ( 'charged + discounted',
- 'discounted',
- 'credited',
- 'charged - credited',
- 'charged - credited - paid',
- )
- );
- $count_addl = [ "$money sales (gross)",
- "− $money discounted",
- "− $money credited",
- "= $money sales (net)",
+ my @sums = ( 'credited', # credits
+ 'charged - credited', # net sales
+ 'charged - credited - paid', # balance due
+ );
+
+ @count_addl = ( "\N{MINUS SIGN} $money credited",
+ "= $money net sales",
"$money outstanding balance",
- ];
+ );
+
+ if ( $params->{'invoiced'} ) {
+
+ unshift @sums, 'charged';
+ unshift @count_addl, "$money invoiced";
+
+ } else {
+
+ unshift @sums, 'charged + discounted', 'discounted';
+ unshift @count_addl, "$money gross sales",
+ "\N{MINUS SIGN} $money discounted";
+
+ }
+
+ $count_query = 'SELECT COUNT(*), '. join(', ', map "SUM($_)", @sums);
}
$count_query .= " FROM cust_bill $join $extra_sql";
'order_by' => 'ORDER BY '. ( $params->{'order_by'} || 'cust_bill._date' ),
'count_query' => $count_query,
- 'count_addl' => $count_addl,
+ 'count_addl' => \@count_addl,
};
}
'start_year' => $syear,
'end_month' => $emonth,
'end_year' => $eyear,
-
+ '12mo' => 0,
#optional, pulled from CGI params if not specified,
#only if 'daily' option is given
$opt{'end_month'} ||= $cgi->param('end_month'); # || $curmon+1;
$opt{'end_year'} ||= $cgi->param('end_year'); # || 1900+$curyear;
+$opt{'12mo'} ||= $cgi->param('12mo') ? 1 : 0;
+
$opt{'projection'} ||= $cgi->param('projection') ? 1 : 0;
if ( $opt{'daily'} ) { # daily granularity
'end_day' => $opt{'end_day'},
'end_month' => $opt{'end_month'},
'end_year' => $opt{'end_year'},
+ '12mo' => $opt{'12mo'},
'projection' => $opt{'projection'},
'agentnum' => $opt{'agentnum'},
'refnum' => $opt{'refnum'},
# need to clean this up. the false symmetry of "gross" and "net" everything
# makes it aesthetically hard to make this report more useful.
-my @items = qw( gross netsales
- discounted
+my @items = ($cgi->param('exclude_discount') ? 'invoiced' : 'gross');
+push @items,
+ qw( discounted netsales
credits netcredits
payments receipts
refunds netrefunds
cashflow netcashflow
- );
-if ( $cgi->param('12mo') == 1 ) {
- @items = map $_.'_12mo', @items;
-}
+ );
my %label = (
'gross' => 'Gross Sales',
- 'netsales' => 'Net Sales',
+ 'invoiced' => 'Invoiced Sales',
+ 'netsales' => 'Net Sales',
'discounted' => 'Discounts',
'credits' => 'Gross Credits',
- 'netcredits' => 'Net Credits',
+ 'netcredits' => 'Net Credits',
'payments' => 'Gross Receipts',
- 'receipts' => 'Net Receipts',
+ 'receipts' => 'Net Receipts',
'refunds' => 'Gross Refunds',
- 'netrefunds' => 'Net Refunds',
+ 'netrefunds' => 'Net Refunds',
'cashflow' => 'Gross Cashflow',
- 'netcashflow' => 'Net Cashflow',
+ 'netcashflow' => 'Net Cashflow',
);
my %graph_suffix = (
'gross' => ' (invoiced + discounts)',
+ 'invoiced' => '',
'netsales' => ' (invoiced - applied credits)',
- 'discounted' => ' (discounts)',
+ 'discounted' => '',
'credits' => ' (credited)',
'netcredits' => ' (applied credits)',
'payments' => ' (payments)',
);
my %graph_label = map { $_ => $label{$_}.$graph_suffix{$_} } keys %label;
-$label{$_.'_12mo'} = $label{$_}. " (prev 12 months)"
- foreach keys %label;
-
-$graph_label{$_.'_12mo'} = $graph_label{$_}. " (prev 12 months)"
- foreach keys %graph_label;
-
my %color = (
'gross' => '9999ff', #light blue
+ 'invoiced' => '9999ff', #light blue
'netsales' => '0000cc', #blue
'credits' => 'ff9999', #light red
'netcredits' => 'cc0000', #red
my %link = (
'gross' => "${p}search/cust_bill.html?$ar;",
+ 'invoiced' => "${p}search/cust_bill.html?$ar;invoiced=1;",
'netsales' => "${p}search/cust_bill.html?$ar;net=1;",
'credits' => "${p}search/cust_credit.html?$ar;",
'netcredits' => "${p}search/cust_credit_bill.html?$ar;",
);
# XXX link 12mo?
+if ( $cgi->param('12mo') ) {
+ $label{$_} .= " (prev 12 months)"
+ foreach keys %label;
+
+ $graph_label{$_} .= " (prev 12 months)"
+ foreach keys %graph_label;
+}
+
</%init>
)
%>
-<TR>
- <TD ALIGN="right"><INPUT TYPE="checkbox" NAME="12mo" VALUE="1"></TD>
- <TD>Show 12 month totals instead of monthly values</TD>
+<tr>
+ <td />
+ <td>
+ <& /elements/checkbox.html,
+ field => '12mo',
+ value => 1,
+ &>
+ <% emt('Show 12 month totals instead of monthly values') %>
+ </td>
+</tr>
+ <td />
+ <td>
+ <& /elements/checkbox.html,
+ field => 'exclude_discount',
+ value => 1,
+ curr_value => 0,
+ &>
+ <% emt('Exclude discounts from total sales') %>
+ </td>
</TR>
</TABLE>
'count_addl' => $count_addl,
'redirect' => $link,
'header' => [ emt('Invoice #'),
- emt('Gross Amount'),
+ emt($invoiced ? 'Charged' : 'Gross Amount'),
emt('Discount'),
emt('Credits'),
emt('Net Amount'),
],
'fields' => [
'display_invnum',
- 'gross',
+ $invoiced ? 'charged' : 'gross',
'discounted',
'credited',
'net',
],
'sort_fields' => [
'COALESCE( agent_invid, invnum )',
- 'gross',
+ $invoiced ? 'charged' : 'gross',
'discounted',
'credited',
'net',
my $count_addl = '';
my %search = ();
+# show invoiced amount (charged) instead of gross sales
+my $invoiced = $cgi->param('invoiced') ? 1 : 0;
+
if ( $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/ ) {
my $join_cust_main = FS::UI::Web::join_cust_main('cust_bill');
#scalars
for (qw( agentnum custnum cust_status refnum invnum_min invnum_max
- open net newest_percust
+ open net newest_percust invoiced
))
{
<TR>
<TD ALIGN="right"><INPUT TYPE="checkbox" NAME="open" VALUE="1" CHECKED></TD>
<TD><% mt('Show only open invoices') |h %></TD>
- </TR>
+</TR>
+
+<TR>
+ <TD ALIGN="right"><INPUT TYPE="checkbox" NAME="invoiced" VALUE="1"></TD>
+ <TD><% emt('Exclude discounts from gross amount billed'), %></TD>
+</TR>
% unless ( $custnum ) {
<TR>