diff options
Diffstat (limited to 'httemplate')
35 files changed, 572 insertions, 138 deletions
diff --git a/httemplate/browse/part_svc.cgi b/httemplate/browse/part_svc.cgi index 88f8d8d19..dee439466 100755 --- a/httemplate/browse/part_svc.cgi +++ b/httemplate/browse/part_svc.cgi @@ -119,9 +119,13 @@ function part_export_areyousure(href) { <% $svcdb %></TD> <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"> - <FONT COLOR="#00CC00"><B><% $num_active_cust_svc{$part_svc->svcpart} %></B></FONT> <% $num_active_cust_svc{$part_svc->svcpart} ? svc_url( 'ahref' => 1, 'm' => $m, 'action' => 'search', 'part_svc' => $part_svc, 'query' => "svcpart=". $part_svc->svcpart ) : '<A NAME="zero">' %>active</A> - -% if ( $num_active_cust_svc{$part_svc->svcpart} ) { +% my $svcurl_active = svc_url( 'ahref' => 1, 'm' => $m, 'action' => 'search', 'part_svc' => $part_svc, 'query' => "svcpart=". $part_svc->svcpart . "&cancelled=0"); +% my $svcurl_cancel = svc_url( 'ahref' => 1, 'm' => $m, 'action' => 'search', 'part_svc' => $part_svc, 'query' => "svcpart=". $part_svc->svcpart . "&cancelled=1"); + <FONT COLOR="#00CC00"><B><% $num_cust_svc_active{$part_svc->svcpart} %></B></FONT> <% $num_cust_svc_active{$part_svc->svcpart} ? $svcurl_active : '' %>active<% $num_cust_svc_active{$part_svc->svcpart} ? '</A>' : '' %> +% if ( $num_cust_svc_cancelled{$part_svc->svcpart} ) { + <BR><FONT COLOR="#FF0000"><B><% $num_cust_svc_cancelled{$part_svc->svcpart} %></B></FONT> <% $svcurl_cancel %>cancelled</A> +% } +% if ( $num_cust_svc{$part_svc->svcpart} ) { <BR><FONT SIZE="-1">[ <A HREF="<%$p%>edit/bulk-cust_svc.html?svcpart=<% $part_svc->svcpart %>">change</A> ]</FONT> % } @@ -245,11 +249,25 @@ my @part_svc = qsearch('part_svc', \%search ); my $total = scalar(@part_svc); -my %num_active_cust_svc = map { $_->svcpart => $_->num_cust_svc } @part_svc; +## The Active/Cancelled distinction is a bit awkward, +## active currently includes unattached and suspended services, +## but we've previously referred to EVERY existing cust_svc as "Active", +## and we don't really want to know numbers by individual package status, +## so for now the UI will distinguish these as "Active" and "Cancelled", +## but please let's not go so far as to introduce the idea of "Service Status" + +my %num_cust_svc_active; +my %num_cust_svc_cancelled; +my %num_cust_svc; +foreach my $part_svc (@part_svc) { + $num_cust_svc{$part_svc->svcpart} = $part_svc->num_cust_svc; + $num_cust_svc_cancelled{$part_svc->svcpart} = $part_svc->num_cust_svc_cancelled; + $num_cust_svc_active{$part_svc->svcpart} = $num_cust_svc{$part_svc->svcpart} - $num_cust_svc_cancelled{$part_svc->svcpart}; +} if ( $cgi->param('orderby') eq 'active' ) { - @part_svc = sort { $num_active_cust_svc{$b->svcpart} <=> - $num_active_cust_svc{$a->svcpart} } @part_svc; + @part_svc = sort { $num_cust_svc{$b->svcpart} <=> + $num_cust_svc{$a->svcpart} } @part_svc; } elsif ( $cgi->param('orderby') eq 'svc' ) { @part_svc = sort { lc($a->svc) cmp lc($b->svc) } @part_svc; } diff --git a/httemplate/browse/tower.html b/httemplate/browse/tower.html index e2f9fd0bd..c8812e57b 100644 --- a/httemplate/browse/tower.html +++ b/httemplate/browse/tower.html @@ -1,22 +1,23 @@ -<% include( 'elements/browse.html', - 'title' => 'Towers', - 'name' => 'towers', - 'menubar' => [ 'Add a new tower' => - $p.'edit/tower.html', - ], - 'query' => { 'table' => 'tower', }, - 'count_query' => 'SELECT COUNT(*) FROM tower', - 'disableable' => 1, - 'disabled_statuspos' => 1, - 'header' => [ 'Name', 'Location', 'Sectors', ], - 'fields' => [ $tower_sub, - $coord_sub, - $sector_sub, - ], - 'links' => [ ], - 'cell_style' => [ $tagdesc_style ], - ) -%> +<& elements/browse.html, + 'title' => 'Towers', + 'name' => 'towers', + 'menubar' => [ 'Add a new tower' => + $p.'edit/tower.html', + 'Download CSV for towercoverage.com' => + $p.'misc/tower-export.html?format=tc' + ], + 'query' => { 'table' => 'tower', }, + 'count_query' => 'SELECT COUNT(*) FROM tower', + 'disableable' => 1, + 'disabled_statuspos' => 1, + 'header' => [ 'Name', 'Location', 'Sectors', ], + 'fields' => [ $tower_sub, + $coord_sub, + $sector_sub, + ], + 'links' => [ ], + 'cell_style' => [ $tagdesc_style ], +&> <%init> die "access denied" diff --git a/httemplate/edit/cust_refund.cgi b/httemplate/edit/cust_refund.cgi index bfcbfe725..32da4543e 100755 --- a/httemplate/edit/cust_refund.cgi +++ b/httemplate/edit/cust_refund.cgi @@ -10,7 +10,7 @@ <% small_custview($custnum, $conf->config('countrydefault')) %> % } -<FORM NAME="RefundForm" ACTION="<% $p1 %>process/cust_refund.cgi" METHOD=POST onSubmit="document.RefundForm.submit.disabled=true"> +<FORM NAME="RefundForm" ACTION="<% $p1 %>process/cust_refund.cgi" METHOD=POST onSubmit="document.RefundForm.submitButton.disabled=true"> <INPUT TYPE="hidden" NAME="popup" VALUE="<% $link %>"> <INPUT TYPE="hidden" NAME="refundnum" VALUE=""> <INPUT TYPE="hidden" NAME="custnum" VALUE="<% $custnum %>"> @@ -116,7 +116,7 @@ </TABLE> <BR> -<INPUT TYPE="submit" ID="confirm_refund_button" VALUE="<% mt('Post refund') |h %>" DISABLED> +<INPUT TYPE="submit" NAME="submitButton" ID="confirm_refund_button" VALUE="<% mt('Post refund') |h %>" DISABLED> </FORM> diff --git a/httemplate/edit/part_referral.html b/httemplate/edit/part_referral.html index e9fd79452..04287d632 100755 --- a/httemplate/edit/part_referral.html +++ b/httemplate/edit/part_referral.html @@ -3,11 +3,13 @@ 'table' => 'part_referral', 'fields' => [ 'referral', { field=>'agentnum', type=>'select-agent', }, + 'title', { field=>'disabled', type=>'checkbox', value=>'Y' } , ], 'labels' => { 'refnum' => 'Ad Source', 'referral' => 'Advertising source', 'agentnum' => 'Agent', + 'title' => 'External ID', 'disabled' => 'Disabled', }, 'viewall_dir' => 'browse', diff --git a/httemplate/edit/tower.html b/httemplate/edit/tower.html index fa3838dcf..4d8ad1e89 100644 --- a/httemplate/edit/tower.html +++ b/httemplate/edit/tower.html @@ -26,9 +26,9 @@ 'default_ip_addr' => 'Tower IP address', 'latitude' => 'Latitude', 'longitude' => 'Longitude', - 'altitude' => 'Altitude', - 'height' => 'Height', - 'veg_height' => 'Vegetation height', + 'altitude' => 'Altitude (feet)', + 'height' => 'Height (feet)', + 'veg_height' => 'Vegetation height (feet)', 'color' => 'Color', }, &> diff --git a/httemplate/elements/tr-cust_svc_cancel.html b/httemplate/elements/tr-cust_svc_cancel.html index 44276ec82..52dedd6c8 100644 --- a/httemplate/elements/tr-cust_svc_cancel.html +++ b/httemplate/elements/tr-cust_svc_cancel.html @@ -18,7 +18,14 @@ for use in view/cust_main. % } </B></TD> </TR> -%# no action links, the service is canceled +%# no action links except unprovision, the service is canceled +% if ( $curuser->access_right('Unprovision customer service') && ! $opt{no_links} ) { +<TR> + <TD COLSPAN="2" ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px; padding-top:0px"> + <FONT SIZE="-2">( <% $svc_unprovision_link %> )</FONT> + </TD> +</TR> +% } <%init> my %opt = @_; @@ -29,4 +36,9 @@ my $part_svc = $opt{'part_svc'} || $cust_svc->part_svc; my $cust_pkg = $opt{'cust_pkg'} || $cust_svc->cust_pkg; my $svc_x = $cust_svc->svc_x; +my $svc_unprovision_link = + qq!<A HREF="javascript:areyousure('${p}misc/unprovision.cgi?! . + $cust_svc->svcnum . + qq!', '!.emt('Permanently unprovision and delete this service?').qq!')">!.emt('Unprovision').'</A>'; + </%init> diff --git a/httemplate/misc/tax-fetch_and_import.cgi b/httemplate/misc/tax-fetch_and_import.cgi index 33a6c9b01..970d47c32 100644 --- a/httemplate/misc/tax-fetch_and_import.cgi +++ b/httemplate/misc/tax-fetch_and_import.cgi @@ -29,8 +29,9 @@ Import a tax data update. <TR> <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> <INPUT TYPE = "submit" + NAME = "submitButton" VALUE = "Download and Import" - onClick = "document.TaxRateImport.submit.disabled=true; process();" + onClick = "document.TaxRateImport.submitButton.disabled=true; process();" > </TD> </TR> diff --git a/httemplate/misc/tax-fetch_and_replace.cgi b/httemplate/misc/tax-fetch_and_replace.cgi index 3290a3c44..ff64e6320 100644 --- a/httemplate/misc/tax-fetch_and_replace.cgi +++ b/httemplate/misc/tax-fetch_and_replace.cgi @@ -29,8 +29,9 @@ Replace tax data. <TR> <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> <INPUT TYPE = "submit" + NAME = "submitButton" VALUE = "Download and Import" - onClick = "document.TaxRateImport.submit.disabled=true; process();" + onClick = "document.TaxRateImport.submitButton.disabled=true; process();" > </TD> </TR> diff --git a/httemplate/misc/tower-export.html b/httemplate/misc/tower-export.html new file mode 100644 index 000000000..9d63640f0 --- /dev/null +++ b/httemplate/misc/tower-export.html @@ -0,0 +1,36 @@ +<%init> +# currently, browse/tower just shows all towers, so do the same here +my @towers = qsearch({ table => 'tower' }); +http_header('Content-Type' => 'text/csv'); +http_header('Content-Disposition' => 'attachment;filename=towers.csv'); +if ( $cgi->param('format') eq 'tc' ) { + # towercoverage.com format: not a true CSV, no quoting (so no way to include + # commas in any field, so we strip them) + + # lat/long are signed decimals, northeast positive + # height is in meters + # Description/Group are not necessary + # sector/antenna information (orientation, beamwidth, gain, frequency, + # etc.) is in what TC calls a "Coverage", which can't be edited this way. + my $text = "SiteName,Latitude,Longitude,Description,Group,Height\n"; + + foreach my $tower (@towers) { + next if ( !$tower->latitude or !$tower->longitude ); + + my $name = $tower->towername; + my $height = ($tower->height || 0) / 3.28; + $name =~ s(,)( )g; + $text .= join(',', + $name, + $tower->latitude, + $tower->longitude, + '', + '', + $height, + ) . "\n"; + } + $m->print($text); +} else { + die('unknown format '.$cgi->param('format')); +} +</%init> diff --git a/httemplate/misc/xmlhttp-ticket-update.html b/httemplate/misc/xmlhttp-ticket-update.html index e81e353c5..01fb1b44d 100644 --- a/httemplate/misc/xmlhttp-ticket-update.html +++ b/httemplate/misc/xmlhttp-ticket-update.html @@ -13,7 +13,13 @@ my $ticket = FS::TicketSystem->get_ticket_object( \%session, ticket_id=>$id ); my $return; if ( $ticket ) { - my($orv, $omsg) = $ticket->SetOwner( $username ); + my $curowner = $ticket->OwnerObj->Name; + my($orv, $omsg); + if (( $curowner eq $FS::CurrentUser::CurrentUser->username ) or ( $curowner eq 'nobody' )) { + ($orv, $omsg) = $ticket->SetOwner( $username ); + } else { + ($orv, $omsg) = $ticket->SetOwner( $username, 'Steal' ); + } $orv = 1 if ! $orv && $omsg =~ /already own/i; if ( $orv ) { @@ -40,15 +46,18 @@ if ( $ticket ) { my %hash = $m->comp('/rt/Ticket/Elements/Customers', Ticket => $ticket); my @cust_main = values( %{$hash{cust_main}} ); + my $timelabel = FS::sched_avail::pretty_time($sh*60+$sm). '-'. + FS::sched_avail::pretty_time($eh*60+$em); + my $titlelabel = encode_entities($cust_main[0]->_FreesideURILabel); + $return = { 'error' => '', #'starts' => $starts, #'due' => $due, #'username' => $username, #false laziness w/CalendarSlotSchedule - 'sched_label' => - FS::sched_avail::pretty_time($sh*60+$sm). '-'. - FS::sched_avail::pretty_time($eh*60+$em). ': '. - encode_entities($cust_main[0]->_FreesideURILabel), + 'sched_label' => $timelabel . ': ' . $titlelabel, + 'sched_label_time' => $timelabel, + 'sched_label_title' => $titlelabel, }; } else { $return = { 'error' => $smsg }; diff --git a/httemplate/search/cust_credit.html b/httemplate/search/cust_credit.html index 2241f02e3..dbf0ff333 100755 --- a/httemplate/search/cust_credit.html +++ b/httemplate/search/cust_credit.html @@ -56,24 +56,29 @@ if ($unapplied) { push @header, emt('Date'), emt('By'), emt('Reason'), + emt('Info'), ; push @fields, sub { time2str('%b %d %Y', shift->_date ) }, 'otaker', - 'reason', + 'reason_only', + 'addlinfo', ; -push @sort_fields, '_date', 'otaker', 'reason'; -$align .= 'rll'; +push @sort_fields, '_date', 'otaker', 'reasonnum', 'addlinfo'; +$align .= 'rlll'; push @links, '', '', '', + '', ; push @color, '', '', '', + '', ; push @style, '', '', '', + '', ; # insert customer email after 'Reason' if this is a commission report diff --git a/httemplate/search/cust_credit_bill_pkg.html b/httemplate/search/cust_credit_bill_pkg.html index b9bbc4dbb..0cdd8defd 100644 --- a/httemplate/search/cust_credit_bill_pkg.html +++ b/httemplate/search/cust_credit_bill_pkg.html @@ -14,6 +14,7 @@ 'Date', 'By', 'Reason', + 'Info', # line item 'Description', @@ -33,7 +34,8 @@ sub { time2str('%b %d %Y', shift->get('cust_credit_date') ) }, sub { shift->cust_credit_bill->cust_credit->otaker }, - sub { shift->cust_credit_bill->cust_credit->reason }, + sub { shift->cust_credit_bill->cust_credit->reason_only }, + sub { shift->cust_credit_bill->cust_credit->addlinfo }, sub { $_[0]->pkgnum > 0 ? $_[0]->get('pkg') # possibly use override.pkg @@ -51,6 +53,7 @@ 'cust_credit_date', '', #'otaker', '', #reason + '', #addlinfo '', #line item description '', #location @post_desc_null, @@ -66,6 +69,7 @@ '', '', '', + '', @post_desc_null, $ilink, $ilink, @@ -73,7 +77,7 @@ FS::UI::Web::cust_header() ), ], - 'align' => 'rrrllll'. + 'align' => 'rrrlllll'. $post_desc_align. 'rr'. FS::UI::Web::cust_aligns(), @@ -85,6 +89,7 @@ '', '', '', + '', @post_desc_null, '', '', @@ -98,6 +103,7 @@ '', '', '', + '', @post_desc_null, '', '', diff --git a/httemplate/search/cust_credit_source_bill_pkg.html b/httemplate/search/cust_credit_source_bill_pkg.html index 3ef88bdf9..1d5f8d2a0 100644 --- a/httemplate/search/cust_credit_source_bill_pkg.html +++ b/httemplate/search/cust_credit_source_bill_pkg.html @@ -28,7 +28,7 @@ sub { time2str('%b %d %Y', shift->get('cust_credit_date') ) }, sub { shift->cust_credit->otaker }, - sub { shift->cust_credit->reason }, + sub { shift->cust_credit->reason }, # split into reason_only/addlinfo if addlinfo ever gets used here sub { $_[0]->pkgnum > 0 ? $_[0]->get('pkg') # possibly use override.pkg diff --git a/httemplate/search/cust_credit_void.html b/httemplate/search/cust_credit_void.html index 18731d144..8a8b4133e 100755 --- a/httemplate/search/cust_credit_void.html +++ b/httemplate/search/cust_credit_void.html @@ -47,6 +47,7 @@ push @header, emt('Void Date'), emt('Date'), emt('By'), emt('Reason'), + emt('Info'), FS::UI::Web::cust_header(), ; push @fields, sub { time2str('%b %d %Y', shift->void_date ) }, @@ -54,7 +55,8 @@ push @fields, sub { time2str('%b %d %Y', shift->void_date ) }, 'void_reason', sub { time2str('%b %d %Y', shift->_date ) }, 'otaker', - 'reason', + 'reason_only', + 'addlinfo', \&FS::UI::Web::cust_fields, ; push @sort_fields, 'void_date', @@ -63,14 +65,16 @@ push @sort_fields, 'void_date', '_date', 'usernum', #ditto 'reasonnum, reason', #ditto + 'addlinfo', FS::UI::Web::cust_sort_fields(); -$align .= 'rllrll'.FS::UI::Web::cust_aligns(); +$align .= 'rllrlll'.FS::UI::Web::cust_aligns(); push @links, '', '', '', '', '', '', + '', ( map { $_ ne 'Cust. Status' ? $clink : '' } FS::UI::Web::cust_header() ), @@ -81,6 +85,7 @@ push @color, '', '', '', '', + '', FS::UI::Web::cust_colors(), ; push @style, '', @@ -89,6 +94,7 @@ push @style, '', '', '', '', + '', FS::UI::Web::cust_styles(), ; diff --git a/httemplate/search/cust_event.html b/httemplate/search/cust_event.html index 757982b95..241a0267a 100644 --- a/httemplate/search/cust_event.html +++ b/httemplate/search/cust_event.html @@ -152,7 +152,12 @@ die "access denied" || $cgi->param('pkgnum') =~ /^(\d+)$/ ); -my $title = $cgi->param('failed') ? 'Failed billing events' : 'Billing events'; +my @statuses = $cgi->multi_param('event_status'); +my $title = 'Billing events'; +if ( $statuses[0] eq 'failed' and !defined($statuses[1]) ) { + # tweak the title if we're showing only failed events + $title = 'Failed billing events'; +} my %search = (); @@ -161,6 +166,7 @@ for my $param (@scalars) { $search{$param} = scalar( $cgi->param($param) ) if $cgi->param($param); } +$search{event_status} = \@statuses; #lists my @lists = qw( eventpart ); diff --git a/httemplate/search/cust_svc.html b/httemplate/search/cust_svc.html index 3b770432e..7000e3048 100644 --- a/httemplate/search/cust_svc.html +++ b/httemplate/search/cust_svc.html @@ -1,50 +1,63 @@ <& elements/search.html, 'title' => emt('Service search results'), - 'name' => emt('services'), - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ emt('#'), - emt('Service'), - # package? - FS::UI::Web::cust_header(), - ], - 'fields' => [ 'svcnum', - sub { - #$_[0]->svc. ': '. $_[0]->label; - my($label, $value, $svcdb) = $_[0]->label; - my $id = $_[0]->agent_svcid - ? $_[0]->agent_svcid.': ' - : ''; - "$label: $id$value"; - }, - # package? - \&FS::UI::Web::cust_fields, - ], - 'links' => [ $link, - $link, - # package? - ( map { $_ ne 'Cust. Status' ? $link_cust : '' } - FS::UI::Web::cust_header() - ), - ], - 'align' => 'rl'. FS::UI::Web::cust_aligns(), - 'color' => [ - '', - '', - FS::UI::Web::cust_colors(), - ], - 'style' => [ - '', - '', - FS::UI::Web::cust_styles(), - ], + 'name' => emt('services'), + 'query' => $sql_query, + 'count_query' => $count_query, + 'redirect' => $link, + 'header' => [ emt('#'), + emt('Service'), + emt('Pkg. Status'), + # package? + FS::UI::Web::cust_header(), + ], + 'fields' => [ 'svcnum', + sub { + #$_[0]->svc. ': '. $_[0]->label; + my($label, $value, $svcdb) = $_[0]->label; + my $id = $_[0]->agent_svcid + ? $_[0]->agent_svcid.': ' + : ''; + "$label: $id$value"; + }, + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, + # package? + \&FS::UI::Web::cust_fields, + ], + 'links' => [ $link, + $link, + '', # pkg status + # package? + ( map { $_ ne 'Cust. Status' ? $link_cust : '' } + FS::UI::Web::cust_header() + ), + ], + 'align' => 'rlr'. FS::UI::Web::cust_aligns(), + 'color' => [ + '', + '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status + FS::UI::Web::cust_colors(), + ], + 'style' => [ + '', + '', + 'b', # pkg status + FS::UI::Web::cust_styles(), + ], &> <%init> die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $sql_query; my $orderby = 'ORDER BY cust_svc.svcnum'; #has to be ordered by something @@ -83,6 +96,13 @@ if ( length( $cgi->param('search_svc') ) ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } else { errorpage("No search term specified"); diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html index 7d7fb73e9..b07f5e9d2 100755 --- a/httemplate/search/elements/cust_pay_or_refund.html +++ b/httemplate/search/elements/cust_pay_or_refund.html @@ -63,7 +63,7 @@ Examples: sub { sprintf($money, $_[0]->$amount_field) }, ], 'total_row' => [ '<B>Total</B>', - sub { warn Dumper @_; sprintf("<B>$money</B>", $_[0]->$amount_field) }, + sub { sprintf("<B>$money</B>", $_[0]->$amount_field) }, ], 'show_combined' => 1, &> diff --git a/httemplate/search/report_cust_event.html b/httemplate/search/report_cust_event.html index 0dd98d479..6453500ad 100644 --- a/httemplate/search/report_cust_event.html +++ b/httemplate/search/report_cust_event.html @@ -5,7 +5,6 @@ %> <FORM ACTION="cust_event.html" METHOD="GET"> - <INPUT TYPE="hidden" NAME="failed" VALUE="<% $cgi->param('failed') ? 1 : 0 %>"> <TABLE BGCOLOR="#cccccc" CELLSPACING=0> <TR> @@ -15,7 +14,8 @@ <% include( '/elements/tr-select-agent.html', 'disable_empty'=>0 ) %> <% include( '/elements/tr-select-cust_main-status.html', - 'label' => 'Status' + 'label' => 'Customer status', + # this field is just called 'status' ) %> @@ -26,6 +26,34 @@ ) %> +% if ( $cgi->param('failed') ) { + <& /elements/tr-fixed.html, + 'label' => 'Event status', + 'field' => 'event_status', + 'curr_value' => 'failed', + 'formatted_value' => 'Failed', + &> +% } else { + +% # 'initial' is not on here, since nobody needs to see it. also, +% # 'done_Y' and 'done_N' are shorthand for "done, and no_action +% # is null" and "done, and no_action = 'Y'". + <& /elements/tr-select.html, + 'label' => 'Event status', + 'field' => 'event_status', + 'multiple' => 1, + 'all_selected' => 1, + 'size' => 5, + 'options' => [ qw( done_Y done_N failed new locked ) ], + 'option_labels' => { done_Y => 'Completed', + done_N => 'Completed, no action taken', + failed => 'Failed', + new => 'Not yet processed', + locked => 'Running', + }, + &> +% } + <% include( '/elements/tr-input-beginning_ending.html' ) %> </TABLE> diff --git a/httemplate/search/report_tax-xls.cgi b/httemplate/search/report_tax-xls.cgi index c914d5adc..30b32e8d8 100755 --- a/httemplate/search/report_tax-xls.cgi +++ b/httemplate/search/report_tax-xls.cgi @@ -13,9 +13,7 @@ my %params = ( beginning => $beginning, ending => $ending, ); -$params{country} = $cgi->param('country'); $params{debug} = $DEBUG; -$params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') }; my $agentname; if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { @@ -24,15 +22,38 @@ if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { $agentname = $agent->agentname; } -# allow anything in here; FS::Report::Tax will treat it as unsafe -if ( length($cgi->param('taxname')) ) { - $params{taxname} = $cgi->param('taxname'); +# credit date behavior: limit by the date of the credit application, or +# the invoice? +if ( $cgi->param('credit_date') eq 'cust_credit_bill' ) { + $params{credit_date} = 'cust_credit_bill'; } else { - die "taxname required"; + $params{credit_date} = 'cust_bill'; +} + +my $all = $cgi->param('all'); +my $report_class; + +if ( $all ) { + $report_class = 'FS::Report::Tax::All'; +} else { + $report_class = 'FS::Report::Tax::ByName'; + $params{country} = $cgi->param('country'); + $params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') }; + + # allow anything in here; FS::Report::Tax will treat it as unsafe + if ( length($cgi->param('taxname')) ) { + $params{taxname} = $cgi->param('taxname'); + } else { + die "taxname required"; + } +} + +if ($DEBUG) { + warn "REPORT: $report_class\nPARAMS:\n".Dumper(\%params)."\n\n"; } # generate the report -my $report = FS::Report::Tax->report_internal(%params); +my $report = $report_class->report(%params); my @rows = $report->table; # array of hashrefs my %pkgclass_name = map { $_->classnum, $_->classname } qsearch('pkg_class'); diff --git a/httemplate/search/report_tax.cgi b/httemplate/search/report_tax.cgi index bbb3bc199..410fe4603 100644 --- a/httemplate/search/report_tax.cgi +++ b/httemplate/search/report_tax.cgi @@ -78,14 +78,6 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } % # cust_bill_pkg.cgi wants a list of specific taxnums (and package class) % # cust_credit_bill_pkg.html wants a geographic scope (and package class) % my $rowlink = ';taxnum=' . $row->{taxnums}; -% # DON'T EVER USE THIS -% # my $rowregion = ';country=' . $cgi->param('country'); -% # foreach my $loc (qw(state county city district)) { -% # if ( $row->{$loc} ) { -% # $rowregion .= ";$loc=" . uri_escape($row->{$loc}); -% # } -% # } -% # and also the package class, if we're limiting package class % if ( $params{breakdown}->{pkgclass} ) { % $rowlink .= ';classnum=' . ($row->{pkgclass} || 0); % # $rowregion .= ';classnum=' . ($row->{pkgclass} || 0); @@ -96,7 +88,26 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } % } <TR CLASS="row<% $rownum % 2 %>"> % # Row label - <TD CLASS="rowhead"><% $row->{label} |h %></TD> +% # Special: If this report is showing all taxes, link the row label to +% # the detailed tax report for that taxname/country. + <TD CLASS="rowhead"> +% if ( $all ) { +% my $newcgi = CGI->new($cgi); +% $newcgi->delete('all'); +% $newcgi->param('country', $row->{country}); +% $newcgi->param('taxname', $row->{taxname}); +% $newcgi->param('breakdown', qw(city district)); + + <A HREF="<% encode_entities( $newcgi->self_url ) %>"> + <% $row->{label} |h %> + </A> + +% } else { # on the per-taxname report, just show the label with no link + + <% $row->{label} |h %> + +% } + </TD> <TD> % # Total sales <A HREF="<% $saleslink . $rowlink %>"> @@ -167,7 +178,8 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } % } # foreach my $row % # at the end of everything </TBODY> -% if ( $report->{out_sales} > 0 ) { +% # the all-taxes report doesn't have "out of region" +% if ( !$all and $report->{out_sales} > 0 ) { <TBODY CLASS="total" STYLE="background-color: #cccccc; line-height: 3"> <TR> <TD CLASS="rowhead"> @@ -175,7 +187,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } </TD> <TD STYLE="text-align: right"> <A HREF="<% $saleslink %>;out=1;taxname=<% encode_entities($params{'taxname'}) %>"> - <% $money_sprintf->( $report->{out_sales } ) %> + <% $money_sprintf->( $report->{out_sales} ) %> </A> </TD> <TD COLSPAN=0></TD> @@ -254,7 +266,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } % $prev_row = $row; % } # foreach my $row % # "out of taxable region" for credits (there is a need for it) -% if ( $report->{out_credit} > 0 ) { +% if ( !$all and $report->{out_credit} > 0 ) { % my $creditlink = "cust_credit_bill_pkg.html?out=1;$dateagentlink"; % if ( $params{'credit_date'} eq 'cust_credit_bill' ) { % $creditlink =~ s/begin/credit_begin/; @@ -268,7 +280,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px } </TD> <TD STYLE="text-align: right"> <A HREF="<% $creditlink %>"> - <% $money_sprintf->( $report->{out_credit } ) %> + <% $money_sprintf->( $report->{out_credit} ) %> </A> </TD> <TD COLSPAN=0></TD> @@ -295,33 +307,48 @@ my %params = ( beginning => $beginning, ending => $ending, ); -$params{country} = $cgi->param('country'); $params{debug} = $DEBUG; -$params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') }; - my $agentname; + +# filter by agentnum if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { my $agent = FS::agent->by_key($1) or die "unknown agentnum $1"; $params{agentnum} = $1; $agentname = $agent->agentname; } -# allow anything in here; FS::Report::Tax will treat it as unsafe -if ( length($cgi->param('taxname')) ) { - $params{taxname} = $cgi->param('taxname'); -} else { - die "taxname required"; -} - +# credit date behavior: limit by the date of the credit application, or +# the invoice? if ( $cgi->param('credit_date') eq 'cust_credit_bill' ) { $params{credit_date} = 'cust_credit_bill'; } else { $params{credit_date} = 'cust_bill'; } -warn "PARAMS:\n".Dumper(\%params)."\n\n" if $DEBUG; +my $all = $cgi->param('all'); +my $report_class; + +if ( $all ) { + # then show the master report, no country, no taxname, no breakdown + $report_class = 'FS::Report::Tax::All'; +} else { + $report_class = 'FS::Report::Tax::ByName'; + $params{country} = $cgi->param('country'); + $params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') }; + + # allow anything in here; FS::Report::Tax will treat it as unsafe + if ( length($cgi->param('taxname')) ) { + $params{taxname} = $cgi->param('taxname'); + } else { + die "taxname required"; + } +} + +if ($DEBUG) { + warn "REPORT: $report_class\nPARAMS:\n".Dumper(\%params)."\n\n"; +} -my $report = FS::Report::Tax->report_internal(%params); +my $report = $report_class->report(%params); my @rows = $report->table; # array of hashrefs my $money_char = $conf->config('money_char') || '$'; diff --git a/httemplate/search/report_tax.html b/httemplate/search/report_tax.html index 8d8d1084c..f920adbac 100755 --- a/httemplate/search/report_tax.html +++ b/httemplate/search/report_tax.html @@ -8,6 +8,20 @@ <& /elements/tr-input-beginning_ending.html &> + <tr> + <td></td> + <td colspan=2 style="font-weight: bold"> + <& /elements/radio.html, + 'field' => 'all', + 'value' => 1, + 'curr_value' => 1, + &> All taxes + <& /elements/radio.html, + 'field' => 'all', + 'value' => 0, + &> A specific tax + </td> + </tr> <& /elements/tr-select.html, 'label' => 'Country', 'field' => 'country', @@ -49,6 +63,21 @@ </FORM> +<script> +$(document).ready(function() { + $('[name=all]').on('change', function(ev) { + // disable country/taxname/breakdown if 'all' = 1 + if (this.checked) { + var disabled = (this.value == 1); + $('[name=country').prop('disabled', disabled); + $('[name=taxname').prop('disabled', disabled); + $('[name=breakdown').prop('disabled', disabled); + } + }); + $('[name=all]').change(); +}); +</script> + <% include('/elements/footer.html') %> <%init> diff --git a/httemplate/search/report_unprovisioned_services.html b/httemplate/search/report_unprovisioned_services.html index fe4d46bf7..54181bb20 100755 --- a/httemplate/search/report_unprovisioned_services.html +++ b/httemplate/search/report_unprovisioned_services.html @@ -13,6 +13,7 @@ 'field' => 'svcpart', 'label' => 'Services', 'multiple' => 1, + 'size' => 20, ) %> diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi index 58764f881..ef89f01c8 100755 --- a/httemplate/search/svc_acct.cgi +++ b/httemplate/search/svc_acct.cgi @@ -59,6 +59,8 @@ my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" unless $curuser->access_right('List services'); +my %cust_pkg_cache; + my $link = [ "${p}view/svc_acct.cgi?", 'svcnum' ]; my $link_cust = sub { my $svc_acct = shift; @@ -130,6 +132,7 @@ for (qw( towernum sectornum )) { my $timepermonth = ''; my $orderby = 'ORDER BY svcnum'; +my $addl_from = ''; if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { $search_hash{'unlinked'} = 1 @@ -281,6 +284,9 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') ) { $orderby = "ORDER BY uid"; #$orderby = "ORDER BY svcnum"; + if ( defined($cgi->param('cancelled')) ) { + $search_hash{'cancelled'} = $cgi->param('cancelled') ? 1 : 0; + } } else { $orderby = "ORDER BY uid"; @@ -347,6 +353,19 @@ foreach my $pkg_field ( @pkg_fields ) { } +push @header, emt('Pkg. Status'); +push @fields, sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status; +}; +push @links, ''; +$align .= 'r'; +push @color, sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; +}; +push @style, 'b'; + push @header, FS::UI::Web::cust_header($cgi->param('cust_fields')); push @fields, \&FS::UI::Web::cust_fields, push @links, map { $_ ne 'Cust. Status' ? $link_cust : '' } @@ -357,6 +376,7 @@ push @style, FS::UI::Web::cust_styles(); $search_hash{'order_by'} = $orderby; $search_hash{'where'} = \@extra_sql; +$search_hash{'addl_from'} = $addl_from; my $sql_query = FS::svc_acct->search(\%search_hash); my $count_query = delete($sql_query->{'count_query'}); diff --git a/httemplate/search/svc_broadband.cgi b/httemplate/search/svc_broadband.cgi index 6bf4f0850..ff2538c93 100755 --- a/httemplate/search/svc_broadband.cgi +++ b/httemplate/search/svc_broadband.cgi @@ -10,6 +10,7 @@ 'Router', @tower_header, 'IP Address', + emt('Pkg. Status'), FS::UI::Web::cust_header($cgi->param('cust_fields')), ], 'fields' => [ 'svcnum', @@ -20,6 +21,10 @@ }, @tower_fields, 'ip_addr', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, @@ -27,11 +32,12 @@ '', #$link_router, (map '', @tower_fields), $link, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header($cgi->param('cust_fields')) ), ], - 'align' => 'rll'.('r' x @tower_fields).'r'. + 'align' => 'rll'.('r' x @tower_fields).'rr'. FS::UI::Web::cust_aligns(), 'color' => [ '', @@ -39,6 +45,10 @@ '', (map '', @tower_fields), '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ @@ -47,6 +57,7 @@ '', (map '', @tower_fields), '', + 'b', FS::UI::Web::cust_styles(), ], @@ -56,6 +67,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my %search_hash; @@ -68,6 +81,9 @@ if ( $cgi->param('magic') eq 'unlinked' ) { foreach (qw(pkgpart routernum towernum sectornum)) { $search_hash{$_} = [ $cgi->param($_) ] if $cgi->param($_); } + if ( defined($cgi->param('cancelled')) ) { + $search_hash{'cancelled'} = $cgi->param('cancelled') ? 1 : 0; + } } if ( $cgi->param('sortby') =~ /^(\w+)$/ ) { diff --git a/httemplate/search/svc_circuit.cgi b/httemplate/search/svc_circuit.cgi index 8f05e0488..2174734ea 100644 --- a/httemplate/search/svc_circuit.cgi +++ b/httemplate/search/svc_circuit.cgi @@ -10,6 +10,7 @@ 'Termination', 'Circuit ID', 'IP Address', + emt('Pkg. Status'), FS::UI::Web::cust_header($cgi->param('cust_fields')), ], 'fields' => [ 'svcnum', @@ -18,6 +19,10 @@ 'termination', 'circuit_id', 'ip_addr', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, @@ -26,15 +31,21 @@ '', $link, $link, + '', # pkg status FS::UI::Web::cust_links($cgi->param('cust_fields')), ], - 'align' => 'rlllll'. FS::UI::Web::cust_aligns(), + 'align' => 'rlllllr'. FS::UI::Web::cust_aligns(), 'color' => [ ('') x 6, + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ ('') x 6, + 'b', FS::UI::Web::cust_styles(), ], @@ -44,6 +55,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my %search_hash; @@ -56,6 +69,9 @@ if ( $cgi->param('magic') eq 'unlinked' ) { foreach (qw(pkgpart routernum towernum sectornum)) { $search_hash{$_} = [ $cgi->param($_) ] if $cgi->param($_); } + if ( defined($cgi->param('cancelled')) ) { + $search_hash{'cancelled'} = $cgi->param('cancelled') ? 1 : 0; + } } my $query = FS::svc_circuit->search(\%search_hash); diff --git a/httemplate/search/svc_dish.cgi b/httemplate/search/svc_dish.cgi index 1f8cbc395..1e7330804 100755 --- a/httemplate/search/svc_dish.cgi +++ b/httemplate/search/svc_dish.cgi @@ -7,31 +7,42 @@ 'header' => [ '#', 'Service', 'Account #', + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', 'svc', 'acctnum', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, $link, $link, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rll'. FS::UI::Web::cust_aligns(), + 'align' => 'rllr'. FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ '', '', '', + 'b', FS::UI::Web::cust_styles(), ], @@ -41,6 +52,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + #my $conf = new FS::Conf; my $orderby = 'ORDER BY svcnum'; @@ -56,6 +69,13 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '. diff --git a/httemplate/search/svc_domain.cgi b/httemplate/search/svc_domain.cgi index 56cfa30c8..c8fca9fdc 100755 --- a/httemplate/search/svc_domain.cgi +++ b/httemplate/search/svc_domain.cgi @@ -7,31 +7,42 @@ 'header' => [ '#', 'Service', 'Domain', + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', 'svc', 'domain', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, $link, $link, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rll'. FS::UI::Web::cust_aligns(), + 'align' => 'rllr'. FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ '', '', '', + 'b', FS::UI::Web::cust_styles(), ], @@ -41,6 +52,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my $orderby = 'ORDER BY svcnum'; @@ -58,6 +71,13 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } else { $cgi->param('domain') =~ /^([\w\-\.]+)$/; $svc_domain{'domain'} = $1; diff --git a/httemplate/search/svc_external.cgi b/httemplate/search/svc_external.cgi index b282939a7..5f9056165 100755 --- a/httemplate/search/svc_external.cgi +++ b/httemplate/search/svc_external.cgi @@ -8,29 +8,39 @@ 'Service', ( FS::Msgcat::_gettext('svc_external-id') || 'External ID' ), ( FS::Msgcat::_gettext('svc_external-title') || 'Title' ), + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', 'svc', 'id', 'title', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, $link, $link, $link, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rlrr'. + 'align' => 'rlrrr'. FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ @@ -38,6 +48,7 @@ '', '', '', + 'b', FS::UI::Web::cust_styles(), ], @@ -47,6 +58,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my %svc_external; @@ -69,6 +82,13 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } elsif ( $cgi->param('title') =~ /^(.*)$/ ) { diff --git a/httemplate/search/svc_fiber.html b/httemplate/search/svc_fiber.html index 0cb735c96..3960a1635 100644 --- a/httemplate/search/svc_fiber.html +++ b/httemplate/search/svc_fiber.html @@ -10,6 +10,7 @@ 'ONT', 'Model', 'Serial', + emt('Pkg. Status'), FS::UI::Web::cust_header($cgi->param('cust_fields')), ], 'fields' => [ 'svcnum', @@ -20,6 +21,10 @@ 'ont_id', 'ont_description', 'ont_serial', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, @@ -28,15 +33,21 @@ $link, $link, $link, + '', # pkg status FS::UI::Web::cust_links($cgi->param('cust_fields')), ], - 'align' => 'rlllll'. FS::UI::Web::cust_aligns(), + 'align' => 'rlllllr'. FS::UI::Web::cust_aligns(), 'color' => [ ('') x 6, + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ ('') x 6, + 'b', FS::UI::Web::cust_styles(), ], @@ -48,6 +59,8 @@ die "access denied" unless 'List services' ]); +my %cust_pkg_cache; + my $conf = new FS::Conf; my %search_hash; @@ -58,6 +71,9 @@ if ( $cgi->param('magic') eq 'unlinked' ) { ont_typenum oltnum shelf olt_port card vlan )) { $search_hash{$_} = $cgi->param($_) if defined($cgi->param($_)); } + if ( defined($cgi->param('cancelled')) ) { + $search_hash{'cancelled'} = $cgi->param('cancelled') ? 1 : 0; + } } my $query = FS::svc_fiber->search(\%search_hash); diff --git a/httemplate/search/svc_forward.cgi b/httemplate/search/svc_forward.cgi index 6a23bb3bb..ca2c28808 100755 --- a/httemplate/search/svc_forward.cgi +++ b/httemplate/search/svc_forward.cgi @@ -8,28 +8,38 @@ 'Service', 'Mail to', 'Forwards to', + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', 'svc', $format_src, $format_dst, + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, $link, $link_src, $link_dst, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rlll'. FS::UI::Web::cust_aligns(), + 'align' => 'rlllr'. FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ @@ -37,6 +47,7 @@ '', '', '', + 'b', FS::UI::Web::cust_styles(), ], @@ -46,6 +57,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my $orderby = 'ORDER BY svcnum'; @@ -62,6 +75,13 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '. diff --git a/httemplate/search/svc_hardware.cgi b/httemplate/search/svc_hardware.cgi index 93fc2c391..78f413e30 100644 --- a/httemplate/search/svc_hardware.cgi +++ b/httemplate/search/svc_hardware.cgi @@ -12,6 +12,7 @@ 'Hardware addr.', 'IP addr.', 'Smartcard', + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', @@ -22,24 +23,36 @@ 'display_hw_addr', 'ip_addr', 'smartcard', + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ ($link_svc) x 8, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ) ], - 'align' => 'rlllllll' . FS::UI::Web::cust_aligns(), + 'align' => 'rlllllllr' . FS::UI::Web::cust_aligns(), 'color' => [ ('') x 8, - FS::UI::Web::cust_colors() ], + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status + FS::UI::Web::cust_colors() ], 'style' => [ $svc_cancel_style, ('') x 7, - FS::UI::Web::cust_styles() ], + 'b', + FS::UI::Web::cust_styles() ], &> <%init> die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) LEFT JOIN part_svc USING ( svcpart ) @@ -93,6 +106,13 @@ if ( $cgi->param('typenum') =~ /^(\d+)$/ ) { if ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "cust_svc.svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } my ($orderby) = $cgi->param('orderby') =~ /^(\w+( ASC| DESC)?)$/i; diff --git a/httemplate/search/svc_phone.cgi b/httemplate/search/svc_phone.cgi index f3a056475..29e745690 100644 --- a/httemplate/search/svc_phone.cgi +++ b/httemplate/search/svc_phone.cgi @@ -9,6 +9,7 @@ 'Country code', 'Phone number', @header, + emt('Pkg. Status'), FS::UI::Web::cust_header($cgi->param('cust_fields')), ], 'fields' => [ 'svcnum', @@ -16,6 +17,10 @@ 'countrycode', 'phonenum', @fields, + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, @@ -23,12 +28,14 @@ $link, $link, ( map '', @header ), + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header($cgi->param('cust_fields')) ), ], 'align' => 'rlrr'. join('', map 'r', @header). + 'r'. FS::UI::Web::cust_aligns(), 'color' => [ '', @@ -36,6 +43,10 @@ '', '', ( map '', @header ), + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ @@ -44,6 +55,7 @@ '', '', ( map '', @header ), + 'b', FS::UI::Web::cust_styles(), ], @@ -53,6 +65,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + my $conf = new FS::Conf; my @select = (); @@ -132,6 +146,9 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { $search_hash{'svcpart'} = [ $1 ]; + if ( defined($cgi->param('cancelled')) ) { + $search_hash{'cancelled'} = $cgi->param('cancelled') ? 1 : 0; + } } else { $cgi->param('phonenum') =~ /^([\d\- ]+)$/; my $phonenum = $1; diff --git a/httemplate/search/svc_www.cgi b/httemplate/search/svc_www.cgi index 7410262e8..4f6611f17 100755 --- a/httemplate/search/svc_www.cgi +++ b/httemplate/search/svc_www.cgi @@ -8,6 +8,7 @@ 'Service', 'Zone', 'User', + emt('Pkg. Status'), FS::UI::Web::cust_header(), ], 'fields' => [ 'svcnum', @@ -20,22 +21,31 @@ ? $svc_acct->email : ''; }, + sub { + $cust_pkg_cache{$_[0]->svcnum} ||= $_[0]->cust_svc->cust_pkg; + $cust_pkg_cache{$_[0]->svcnum}->ucfirst_status + }, \&FS::UI::Web::cust_fields, ], 'links' => [ $link, $link, '', $ulink, + '', # pkg status ( map { $_ ne 'Cust. Status' ? $link_cust : '' } FS::UI::Web::cust_header() ), ], - 'align' => 'rlll'. FS::UI::Web::cust_aligns(), + 'align' => 'rlllr'. FS::UI::Web::cust_aligns(), 'color' => [ '', '', '', '', + sub { + my $c = FS::cust_pkg::statuscolors; + $c->{$cust_pkg_cache{$_[0]->svcnum}->status }; + }, # pkg status FS::UI::Web::cust_colors(), ], 'style' => [ @@ -43,6 +53,7 @@ '', '', '', + 'b', FS::UI::Web::cust_styles(), ], @@ -52,6 +63,8 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('List services'); +my %cust_pkg_cache; + #my $conf = new FS::Conf; my $orderby = 'ORDER BY svcnum'; @@ -68,6 +81,13 @@ if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) { } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { push @extra_sql, "svcpart = $1"; + if (defined($cgi->param('cancelled'))) { + if ($cgi->param('cancelled')) { + push @extra_sql, "cust_pkg.cancel IS NOT NULL"; + } else { + push @extra_sql, "cust_pkg.cancel IS NULL"; + } + } } my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '. diff --git a/httemplate/search/tax_sales.cgi b/httemplate/search/tax_sales.cgi index 4b28c934a..91abd1bd3 100644 --- a/httemplate/search/tax_sales.cgi +++ b/httemplate/search/tax_sales.cgi @@ -113,7 +113,7 @@ while ($countdate < $enddate) { # run a report for each tax name foreach my $taxname (@taxnames) { $params{'taxname'} = $taxname; - my $report = FS::Report::Tax->report_internal(%params); + my $report = FS::Report::Tax::ByName->report(%params); # extract totals from report, kinda awkward my $pkgclass = ''; # this will get more complicated if we breakdown by pkgclass diff --git a/httemplate/view/elements/svc_edit_link.html b/httemplate/view/elements/svc_edit_link.html index 3ff2f58b6..2de5ecf9c 100644 --- a/httemplate/view/elements/svc_edit_link.html +++ b/httemplate/view/elements/svc_edit_link.html @@ -1,18 +1,18 @@ -% if ( $cancel_date ) { -<I><% mt("Canceled [_1]", time2str('%b %o %Y', $cancel_date) ) |h %></I> -% } else { <SCRIPT> function areyousure_delete() { if (confirm(<% mt('Permanently delete this service?') |js_string %>) == true) window.location.href = '<% $cancel_url %>'; } </SCRIPT> +% if ( $cancel_date ) { +| <I><% mt("Canceled [_1]", time2str('%b %o %Y', $cancel_date) ) |h %></I> +% } else { % if ( $curuser->access_right('Provision customer service') ) { | <A HREF="<% $edit_url %>"><% mt("Edit this [_1]", $label) |h %></A> % } -% if ( $curuser->access_right('Unprovision customer service') ) { +% } +% if ( $curuser->access_right('Unprovision customer service') ) { | <A HREF="javascript:areyousure_delete()"><% mt('Unprovision this Service') |h %></A> -% } % } <& /elements/manage_device_link.html, 'svc' => $svc_x, |