X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FReport%2FTable%2FMonthly.pm;h=ee4dc5fe8b8fdeaf939d17ff69552e6b5ec42fc5;hb=044e4ea5533f1c14697b7ad408dc0cf0e0327abb;hp=e7f05e5f2b0c624e0f9206f69d3dc4327f99c256;hpb=f29c752d6f9e813c10295b334eefb924216e34cf;p=freeside.git diff --git a/FS/FS/Report/Table/Monthly.pm b/FS/FS/Report/Table/Monthly.pm index e7f05e5f2..ee4dc5fe8 100644 --- a/FS/FS/Report/Table/Monthly.pm +++ b/FS/FS/Report/Table/Monthly.pm @@ -1,15 +1,13 @@ package FS::Report::Table::Monthly; use strict; -use vars qw( @ISA $expenses_kludge ); -use Time::Local; -use FS::UID qw( dbh ); +use vars qw( @ISA ); +use FS::UID qw(dbh); use FS::Report::Table; +use Time::Local qw( timelocal ); @ISA = qw( FS::Report::Table ); -$expenses_kludge = 0; - =head1 NAME FS::Report::Table::Monthly - Tables of report data, indexed monthly @@ -24,245 +22,237 @@ FS::Report::Table::Monthly - Tables of report data, indexed monthly 'start_year' => 2000, 'end_month' => 4, 'end_year' => 2020, + #opt + 'agentnum' => 54 + 'refnum' => 54 + 'params' => [ [ 'paramsfor', 'item_one' ], [ 'item', 'two' ] ], # ... + 'remove_empty' => 1, #collapse empty rows, default 0 + 'item_labels' => [ ], #useful with remove_empty ); my $data = $report->data; -=head1 METHODS +=head1 PARAMETERS + +=head2 TIME PERIOD + +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. + +=head2 REPORT ITEMS =over 4 -=item data +=item items: An arrayref of observables to calculate for each month. See +L for a list of observables and their parameters. -Returns a hashref of data (!! describe) +=item params: An arrayref, parallel to C, of arrayrefs of parameters +(in paired name/value form) to be passed to the observables. -=cut +=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. -sub data { - my $self = shift; +=back - my $smonth = $self->{'start_month'}; - my $syear = $self->{'start_year'}; - my $emonth = $self->{'end_month'}; - my $eyear = $self->{'end_year'}; - my $agentnum = $self->{'agentnum'}; +=head2 FILTERING - my %data; +=over 4 - while ( $syear < $eyear || ( $syear == $eyear && $smonth < $emonth+1 ) ) { +=item agentnum: Limit to customers with this agent. - push @{$data{label}}, "$smonth/$syear"; +=item refnum: Limit to customers with this advertising source. - 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; - - foreach my $item ( @{$self->{'items'}} ) { - push @{$data{$item}}, $self->$item($speriod, $eperiod, $agentnum); - } +=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. - } +=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 ) = @_; - $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) - ); -} +=head1 RETURNED DATA -sub netsales { #net sales - my( $self, $speriod, $eperiod, $agentnum ) = @_; +The C method runs the report and returns a hashref of the following: - my $credited = $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') - ); +=over 4 - #horrible local kludge - my $expenses = !$expenses_kludge ? 0 : $self->scalar_sql(" - SELECT SUM(cust_bill_pkg.setup) - FROM cust_bill_pkg - LEFT JOIN cust_bill USING ( invnum ) - LEFT JOIN cust_main USING ( custnum ) - LEFT JOIN cust_pkg USING ( pkgnum ) - LEFT JOIN part_pkg USING ( pkgpart ) - WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum, 'cust_bill'). " - AND LOWER(part_pkg.pkg) LIKE 'expense _%' - "); - - $self->invoiced($speriod,$eperiod,$agentnum) - $credited - $expenses; -} +=item label -#deferred revenue +Month labels, in MM/YYYY format. -sub receipts { #cashflow - my( $self, $speriod, $eperiod, $agentnum ) = @_; +=item speriod, eperiod - my $refunded = $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) - ); +Absolute start and end times of each month, in unix time format. - #horrible local kludge that doesn't even really work right - my $expenses = !$expenses_kludge ? 0 : $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_pay'). " - AND 0 < ( SELECT COUNT(*) from cust_bill_pkg, cust_pkg, part_pkg - WHERE cust_bill.invnum = cust_bill_pkg.invnum - AND cust_pkg.pkgnum = cust_bill_pkg.pkgnum - AND cust_pkg.pkgpart = part_pkg.pkgpart - AND LOWER(part_pkg.pkg) LIKE 'expense _%' - ) - "); - # my $expenses_sql2 = "SELECT SUM(cust_bill_pay.amount) FROM cust_bill_pay, cust_bill_pkg, cust_bill, cust_pkg, part_pkg WHERE cust_bill_pay.invnum = cust_bill.invnum AND cust_bill.invnum = cust_bill_pkg.invnum AND cust_bill_pay._date >= $speriod AND cust_bill_pay._date < $eperiod AND cust_pkg.pkgnum = cust_bill_pkg.pkgnum AND cust_pkg.pkgpart = part_pkg.pkgpart AND LOWER(part_pkg.pkg) LIKE 'expense _%'"; - - $self->payments($speriod, $eperiod, $agentnum) - $refunded - $expenses; -} +=item items -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) - ); -} +The values passed in as C, with any suppressed rows deleted. -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) - ); -} +=item indices -#these should be auto-generated -sub invoiced_12mo { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $speriod = $self->_subtract_11mo($speriod); - $self->invoiced($speriod, $eperiod, $agentnum); -} +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 netsales_12mo { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $speriod = $self->_subtract_11mo($speriod); - $self->netsales($speriod, $eperiod, $agentnum); -} +=item item_labels, colors, links - see PASS-THROUGH above -sub receipts_12mo { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $speriod = $self->_subtract_11mo($speriod); - $self->receipts($speriod, $eperiod, $agentnum); -} +=item data -sub payments_12mo { - my( $self, $speriod, $eperiod, $agentnum ) = @_; - $speriod = $self->_subtract_11mo($speriod); - $self->payments($speriod, $eperiod, $agentnum); -} +The actual results. An arrayref corresponding to C