fix 477 reporting w/multiple classnums, RT#13922
[freeside.git] / httemplate / search / cust_pkg.cgi
1 <& elements/search.html,
2                   'html_init'   => $html_init, 
3                   'title'       => emt('Package Search Results'), 
4                   'name'        => 'packages',
5                   'query'       => $sql_query,
6                   'count_query' => $count_query,
7                   'header'      => [ emt('#'),
8                                      emt('Quan.'),
9                                      emt('Package'),
10                                      emt('Class'),
11                                      emt('Status'),
12                                      emt('Setup'),
13                                      emt('Base Recur'),
14                                      emt('Freq.'),
15                                      emt('Setup'),
16                                      emt('Last bill'),
17                                      emt('Next bill'),
18                                      emt('Adjourn'),
19                                      emt('Susp.'),
20                                      emt('Susp. delay'),
21                                      emt('Expire'),
22                                      emt('Contract end'),
23                                      emt('Cancel'),
24                                      emt('Reason'),
25                                      FS::UI::Web::cust_header(
26                                        $cgi->param('cust_fields')
27                                      ),
28                                      emt('Services'),
29                                    ],
30                   'fields'      => [
31                     'pkgnum',
32                     'quantity',
33                     sub { $_[0]->pkg; },
34                     'classname',
35                     sub { ucfirst(shift->status); },
36                     sub { sprintf( $money_char.'%.2f',
37                                    shift->part_pkg->option('setup_fee'),
38                                  );
39                         },
40                     sub { my $c = shift;
41                           sprintf( $money_char.'%.2f',
42                                    $c->part_pkg->base_recur($c)
43                                  );
44                         },
45                     sub { FS::part_pkg::freq_pretty(shift); },
46
47                     ( map { time_or_blank($_) }
48           qw( setup last_bill bill adjourn susp dundate expire contract_end cancel ) ),
49
50                     sub { my $self = shift;
51                           my $return = '';
52                           foreach my $action ( qw ( cancel susp ) ) {
53                             my $reason = $self->last_reason($action);
54                             $return = $reason->reason if $reason;
55                             last if $return;
56                           }
57                           $return;
58                         },
59
60                     \&FS::UI::Web::cust_fields,
61                     sub {
62                       my $cust_pkg = shift;
63                       my $type = $cgi->param('_type') || '';
64                       if ($type =~ /xls|csv/) {
65                         my $cust_svc = $cust_pkg->primary_cust_svc;
66                         if($cust_svc) {
67                           return join ": ",($cust_svc->label)[0,1];
68                         }
69                         else {
70                           return '';
71                         }
72                       }
73                       else {
74                           [ $process_svc_labels->( $cust_pkg ) ]
75                       }
76                     }
77                   ],
78                   'color' => [
79                     '',
80                     '',
81                     '',
82                     '',
83                     sub { shift->statuscolor; },
84                     '',
85                     '',
86                     '',
87                     '',
88                     '',
89                     '',
90                     '',
91                     '',
92                     '',
93                     '',
94                     '',
95                     '',
96                     '',
97                     FS::UI::Web::cust_colors(),
98                     '',
99                   ],
100                   'style' => [ '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '',
101                                FS::UI::Web::cust_styles() ],
102                   'size'  => [ '', '', '', '', '-1' ],
103                   'align' => 'rrlccrrlrrrrrrrrrl'. FS::UI::Web::cust_aligns(). 'r',
104                   'links' => [
105                     $link,
106                     $link,
107                     $link,
108                     '',
109                     '',
110                     '',
111                     '',
112                     '',
113                     '',
114                     '',
115                     '',
116                     '',
117                     '',
118                     '',
119                     '',
120                     '',
121                     '',
122                     '',
123                     ( map { $_ ne 'Cust. Status' ? $clink : '' }
124                           FS::UI::Web::cust_header(
125                                                     $cgi->param('cust_fields')
126                                                   )
127                     ),
128                     '',
129                   ],
130 &>
131 <%init>
132
133 my $curuser = $FS::CurrentUser::CurrentUser;
134
135 die "access denied"
136   unless $curuser->access_right('List packages');
137
138 my $conf = new FS::Conf;
139 my $money_char = $conf->config('money_char') || '$';
140
141 my %search_hash = ();
142
143 #some false laziness w/misc/bulk_change_pkg.cgi
144   
145 $search_hash{'query'} = $cgi->keywords;
146
147 #scalars
148 for (qw( agentnum custnum magic status custom cust_fields pkgbatch )) {
149   $search_hash{$_} = $cgi->param($_) if $cgi->param($_);
150 }
151
152 #arrays
153 for my $param (qw( pkgpart classnum )) {
154   $search_hash{$param} = [ $cgi->param($param) ];
155     if grep { $_ eq $param } $cgi->param;
156 }
157
158 #scalars that need to be passed if empty
159 for my $param (qw( censustract censustract2 )) {
160   $search_hash{$param} = $cgi->param($param) || ''
161     if grep { $_ eq $param } $cgi->param;
162 }
163
164 my @report_option = $cgi->param('report_option')
165   if $cgi->param('report_option');
166 $search_hash{report_option} = join(',', @report_option) if @report_option;
167
168 ###
169 # parse dates
170 ###
171
172 #false laziness w/report_cust_pkg.html
173 my %disable = (
174   'all'             => {},
175   'one-time charge' => { 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'susp'=>1, 'expire'=>1, 'cancel'=>1, 'contract_end'=>1, 'dundate'=>1, },
176   'active'          => { 'susp'=>1, 'cancel'=>1 },
177   'suspended'       => { 'cancel' =>1, 'dundate'=>1, },
178   'cancelled'       => {},
179   ''                => {},
180 );
181
182 foreach my $field (qw( setup last_bill bill adjourn susp expire contract_end cancel active )) {
183
184   my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi, $field);
185
186   next if $beginning == 0 && $ending == 4294967295
187        or $disable{$cgi->param('status')}->{$field};
188
189   $search_hash{$field} = [ $beginning, $ending ];
190
191 }
192
193 my $sql_query = FS::cust_pkg->search(\%search_hash);
194 my $count_query = delete($sql_query->{'count_query'});
195
196 my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/
197              ? ''
198              : ';show=packages';
199
200 my $link = sub {
201   my $self = shift;
202   my $frag = 'cust_pkg'. $self->pkgnum; #hack for IE ignoring real #fragment
203   [ "${p}view/cust_main.cgi?custnum=".$self->custnum.
204                            "$show;fragment=$frag#cust_pkg",
205     'pkgnum'
206   ];
207 };
208
209 my $clink = sub {
210   my $cust_pkg = shift;
211   $cust_pkg->cust_main_custnum
212     ? [ "${p}view/cust_main.cgi?", 'custnum' ] 
213     : '';
214 };
215
216 sub time_or_blank {
217    my $column = shift;
218    return sub {
219      my $record = shift;
220      my $value = $record->get($column); #mmm closures
221      $value ? time2str('%b %d %Y', $value ) : '';
222    };
223 }
224
225 my $html_init = sub {
226   my $query = shift;
227   my $text = '';
228   my $curuser = $FS::CurrentUser::CurrentUser;
229
230   if ( $curuser->access_right('Bulk change customer packages') ) {
231     $text .= include('/elements/init_overlib.html').
232              include( '/elements/popup_link.html',
233                'label'       => emt('Change these packages'),
234                'action'      => "${p}misc/bulk_change_pkg.cgi?$query",
235                'actionlabel' => emt('Change Packages'),
236                'width'       => 569,
237                'height'      => 210,
238              ). '<BR>';
239
240     if ( $curuser->access_right('Edit customer package dates') ) {
241       $text .= include( '/elements/popup_link.html',
242                  'label'       => emt('Increment next bill date'),
243                  'action'      => "${p}misc/bulk_pkg_increment_bill.cgi?$query",
244                  'actionlabel' => emt('Increment Bill Date'),
245                  'width'       => 569,
246                  'height'      => 210,
247               ). '<BR>';
248     }
249     $text .= include( '/elements/email-link.html',
250                 'search_hash' => \%search_hash,
251                 'table'       => 'cust_pkg',
252                 );
253   }
254   return $text;
255 };
256
257 my $large_pkg_size = $conf->config('cust_pkg-large_pkg_size');
258
259 my $process_svc_labels = sub {
260   my $cust_pkg = shift;
261   my @out;
262   foreach my $part_svc ( $cust_pkg->part_svc) {
263     # some false laziness with view/cust_main/packages/services.html
264
265     my $num_cust_svc = $cust_pkg->num_cust_svc( $part_svc->svcpart );
266
267     if ( $large_pkg_size > 0 and $large_pkg_size <= $num_cust_svc ) {
268       my $href = $p.'search/cust_pkg_svc.html?svcpart='.$part_svc->svcpart.
269           ';pkgnum='.$cust_pkg->pkgnum;
270       push @out, [
271         { 'data'  => $part_svc->svc . ':',
272           'align' => 'right',
273           'rowspan' => 2 },
274         { 'data'  => mt('(view all [_1])', $num_cust_svc),
275           'data_style' => 'b',
276           'align' => 'left',
277           'link'  => $href, },
278       ],
279       [
280         { 'data'  => include('/elements/search-cust_svc.html',
281                         'svcpart' => $part_svc->svcpart,
282                         'pkgnum'  => $cust_pkg->pkgnum,
283                     ),
284           'align' => 'left' },
285       ];
286     }
287     else {
288       foreach ( map { [ $_->label ] } @{ $part_svc->cust_pkg_svc } ) {
289         push @out, [ 
290         { 'data' => $_->[0]. ':',
291           'align'=> 'right', },
292         { 'data' => $_->[1],
293           'align'=> 'left',
294           'link' => $p. 'view/' .
295           $_->[2]. '.cgi?'. $_->[3], },
296         ];
297       }
298     }
299   } #foreach $cust_pkg
300   return @out;
301 };
302
303 </%init>