d9d8754ebc606af3d03eeed8ec05927dedb2918f
[freeside.git] / FS / FS / Report / Table / Monthly.pm
1 package FS::Report::Table::Monthly;
2
3 use strict;
4 use vars qw( @ISA );
5 use FS::Report::Table;
6 use Time::Local qw( timelocal );
7
8 @ISA = qw( FS::Report::Table );
9
10 =head1 NAME
11
12 FS::Report::Table::Monthly - Tables of report data, indexed monthly
13
14 =head1 SYNOPSIS
15
16   use FS::Report::Table::Monthly;
17
18   my $report = new FS::Report::Table::Monthly (
19     'items' => [ 'invoiced', 'netsales', 'credits', 'receipts', ],
20     'start_month' => 4,
21     'start_year'  => 2000,
22     'end_month'   => 4,
23     'end_year'    => 2020,
24     #opt
25     'agentnum'    => 54
26     'params'      => [ [ 'paramsfor', 'item_one' ], [ 'item', 'two' ] ], # ...
27     'remove_empty' => 1, #collapse empty rows, default 0
28     'item_labels' => [ ], #useful with remove_empty
29   );
30
31   my $data = $report->data;
32
33 =head1 METHODS
34
35 =over 4
36
37 =item data
38
39 Returns a hashref of data (!! describe)
40
41 =cut
42
43 sub data {
44   my $self = shift;
45
46   my $smonth = $self->{'start_month'};
47   my $syear = $self->{'start_year'};
48   my $emonth = $self->{'end_month'};
49   my $eyear = $self->{'end_year'};
50   my $agentnum = $self->{'agentnum'};
51
52   my %data;
53
54   while ( $syear < $eyear || ( $syear == $eyear && $smonth < $emonth+1 ) ) {
55
56     if ( $self->{'doublemonths'} ) {
57         my($firstLabel,$secondLabel) = @{$self->{'doublemonths'}};
58         push @{$data{label}}, "$smonth/$syear $firstLabel";
59         push @{$data{label}}, "$smonth/$syear $secondLabel";
60     }
61     else {
62         push @{$data{label}}, "$smonth/$syear";
63     }
64
65     my $speriod = timelocal(0,0,0,1,$smonth-1,$syear);
66     push @{$data{speriod}}, $speriod;
67     if ( ++$smonth == 13 ) { $syear++; $smonth=1; }
68     my $eperiod = timelocal(0,0,0,1,$smonth-1,$syear);
69     push @{$data{eperiod}}, $eperiod;
70   
71     my $col = 0;
72     my @items = @{$self->{'items'}};
73     my $i;
74     for ( $i = 0; $i < scalar(@items); $i++ ) {
75       if ( $self->{'doublemonths'} ) {
76           my $item = $items[$i]; 
77           my @param = $self->{'params'} ? @{ $self->{'params'}[$i] }: ();
78           my $value = $self->$item($speriod, $eperiod, $agentnum, @param);
79           push @{$data{data}->[$col]}, $value;
80           $item = $items[$i+1]; 
81           @param = $self->{'params'} ? @{ $self->{'params'}[++$i] }: ();
82           $value = $self->$item($speriod, $eperiod, $agentnum, @param);
83           push @{$data{data}->[$col++]}, $value;
84       }
85       else {
86           my $item = $items[$i];
87           my @param = $self->{'params'} ? @{ $self->{'params'}[$col] }: ();
88           my $value = $self->$item($speriod, $eperiod, $agentnum, @param);
89           push @{$data{data}->[$col++]}, $value;
90       }
91     }
92
93   }
94
95   #these need to get generalized, sheesh
96   $data{'items'}       = $self->{'items'};
97   $data{'item_labels'} = $self->{'item_labels'} || $self->{'items'};
98   $data{'colors'}      = $self->{'colors'};
99   $data{'links'}       = $self->{'links'} || [];
100
101   if ( $self->{'remove_empty'} ) {
102
103     my $col = 0;
104     #these need to get generalized, sheesh
105     #(though we now return a list of item indices that are present in the 
106     #output, so the front-end code could do this)
107     my @newitems = ();
108     my @newlabels = ();
109     my @newdata = ();
110     my @newcolors = ();
111     my @newlinks = ();
112     my @indices = ();
113     foreach my $item ( @{$self->{'items'}} ) {
114
115       if ( grep { $_ != 0 } @{$data{'data'}->[$col]} ) {
116         push @newitems,  $data{'items'}->[$col];
117         push @newlabels, $data{'item_labels'}->[$col];
118         push @newdata,   $data{'data'}->[$col];
119         push @newcolors, $data{'colors'}->[$col];
120         push @newlinks,  $data{'links'}->[$col];
121         push @indices,   $col;
122       }
123
124       $col++;
125     }
126
127     $data{'items'}       = \@newitems;
128     $data{'item_labels'} = \@newlabels;
129     $data{'data'}        = \@newdata;
130     $data{'colors'}      = \@newcolors;
131     $data{'links'}       = \@newlinks;
132     $data{'indices'}     = \@indices;
133
134   }
135
136   \%data;
137 }
138
139 =back
140
141 =head1 BUGS
142
143 Documentation.
144
145 =head1 SEE ALSO
146
147 =cut
148
149 1;
150