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