Optimize "Customer has a referring customer" condition, RT#74452
[freeside.git] / httemplate / search / customer_cdr_profit.html
1 <& elements/grid-report.html,
2   title => $title,
3   rows  => \@rows,
4   cells => \@cells,
5   head  => $head,
6   # would be better handled with Mason inheritance? consider this. easy enough
7   # to change it at this point.
8 &>
9 <%init>
10
11 die "access denied"
12   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports')
13       && $FS::CurrentUser::CurrentUser->access_right('List rating data');
14
15 my ($agentnum,$sel_agent);
16 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
17   $agentnum = $1;
18   $sel_agent = qsearchs('agent', { 'agentnum' => $agentnum } );
19   die "agentnum $agentnum not found!" unless $sel_agent;
20 }
21 my $title = $sel_agent ? $sel_agent->agent.' ' : '';
22
23 $title .= 'Customer CDRs Profit/Loss Report';
24
25 my @items  = ('cust_bill_pkg_recur', 'cust_bill_pkg_recur', 'cust_bill_pkg_detail', 'cust_bill_pkg_detail' );
26 my @params = ( [], [ 'cost' => 1 ], [], [ 'cost' => 1 ] );
27
28 my @labels = ();
29 my @cross_params = ();
30
31 my %search_hash;
32 foreach (qw(agentnum)) {
33   if ( defined $cgi->param($_) ) {
34     $search_hash{$_} = $cgi->param($_);
35   }
36 }
37
38 my $query = FS::cust_main::Search->search(\%search_hash);
39 my @cust_main = qsearch($query);
40
41 foreach my $cust_main (@cust_main) {
42   push @cross_params, [ ('custnum' => $cust_main->custnum) ];
43 }
44
45 my %opt = (
46   items         => \@items,
47   params        => \@params,
48   cross_params  => \@cross_params,
49   agentnum      => $agentnum,
50 );
51 for ( qw(start_month start_year end_month end_year) ) {
52   if ( $cgi->param($_) =~ /^(\d+)$/ ) {
53     $opt{$_} = $1;
54   }
55 }
56
57 my $report = FS::Report::Table::Monthly->new(%opt);
58 my $data = $report->data;
59
60 ### False laziness with customer_accounting_summary.html
61 my @total;
62
63 my @rows; # hashes of row info
64 my @cells; # arrayrefs of cell info
65 # We use Excel currency format, but not Excel dates, because
66 # these are whole months and there's no nice way to express that.
67 # This is the historical behavior for monthly reports.
68
69 # header row
70 $rows[0] = {};
71 $cells[0] = [
72   { header => 1, rowspan => 2 },
73   map {
74     { header => 1, colspan => 5, value => time2str('%b %Y', $_) }
75   } @{ $data->{speriod} }
76 ];
77 my $ncols = scalar(@{ $data->{speriod} });
78
79 $rows[1] = {};
80 $cells[1] = [ '',
81   map { 
82   ( 
83     { header => 1, value => mt('Recur Fee') },
84     { header => 1, value => mt('Recur Cost') },
85     { header => 1, value => mt('Usage Fee') },
86     { header => 1, value => mt('Usage Cost') },
87     { header => 1, value => mt('Profit'), class => 'shaded' },
88   ) } (1..$ncols)
89 ];
90
91 my $row = 0;
92 foreach my $cust_main (@cust_main) { # correspond to cross_params
93   my $skip = 1; # skip the customer iff ALL of their values are zero
94   push @rows, {};
95   my @thisrow;
96   # customer name
97   push @thisrow,
98     { value   => $cust_main->name,
99       header  => 1
100     };
101   for my $col (0..$ncols-1) { # the month
102     my $profit = 0;
103     for my $item (0..3) { # recur/recur_cost/usage/usage_cost
104       my $value = $data->{data}[$item][$col][$row];
105       $skip = 0 if abs($value) > 0.005;
106       push @thisrow, {
107         value => sprintf('%0.2f', $value),
108         format => 'money',
109         class => ($value < 0 ? 'negative' : ''),
110       };
111       $total[$col * 5 + $item] += $value;
112       $profit += (($item % 2) ? -1 : 1) * $value;
113     } #item
114     push @thisrow, { 
115       value => sprintf('%0.2f', $profit), 
116       format => 'money',
117       class => 'shaded',
118     };
119     $total[$col * 5 + 4] += $profit;
120   } #month
121   push @cells, \@thisrow;
122
123   if ( $skip ) {
124     # all values are zero--remove the rows we just added
125     pop @rows;
126     pop @cells;
127   }
128   $row++;
129 }
130
131 push @rows, { class => 'total' };
132 my @thisrow;
133 push @thisrow,
134   { value => mt('Total'),
135     header => 1
136   };
137 for my $col (0..($ncols * 5)-1) { # month and recur/recur_cost/usage/usage_cost/profit
138   my $value = $total[$col];
139   push @thisrow, { 
140     value => sprintf('%0.2f', $value), 
141     format => 'money',
142     class => ($col % 5 == 4) ? 'totalshaded' : 'total',
143   };
144 }
145 push @cells, \@thisrow;
146
147 my $head = q[
148 <style>
149   .negative { color: red }
150 </style>
151 ];
152 </%init>