1 <& elements/search.html,
5 'count_query' => $count_query,
6 'header' => [ emt('#'),
22 FS::UI::Web::cust_header(
23 $cgi->param('cust_fields')
25 #emt('Services'), # even harder
34 sub { sprintf( $money_char.'%.2f',
35 shift->part_pkg->option('setup_fee'),
39 sprintf( $money_char.'%.2f',
40 $c->part_pkg->base_recur($c)
43 sub { FS::part_pkg::freq_pretty(shift); },
45 ( map { time_or_blank($_) }
46 qw( setup last_bill bill susp change_date cancel ) ),
49 \&FS::UI::Web::cust_fields,
53 ('') x 5, # can use as-is
54 ('') x 3, # can't use at all
55 # use the plain SQL column names
56 qw( setup last_bill bill susp change_date cancel ),
58 # cust_fields can take care of themselves
63 FS::UI::Web::cust_colors(),
65 'style' => [ ('') x 15,
67 FS::UI::Web::cust_styles() ],
68 'size' => [ '', '', '', '', '-1' ],
69 'align' => 'rrlcccrrlrrrrrr'.$reason_align. FS::UI::Web::cust_aligns(). 'r',
76 ( map { $_ ne 'Cust. Status' ? $clink : '' }
77 FS::UI::Web::cust_header(
78 $cgi->param('cust_fields')
85 'active' => 'Active packages as of ',
86 'setup' => 'Packages started between ',
87 'cancel' => 'Packages canceled between ',
88 'susp' => 'Packages suspended between ',
89 'unsusp' => 'Packages unsuspended between ',
94 my $curuser = $FS::CurrentUser::CurrentUser;
97 unless $curuser->access_right('List packages');
99 my $conf = new FS::Conf;
100 my $money_char = $conf->config('money_char') || '$';
102 my %search_hash = ();
104 # pass a very limited set of parameters through
106 for (qw( agentnum zip ))
108 $search_hash{$_} = $cgi->param($_) if length($cgi->param($_));
111 #arrays / comma-separated lists
112 for my $param (qw( pkgpart classnum refnum towernum )) {
113 my @values = map { split(',') } $cgi->param($param);
114 $search_hash{$param} = \@values if scalar(@values);
118 # do not pass dates to FS::cust_pkg->search; use the special churn_fromwhere
122 my $pkg_query = FS::cust_pkg->search(\%search_hash);
123 #warn Dumper $pkg_query;
125 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
126 my $status = $cgi->param('status');
128 my $title = emt($title{$status}) .
129 time2str('%b %o %Y', $beginning);
130 if ($status ne 'active') {
131 $title .= emt(' to ') . time2str('%b %o %Y', $ending);
134 my ($from, @where) = FS::h_cust_pkg->churn_fromwhere_sql($status, $beginning, $ending);
136 push @where, "freq != '0'";
138 # split off the primary table name
139 $from =~ s/^(\w+)(.*)$/$2/s;
142 # merge with $pkg_query
143 $from .= ' ' . $pkg_query->{addl_from};
146 if ($pkg_query->{extra_sql}) {
147 $extra_sql = $pkg_query->{extra_sql} . ' AND ';
149 $extra_sql = 'WHERE ';
151 $extra_sql .= join(' AND ', @where);
154 'select' => $pkg_query->{select},
156 'addl_from' => $from,
157 'extra_sql' => $extra_sql,
159 warn (Dumper $sql_query) if $cgi->param('debug');
161 my $count_query = "SELECT COUNT(*) FROM $table $from $extra_sql";
163 my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/
169 my $frag = 'cust_pkg'. $self->pkgnum; #hack for IE ignoring real #fragment
170 [ "${p}view/cust_main.cgi?custnum=".$self->custnum.
171 "$show;fragment=$frag#cust_pkg",
177 my $cust_pkg = shift;
178 $cust_pkg->cust_main_custnum
179 ? [ "${p}view/cust_main.cgi?", 'custnum' ]
187 my $value = $record->get($column); #mmm closures
188 $value ? time2str('%b %d %Y', $value ) : '';
192 my (@reason_header,@reason_fields,@reason_blank);
193 my $reason_align = '';
194 if ($status eq 'cancel') {
195 push @reason_header, emt('Cancel Reason');
196 push @reason_fields, sub {
198 my $cust_pkg_reason = $c->last_cust_pkg_reason('cancel');
199 $cust_pkg_reason ? $cust_pkg_reason->reason->reason : '';
201 push @reason_blank, '';