create a Sales, Credits, and Receipts report broken down by day, RT11470
[freeside.git] / FS / FS / Report / Table / Daily.pm
1 package FS::Report::Table::Daily;
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::Daily - Tables of report data, indexed daily
13
14 =head1 SYNOPSIS
15
16   use FS::Report::Table::Daily;
17
18   my $report = new FS::Report::Table::Daily (
19     'items' => [ 'invoiced', 'netsales', 'credits', 'receipts', ],
20     'start_month' => 4,
21     'start_year'  => 2000,
22     'end_month'   => 4,
23     'end_year'    => 2020,
24     'start_day'   => 2,
25     'end_day'     => 27,
26     #opt
27     'agentnum'    => 54
28     'params'      => [ [ 'paramsfor', 'item_one' ], [ 'item', 'two' ] ], # ...
29     'remove_empty' => 1, #collapse empty rows, default 0
30     'item_labels' => [ ], #useful with remove_empty
31   );
32
33   my $data = $report->data;
34
35 =head1 METHODS
36
37 =over 4
38
39 =item data
40
41 Returns a hashref of data (!! describe)
42
43 =cut
44
45 sub data {
46   my $self = shift;
47
48   my $sday = $self->{'start_day'};
49   my $smonth = $self->{'start_month'};
50   my $syear = $self->{'start_year'};
51   my $eday = $self->{'end_day'};
52   my $emonth = $self->{'end_month'};
53   my $eyear = $self->{'end_year'};
54   my $agentnum = $self->{'agentnum'};
55
56   my %data;
57
58   my $sdate = timelocal(0,0,0,$sday,$smonth-1,$syear);
59   my $edate = timelocal(0,0,0,$eday,$emonth-1,$eyear);
60
61   warn "daily range $sdate $edate\n";
62
63   # XXX: use date_format config for the labels since we have day in the labels now?
64   # XXX: leap seconds / DST 
65   while ( $sdate < $edate ) {
66     my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($sdate);
67     $mon++;
68     $year += 1900;
69     warn "label=$mday/$mon/$year\n";
70     push @{$data{label}}, "$mday/$mon/$year";
71
72     my $speriod = $sdate;
73     $sdate += 86400;
74     my $eperiod = $sdate;
75
76     push @{$data{speriod}}, $speriod;
77     push @{$data{eperiod}}, $eperiod;
78
79     my $col = 0;
80     my @items = @{$self->{'items'}};
81     my $i;
82     for ( $i = 0; $i < scalar(@items); $i++ ) {
83           my $item = $items[$i];
84           my @param = $self->{'params'} ? @{ $self->{'params'}[$col] }: ();
85           my $value = $self->$item($speriod, $eperiod, $agentnum, @param);
86           push @{$data{data}->[$col++]}, $value;
87     }
88   }
89
90   #these need to get generalized, sheesh
91   $data{'items'}       = $self->{'items'};
92   $data{'item_labels'} = $self->{'item_labels'} || $self->{'items'};
93   $data{'colors'}      = $self->{'colors'};
94   $data{'links'}       = $self->{'links'} || [];
95
96   if ( $self->{'remove_empty'} ) {
97
98     my $col = 0;
99     #these need to get generalized, sheesh
100     my @newitems = ();
101     my @newlabels = ();
102     my @newdata = ();
103     my @newcolors = ();
104     my @newlinks = ();
105     foreach my $item ( @{$self->{'items'}} ) {
106
107       if ( grep { $_ != 0 } @{$data{'data'}->[$col]} ) {
108         push @newitems,  $data{'items'}->[$col];
109         push @newlabels, $data{'item_labels'}->[$col];
110         push @newdata,   $data{'data'}->[$col];
111         push @newcolors, $data{'colors'}->[$col];
112         push @newlinks,  $data{'links'}->[$col];
113       }
114
115       $col++;
116     }
117
118     $data{'items'}       = \@newitems;
119     $data{'item_labels'} = \@newlabels;
120     $data{'data'}        = \@newdata;
121     $data{'colors'}      = \@newcolors;
122     $data{'links'}       = \@newlinks;
123
124   }
125
126   \%data;
127
128 }
129
130 =back
131
132 =head1 BUGS
133
134 Documentation.
135
136 =head1 SEE ALSO
137
138 =cut
139
140 1;