allow multiple classnums in package search, 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 (qw( pkgpart classnum )) {
154   $search_hash{$_} = [ $cgi->param($_) ];
155 }
156
157 for my $param ( qw(censustract) ) {
158   $search_hash{$param} = $cgi->param($param) || ''
159     if ( grep { /$param/ } $cgi->param );
160 }
161
162 my @report_option = $cgi->param('report_option')
163   if $cgi->param('report_option');
164 $search_hash{report_option} = join(',', @report_option) if @report_option;
165
166 ###
167 # parse dates
168 ###
169
170 #false laziness w/report_cust_pkg.html
171 my %disable = (
172   'all'             => {},
173   'one-time charge' => { 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'susp'=>1, 'expire'=>1, 'cancel'=>1, 'contract_end'=>1, 'dundate'=>1, },
174   'active'          => { 'susp'=>1, 'cancel'=>1 },
175   'suspended'       => { 'cancel' =>1, 'dundate'=>1, },
176   'cancelled'       => {},
177   ''                => {},
178 );
179
180 foreach my $field (qw( setup last_bill bill adjourn susp expire contract_end cancel active )) {
181
182   my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi, $field);
183
184   next if $beginning == 0 && $ending == 4294967295
185        or $disable{$cgi->param('status')}->{$field};
186
187   $search_hash{$field} = [ $beginning, $ending ];
188
189 }
190
191 my $sql_query = FS::cust_pkg->search(\%search_hash);
192 my $count_query = delete($sql_query->{'count_query'});
193
194 my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/
195              ? ''
196              : ';show=packages';
197
198 my $link = sub {
199   my $self = shift;
200   my $frag = 'cust_pkg'. $self->pkgnum; #hack for IE ignoring real #fragment
201   [ "${p}view/cust_main.cgi?custnum=".$self->custnum.
202                            "$show;fragment=$frag#cust_pkg",
203     'pkgnum'
204   ];
205 };
206
207 my $clink = sub {
208   my $cust_pkg = shift;
209   $cust_pkg->cust_main_custnum
210     ? [ "${p}view/cust_main.cgi?", 'custnum' ] 
211     : '';
212 };
213
214 sub time_or_blank {
215    my $column = shift;
216    return sub {
217      my $record = shift;
218      my $value = $record->get($column); #mmm closures
219      $value ? time2str('%b %d %Y', $value ) : '';
220    };
221 }
222
223 my $html_init = sub {
224   my $query = shift;
225   my $text = '';
226   my $curuser = $FS::CurrentUser::CurrentUser;
227
228   if ( $curuser->access_right('Bulk change customer packages') ) {
229     $text .= include('/elements/init_overlib.html').
230              include( '/elements/popup_link.html',
231                'label'       => emt('Change these packages'),
232                'action'      => "${p}misc/bulk_change_pkg.cgi?$query",
233                'actionlabel' => emt('Change Packages'),
234                'width'       => 569,
235                'height'      => 210,
236              ). '<BR>';
237
238     if ( $curuser->access_right('Edit customer package dates') ) {
239       $text .= include( '/elements/popup_link.html',
240                  'label'       => emt('Increment next bill date'),
241                  'action'      => "${p}misc/bulk_pkg_increment_bill.cgi?$query",
242                  'actionlabel' => emt('Increment Bill Date'),
243                  'width'       => 569,
244                  'height'      => 210,
245               ). '<BR>';
246     }
247     $text .= include( '/elements/email-link.html',
248                 'search_hash' => \%search_hash,
249                 'table'       => 'cust_pkg',
250                 );
251   }
252   return $text;
253 };
254
255 my $large_pkg_size = $conf->config('cust_pkg-large_pkg_size');
256
257 my $process_svc_labels = sub {
258   my $cust_pkg = shift;
259   my @out;
260   foreach my $part_svc ( $cust_pkg->part_svc) {
261     # some false laziness with view/cust_main/packages/services.html
262
263     my $num_cust_svc = $cust_pkg->num_cust_svc( $part_svc->svcpart );
264
265     if ( $large_pkg_size > 0 and $large_pkg_size <= $num_cust_svc ) {
266       my $href = $p.'search/cust_pkg_svc.html?svcpart='.$part_svc->svcpart.
267           ';pkgnum='.$cust_pkg->pkgnum;
268       push @out, [
269         { 'data'  => $part_svc->svc . ':',
270           'align' => 'right',
271           'rowspan' => 2 },
272         { 'data'  => mt('(view all [_1])', $num_cust_svc),
273           'data_style' => 'b',
274           'align' => 'left',
275           'link'  => $href, },
276       ],
277       [
278         { 'data'  => include('/elements/search-cust_svc.html',
279                         'svcpart' => $part_svc->svcpart,
280                         'pkgnum'  => $cust_pkg->pkgnum,
281                     ),
282           'align' => 'left' },
283       ];
284     }
285     else {
286       foreach ( map { [ $_->label ] } @{ $part_svc->cust_pkg_svc } ) {
287         push @out, [ 
288         { 'data' => $_->[0]. ':',
289           'align'=> 'right', },
290         { 'data' => $_->[1],
291           'align'=> 'left',
292           'link' => $p. 'view/' .
293           $_->[2]. '.cgi?'. $_->[3], },
294         ];
295       }
296     }
297   } #foreach $cust_pkg
298   return @out;
299 };
300
301 </%init>