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