f57fb064ba71572032c9fabb8cd7f5aebb86cfe6
[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     my @newitems = ();
106     my @newlabels = ();
107     my @newdata = ();
108     my @newcolors = ();
109     my @newlinks = ();
110     foreach my $item ( @{$self->{'items'}} ) {
111
112       if ( grep { $_ != 0 } @{$data{'data'}->[$col]} ) {
113         push @newitems,  $data{'items'}->[$col];
114         push @newlabels, $data{'item_labels'}->[$col];
115         push @newdata,   $data{'data'}->[$col];
116         push @newcolors, $data{'colors'}->[$col];
117         push @newlinks,  $data{'links'}->[$col];
118       }
119
120       $col++;
121     }
122
123     $data{'items'}       = \@newitems;
124     $data{'item_labels'} = \@newlabels;
125     $data{'data'}        = \@newdata;
126     $data{'colors'}      = \@newcolors;
127     $data{'links'}       = \@newlinks;
128
129   }
130
131   \%data;
132 }
133
134 =back
135
136 =head1 BUGS
137
138 Documentation.
139
140 =head1 SEE ALSO
141
142 =cut
143
144 1;
145