X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FReport%2FTable%2FMonthly.pm;h=f4ba02008f3e83a10d21d1371c05056d65be054d;hb=155cb2a71481bdcaad6fd66bbe9d804c64d7c29d;hp=fa9949d4904557952bedde4faf3a87c0c96a5db3;hpb=63a268637b2d51a8766412617724b9436439deb6;p=freeside.git diff --git a/FS/FS/Report/Table/Monthly.pm b/FS/FS/Report/Table/Monthly.pm index fa9949d49..f4ba02008 100644 --- a/FS/FS/Report/Table/Monthly.pm +++ b/FS/FS/Report/Table/Monthly.pm @@ -2,10 +2,9 @@ package FS::Report::Table::Monthly; use strict; use vars qw( @ISA ); -use Time::Local; -use FS::UID qw( dbh ); +use FS::UID qw(dbh); use FS::Report::Table; -use FS::CurrentUser; +use Time::Local qw( timelocal ); @ISA = qw( FS::Report::Table ); @@ -25,6 +24,8 @@ FS::Report::Table::Monthly - Tables of report data, indexed monthly 'end_year' => 2020, #opt 'agentnum' => 54 + 'refnum' => 54 + 'cust_classnum' => [ 1,2,4 ], 'params' => [ [ 'paramsfor', 'item_one' ], [ 'item', 'two' ] ], # ... 'remove_empty' => 1, #collapse empty rows, default 0 'item_labels' => [ ], #useful with remove_empty @@ -32,449 +33,276 @@ FS::Report::Table::Monthly - Tables of report data, indexed monthly my $data = $report->data; -=head1 METHODS +=head1 PARAMETERS -=over 4 - -=item data - -Returns a hashref of data (!! describe) - -=cut - -sub data { - my $self = shift; - - #use Data::Dumper; - #warn Dumper($self); +=head2 TIME PERIOD - my $smonth = $self->{'start_month'}; - my $syear = $self->{'start_year'}; - my $emonth = $self->{'end_month'}; - my $eyear = $self->{'end_year'}; - my $agentnum = $self->{'agentnum'}; - - my %data; +C, C, C, and C specify the date +range to be included in the report. The start and end months are included. +Each month's values are summed from midnight on the first of the month to +23:59:59 on the last day of the month. - while ( $syear < $eyear || ( $syear == $eyear && $smonth < $emonth+1 ) ) { +=head2 REPORT ITEMS - push @{$data{label}}, "$smonth/$syear"; - - 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); - push @{$data{eperiod}}, $eperiod; - - my $col = 0; - my @row = (); - foreach my $item ( @{$self->{'items'}} ) { - my @param = $self->{'params'} ? @{ $self->{'params'}[$col] }: (); - my $value = $self->$item($speriod, $eperiod, $agentnum, @param); - #push @{$data{$item}}, $value; - push @{$data{data}->[$col++]}, $value; - } +=over 4 - } +=item items: An arrayref of observables to calculate for each month. See +L for a list of observables and their parameters. - #these need to get generalized, sheesh - $data{'items'} = $self->{'items'}; - $data{'item_labels'} = $self->{'item_labels'} || $self->{'items'}; - $data{'colors'} = $self->{'colors'}; - $data{'links'} = $self->{'links'} || []; +=item params: An arrayref, parallel to C, of arrayrefs of parameters +(in paired name/value form) to be passed to the observables. - #use Data::Dumper; - #warn Dumper(\%data); +=item cross_params: Cross-product parameters. This must be an arrayref of +arrayrefs of parameters (paired name/value form). This creates an additional +"axis" (orthogonal to the time and C axes) in which the item is +calculated once with each set of parameters in C. These +parameters are merged with those in C. Instead of being nested two +levels, C will be nested three levels, with the third level +corresponding to this arrayref. - if ( $self->{'remove_empty'} ) { +=back - #warn "removing empty rows\n"; +=head2 FILTERING - my $col = 0; - #these need to get generalized, sheesh - my @newitems = (); - my @newlabels = (); - my @newdata = (); - my @newcolors = (); - my @newlinks = (); - foreach my $item ( @{$self->{'items'}} ) { +=over 4 - if ( grep { $_ != 0 } @{$data{'data'}->[$col]} ) { - push @newitems, $data{'items'}->[$col]; - push @newlabels, $data{'item_labels'}->[$col]; - push @newdata, $data{'data'}->[$col]; - push @newcolors, $data{'colors'}->[$col]; - push @newlinks, $data{'links'}->[$col]; - } +=item agentnum: Limit to customers with this agent. - $col++; - } +=item refnum: Limit to customers with this advertising source. - $data{'items'} = \@newitems; - $data{'item_labels'} = \@newlabels; - $data{'data'} = \@newdata; - $data{'colors'} = \@newcolors; - $data{'links'} = \@newlinks; +=item cust_classnum: Limit to customers with this classnum; can be an +arrayref. - } +=item remove_empty: Set this to a true value to hide rows that contain +only zeroes. The C array in the returned data will list the item +indices that are actually present in the output so that you know what they +are. Ignored if C is in effect. - #use Data::Dumper; - #warn Dumper(\%data); +=back - \%data; +=head2 PASS-THROUGH -} +C, C, and C may be specified as arrayrefs +parallel to C. Those values will be returned in C, with any +hidden rows (due to C) filtered out, which is the only +reason to do this. Now that we have C it's probably better to +use that. -sub invoiced { #invoiced - my( $self, $speriod, $eperiod, $agentnum ) = @_; +=item PROCESSING - $self->scalar_sql(" - SELECT SUM(charged) - FROM cust_bill - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum) - ); - -} +=item normalize: Set this to an item index to have all other items expressed +as a percentage of that one. That item will then be omitted from the output. +If the normalization item is zero in some period, all the values in that +period will be undef. -sub netsales { #net sales - my( $self, $speriod, $eperiod, $agentnum ) = @_; +=head1 RETURNED DATA - $self->invoiced($speriod,$eperiod,$agentnum) - - $self->credits( $speriod,$eperiod,$agentnum); -} +The C method runs the report and returns a hashref of the following: -#deferred revenue +=over 4 -sub cashflow { - my( $self, $speriod, $eperiod, $agentnum ) = @_; +=item label - $self->payments($speriod, $eperiod, $agentnum) - - $self->refunds( $speriod, $eperiod, $agentnum); -} +Month labels, in MM/YYYY format. -sub netcashflow { - my( $self, $speriod, $eperiod, $agentnum ) = @_; +=item speriod, eperiod - $self->receipts($speriod, $eperiod, $agentnum) - - $self->netrefunds( $speriod, $eperiod, $agentnum); -} +Absolute start and end times of each month, in unix time format. -sub payments { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(paid) - FROM cust_pay - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum) - ); -} +=item items -sub credits { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(amount) - FROM cust_credit - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum) - ); -} +The values passed in as C, with any suppressed rows deleted. -sub refunds { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(refund) - FROM cust_refund - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum) - ); -} +=item indices -sub netcredits { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(cust_credit_bill.amount) - FROM cust_credit_bill - LEFT JOIN cust_bill USING ( invnum ) - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent( $speriod, - $eperiod, - $agentnum, - 'cust_bill._date' - ) - ); -} +The indices of items in the input C list that appear in the result +set. Useful for figuring out what they are when C has deleted +some items. -sub receipts { #net payments - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(cust_bill_pay.amount) - FROM cust_bill_pay - LEFT JOIN cust_bill USING ( invnum ) - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent( $speriod, - $eperiod, - $agentnum, - 'cust_bill._date' - ) - ); -} +=item item_labels, colors, links - see PASS-THROUGH above -sub netrefunds { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $self->scalar_sql(" - SELECT SUM(cust_credit_refund.amount) - FROM cust_credit_refund - LEFT JOIN cust_credit USING ( crednum ) - LEFT JOIN cust_main USING ( custnum ) - WHERE ". $self->in_time_period_and_agent( $speriod, - $eperiod, - $agentnum, - 'cust_credit._date' - ) - ); -} +=item data -#these should be auto-generated or $AUTOLOADed or something -sub invoiced_12mo { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $speriod = $self->_subtract_11mo($speriod); - $self->invoiced($speriod, $eperiod, $agentnum); -} +The actual results. An arrayref corresponding to C