daily sales/receipts report: fix customer class and date selection, #24853
[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 FS::Conf;
7 use Time::Local qw( timelocal );
8 use Date::Format qw( time2str );
9
10 @ISA = qw( FS::Report::Table );
11
12 =head1 NAME
13
14 FS::Report::Table::Daily - Tables of report data, indexed daily
15
16 =head1 SYNOPSIS
17
18   use FS::Report::Table::Daily;
19
20   my $report = new FS::Report::Table::Daily (
21     'items' => [ 'invoiced', 'netsales', 'credits', 'receipts', ],
22     'start_month' => 4,
23     'start_year'  => 2000,
24     'end_month'   => 4,
25     'end_year'    => 2020,
26     'start_day'   => 2,
27     'end_day'     => 27,
28     #opt
29     'agentnum'    => 54
30     'cust_classnum' => [ 1,2,4 ],
31     'params'      => [ [ 'paramsfor', 'item_one' ], [ 'item', 'two' ] ], # ...
32     'remove_empty' => 1, #collapse empty rows, default 0
33     'item_labels' => [ ], #useful with remove_empty
34   );
35
36   my $data = $report->data;
37
38 =head1 METHODS
39
40 =over 4
41
42 =item data
43
44 Returns a hashref of data (!! describe)
45
46 =cut
47
48 sub data {
49   my $self = shift;
50
51   my $sday = $self->{'start_day'};
52   my $smonth = $self->{'start_month'};
53   my $syear = $self->{'start_year'};
54   my $eday = $self->{'end_day'};
55   my $emonth = $self->{'end_month'};
56   my $eyear = $self->{'end_year'};
57   my $agentnum = $self->{'agentnum'};
58   my $cust_classnum = $self->{'cust_classnum'} || [];
59   $cust_classnum = [ $cust_classnum ] if !ref($cust_classnum);
60
61   my %data;
62
63   my $sdate = timelocal(0,0,0,$sday,$smonth-1,$syear);
64   my $edate = timelocal(0,0,0,$eday,$emonth-1,$eyear);
65
66   my $conf = FS::Conf->new;
67   my $date_format = $conf->config('date_format') || '%d/%m/%Y';
68
69   #warn "daily range $sdate $edate\n";
70
71   # XXX: use date_format config for the labels since we have day in the labels now?
72   # XXX: leap seconds / DST 
73   while ( $sdate < $edate ) {
74     push @{$data{label}}, time2str($date_format, $sdate);
75
76     my $speriod = $sdate;
77     $sdate += 86400;
78     my $eperiod = $sdate;
79
80     push @{$data{speriod}}, $speriod;
81     push @{$data{eperiod}}, $eperiod;
82
83     my $col = 0;
84     my @items = @{$self->{'items'}};
85     my $i;
86     for ( $i = 0; $i < scalar(@items); $i++ ) {
87           my $item = $items[$i];
88           my @param = $self->{'params'} ? @{ $self->{'params'}[$col] }: ();
89           push @param, 'cust_classnum' => $cust_classnum if @$cust_classnum;
90           my $value = $self->$item($speriod, $eperiod, $agentnum, @param);
91           push @{$data{data}->[$col++]}, $value;
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
135 =back
136
137 =head1 BUGS
138
139 Documentation.
140
141 =head1 SEE ALSO
142
143 =cut
144
145 1;