X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=httemplate%2Fgraph%2Fcust_bill_pkg.cgi;h=b5486f4af06c5c9c9c823bd69e2eaaf16bbd25a1;hp=01d309df8c823ec4781b5f80c56bc1c3a0cd72b3;hb=9aee669886202be7035e6c6049fc71bc99dd3013;hpb=ecd1baba392d971b49a50f133349f85aaec548a0 diff --git a/httemplate/graph/cust_bill_pkg.cgi b/httemplate/graph/cust_bill_pkg.cgi index 01d309df8..b5486f4af 100644 --- a/httemplate/graph/cust_bill_pkg.cgi +++ b/httemplate/graph/cust_bill_pkg.cgi @@ -1,7 +1,7 @@ <% include('elements/monthly.html', #Dumper( 'title' => $title, - 'graph_type' => 'Mountain', + 'graph_type' => $graph_type, 'items' => \@items, 'params' => \@params, 'labels' => \@labels, @@ -10,7 +10,8 @@ '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, @@ -26,16 +27,29 @@ my $bottom_link = "$link;"; 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 @@ -84,34 +98,40 @@ $bottom_link .= "cust_classnum=$_;" foreach @cust_classnums; #started out as false lazinessish w/FS::cust_pkg::search_sql (previously search/cust_pkg.cgi), but not much left the sane now after #24776 my ($class_table, $name_col, $value_col, $class_param); +my $all_report_options; if ( $cgi->param('class_mode') eq 'report' ) { $class_param = 'report_optionnum'; # CGI param name, also used in the report engine $class_table = 'part_pkg_report_option'; # table containing classes $name_col = 'name'; # the column of that table containing the label $value_col = 'num'; # the column containing the class number -} else { + # in 'exact' mode we want to run the query in ALL mode. + # in 'breakdown' mode want to run the query in ALL mode but using the + # power set of the classes selected. + $all_report_options = 1 + unless $cgi->param('class_agg_break') eq 'aggregate'; +} else { # class_mode eq 'pkg' $class_param = 'classnum'; $class_table = 'pkg_class'; $name_col = 'classname'; $value_col = 'classnum'; } -my @classnums = grep /^\d+$/, $cgi->param($value_col); +my @classnums = sort {$a <=> $b} grep /^\d+$/, $cgi->param($class_param); my @classnames = map { if ( $_ ) { my $class = qsearchs($class_table, {$value_col=>$_} ); - $class->classname; + $class->$name_col; } else { '(empty class)'; } } @classnums; +my @not_classnums; $bottom_link .= "$class_param=$_;" foreach @classnums; -if ( $cgi->param('class_agg_break') eq 'aggregate' ) { - - $link .= ";$class_param=$_" foreach @classnums; +if ( $cgi->param('class_agg_break') eq 'aggregate' or + $cgi->param('class_agg_break') eq 'exact' ) { $title .= ' '. join(', ', @classnames) unless scalar(@classnames) > scalar(qsearch($class_table,{'disabled'=>''})); @@ -119,15 +139,28 @@ if ( $cgi->param('class_agg_break') eq 'aggregate' ) { } elsif ( $cgi->param('class_agg_break') eq 'breakdown' ) { - if ( $cgi->param('mode') eq 'report' ) { - # In theory, a package can belong to any subset of the report classes, - # so the report groups should be all the _subsets_, but for now we're - # handling the simple case where each package belongs to one report - # class. Packages with multiple classes will go into one bin at the - # end. - push @classnames, '(multiple classes)'; - push @classnums, 'multiple'; + if ( $cgi->param('class_mode') eq 'report' ) { + # The new way: + # Actually break down all subsets of the (selected) report classes. + 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); + } + 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 } else { die "guru meditation #434"; @@ -135,11 +168,6 @@ if ( $cgi->param('class_agg_break') eq 'aggregate' ) { #eslaf -my $hue = 0; -#my $hue_increment = 170; -#my $hue_increment = 145; -my $hue_increment = 125; - my @items = (); my @params = (); my @labels = (); @@ -162,19 +190,24 @@ elsif ( $use_usage == 2 ) { $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. # There aren't any other kinds of subtotals. -foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => '' } ) ) { +my $anum = 0; +foreach my $agent ( $all_agent || $sel_agent || $FS::CurrentUser::CurrentUser->agents ) { - my $col_scheme = Color::Scheme->new - ->from_hue($hue) #->from_hex($agent->color) - ->scheme('analogic') - ; - my @recur_colors = (); - my @onetime_colors = (); + my @agent_colors = map { my $col = $cgi->param("agent$anum-color$_"); + $col =~ s/^#//; + $col; + } + (0 .. 5); + my @colorbuf = (); ### fixup the color handling for package classes... ### and usage @@ -191,7 +224,10 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => 'distribute' => $distribute, ); - if ( $cgi->param('class_agg_break') eq 'aggregate' ) { + if ( $cgi->param('class_agg_break') eq 'aggregate' or + $cgi->param('class_agg_break') eq 'exact' ) { + # the only difference between 'aggregate' and 'exact' is whether + # we pass the 'all_report_options' flag. foreach my $component ( @components ) { @@ -204,28 +240,37 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => my $row_agentnum = $all_agent || $agent->agentnum; my $row_refnum = $all_part_referral || $part_referral->refnum; - push @params, [ + my @row_params = ( @base_params, $class_param => \@classnums, ($all_agent ? () : ('agentnum' => $row_agentnum) ), ($all_part_referral ? () : ('refnum' => $row_refnum) ), - 'charges' => $component, - ]; + 'charges' => $component, + ); + + my $row_link = "$link;". + "charges=$component;". + "distribute=$distribute;"; - my $rowlink = "$link;". - ($all_agent ? '' : "agentnum=$row_agentnum;"). + 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; - push @links, $rowlink; - - @recur_colors = ($col_scheme->colors)[0,4,8,1,5,9] - unless @recur_colors; - @onetime_colors = ($col_scheme->colors)[2,6,10,3,7,11] - unless @onetime_colors; - push @colors, shift @recur_colors; + "use_override=$use_override;"; + $row_link .= "$class_param=$_;" foreach @classnums; + if ( $all_report_options ) { + push @row_params, 'all_report_options', 1; + $row_link .= 'all_report_options=1'; + } + push @params, \@row_params; + push @links, $row_link; + + @colorbuf = @agent_colors unless @colorbuf; + push @colors, shift @colorbuf; push @no_graph, 0; } #foreach $component @@ -235,6 +280,14 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => for (my $i = 0; $i < scalar @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'; @@ -246,27 +299,42 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => my $row_agentnum = $all_agent || $agent->agentnum; my $row_refnum = $all_part_referral || $part_referral->refnum; - push @params, [ + my @row_params = ( @base_params, $class_param => $row_classnum, ($all_agent ? () : ('agentnum' => $row_agentnum) ), ($all_part_referral ? () : ('refnum' => $row_refnum)), 'charges' => $component, - ]; + ); + + 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?"; + } - push @links, "$link;". - ($all_agent ? '' : "agentnum=$row_agentnum;"). + $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;"; - - @recur_colors = ($col_scheme->colors)[0,4,8,1,5,9] - unless @recur_colors; - @onetime_colors = ($col_scheme->colors)[2,6,10,3,7,11] - unless @onetime_colors; - push @colors, shift @recur_colors; + "use_override=$use_override;"; + + if ( $class_param eq 'report_optionnum' ) { + push @row_params, + 'all_report_options' => 1, + 'not_report_optionnum' => $not_row_classnum, + ; + $row_link .= "all_report_options=1;". + "not_report_optionnum=$not_row_classnum;"; + } + push @params, \@row_params; + push @links, $row_link; + + @colorbuf = @agent_colors unless @colorbuf; + push @colors, shift @colorbuf; push @no_graph, 0; } #foreach $component @@ -291,22 +359,22 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => my $row_link = "$link;". "agentnum=$row_agentnum;". "distribute=$distribute;". - "charges=$component"; + "charges=$component;"; # package class filters if ( $cgi->param('class_agg_break') eq 'aggregate' ) { push @row_params, $class_param => \@classnums; - $row_link .= ";$class_param=".$_ foreach @classnums; + $row_link .= "$class_param=$_;" foreach @classnums; } # refnum filters if ( $sel_part_referral ) { push @row_params, 'refnum' => $sel_part_referral->refnum; - $row_link .= ";refnum=".$sel_part_referral->refnum; + $row_link .= "refnum=;".$sel_part_referral->refnum; } # customer class filters - $row_link .= ";cust_classnum=$_" foreach @cust_classnums; + $row_link .= "cust_classnum=$_;" foreach @cust_classnums; push @items, 'cust_bill_pkg'; push @labels, mt('[_1] - Subtotal', $agent->agent); @@ -316,7 +384,7 @@ foreach my $agent ( $all_agent || $sel_agent || qsearch('agent', { 'disabled' => push @no_graph, 1; } - $hue += $hue_increment; + $anum++; }