<% include('elements/monthly.html',
#Dumper(
'title' => $title,
- 'graph_type' => 'Mountain',
+ 'graph_type' => $graph_type,
'items' => \@items,
'params' => \@params,
'labels' => \@labels,
'links' => \@links,
'no_graph' => \@no_graph,
'remove_empty' => 1,
- 'bottom_total' => 1,
+ 'bottom_total' => $show_total,
+ 'nototal' => !$show_total,
'bottom_link' => $bottom_link,
'agentnum' => $agentnum,
'cust_classnum'=> \@cust_classnums,
my $use_usage = $cgi->param('use_usage') || 0;
my $use_setup = $cgi->param('use_setup') || 0;
+my $use_discount = $cgi->param('use_discount') || 2;
+
my $use_override = $cgi->param('use_override') ? 1 : 0;
my $average_per_cust_pkg = $cgi->param('average_per_cust_pkg') ? 1 : 0;
my $distribute = $cgi->param('distribute') ? 1 : 0;
+my $show_total = 1;
+my $graph_type = 'Mountain';
+
+if ( $average_per_cust_pkg ) {
+ # then the rows are not additive
+ $show_total = 0;
+ $graph_type = 'LinesPoints';
+}
+
my %charge_labels = (
+ 'SRU'=> 'setup + recurring',
'SR' => 'setup + recurring',
'RU' => 'recurring',
'S' => 'setup',
'R' => 'recurring',
'U' => 'usage',
+ 'D' => 'discount',
);
#XXX or virtual
$value_col = 'classnum';
}
-my @classnums = grep /^\d+$/, $cgi->param($class_param);
+my @classnums = sort {$a <=> $b} grep /^\d+$/, $cgi->param($class_param);
my @classnames = map { if ( $_ ) {
my $class = qsearchs($class_table, {$value_col=>$_} );
$class->$name_col;
if ( $cgi->param('class_mode') eq 'report' ) {
# The new way:
# Actually break down all subsets of the (selected) report classes.
- my $powerset = sub {
- my @set = [];
- foreach my $x (@_) {
- @set = map { $_, [ @$_, $x ] } @set;
+ my @subsets = FS::part_pkg_report_option->subsets(@classnums);
+ my @classnum_space = @classnums;
+ @classnums = @classnames = ();
+ while(@subsets) {
+ my $these = shift @subsets;
+ # applied topology!
+ my $not_these = [ @classnum_space ];
+ my $i = 0;
+ foreach (@$these) {
+ $i++ until $not_these->[$i] == $_;
+ splice(@$not_these, $i, 1);
}
- @set;
- };
- @classnums = $powerset->(@classnums);
- @classnames = $powerset->(@classnames);
- # this is pairwise complementary to @classnums, because math
- @not_classnums = reverse(@classnums);
-warn Dumper(\@classnums, \@classnames, \@not_classnums);
- # remove the null set
- shift @classnums;
- shift @classnames;
- shift @not_classnums;
+ push @classnums, $these;
+ push @not_classnums, $not_these;
+ push @classnames, shift @subsets;
+ } #while subsets
}
# else it's 'pkg', i.e. part_pkg.classnum, which is singular on pkgpart
# and much simpler
$components[-1] =~ s/U//;
}
+if ( $use_discount == 1 ) {
+ push @components, 'D';
+} # else leave discounts off entirely; never combine them with setup/recur
+
# Categorization of line items goes
# Agent -> Referral -> Package class -> Component (setup/recur/usage)
# If per-agent totals are enabled, they go under the Agent level.
'charges' => $component,
);
- # XXX this is very silly. we should cache it server-side and
- # just put a cache identifier in the link
- my $rowlink = "$link;".
- ($all_agent ? '' : "agentnum=$row_agentnum;").
+ my $row_link = "$link;".
+ "charges=$component;".
+ "distribute=$distribute;";
+
+ if ( $component eq 'D' ) {
+ # discounts ignore 'charges' and 'distribute'
+ $row_link = "${p}search/cust_bill_pkg_discount.html?";
+ }
+
+ $row_link .= ($all_agent ? '' : "agentnum=$row_agentnum;").
($all_part_referral ? '' : "refnum=$row_refnum;").
(join('',map {"cust_classnum=$_;"} @cust_classnums)).
- "distribute=$distribute;".
- "use_override=$use_override;charges=$component;";
- $rowlink .= "$class_param=$_;" foreach @classnums;
+ "use_override=$use_override;";
+ $row_link .= "$class_param=$_;" foreach @classnums;
if ( $all_report_options ) {
push @row_params, 'all_report_options', 1;
- $rowlink .= 'all_report_options=1';
+ $row_link .= 'all_report_options=1';
}
push @params, \@row_params;
- push @links, $rowlink;
+ push @links, $row_link;
@colorbuf = @agent_colors unless @colorbuf;
push @colors, shift @colorbuf;
} elsif ( $cgi->param('class_agg_break') eq 'breakdown' ) {
- # if we're working with report options, @classnums here contains
- # arrays of multiple classnums
for (my $i = 0; $i < scalar @classnums; $i++) {
- my $row_classnum = join(',', @{ $classnums[$i] });
- my $row_classname = join(', ', @{ $classnames[$i] });
- my $not_row_classnum = join(',', @{ $not_classnums[$i] });
+ my $row_classnum = $classnums[$i];
+ my $row_classname = $classnames[$i];
+ my $not_row_classnum = '';
+ if ( $class_param eq 'report_optionnum' ) {
+ # if we're working with report options, @classnums here contains
+ # arrays of multiple classnums
+ $row_classnum = join(',', @$row_classnum);
+ $row_classname = join(', ', @$row_classname);
+ $not_row_classnum = join(',', @{ $not_classnums[$i] });
+ }
foreach my $component ( @components ) {
push @items, 'cust_bill_pkg';
($all_part_referral ? () : ('refnum' => $row_refnum)),
'charges' => $component,
);
+
my $row_link = "$link;".
- ($all_agent ? '' : "agentnum=$row_agentnum;").
+ "charges=$component;".
+ "distribute=$distribute;";
+
+ if ( $component eq 'D' ) {
+ # discounts ignore 'charges' and 'distribute'
+ $row_link ="${p}search/cust_bill_pkg_discount.html?";
+ }
+
+ $row_link .= ($all_agent ? '' : "agentnum=$row_agentnum;").
($all_part_referral ? '' : "refnum=$row_refnum;").
(join('',map {"cust_classnum=$_;"} @cust_classnums)).
"$class_param=$row_classnum;".
- "distribute=$distribute;".
- "use_override=$use_override;charges=$component;";
+ "use_override=$use_override;";
+
if ( $class_param eq 'report_optionnum' ) {
push @row_params,
'all_report_options' => 1,