enable CardFortress in test database, #71513
[freeside.git] / httemplate / search / h_inventory_item.html
1 <% include('/elements/header.html', "$classname Inventory Activity Report") %>
2 <% include('/elements/table-grid.html') %>
3   <TR>
4 % my $TH = 'TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=1';
5     <<%$TH%> WIDTH="10%" ALIGN="left">Day (<% time2str("%B %Y", $sdate) %>)</TH>
6 % foreach my $day (0..$numdays-1) {
7     <<%$TH%> WIDTH="2%" ALIGN="right"><% $day+1 %></TH>
8 % }
9   </TR>
10 % for (my $r=0; $r < scalar(@rows); $r++) {
11   <TR>
12 % my $TD = 'TD CLASS="grid" BGCOLOR="'.($r % 2 ? '#ffffff' : '#eeeeee').'"';
13     <<%$TD%>><% $labels[$r] %></TD>
14 %   for my $day (0..$numdays-1) {
15     <<%$TD%> ALIGN="right"><% $rows[$r][$day] %></TD>
16 %   }
17   </TR>
18 % }
19 </TABLE>
20
21 <%init>
22 use Date::Parse 'str2time';
23 use Date::Format 'time2str';
24 use Data::Dumper 'Dumper';
25
26 my ($agentnum, $classnum, $month, $year, $sdate, $edate);
27 $classnum = $cgi->param('classnum'); # may be empty
28 $agentnum = $cgi->param('agentnum'); # may also be empty
29 my $classname = '';
30 if($classnum) {
31   my $class = qsearchs('inventory_class', { classnum => $classnum });
32   die "classnum $classnum not found!" if !$class;
33   $classname = $class->classname . ' ';
34 }
35
36 $month = $cgi->param('_month') || time2str('%m', time);
37 $year = $cgi->param('_year') || time2str('%Y', time);
38
39 $sdate = str2time("$year-$month-01");
40 $edate = str2time($year + ($month == 12 ? 1 : 0) .
41                   '-' .
42                   (($month + 1) % 12 || 12) .
43                   '-01');
44 my $numdays = sprintf("%.0f",($edate-$sdate)/86400);
45 my @days = (0..$numdays - 1);
46 # Initialize each row with zeroes.
47 my @labels = (
48   'Opening Balance',
49   'Quantity Received',
50   'Quantity Sold',
51   'Quantity Returned',
52 );
53
54 if($agentnum) {
55   push @labels, 'Transfer In', 'Transfer Out';
56 }
57 push @labels, 'Closing Balance';
58
59 my %agent = ('agentnum' => $agentnum) if $agentnum;
60 my %class = ('classnum' => $classnum) if $classnum;
61
62 my @rows = ( map {[ (0) x $numdays ]} @labels);
63 local($FS::Record::qsearch_qualify_columns) = 0;
64 my $opening_balance = scalar(
65   qsearch('h_inventory_item', 
66           { 'svcnum' => '',
67             %agent,
68             %class },
69           FS::h_inventory_item->sql_h_search($sdate) )
70   ) || 0;
71
72 foreach my $day (0..$numdays-1) {
73   $rows[0][$day] = ($day == 0) ? 
74                     $opening_balance : 
75                     $rows[-1][$day-1];
76
77   my %history;
78   foreach my $action (qw(insert replace_new replace_old)) {
79     $history{$action} = [
80                         qsearch({
81                           'table'     => 'h_inventory_item',
82                           'hashref'   => { 'history_action' => $action,
83                                            %class },
84                           'order_by'  => 'ORDER BY itemnum, history_date',
85                           'extra_sql' => 
86                             ' AND history_date >= '.($sdate + 86400*$day).
87                             ' AND history_date < ' .($sdate + 86400*($day+1)),
88                           } ) 
89                         ];
90   }
91   # Incoming items: simple, just count the inserts
92   $rows[1][$day] = scalar(grep {!$agentnum or $_->agentnum == $agentnum}
93                               @{ $history{'insert'} });
94
95   # Other item changes: trickier.
96   # Notice the order_by parameter above.
97   # Both lists are sorted by itemnum, then by date, so unless some villain has 
98   # been rapidly replacing the same record several times per second, the 
99   # replace_old and replace_new from the same operation will be in the same 
100   # position.
101   while(my $h_new = shift @{ $history{'replace_new'} }) {
102     my $h_old = shift @{ $history{'replace_old'} };
103     die "history error" if !defined($h_old) 
104                            or $h_old->itemnum != $h_new->itemnum;
105     if(!$agentnum or $h_new->agentnum == $agentnum) {
106       if(!$h_old->svcnum and $h_new->svcnum) {
107         # item was put into service.
108         $rows[2][$day]++;
109       }
110       elsif($h_old->svcnum and !$h_new->svcnum) {
111         # item was taken out of service.
112         $rows[3][$day]++;
113       }
114     }
115     if($agentnum and $h_old->agentnum != $agentnum and $h_new->agentnum == $agentnum) {
116       # item was transferred from another agent
117       $rows[4][$day]++;
118     }
119     elsif($agentnum and $h_old->agentnum == $agentnum and $h_new->agentnum != $agentnum) {
120       # item was transferred to another agent
121       $rows[5][$day]++;
122     }
123     # Add other cases here.
124   }
125   # Closing balance
126   $rows[-1][$day] = $rows[0][$day]
127                   + $rows[1][$day]
128                   - $rows[2][$day]
129                   + $rows[3][$day];
130   if($agentnum) {
131     $rows[-1][$day] += $rows[4][$day] - $rows[5][$day];
132   }
133 }
134
135 </%init>
136