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