summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/part_svc.pm20
-rw-r--r--FS/FS/svc_Common.pm16
-rwxr-xr-xhttemplate/browse/part_svc.cgi30
-rw-r--r--httemplate/elements/tr-cust_svc_cancel.html14
-rw-r--r--httemplate/search/cust_svc.html98
-rwxr-xr-xhttemplate/search/svc_acct.cgi20
-rwxr-xr-xhttemplate/search/svc_broadband.cgi18
-rw-r--r--httemplate/search/svc_circuit.cgi18
-rwxr-xr-xhttemplate/search/svc_dish.cgi22
-rwxr-xr-xhttemplate/search/svc_domain.cgi22
-rwxr-xr-xhttemplate/search/svc_external.cgi22
-rw-r--r--httemplate/search/svc_fiber.html18
-rwxr-xr-xhttemplate/search/svc_forward.cgi22
-rw-r--r--httemplate/search/svc_hardware.cgi26
-rw-r--r--httemplate/search/svc_phone.cgi17
-rwxr-xr-xhttemplate/search/svc_www.cgi22
-rw-r--r--httemplate/view/elements/svc_edit_link.html10
17 files changed, 352 insertions, 63 deletions
diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm
index 612c59013..621a55410 100644
--- a/FS/FS/part_svc.pm
+++ b/FS/FS/part_svc.pm
@@ -590,6 +590,26 @@ sub num_cust_svc {
$sth->fetchrow_arrayref->[0];
}
+=item num_cust_svc_cancelled
+
+Returns the number of associated customer services that are
+attached to cancelled packages.
+
+=cut
+
+sub num_cust_svc_cancelled {
+ my $self = shift;
+ my $sth = dbh->prepare(
+ "SELECT COUNT(*) FROM cust_svc
+ LEFT JOIN cust_pkg USING ( pkgnum )
+ WHERE svcpart = ?
+ AND cust_pkg.cancel IS NOT NULL"
+ ) or die dbh->errstr;
+ $sth->execute($self->svcpart)
+ or die $sth->errstr;
+ $sth->fetchrow_arrayref->[0];
+}
+
=item svc_x
Returns a list of associated FS::svc_* records.
diff --git a/FS/FS/svc_Common.pm b/FS/FS/svc_Common.pm
index 73658f67a..4fd2d0b63 100644
--- a/FS/FS/svc_Common.pm
+++ b/FS/FS/svc_Common.pm
@@ -1385,11 +1385,17 @@ Parameters:
=item order_by
+=item cancelled - if true, only returns svcs attached to cancelled pkgs;
+if defined and false, only returns svcs not attached to cancelled packages
+
=back
=cut
-# svc_broadband::search should eventually use this instead
+### Don't call the 'cancelled' option 'Service Status'
+### There is no such thing
+### See cautionary note in httemplate/browse/part_svc.cgi
+
sub search {
my ($class, $params) = @_;
@@ -1493,6 +1499,14 @@ sub search {
push @where, "exportnum = $1";
}
+ if ( defined($params->{'cancelled'}) ) {
+ if ($params->{'cancelled'}) {
+ push @where, "cust_pkg.cancel IS NOT NULL";
+ } else {
+ push @where, "cust_pkg.cancel IS NULL";
+ }
+ }
+
# # sector and tower
# my @where_sector = $class->tower_sector_sql($params);
# if ( @where_sector ) {
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>&nbsp;<% $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>&nbsp;<% $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>&nbsp;<% $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/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">(&nbsp;<% $svc_unprovision_link %>&nbsp;)</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/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/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/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,