1 <STYLE TYPE="text/css">
14 border: 1px solid black;
20 background-color: #ffffaa;
22 .row0 { background-color: #eeeeee; }
23 .row1 { background-color: #ffffff; }
28 border: 1px solid #7E0079;
29 background-color: #cccccc;
40 background-color: #efefef;
41 border: 1px solid #7e0079;
47 % # activate rolldown buttons for hidden package blocks
48 <SCRIPT TYPE="text/javascript">
49 function toggle_rolldown() {
50 var up_arrow = <% decode_entities('⬆') |js_string %>;
51 var dn_arrow = <% decode_entities('⬇') |js_string %>;
52 var pkgnum = this.id.replace('rolldown_', '');
53 var hidden = document.getElementById('cust_pkg'+pkgnum+'_block');
54 if (hidden.style.display == 'none') {
55 hidden.style.display = '';
56 this.textContent = this.textContent.replace(dn_arrow, up_arrow);
58 hidden.style.display = 'none';
59 this.textContent = this.textContent.replace(up_arrow, dn_arrow);
62 <&| /elements/onload.js &>
64 % if ( $cgi->param('fragment') =~ /^cust_pkg(\d+)$/ ) {
65 % # IE-specific hack, but also unhide the row if it's in a hidden block
66 el = document.getElementById('cust_pkg<% $1 %>');
68 var all_buttons = document.getElementsByClassName('rolldown_button');
69 for (var i = 0; i < all_buttons.length; i++) {
70 all_buttons[i].onclick = toggle_rolldown;
71 var block_id = all_buttons[i].id.replace('rolldown_', '');
72 if ( el && document.getElementById('cust_pkg'+block_id+'_block')
76 all_buttons[i].click();
79 if ( el ) el.scrollIntoView(true);
84 <TD ALIGN="left" VALIGN="top">
86 % if ( $cust_main->num_cancelled_pkgs ) {
87 % if ( $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
88 % || ( $conf->exists('hidecancelledpackages')
89 % && ! $cgi->param('showcancelledpackages')
93 % my $prev = $cgi->param('showcancelledpackages');
94 % $cgi->param('showcancelledpackages', 1);
95 ( <a href="<% $cgi->self_url %>"><% mt('show') |h %>
96 % $cgi->param('showcancelledpackages', $prev);
98 % $cgi->param('showcancelledpackages', 0);
99 ( <a href="<% $cgi->self_url %>"><% mt('hide') |h %>
100 % $cgi->param('showcancelledpackages', 1);
103 <% mt('cancelled packages') |h %></a> )
106 % if ( $cgi->param('showoldpackages') ) {
107 % $cgi->param('showoldpackages', 0);
108 ( <a href="<% $cgi->self_url %>"><% mt('hide old packages') |h %></a> )
109 % $cgi->param('showoldpackages', 1);
111 % $cgi->param('showoldpackages', 1);
112 ( <a href="<% $cgi->self_url %>"><% mt('show old packages') |h %></a> )
113 % $cgi->param('showoldpackages', 0);
120 % my $pager = include('/elements/pager.html',
122 % num_rows => scalar(@packages),
123 % total => $num_pkgs,
124 % maxrecords => $maxrecords,
126 % if ( $num_pkgs > $maxrecords ) {
137 % $opt{cust_main} = $cust_main;
138 % $opt{packages} = \@packages;
139 % $opt{cust_location_cache} = {};
140 % if ( $conf->exists('cust_pkg-group_by_location') ) {
141 <& locations.html, %opt &>
142 % } else { # in this format, put all packages in one section
143 <& /elements/table-grid.html &>
144 <& packages/section.html, %opt &>
151 % if ( $num_pkgs > $maxrecords ) {
162 my $cust_main = shift;
164 my $conf = new FS::Conf;
166 my $curuser = $FS::CurrentUser::CurrentUser;
168 my $countrydefault = scalar($conf->config('countrydefault')) || 'US';
170 my $hide_cancelled = 0;
171 if ( $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
172 || ( $conf->exists('hidecancelledpackages')
173 && ! $cgi->param('showcancelledpackages') )
179 my $cust_pkg_fields =
180 join(', ', map { "cust_pkg.$_ AS $_" } fields('cust_pkg') );
182 my $part_pkg_fields =
183 join(', ', ( map { "part_pkg.$_ AS part_pkg_$_" } fields('part_pkg') ),
184 'setup_option.optionvalue AS part_pkg__setup_fee',
185 'recur_option.optionvalue AS part_pkg__recur_fee',
189 join(', ', map "cust_pkg.$_", fields('cust_pkg') ). ', '.
190 join(', ', map "part_pkg.$_", fields('part_pkg') );
192 my $num_svcs = '( SELECT COUNT(*) FROM cust_svc '.
193 ' WHERE cust_svc.pkgnum = cust_pkg.pkgnum ) AS num_svcs';
196 ' AND main_pkgnum IS NULL '. # supplemental package of something else
197 ' AND change_to_pkgnum IS NULL '. # ordered, not-yet-active change target
198 ' AND change_pkgnum IS NULL '; # canceled package changed into another
200 unless ( $cgi->param('showoldpackages') ) {
201 my $years = $conf->config('cust_main-packages-years') || 2;
202 my $then = time - $years * 31556926; #60*60*24*365.2422 is close enough
204 $extra_sql .= " AND (
205 ( part_pkg.freq = '0' AND ( setup IS NULL OR setup > $then ) )
206 OR ( part_pkg.freq != '0' AND ( cancel IS NULL OR cancel > $then ) )
207 OR EXISTS ( SELECT 1 FROM cust_svc WHERE cust_svc.pkgnum = cust_pkg.pkgnum )
211 my $num_method = $hide_cancelled ? 'ncancelled_pkgs' : 'all_pkgs';
212 my $num_pkgs = $cust_main->$num_method({
213 'addl_from' => 'LEFT JOIN part_pkg USING ( pkgpart )',
214 'extra_sql' => $extra_sql,
218 my $offset = $cgi->param('offset') =~ /^(\d+)$/ ? $1 : 0;
220 my @packages = $cust_main->all_pkgs( {
221 'select' => "$cust_pkg_fields, $part_pkg_fields, $num_svcs",
223 LEFT JOIN part_pkg USING ( pkgpart )
224 LEFT JOIN part_pkg_option AS setup_option
225 ON ( cust_pkg.pkgpart = setup_option.pkgpart
226 AND setup_option.optionname = 'setup_fee' )
227 LEFT JOIN part_pkg_option AS recur_option
228 ON ( cust_pkg.pkgpart = recur_option.pkgpart
229 AND recur_option.optionname = 'recur_fee' )
231 'extra_sql' => $extra_sql,
232 'order_by' => "ORDER BY pkgnum ASC LIMIT $maxrecords OFFSET $offset",
235 foreach my $cust_pkg ( @packages ) {
236 my %hash = $cust_pkg->hash;
237 my %part_pkg = map { /^part_pkg_(.+)$/ or die; ( $1 => $hash{$_} ); }
238 grep { /^part_pkg_/ } keys %hash;
239 $cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
241 #arrayref of supplementals
242 $cust_pkg->set('_supplemental', [
243 qsearch('cust_pkg', { main_pkgnum=>$cust_pkg->pkgnum })
248 qsearchs('cust_pkg', { change_to_pkgnum=>$cust_pkg->pkgnum });
250 $change_to->set('change_from_pkg', $cust_pkg);
251 $cust_pkg->set('change_to_pkg', $change_to);
256 qsearchs('cust_pkg', { change_pkgnum=>$cust_pkg->pkgnum });
257 if ( $changed_from ) {
258 $changed_from->set('changed_to_pkg', $cust_pkg);
259 $cust_pkg->set('changed_from_pkg', $changed_from);
262 $cust_pkg->{'_cust_pkg_discount_active'} =
263 [ $cust_pkg->cust_pkg_discount_active ];