summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rwxr-xr-xhttemplate/browse/part_svc.cgi86
-rw-r--r--httemplate/edit/elements/edit.html18
-rw-r--r--httemplate/edit/elements/svc_Common.html16
-rwxr-xr-xhttemplate/edit/part_svc.cgi176
-rw-r--r--httemplate/edit/process/elements/process.html5
-rw-r--r--httemplate/edit/process/svc_Common.html13
-rw-r--r--httemplate/edit/svc_Common.html30
-rwxr-xr-xhttemplate/edit/svc_acct.cgi46
-rw-r--r--httemplate/edit/svc_broadband.cgi4
-rwxr-xr-xhttemplate/edit/svc_domain.cgi56
-rw-r--r--httemplate/edit/svc_external.cgi54
-rwxr-xr-xhttemplate/edit/svc_forward.cgi49
-rw-r--r--httemplate/edit/svc_www.cgi55
-rw-r--r--httemplate/elements/header.html8
-rw-r--r--httemplate/elements/menu.html85
-rwxr-xr-xhttemplate/misc/link.cgi15
-rwxr-xr-xhttemplate/search/cust_main.cgi10
-rw-r--r--httemplate/search/cust_svc.html110
-rwxr-xr-xhttemplate/search/svc_acct.cgi33
-rwxr-xr-xhttemplate/search/svc_broadband.cgi45
-rwxr-xr-xhttemplate/search/svc_domain.cgi28
-rwxr-xr-xhttemplate/search/svc_external.cgi101
-rwxr-xr-xhttemplate/search/svc_forward.cgi26
-rw-r--r--httemplate/search/svc_phone.cgi20
-rwxr-xr-xhttemplate/search/svc_www.cgi39
-rwxr-xr-xhttemplate/view/cust_main/packages.html367
-rw-r--r--httemplate/view/elements/svc_Common.html18
27 files changed, 787 insertions, 726 deletions
diff --git a/httemplate/browse/part_svc.cgi b/httemplate/browse/part_svc.cgi
index 795393574..6198a1aec 100755
--- a/httemplate/browse/part_svc.cgi
+++ b/httemplate/browse/part_svc.cgi
@@ -72,21 +72,33 @@ function part_export_areyousure(href) {
%>
% $cgi->param('showdisabled', ( 1 ^ $cgi->param('showdisabled') ) );
-<% table() %>
+<% include('/elements/table-grid.html') %>
+% my $bgcolor1 = '#eeeeee';
+% my $bgcolor2 = '#ffffff';
+% my $bgcolor = '';
+
<TR>
- <TH><A HREF="<% do { $cgi->param('orderby', 'svcpart'); $cgi->self_url } %>">#</A></TH>
-% if ( $cgi->param('showdisabled') ) {
- <TH>Status</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'svcpart'); $cgi->self_url } %>">#</A></TH>
+
+% if ( $cgi->param('showdisabled') ) {
+ <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
% }
- <TH><A HREF="<% do { $cgi->param('orderby', 'svc'); $cgi->self_url; } %>">Service</A></TH>
- <TH>Table</TH>
- <TH><A HREF="<% do { $cgi->param('orderby', 'active'); $cgi->self_url; } %>"><FONT SIZE=-1>Customer<BR>Services</FONT></A></TH>
- <TH>Export</TH>
- <TH>Field</TH>
- <TH COLSPAN=2>Modifier</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'svc'); $cgi->self_url; } %>">Service</A></TH>
+
+ <TH CLASS="grid" BGCOLOR="#cccccc">Table</TH>
+
+ <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'active'); $cgi->self_url; } %>"><FONT SIZE=-1>Customer<BR>Services</FONT></A></TH>
+
+ <TH CLASS="grid" BGCOLOR="#cccccc">Export</TH>
+
+ <TH CLASS="grid" BGCOLOR="#cccccc">Field</TH>
+
+ <TH COLSPAN=2 CLASS="grid" BGCOLOR="#cccccc">Modifier</TH>
+
</TR>
+
% foreach my $part_svc ( @part_svc ) {
% my $svcdb = $part_svc->svcdb;
% my $svc_x = "FS::$svcdb"->new( { svcpart => $part_svc->svcpart } );
@@ -99,14 +111,21 @@ function part_export_areyousure(href) {
% my $rowspan = scalar(@fields) || 1;
% my $url = "${p}edit/part_svc.cgi?". $part_svc->svcpart;
%
+% if ( $bgcolor eq $bgcolor1 ) {
+% $bgcolor = $bgcolor2;
+% } else {
+% $bgcolor = $bgcolor1;
+% }
<TR>
- <TD ROWSPAN=<% $rowspan %>><A HREF="<% $url %>">
- <% $part_svc->svcpart %></A></TD>
-% if ( $cgi->param('showdisabled') ) {
- <TD ROWSPAN=<% $rowspan %>>
+ <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>">
+ <A HREF="<% $url %>"><% $part_svc->svcpart %></A>
+ </TD>
+
+% if ( $cgi->param('showdisabled') ) {
+ <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>">
<% $part_svc->disabled
? '<FONT COLOR="#FF0000"><B>Disabled</B></FONT>'
: '<FONT COLOR="#00CC00"><B>Enabled</B></FONT>'
@@ -114,19 +133,23 @@ function part_export_areyousure(href) {
</TD>
% }
- <TD ROWSPAN=<% $rowspan %>><A HREF="<% $url %>">
+ <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<% $url %>">
<% $part_svc->svc %></A></TD>
- <TD ROWSPAN=<% $rowspan %>>
+
+ <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>">
<% $svcdb %></TD>
- <TD ROWSPAN=<% $rowspan %>>
- <FONT COLOR="#00CC00"><B><% $num_active_cust_svc{$part_svc->svcpart} %></B></FONT>&nbsp;<A HREF="<%$p%>search/<% $svcdb %>.cgi?svcpart=<% $part_svc->svcpart %>">active</A>
-% if ( $num_active_cust_svc{$part_svc->svcpart} ) {
+ <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} ? FS::UI::Web::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} ) {
<BR><FONT SIZE="-1">[ <A HREF="<%$p%>edit/bulk-cust_svc.html?svcpart=<% $part_svc->svcpart %>">change</A> ]</FONT>
% }
</TD>
- <TD ROWSPAN=<% $rowspan %>><% itable() %>
+
+ <TD ROWSPAN=<% $rowspan %> CLASS="inv" BGCOLOR="<% $bgcolor %>">
+ <TABLE CLASS="inv">
%
%# my @part_export =
%map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export_svc', { svcpart => $part_svc->svcpart } ) ;
@@ -136,21 +159,30 @@ function part_export_areyousure(href) {
% ) {
%
- <TR>
- <TD><A HREF="<% $p %>edit/part_export.cgi?<% $part_export->exportnum %>"><% $part_export->exportnum %>:&nbsp;<% $part_export->exporttype %>&nbsp;to&nbsp;<% $part_export->machine %></A></TD></TR>
+ <TR>
+ <TD><A HREF="<% $p %>edit/part_export.cgi?<% $part_export->exportnum %>"><% $part_export->exportnum %>:&nbsp;<% $part_export->exporttype %>&nbsp;to&nbsp;<% $part_export->machine %></A></TD>
+ </TR>
% }
- </TABLE></TD>
-% my($n1)='';
+ </TABLE>
+ </TD>
+
+% unless ( @fields ) {
+% for ( 1..3 ) {
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"</TD>
+% }
+% }
+%
+% my($n1)='';
% foreach my $field ( @fields ) {
% my $flag = $part_svc->part_svc_column($field)->columnflag;
%
<% $n1 %>
- <TD><% $field %></TD>
- <TD><% $flag{$flag} %></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $field %></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $flag{$flag} %></TD>
- <TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
% my $value = $part_svc->part_svc_column($field)->columnvalue;
% if ( $flag =~ /^[MA]$/ ) {
% $inventory_class{$value}
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index c2ea22f27..17c5ad3eb 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -53,6 +53,9 @@
% # # ...
% # "html_string";
% # },
+% #
+% # # overrides default popurl(1)."process/$table.html"
+% # 'post_url' => popurl(1).'process/something',
%
% my(%opt) = @_;
%
@@ -77,9 +80,14 @@
%
% } elsif ( $cgi->keywords || $cgi->param($pkey) ) { #editing
%
-% my( $query ) = $cgi->keywords;
-% $query = $cgi->param($pkey) unless $query;
-% $query =~ /^(\d+)$/;
+% my $value;
+% if ( $cgi->param($pkey) ) {
+% $value = $cgi->param($pkey)
+% } else {
+% my( $query ) = $cgi->keywords;
+% $value = $query;
+% }
+% $value =~ /^(\d+)$/ or die "unparsable $pkey";
% $object = qsearchs( $table, { $pkey => $1 } );
% warn "$table $pkey => $1"
% if $opt{'debug'};
@@ -129,8 +137,10 @@
<BR><BR>
% }
+% my $url = $opt{'post_url'} || popurl(1)."process/$table.html";
-<FORM ACTION="<% popurl(1) %>process/<% $table %>.html" METHOD=POST>
+<FORM ACTION="<% $url %>" METHOD=POST>
+<INPUT TYPE="hidden" NAME="svcdb" VALUE="<% $table %>">
<INPUT TYPE="hidden" NAME="<% $pkey %>" VALUE="<% $object->$pkey() %>">
<% ( $opt{labels} && exists $opt{labels}->{$pkey} )
? $opt{labels}->{$pkey}
diff --git a/httemplate/edit/elements/svc_Common.html b/httemplate/edit/elements/svc_Common.html
index da59cc9ed..1fd66c251 100644
--- a/httemplate/edit/elements/svc_Common.html
+++ b/httemplate/edit/elements/svc_Common.html
@@ -1,19 +1,21 @@
%
-%
% my %opt = @_;
%
% #my( $svcnum, $pkgnum, $svcpart, $part_svc );
% my( $pkgnum, $svcpart, $part_svc );
%
% #get & untaint pkgnum & svcpart
-% my($query) = $cgi->keywords; #they're not proper cgi params
-% if ( $query =~ /^pkgnum(\d+)-svcpart(\d+)$/ ) {
-% $pkgnum = $1;
-% $svcpart = $2;
-% $cgi->delete_all(); #so the standard edit.html treats this correctly as new
+% if ( ! $cgi->param('error')
+% && $cgi->param('pkgnum') && $cgi->param('svcpart')
+% )
+% {
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
+% $cgi->delete_all(); #so edit.html treats this correctly as new??
% }
%
-%
<% include( 'edit.html',
'menubar' => [],
diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi
index cc9145f45..ba152db9c 100755
--- a/httemplate/edit/part_svc.cgi
+++ b/httemplate/edit/part_svc.cgi
@@ -55,159 +55,37 @@ For the selected table, you can give fields default or fixed (unchangable)
values, or select an inventory class to manually or automatically fill in
that field.
<BR><BR>
-%
-%
-%#these might belong somewhere else for other user interfaces
-%#pry need to eventually create stuff that's shared amount UIs
-%my $conf = new FS::Conf;
-%my %defs = (
-%
-% 'svc_acct' => {
-% 'dir' => 'Home directory',
-% 'uid' => 'UID (set to fixed and blank for no UIDs)',
-% 'slipip' => 'IP address',
-%# 'popnum' => qq!<A HREF="$p/browse/svc_acct_pop.cgi/">POP number</A>!,
-% 'popnum' => {
-% desc => 'Access number',
-% type => 'select',
-% select_table => 'svc_acct_pop',
-% select_key => 'popnum',
-% select_label => 'city',
-% disable_select => 1,
-% },
-% 'username' => {
-% desc => 'Username',
-% type => 'text',
-% disable_default => 1,
-% disable_fixed => 1,
-% disable_select => 1,
-% },
-% 'quota' => {
-% desc => '',
-% type => 'text',
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% '_password' => 'Password',
-% 'gid' => 'GID (when blank, defaults to UID)',
-% 'shell' => {
-% #desc =>'Shell (all service definitions should have a default or fixed shell that is present in the <b>shells</b> configuration file, set to blank for no shell tracking)',
-% desc =>'Shell ( set to blank for no shell tracking)',
-% type =>'select',
-% select_list => [ $conf->config('shells') ],
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% 'finger' => 'Real name (GECOS)',
-% 'domsvc' => {
-% desc =>'svcnum from svc_domain',
-% type =>'select',
-% select_table => 'svc_domain',
-% select_key => 'svcnum',
-% select_label => 'domain',
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% 'usergroup' => {
-% desc =>'RADIUS groups',
-% type =>'radius_usergroup_selector',
-% disable_select => 1,
-% disable_inventory => 1,
-% },
-% 'seconds' => { desc => '',
-% type => 'text',
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% },
-%
-% 'svc_domain' => {
-% 'domain' => 'Domain',
-% },
-%
-% 'svc_forward' => {
-% 'srcsvc' => 'service from which mail is to be forwarded',
-% 'dstsvc' => 'service to which mail is to be forwarded',
-% 'dst' => 'someone@another.domain.com to use when dstsvc is 0',
-% },
-%
-%# 'svc_charge' => {
-%# 'amount' => 'amount',
-%# },
-%# 'svc_wo' => {
-%# 'worker' => 'Worker',
-%# '_date' => 'Date',
-%# },
-%
-% 'svc_www' => {
-% #'recnum' => '',
-% #'usersvc' => '',
-% },
-%
-% 'svc_broadband' => {
-% 'speed_down' => 'Maximum download speed for this service in Kbps. 0 denotes unlimited.',
-% 'speed_up' => 'Maximum upload speed for this service in Kbps. 0 denotes unlimited.',
-% 'ip_addr' => 'IP address. Leave blank for automatic assignment.',
-% 'blocknum' => 'Address block.',
-% },
-%
-% 'svc_phone' => {
-% 'countrycode' => { desc => 'Country code',
-% type => 'text',
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% 'phonenum' => 'Phone number',
-% 'pin' => { desc => 'Personal Identification Number',
-% type => 'text',
-% disable_inventory => 1,
-% disable_select => 1,
-% },
-% },
-%
-% 'svc_external' => {
-% #'id' => '',
-% #'title' => '',
-% },
-%
-%);
-%
-% my %vfields;
-% foreach my $svcdb (grep dbdef->table($_), keys %defs ) {
-% my $self = "FS::$svcdb"->new;
-% $vfields{$svcdb} = {};
-% foreach my $field ($self->virtual_fields) { # svc_Common::virtual_fields with a null svcpart returns all of them
-% my $pvf = $self->pvf($field);
-% my @list = $pvf->list;
-% if (scalar @list) {
-% $defs{$svcdb}->{$field} = { desc => $pvf->label,
-% type => 'select',
-% select_list => \@list };
-% } else {
-% $defs{$svcdb}->{$field} = $pvf->label;
-% } #endif
-% $vfields{$svcdb}->{$field} = $pvf;
-% warn "\$vfields{$svcdb}->{$field} = $pvf";
-% } #next $field
-% } #next $svcdb
+
+% #YUCK. false laziness w/part_svc.pm. go away virtual fields, please
+% my %vfields;
+% foreach my $svcdb ( FS::part_svc->svc_tables() ) {
+% eval "use FS::$svcdb;";
+% my $self = "FS::$svcdb"->new;
+% $vfields{$svcdb} = {};
+% foreach my $field ($self->virtual_fields) { # svc_Common::virtual_fields with a null svcpart returns all of them
+% my $pvf = $self->pvf($field);
+% $vfields{$svcdb}->{$field} = $pvf;
+% #warn "\$vfields{$svcdb}->{$field} = $pvf";
+% } #next $field
+% } #next $svcdb
%
% #code duplication w/ edit/part_svc.cgi, should move this hash to part_svc.pm
% # and generalize the subs
% # condition sub is tested to see whether to disable display of this choice
% # params: ( $def, $layer, $field ) (see SUB below)
% my $inv_sub = sub {
-% ref($_[0]) && ( $_[0]->{disable_inventory}
-% || $_[0]->{'type'} ne 'text' )
-% };
+% $_[0]->{disable_inventory}
+% || $_[0]->{'type'} ne 'text'
+% };
% tie my %flag, 'Tie::IxHash',
% '' => { 'desc' => 'No default', },
% 'D' => { 'desc' => 'Default',
% 'condition' =>
-% sub { ref($_[0]) && $_[0]->{disable_default} },
+% sub { $_[0]->{disable_default} },
% },
% 'F' => { 'desc' => 'Fixed (unchangeable)',
% 'condition' =>
-% sub { ref($_[0]) && $_[0]->{disable_fixed} },
+% sub { $_[0]->{disable_fixed} },
% },
% 'S' => { 'desc' => 'Selectable Choice',
% 'condition' =>
@@ -229,7 +107,7 @@ that field.
%
% my @dbs = $hashref->{svcdb}
% ? ( $hashref->{svcdb} )
-% : qw( svc_acct svc_domain svc_forward svc_www svc_broadband svc_phone svc_external );
+% : FS::part_svc->svc_tables();
%
% tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } grep dbdef->table($_), @dbs;
% my $widget = new HTML::Widgets::SelectLayers(
@@ -291,8 +169,9 @@ that field.
% my $part_svc_column = $part_svc->part_svc_column($field);
% my $value = $part_svc_column->columnvalue;
% my $flag = $part_svc_column->columnflag;
-% my $def = $defs{$layer}{$field};
-% my $desc = ref($def) ? $def->{desc} : $def;
+% #my $def = $defs{$layer}{$field};
+% my $def = FS::part_svc->svc_table_fields($layer)->{$field};
+% my $label = $def->{'def_label'} || $def->{'label'};
%
% if ( $bgcolor eq $bgcolor1 ) {
% $bgcolor = $bgcolor2;
@@ -301,14 +180,13 @@ that field.
% }
%
% $html .= qq!<TR><TD CLASS="grid" BGCOLOR="$bgcolor" ALIGN="right">!.
-% $field;
-% $html .= "- <FONT SIZE=-1>$desc</FONT>" if $desc;
-% $html .= "</TD>";
-% $flag = '' if ref($def) && $def->{type} eq 'disabled';
+% ( $label || $field ).
+% "</TD>";
+% $flag = '' if $def->{type} eq 'disabled';
%
% $html .= qq!<TD CLASS="grid" BGCOLOR="$bgcolor">!;
%
-% if ( ref($def) && $def->{type} eq 'disabled' ) {
+% if ( $def->{type} eq 'disabled' ) {
%
% $html .= 'No default';
%
@@ -372,7 +250,7 @@ that field.
% my $disabled = $flag ? ''
% : 'DISABLED STYLE="background-color: #dddddd"';
%
-% if ( ! ref($def) || $def->{type} eq 'text' ) {
+% if ( !$def->{type} || $def->{type} eq 'text' ) {
%
% my $nodisplay = ' STYLE="display:none"';
% my $is_inv = ( $flag =~ /^[MA]$/ );
diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html
index 96d568754..4b1d2c840 100644
--- a/httemplate/edit/process/elements/process.html
+++ b/httemplate/edit/process/elements/process.html
@@ -19,6 +19,8 @@
% # OR
% # 'redirect' => 'view/table.cgi?', # value of primary key is appended
% #
+% # 'error_redirect' => popurl(2).'edit/table.cgi?', #query string appended
+% #
% # 'edit_ext' => 'html', #defaults to 'html', you might want 'cgi' while the
% # #naming is still inconsistent
% #
@@ -78,7 +80,8 @@
% if ( $error ) {
% $cgi->param('error', $error);
% my $edit_ext = $opt{'edit_ext'} || 'html';
-% print $cgi->redirect(popurl(2). "$table.$edit_ext?". $cgi->query_string );
+% my $url = $opt{'error_redirect'} || popurl(2)."$table.$edit_ext?";
+% print $cgi->redirect($url. $cgi->query_string );
% } elsif ( $opt{'redirect'} ) {
% print $cgi->redirect( $opt{'redirect'}. $pkeyvalue );
% } else {
diff --git a/httemplate/edit/process/svc_Common.html b/httemplate/edit/process/svc_Common.html
new file mode 100644
index 000000000..f5c869a12
--- /dev/null
+++ b/httemplate/edit/process/svc_Common.html
@@ -0,0 +1,13 @@
+<%init>
+
+$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparsable svcdb";
+my $table = $1;
+require "FS/$table.pm";
+
+</%init>
+<% include( 'elements/svc_Common.html',
+ 'table' => $table,
+ 'redirect' => popurl(3)."view/svc_Common.html?svcdb=$table;svcnum=",
+ 'error_redirect' => popurl(3)."edit/svc_Common.html?svcdb=$table;",
+ )
+%>
diff --git a/httemplate/edit/svc_Common.html b/httemplate/edit/svc_Common.html
new file mode 100644
index 000000000..6393f9ebc
--- /dev/null
+++ b/httemplate/edit/svc_Common.html
@@ -0,0 +1,30 @@
+<%init>
+
+# false laziness w/view/svc_Common.html
+
+$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparsable svcdb";
+my $table = $1;
+require "FS/$table.pm";
+
+my %opt;
+if ( UNIVERSAL::can("FS::$table", 'table_info') ) {
+ $opt{'name'} = "FS::$table"->table_info->{'name'};
+
+ my $fields = "FS::$table"->table_info->{'fields'};
+ my %labels = map { $_ => ( ref($fields->{$_})
+ ? $fields->{$_}{'label'}
+ : $fields->{$_}
+ );
+ }
+ keys %$fields;
+ $opt{'labels'} = \%labels;
+
+}
+
+</%init>
+<% include('elements/svc_Common.html',
+ 'table' => $table,
+ 'post_url' => popurl(1). "process/svc_Common.html",
+ %opt,
+ )
+%>
diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi
index f552967e7..f42c14618 100755
--- a/httemplate/edit/svc_acct.cgi
+++ b/httemplate/edit/svc_acct.cgi
@@ -18,39 +18,39 @@
% die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
% @groups = $cgi->param('radius_usergroup');
%
-%} else {
+%} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
%
-% my($query) = $cgi->keywords;
-% if ( $query =~ /^(\d+)$/ ) { #editing
-% $svcnum=$1;
-% $svc_acct=qsearchs('svc_acct',{'svcnum'=>$svcnum})
-% or die "Unknown (svc_acct) svcnum!";
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
%
-% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-% or die "Unknown (cust_svc) svcnum!";
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% $pkgnum=$cust_svc->pkgnum;
-% $svcpart=$cust_svc->svcpart;
+% $svc_acct = new FS::svc_acct({svcpart => $svcpart});
%
-% $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
-% die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
+% $svcnum='';
%
-% @groups = $svc_acct->radius_groups;
+%} else { #editing
%
-% } else { #adding
+% my($query) = $cgi->keywords;
+% $query =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum=$1;
+% $svc_acct=qsearchs('svc_acct',{'svcnum'=>$svcnum})
+% or die "Unknown (svc_acct) svcnum!";
%
-% foreach $_ (split(/-/,$query)) {
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-% }
-% $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
-% die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
+% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+% or die "Unknown (cust_svc) svcnum!";
%
-% $svc_acct = new FS::svc_acct({svcpart => $svcpart});
+% $pkgnum=$cust_svc->pkgnum;
+% $svcpart=$cust_svc->svcpart;
%
-% $svcnum='';
+% $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
+% die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
+%
+% @groups = $svc_acct->radius_groups;
%
-% }
%}
%
%my( $cust_pkg, $cust_main ) = ( '', '' );
diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi
index 6b9535508..30eb6319f 100644
--- a/httemplate/edit/svc_broadband.cgi
+++ b/httemplate/edit/svc_broadband.cgi
@@ -1,10 +1,6 @@
-<!-- mason kludge -->
-%
-%
%# If it's stupid but it works, it's still stupid.
%# -Kristian
%
-%
%use HTML::Widgets::SelectLayers;
%use Tie::IxHash;
%
diff --git a/httemplate/edit/svc_domain.cgi b/httemplate/edit/svc_domain.cgi
index 19e0e1285..5ec074bda 100755
--- a/httemplate/edit/svc_domain.cgi
+++ b/httemplate/edit/svc_domain.cgi
@@ -1,8 +1,7 @@
-%
-%
%my($svcnum, $pkgnum, $svcpart, $kludge_action, $purpose, $part_svc,
% $svc_domain);
%if ( $cgi->param('error') ) {
+%
% $svc_domain = new FS::svc_domain ( {
% map { $_, scalar($cgi->param($_)) } fields('svc_domain')
% } );
@@ -13,40 +12,41 @@
% $purpose = $cgi->param('purpose');
% $part_svc = qsearchs('part_svc', { 'svcpart' => $svcpart } );
% die "No part_svc entry!" unless $part_svc;
-%} else {
-% $kludge_action = '';
-% $purpose = '';
-% my($query) = $cgi->keywords;
-% if ( $query =~ /^(\d+)$/ ) { #editing
-% $svcnum=$1;
-% $svc_domain=qsearchs('svc_domain',{'svcnum'=>$svcnum})
-% or die "Unknown (svc_domain) svcnum!";
%
-% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-% or die "Unknown (cust_svc) svcnum!";
+%} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
+%
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
%
-% $pkgnum=$cust_svc->pkgnum;
-% $svcpart=$cust_svc->svcpart;
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $svc_domain = new FS::svc_domain({});
%
-% } else { #adding
+% $svcnum='';
%
-% $svc_domain = new FS::svc_domain({});
-%
-% foreach $_ (split(/-/,$query)) {
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-% }
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $svc_domain->set_default_and_fixed;
%
-% $svcnum='';
+%} else { #editing
%
-% $svc_domain->set_default_and_fixed;
+% $kludge_action = '';
+% $purpose = '';
+% my($query) = $cgi->keywords;
+% $query =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum=$1;
+% $svc_domain=qsearchs('svc_domain',{'svcnum'=>$svcnum})
+% or die "Unknown (svc_domain) svcnum!";
%
-% }
+% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+% or die "Unknown (cust_svc) svcnum!";
+%
+% $pkgnum=$cust_svc->pkgnum;
+% $svcpart=$cust_svc->svcpart;
+%
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
%}
%my $action = $svcnum ? 'Edit' : 'Add';
diff --git a/httemplate/edit/svc_external.cgi b/httemplate/edit/svc_external.cgi
index 1230340ac..393e71c38 100644
--- a/httemplate/edit/svc_external.cgi
+++ b/httemplate/edit/svc_external.cgi
@@ -1,8 +1,6 @@
-<!-- mason kludge -->
-%
-%
%my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_external );
%if ( $cgi->param('error') ) {
+%
% $svc_external = new FS::svc_external ( {
% map { $_, scalar($cgi->param($_)) } fields('svc_external')
% } );
@@ -11,38 +9,40 @@
% $svcpart = $cgi->param('svcpart');
% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
% die "No part_svc entry!" unless $part_svc;
-%} else {
-% my($query) = $cgi->keywords;
-% if ( $query =~ /^(\d+)$/ ) { #editing
-% $svcnum=$1;
-% $svc_external=qsearchs('svc_external',{'svcnum'=>$svcnum})
-% or die "Unknown (svc_external) svcnum!";
%
-% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-% or die "Unknown (cust_svc) svcnum!";
+%} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
%
-% $pkgnum=$cust_svc->pkgnum;
-% $svcpart=$cust_svc->svcpart;
-%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
%
-% } else { #adding
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-% }
-% $svc_external = new FS::svc_external { svcpart => $svcpart };
+% $svc_external = new FS::svc_external { svcpart => $svcpart };
%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $svcnum='';
%
-% $svcnum='';
+% $svc_external->set_default_and_fixed;
%
-% $svc_external->set_default_and_fixed;
+%} else { #adding
+%
+% my($query) = $cgi->keywords;
+% $query =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum=$1;
+% $svc_external=qsearchs('svc_external',{'svcnum'=>$svcnum})
+% or die "Unknown (svc_external) svcnum!";
+%
+% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+% or die "Unknown (cust_svc) svcnum!";
+%
+% $pkgnum=$cust_svc->pkgnum;
+% $svcpart=$cust_svc->svcpart;
+%
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% }
%}
%my $action = $svc_external->svcnum ? 'Edit' : 'Add';
%
diff --git a/httemplate/edit/svc_forward.cgi b/httemplate/edit/svc_forward.cgi
index 73b32dc7b..ef08ffc16 100755
--- a/httemplate/edit/svc_forward.cgi
+++ b/httemplate/edit/svc_forward.cgi
@@ -13,39 +13,40 @@
% $svcpart = $cgi->param('svcpart');
% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
% die "No part_svc entry!" unless $part_svc;
-%} else {
%
-% my($query) = $cgi->keywords;
+%} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
+%
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
%
-% if ( $query =~ /^(\d+)$/ ) { #editing
-% $svcnum=$1;
-% $svc_forward=qsearchs('svc_forward',{'svcnum'=>$svcnum})
-% or die "Unknown (svc_forward) svcnum!";
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-% or die "Unknown (cust_svc) svcnum!";
+% $svc_forward = new FS::svc_forward({});
%
-% $pkgnum=$cust_svc->pkgnum;
-% $svcpart=$cust_svc->svcpart;
-%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $svcnum='';
%
-% } else { #adding
+% $svc_forward->set_default_and_fixed;
%
-% $svc_forward = new FS::svc_forward({});
+%} else { #editing
%
-% foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-% }
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% my($query) = $cgi->keywords;
%
-% $svcnum='';
+% $query =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum=$1;
+% $svc_forward=qsearchs('svc_forward',{'svcnum'=>$svcnum})
+% or die "Unknown (svc_forward) svcnum!";
%
-% $svc_forward->set_default_and_fixed;
-% }
+% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+% or die "Unknown (cust_svc) svcnum!";
+%
+% $pkgnum=$cust_svc->pkgnum;
+% $svcpart=$cust_svc->svcpart;
+%
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
%}
%my $action = $svc_forward->svcnum ? 'Edit' : 'Add';
diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi
index 30d98f08b..4b27752ff 100644
--- a/httemplate/edit/svc_www.cgi
+++ b/httemplate/edit/svc_www.cgi
@@ -1,10 +1,9 @@
-<!-- mason kludge -->
-%
-%
%my $conf = new FS::Conf;
%
%my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_www );
+%
%if ( $cgi->param('error') ) {
+%
% $svc_www = new FS::svc_www ( {
% map { $_, scalar($cgi->param($_)) } fields('svc_www')
% } );
@@ -13,38 +12,40 @@
% $svcpart = $cgi->param('svcpart');
% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
% die "No part_svc entry!" unless $part_svc;
-%} else {
-% my($query) = $cgi->keywords;
-% if ( $query =~ /^(\d+)$/ ) { #editing
-% $svcnum=$1;
-% $svc_www=qsearchs('svc_www',{'svcnum'=>$svcnum})
-% or die "Unknown (svc_www) svcnum!";
%
-% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-% or die "Unknown (cust_svc) svcnum!";
+%} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
%
-% $pkgnum=$cust_svc->pkgnum;
-% $svcpart=$cust_svc->svcpart;
-%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+% $pkgnum = $1;
+% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+% $svcpart = $1;
+%
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% } else { #adding
+% $svc_www = new FS::svc_www { svcpart => $svcpart };
%
-% foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-% }
-% $svc_www = new FS::svc_www { svcpart => $svcpart };
+% $svcnum='';
%
-% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-% die "No part_svc entry!" unless $part_svc;
+% $svc_www->set_default_and_fixed;
%
-% $svcnum='';
+%} else { #editing
%
-% $svc_www->set_default_and_fixed;
+% my($query) = $cgi->keywords;
+% $query =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum=$1;
+% $svc_www=qsearchs('svc_www',{'svcnum'=>$svcnum})
+% or die "Unknown (svc_www) svcnum!";
+%
+% my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+% or die "Unknown (cust_svc) svcnum!";
+%
+% $pkgnum=$cust_svc->pkgnum;
+% $svcpart=$cust_svc->svcpart;
+%
+% $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+% die "No part_svc entry!" unless $part_svc;
%
-% }
%}
%my $action = $svc_www->svcnum ? 'Edit' : 'Add';
%
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
index c543ac040..0e69b19ca 100644
--- a/httemplate/elements/header.html
+++ b/httemplate/elements/header.html
@@ -132,7 +132,7 @@ input.fsblackbuttonselected {
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
<FORM ACTION="<%$fsurl%>search/cust_main.cgi" METHOD="GET" STYLE="margin:0">
<INPUT NAME="search_cust" TYPE="text" VALUE="(cust #, name, company or phone)" SIZE="28" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" STYLE="vertical-align:bottom;text-align:right"><BR>
- <A HREF="<%$fsurl%>search/cust_main.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
+ <A NOTYET="<%$fsurl%>search/cust_main.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
<INPUT TYPE="submit" VALUE="Search customers" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
</FORM>
</TD>
@@ -155,10 +155,10 @@ input.fsblackbuttonselected {
</TD>
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
- <FORM ACTION="<%$fsurl%>search/svc_Smart.html" METHOD="GET" STYLE="margin:0">
+ <FORM ACTION="<%$fsurl%>search/cust_svc.html" METHOD="GET" STYLE="margin:0">
<INPUT NAME="search_svc" TYPE="text" VALUE="(user, user@domain or domain)" SIZE="26" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" STYLE="vertical-align:bottom;text-align:right"><BR>
- <A HREF="<%$fsurl%>search/svc_Smarter.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
- <INPUT TYPE="submit" VALUE="Search services"CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
+ <A NOTYET="<%$fsurl%>search/svc_Smarter.html" STYLE="color: #000000; font-size: 70%">Advanced</A>
+ <INPUT TYPE="submit" VALUE="Search services" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
</FORM>
</TD>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 328e24a29..18a499b7b 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -80,58 +80,49 @@ tie my %report_invoices, 'Tie::IxHash',
'Advanced invoice reports' => [ $fsurl.'search/report_cust_bill.html', 'by agent, date range, etc.' ],
;
-tie my %report_services_acct, 'Tie::IxHash',
- 'All accounts by username' => [ $fsurl.'search/svc_acct.cgi?username', '' ],
- 'All accounts by UID' => [ $fsurl.'search/svc_acct.cgi?uid', '' ],
-;
-$report_services_acct{'Unlinked accounts'} = [ $fsurl.'search/svc_acct.cgi?UN_username', 'Pre-Freeside accounts without a customer record' ]
- if $curuser->access_right('View/link unlinked services');
-
-tie my %report_services_domain, 'Tie::IxHash',
- 'All domains' => [ $fsurl.'search/svc_domain.cgi?domain', '' ],
-;
-$report_services_domain{'Unlinked domains'} = [ $fsurl.'search/svc_domain.cgi?UN_domain', 'Pre-Freeside domains without a customer record' ]
- if $curuser->access_right('View/link unlinked services');
-
-tie my %report_services_forward, 'Tie::IxHash',
- 'All mail forwards' => [ $fsurl.'search/svc_forward.cgi?svcnum', '' ],
-;
-$report_services_forward{'Unlinked mail forwards'} = [ $fsurl.'search/svc_forward.cgi?UN_svcnum', 'Pre-Freeside mail forwards without a customer record' ]
- if $curuser->access_right('View/link unlinked services');
-
-tie my %report_services_www, 'Tie::IxHash',
- 'All virtual hosts' => [ $fsurl.'search/svc_www.cgi?svcnum', '' ],
-;
-$report_services_www{'Unlinked virtual hosts'} = [ $fsurl.'search/svc_www.cgi?UN_svcnum', 'Pre-Freeside virtual hosts without a customer record' ]
- if $curuser->access_right('View/link unlinked services');
-
-tie my %report_services_broadband, 'Tie::IxHash',
- 'All broadband services' => [ $fsurl.'search/svc_broadband.cgi?svcnum', '' ],
- #'Unlinked domain' => [ $fsurl.'search/svc_acct.cgi?UN_uid', 'Pre-Freeside broadband services without a customer record' ],
-;
-
-tie my %report_services_phone, 'Tie::IxHash',
- 'All phone numbers' => [ $fsurl.'search/svc_phone.cgi?svcnum', '' ],
-;
-
-tie my %report_services_external, 'Tie::IxHash',
- 'All external services' => [ $fsurl.'search/svc_external.cgi?id', '' ],
-;
-$report_services_external{'Unlinked external services'} = [ $fsurl.'search/svc_external.cgi?UN_id', 'Pre-Freeside external services without a customer record' ]
- if $curuser->access_right('View/link unlinked services');
-
tie my %report_services, 'Tie::IxHash';
if ( $curuser->access_right('Configuration') ) {
$report_services{'Service definitions'} = [ $fsurl.'browse/part_svc.cgi?orderby=active', 'Service definitions by number of active packages' ];
$report_services{'separator'} = '';
}
-$report_services{'Accounts'} = [ \%report_services_acct, 'Access accounts and mailboxes' ];
-$report_services{'Domains'} = [ \%report_services_domain, 'Domains', ];
-$report_services{'Mail forwards'} = [ \%report_services_forward, 'Mail forwards', ];
-$report_services{'Virtual hosts'} = [ \%report_services_www, 'Virtual hosting', ];
-$report_services{'Broadband services'} = [ \%report_services_broadband, 'Fixed (username-less) broadband services', ];
-$report_services{'Phone numbers'} = [ \%report_services_phone, 'Telephone numbers', ];
-$report_services{'External services'} = [ \%report_services_external, 'External services', ];
+foreach my $svcdb ( FS::part_svc->svc_tables() ) {
+
+ my $name = "FS::$svcdb"->table_info->{'name_plural'}
+ || PL( "FS::$svcdb"->table_info->{'name'} );
+ my $lcname = lc($name);
+ my $longname = "FS::$svcdb"->table_info->{'longname_plural'} || $name;
+ my $lclongname = lc($longname);
+ my $sorts = "FS::$svcdb"->table_info->{'sorts'} || [ 'svcnum' ];
+ $sorts = [ $sorts ] unless ref($sorts);
+ my %svc_url = ( 'm' => $m,
+ 'action' => 'search',
+ 'svcdb' => $svcdb,
+ );
+
+ tie my %report_svc, 'Tie::IxHash';
+
+ foreach my $sort ( @$sorts ) {
+
+ my $title = "All $lcname";
+ $title .= " by ". FS::part_svc->svc_table_fields($svcdb)->{$sort}->{'label'}
+ if scalar(@$sorts) > 1;
+
+ $report_svc{$title} =
+ [ FS::UI::Web::svc_url( %svc_url, 'query' => "magic=all;sortby=$sort" ),
+ '',
+ ];
+ }
+
+ if ( $curuser->access_right('View/link unlinked services') ) {
+ $report_svc{"Unlinked $lcname"} =
+ [ FS::UI::Web::svc_url( %svc_url, 'query' => "magic=unlinked;sortby=". $sorts->[0] ),
+ "Pre-Freeside $lcname without a customer record",
+ ];
+ }
+
+ $report_services{$name} = [ \%report_svc, $longname ];
+
+}
tie my %report_packages, 'Tie::IxHash';
if ( $curuser->access_right('Configuration') ) {
diff --git a/httemplate/misc/link.cgi b/httemplate/misc/link.cgi
index 1d1f5e133..ef72b4a5c 100755
--- a/httemplate/misc/link.cgi
+++ b/httemplate/misc/link.cgi
@@ -1,6 +1,3 @@
-<!-- mason kludge -->
-%
-%
%my %link_field = (
% 'svc_acct' => 'username',
% 'svc_domain' => 'domain',
@@ -16,12 +13,10 @@
% },
%);
%
-%my($query) = $cgi->keywords;
-%my($pkgnum, $svcpart) = ('', '');
-%foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
-% $pkgnum=$1 if /^pkgnum(\d+)$/;
-% $svcpart=$1 if /^svcpart(\d+)$/;
-%}
+%$cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
+%my $pkgnum = $1;
+%$cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
+%my $svcpart = $1;
%
%my $part_svc = qsearchs('part_svc',{'svcpart'=>$svcpart});
%my $svc = $part_svc->getfield('svc');
@@ -29,8 +24,6 @@
%my $link_field = $link_field{$svcdb};
%my $link_field2 = $link_field2{$svcdb};
%
-%
-
<% include("/elements/header.html","Link to existing $svc") %>
<FORM ACTION="<% popurl(1) %>process/link.cgi" METHOD=POST>
diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi
index 1b6b52675..e15447ae0 100755
--- a/httemplate/search/cust_main.cgi
+++ b/httemplate/search/cust_main.cgi
@@ -1,5 +1,3 @@
-%
-%
%my $conf = new FS::Conf;
%my $maxrecords = $conf->config('maxsearchrecordsperpage');
%
@@ -486,8 +484,9 @@
% my($label, $value, $svcdb) = $cust_svc->label;
% my($svcnum) = $cust_svc->svcnum;
% my($sview) = $p.'view';
-% print $n2,qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
-% qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
+% print $n2,
+% qq!<TD CLASS="grid" BGCOLOR="$bgcolor" >!. FS::UI::Web::svc_link($m, $cust_svc->part_svc, $cust_svc) . qq!</TD> !.
+% qq!<TD CLASS="grid" BGCOLOR="$bgcolor" >!. FS::UI::Web::svc_label_link($m, $cust_svc->part_svc, $cust_svc) . qq!</TD> !;
% $n2="</TR><TR>";
% }
%
@@ -719,6 +718,3 @@
%
% \@cust_main;
%}
-%
-%
-
diff --git a/httemplate/search/cust_svc.html b/httemplate/search/cust_svc.html
new file mode 100644
index 000000000..568b43b18
--- /dev/null
+++ b/httemplate/search/cust_svc.html
@@ -0,0 +1,110 @@
+<% include( 'elements/search.html',
+ 'title' => 'Service search results',
+ 'name' => 'services',
+ 'query' => $sql_query,
+ 'count_query' => $count_query,
+ 'redirect' => $link,
+ 'header' => [ '#',
+ 'Service',
+ # package?
+ FS::UI::Web::cust_header(),
+ ],
+ 'fields' => [ 'svcnum',
+ sub {
+ #$_[0]->svc. ': '. $_[0]->label;
+ my($label, $value, $svcdb) = $_[0]->label;
+ "$label: $value";
+ },
+ # package?
+ \&FS::UI::Web::cust_fields,
+ ],
+ 'links' => [ $link,
+ $link,
+ # package?
+ ( map { $link_cust }
+ FS::UI::Web::cust_header()
+ ),
+ ],
+ )
+%>
+<%init>
+
+my $addl_from = ' LEFT JOIN part_svc USING ( svcpart ) '.
+ ' LEFT JOIN cust_pkg USING ( pkgnum ) '.
+ ' LEFT JOIN cust_main USING ( custnum ) ';
+
+my @extra_sql = ();
+my $orderby = 'ORDER BY svcnum'; #has to be ordered by something
+ #for pagination to work
+if ( length( $cgi->param('search_svc') ) ) {
+
+ my $string = $cgi->param('search_svc');
+
+ # implement fuzzy searching in subclasses too at some point?
+ # service searching maybe shouldn't be fuzzy...
+
+ push @extra_sql,
+ ' ( '. join(' OR ',
+ map { my $table = $_;
+ my $search_sql = "FS::$table"->search_sql($string);
+ " ( svcdb = '$table'
+ AND 0 < ( SELECT COUNT(*) FROM $table
+ WHERE $table.svcnum = cust_svc.svcnum
+ AND $search_sql
+ )
+ ) ";
+ }
+ FS::part_svc->svc_tables
+ ). ' ) ';
+
+} elsif ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+
+ $cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unknown svcdb";
+ push @extra_sql, "svcdb = '$1'";
+
+ push @extra_sql, 'pkgnum IS NULL'
+ if $cgi->param('magic') eq 'unlinked';
+
+ if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+ my $sortby = $1;
+ $orderby = "ORDER BY $sortby";
+ }
+
+} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+
+ push @extra_sql, "svcpart = $1";
+
+} else {
+ eidiot("No search term specified");
+}
+
+#here is the agent virtualization
+push @extra_sql, $FS::CurrentUser::CurrentUser->agentnums_sql;
+
+my $extra_sql = ' WHERE '. join(' AND ', @extra_sql );
+
+my $sql_query = {
+ 'select' => join(', ',
+ 'cust_svc.*',
+ 'part_svc.*',
+ 'cust_main.custnum',
+ FS::UI::Web::cust_sql_fields(),
+ ),
+ 'table' => 'cust_svc',
+ 'addl_from' => $addl_from,
+ 'hashref' => {},
+ 'extra_sql' => "$extra_sql $orderby",
+};
+
+my $count_query = "SELECT COUNT(*) FROM cust_svc $addl_from $extra_sql";
+
+my $link = sub {
+ my $cust_svc = shift;
+ my $url = FS::UI::Web::svc_url(
+ 'm' => $m,
+ 'action' => 'view',
+ #'part_svc' => $cust_svc->part_svc,
+ 'svcdb' => $cust_svc->svcdb, #we have it from the joined search
+ #'svc' => $cust_svc, #redundant
+ 'query' => 'svcnum=',
+ );
diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi
index 2a1414bea..592aa150a 100755
--- a/httemplate/search/svc_acct.cgi
+++ b/httemplate/search/svc_acct.cgi
@@ -1,15 +1,4 @@
-%
-%
-%my $orderby = 'ORDER BY svcnum';
-%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%
%my @extra_sql = ();
-%if ( $query =~ /^UN_(.*)$/ ) {
-% $query = $1;
-% push @extra_sql, 'pkgnum IS NULL';
-%}
%
% if ( $cgi->param('domain') ) {
% my $svc_domain =
@@ -23,13 +12,21 @@
% }
% }
%
-%if ( $query eq 'svcnum' ) {
-% #$orderby = "ORDER BY svcnum";
-%} elsif ( $query eq 'username' ) {
-% $orderby = "ORDER BY LOWER(username)";
-%} elsif ( $query eq 'uid' ) {
-% $orderby = "ORDER BY uid";
-% push @extra_sql, "uid IS NOT NULL";
+%my $orderby = 'ORDER BY svcnum';
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+%
+% push @extra_sql, 'pkgnum IS NULL'
+% if $cgi->param('magic') eq 'unlinked';
+%
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% $sortby = "LOWER($sortby)"
+% if $sortby eq 'username';
+% push @extra_sql, "$sortby IS NOT NULL"
+% if $sortby eq 'uid';
+% $orderby = "ORDER BY $sortby";
+% }
+%
%} elsif ( $cgi->param('popnum') =~ /^(\d+)$/ ) {
% push @extra_sql, "popnum = $1";
% $orderby = "ORDER BY LOWER(username)";
diff --git a/httemplate/search/svc_broadband.cgi b/httemplate/search/svc_broadband.cgi
index ae32ccd7e..297d74c1d 100755
--- a/httemplate/search/svc_broadband.cgi
+++ b/httemplate/search/svc_broadband.cgi
@@ -1,19 +1,38 @@
-%
-%
%my $conf = new FS::Conf;
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%my(@svc_broadband,$sortby);
-%if ( $query eq 'svcnum' ) {
-% $sortby=\*svcnum_sort;
-% @svc_broadband=qsearch('svc_broadband',{});
-%} elsif ( $query eq 'blocknum' ) {
-% $sortby=\*blocknum_sort;
+%my @svc_broadband = ();
+%my $sortby=\*svcnum_sort;
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+%
% @svc_broadband=qsearch('svc_broadband',{});
-%} else {
-% $cgi->param('ip_addr') =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/;
-% my($ip_addr)=$1;
+%
+% if ( $cgi->param('magic') eq 'unlinked' ) {
+% @svc_broadband = grep { qsearchs('cust_svc', {
+% 'svcnum' => $_->svcnum,
+% 'pkgnum' => '',
+% }
+% )
+% }
+% @svc_broadband;
+% }
+%
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% if ( $sortby eq 'blocknum' ) {
+% $sortby = \*blocknum_sort;
+% }
+% }
+%
+%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+%
+% @svc_broadband =
+% qsearch( 'svc_broadband', {}, '',
+% " WHERE $1 = ( SELECT svcpart FROM cust_svc ".
+% " WHERE cust_svc.svcnum = svc_external.svcnum ) "
+% );
+%
+%} elsif ( $cgi->param('ip_addr') =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) {
+% my $ip_addr = $1;
% @svc_broadband = qsearchs('svc_broadband',{'ip_addr'=>$ip_addr});
%}
%
diff --git a/httemplate/search/svc_domain.cgi b/httemplate/search/svc_domain.cgi
index 85ae94a80..8643ea0dc 100755
--- a/httemplate/search/svc_domain.cgi
+++ b/httemplate/search/svc_domain.cgi
@@ -1,27 +1,19 @@
-%
-%
%my $conf = new FS::Conf;
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%
%my $orderby = 'ORDER BY svcnum';
%my %svc_domain = ();
%my @extra_sql = ();
-%if ( $query eq 'svcnum' ) {
-% #$orderby = 'ORDER BY svcnum';
-%} elsif ( $query eq 'domain' ) {
-% $orderby = 'ORDER BY domain';
-%} elsif ( $query eq 'UN_svcnum' ) { #UN searches need to be acl'ed (and need to
-% #fix $agentnums_sql
-% #$orderby = 'ORDER BY svcnum';
-% push @extra_sql, 'pkgnum IS NULL';
-%} elsif ( $query eq 'UN_domain' ) { #UN searches need to be acl'ed (and need to
-% #fix $agentnums_sql
-% $orderby = 'ORDER BY domain';
-% push @extra_sql, 'pkgnum IS NULL';
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+%
+% push @extra_sql, 'pkgnum IS NULL'
+% if $cgi->param('magic') eq 'unlinked';
+%
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% $orderby = "ORDER BY $sortby";
+% }
+%
%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
-% #$orderby = 'ORDER BY svcnum';
% push @extra_sql, "svcpart = $1";
%} else {
% $cgi->param('domain') =~ /^([\w\-\.]+)$/;
diff --git a/httemplate/search/svc_external.cgi b/httemplate/search/svc_external.cgi
index e85d6d7b3..5502bfc25 100755
--- a/httemplate/search/svc_external.cgi
+++ b/httemplate/search/svc_external.cgi
@@ -1,39 +1,45 @@
-%
-%
%my $conf = new FS::Conf;
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%my(@svc_external,$sortby);
-%if ( $query eq 'svcnum' ) {
-% $sortby=\*svcnum_sort;
-% @svc_external=qsearch('svc_external',{});
-%} elsif ( $query eq 'id' ) {
-% $sortby=\*id_sort;
+%my @svc_external = ();
+%my @h_svc_external = ();
+%my $sortby=\*svcnum_sort;
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+%
% @svc_external=qsearch('svc_external',{});
-%} elsif ( $query eq 'UN_svcnum' ) {
-% $sortby=\*svcnum_sort;
-% @svc_external = grep qsearchs('cust_svc',{
-% 'svcnum' => $_->svcnum,
-% 'pkgnum' => '',
-% }), qsearch('svc_external',{});
-%} elsif ( $query eq 'UN_id' ) {
-% $sortby=\*id_sort;
-% @svc_external = grep qsearchs('cust_svc',{
-% 'svcnum' => $_->svcnum,
-% 'pkgnum' => '',
-% }), qsearch('svc_external',{});
+%
+% if ( $cgi->param('magic') eq 'unlinked' ) {
+% @svc_external = grep { qsearchs('cust_svc', {
+% 'svcnum' => $_->svcnum,
+% 'pkgnum' => '',
+% }
+% )
+% }
+% @svc_external;
+% }
+%
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% if ( $sortby eq 'id' ) {
+% $sortby = \*id_sort;
+% }
+% }
+%
%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+%
% @svc_external =
% qsearch( 'svc_external', {}, '',
% " WHERE $1 = ( SELECT svcpart FROM cust_svc ".
% " WHERE cust_svc.svcnum = svc_external.svcnum ) "
% );
-% $sortby=\*svcnum_sort;
-%} else {
-% $cgi->param('id') =~ /^([\w\-\.]+)$/;
-% my($id)=$1;
-% #push @svc_domain, qsearchs('svc_domain',{'domain'=>$domain});
+%
+%} elsif ( $cgi->param('title') =~ /^(.*)$/ ) {
+% $sortby=\*id_sort;
+% @svc_external=qsearch('svc_external',{ title => $1 });
+% if( $cgi->param('history') == 1 ) {
+% @h_svc_external=qsearch('h_svc_external',{ title => $1 });
+% }
+%} elsif ( $cgi->param('id') =~ /^([\w\-\.]+)$/ ) {
+% my $id = $1;
% @svc_external = qsearchs('svc_external',{'id'=>$id});
%}
%
@@ -84,7 +90,46 @@
% print "</TR>";
%
% }
-%
+% if( scalar(@h_svc_external) > 0 ) {
+% print <<HTML;
+% </TABLE>
+% <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
+% <TR>
+% <TH>Freeside ID</TH>
+% <TH>Service #</TH>
+% <TH>Title</TH>
+% <TH>Date</TH>
+% </TR>
+%HTML
+%
+% foreach my $h_svc ( @h_svc_external ) {
+% my($svcnum, $id, $title, $user, $date)=(
+% $h_svc->svcnum,
+% $h_svc->id,
+% $h_svc->title,
+% $h_svc->history_user,
+% $h_svc->history_date,
+% );
+% my $rowspan = 1;
+% my ($h_cust_svc) = qsearchs( 'h_cust_svc', {
+% svcnum => $svcnum,
+% });
+% my $cust_pkg = qsearchs( 'cust_pkg', {
+% pkgnum => $h_cust_svc->pkgnum,
+% });
+% my $custnum = $cust_pkg->custnum;
+%
+% print <<END;
+% <TR>
+% <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_main.cgi?$custnum">$custnum</A></TD>
+% <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_main.cgi?$custnum">$svcnum</A></TD>
+% <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_main.cgi?$custnum">$title</A></TD>
+% <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_main.cgi?$custnum">$date</A></TD>
+% </TR>
+%END
+% }
+% }
+%
% print <<END;
% </TABLE>
% </BODY>
diff --git a/httemplate/search/svc_forward.cgi b/httemplate/search/svc_forward.cgi
index dc002d96a..4d44c9ca6 100755
--- a/httemplate/search/svc_forward.cgi
+++ b/httemplate/search/svc_forward.cgi
@@ -1,23 +1,19 @@
-%
-%
%my $conf = new FS::Conf;
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
+%my $orderby = 'ORDER BY svcnum';
+%my @extra_sql = ();
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
%
-%my $orderby;
+% push @extra_sql, 'pkgnum IS NULL'
+% if $cgi->param('magic') eq 'unlinked';
%
-%my @extra_sql = ();
-%if ( $query =~ /^UN_(.*)$/ ) { #UN searches need to be acl'ed (and need to
-% #fix $agentnums_sql
-% $query = $1;
-% push @extra_sql, 'pkgnum IS NULL';
-%}
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% $orderby = "ORDER BY $sortby";
+% }
%
-%if ( $query eq 'svcnum' ) {
-% $orderby = 'ORDER BY svcnum';
-%} else {
-% eidiot('unimplemented');
+%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+% push @extra_sql, "svcpart = $1";
%}
%
%my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '.
diff --git a/httemplate/search/svc_phone.cgi b/httemplate/search/svc_phone.cgi
index 26e2090e6..229dd5d89 100644
--- a/httemplate/search/svc_phone.cgi
+++ b/httemplate/search/svc_phone.cgi
@@ -1,19 +1,19 @@
-%
-%
%my $conf = new FS::Conf;
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%
%my $orderby = 'ORDER BY svcnum';
%my %svc_phone = ();
%my @extra_sql = ();
-%if ( $query eq 'svcnum' ) {
-% #$orderby = 'ORDER BY svcnum';
-%} elsif ( $query eq 'phonenum' ) {
-% $orderby = 'ORDER BY phonenum';
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
+%
+% push @extra_sql, 'pkgnum IS NULL'
+% if $cgi->param('magic') eq 'unlinked';
+%
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% $orderby = "ORDER BY $sortby";
+% }
+%
%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
-% #$orderby = 'ORDER BY svcnum';
% push @extra_sql, "svcpart = $1";
%} else {
% $cgi->param('phonenum') =~ /^([\d\- ]+)$/;
diff --git a/httemplate/search/svc_www.cgi b/httemplate/search/svc_www.cgi
index b0f1d5c80..ae1482b9f 100755
--- a/httemplate/search/svc_www.cgi
+++ b/httemplate/search/svc_www.cgi
@@ -1,16 +1,35 @@
+%#my $conf = new FS::Conf;
%
+%my $orderby = 'ORDER BY svcnum';
+%my @extra_sql = ();
+%if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
%
-%#my $conf = new FS::Conf;
+% push @extra_sql, 'pkgnum IS NULL'
+% if $cgi->param('magic') eq 'unlinked';
%
-%my($query)=$cgi->keywords;
-%$query ||= ''; #to avoid use of unitialized value errors
-%my $orderby;
-%if ( $query eq 'svcnum' ) {
-% $orderby = 'ORDER BY svcnum';
-%} else {
-% eidiot('unimplemented');
+% if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+% my $sortby = $1;
+% $orderby = "ORDER BY $sortby";
+% }
+%
+%} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+% push @extra_sql, "svcpart = $1";
%}
%
+%my $addl_from = ' LEFT JOIN cust_svc USING ( svcnum ) '.
+% ' LEFT JOIN part_svc USING ( svcpart ) '.
+% ' LEFT JOIN cust_pkg USING ( pkgnum ) '.
+% ' LEFT JOIN cust_main USING ( custnum ) ';
+%
+%#here is the agent virtualization
+%push @extra_sql, $FS::CurrentUser::CurrentUser->agentnums_sql;
+%
+%my $extra_sql =
+% scalar(@extra_sql)
+% ? ' WHERE '. join(' AND ', @extra_sql )
+% : '';
+%
+%
%my $count_query = 'SELECT COUNT(*) FROM svc_www';
%my $sql_query = {
% 'table' => 'svc_www',
@@ -22,9 +41,7 @@
% FS::UI::Web::cust_sql_fields(),
% ),
% 'extra_sql' => $orderby,
-% 'addl_from' => 'LEFT JOIN cust_svc USING ( svcnum )'.
-% 'LEFT JOIN cust_pkg USING ( pkgnum )'.
-% 'LEFT JOIN cust_main USING ( custnum )',
+% 'addl_from' => $addl_from,
%};
%
%my $link = [ "${p}view/svc_www.cgi?", 'svcnum', ];
diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html
index 0a386f265..841605028 100755
--- a/httemplate/view/cust_main/packages.html
+++ b/httemplate/view/cust_main/packages.html
@@ -1,11 +1,9 @@
-%
% my( $cust_main ) = @_;
% my $conf = new FS::Conf;
%
% my $curuser = $FS::CurrentUser::CurrentUser;
%
% my $packages = get_packages($cust_main, $conf);
-%
<A NAME="cust_pkg"><FONT SIZE="+2">Packages</FONT></A>
@@ -58,44 +56,42 @@ Current packages
% my $bgcolor1 = '#eeeeee';
% my $bgcolor2 = '#ffffff';
% my $bgcolor = '';
-%
-
<TR>
<TH CLASS="grid" BGCOLOR="#cccccc">Package</TH>
<TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
<TH CLASS="grid" BGCOLOR="#cccccc">Services</TH>
</TR>
+
+%foreach my $cust_pkg (@$packages) {
%
-%foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
+% my $part_pkg = $cust_pkg->part_pkg;
%
% if ( $bgcolor eq $bgcolor1 ) {
% $bgcolor = $bgcolor2;
% } else {
% $bgcolor = $bgcolor1;
% }
-%
-%
-<!--pkgnum: <%$pkg->{pkgnum}%>-->
+<!--pkgnum: <% $cust_pkg->pkgnum %>-->
<TR>
<TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
- <A NAME="cust_pkg<%$pkg->{pkgnum}%>"><%$pkg->{pkgnum}%></A>:
- <%$pkg->{pkg}%> - <%$pkg->{comment}%><BR>
+ <A NAME="cust_pkg<% $cust_pkg->pkgnum %>"><% $cust_pkg->pkgnum %></A>:
+ <% $part_pkg->pkg %> - <% $part_pkg->comment %><BR>
<FONT SIZE=-1>
-% unless ( $pkg->{cancel} ) {
+% unless ( $cust_pkg->get('cancel') ) {
% if ( $curuser->access_right('Change customer package') ) {
- (&nbsp;<%pkg_change_link($pkg)%>&nbsp;)
+ (&nbsp;<%pkg_change_link($cust_pkg)%>&nbsp;)
% }
% if ( $curuser->access_right('Edit customer package dates') ) {
- (&nbsp;<%pkg_dates_link($pkg)%>&nbsp;)
+ (&nbsp;<%pkg_dates_link($cust_pkg)%>&nbsp;)
% }
% if ( $curuser->access_right('Customize customer package') ) {
- (&nbsp;<%pkg_customize_link($pkg,$cust_main->custnum)%>&nbsp;)
+ (&nbsp;<%pkg_customize_link($cust_pkg,$cust_main->custnum)%>&nbsp;)
% }
% }
@@ -118,7 +114,7 @@ Current packages
%
% #false laziness w/edit/REAL_cust_pkg.cgi
% my( $billed_or_prepaid, $last_bill_or_renewed, $next_bill_or_prepaid_until );
-% unless ( $pkg->{'part_pkg'}->is_prepaid ) {
+% unless ( $part_pkg->is_prepaid ) {
% $billed_or_prepaid = 'billed';
% $last_bill_or_renewed = 'Last&nbsp;bill';
% $next_bill_or_prepaid_until = 'Next&nbsp;bill';
@@ -129,19 +125,19 @@ Current packages
% }
%
%
-% if ( $pkg->{cancel} ) {
+% if ( $cust_pkg->get('cancel') ) {
<!-- #status: cancelled -->
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#ff0000"><B>Cancelled&nbsp;</B></FONT></TD>
- <% pkg_datestr($pkg,'cancel',$conf) %>
+ <% pkg_datestr($cust_pkg, 'cancel', $conf) %>
</TR>
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#ff0000" SIZE="-2">
- <% $pkg->{reason} %>
+ <% $cust_pkg->last_reason ? $cust_pkg->last_reason->reason : '' %>
</FONT></TD>
</TR>
-% unless ( $pkg->{setup} ) {
+% unless ( $cust_pkg->get('setup') ) {
<TR>
@@ -152,37 +148,37 @@ Current packages
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
- <% pkg_datestr($pkg, 'setup',$conf) %>
+ <% pkg_datestr($cust_pkg, 'setup', $conf) %>
</TR>
-% if ( $pkg->{'last_bill'} ) {
+% if ( $cust_pkg->get('last_bill') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
- <% pkg_datestr($pkg, 'last_bill',$conf) %>
+ <% pkg_datestr($cust_pkg, 'last_bill',$conf) %>
</TR>
% }
-% if ( $pkg->{'susp'} ) {
+% if ( $cust_pkg->get('susp') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Suspended&nbsp;</TD>
- <% pkg_datestr($pkg, 'susp',$conf) %>
+ <% pkg_datestr($cust_pkg, 'susp', $conf) %>
</TR>
% }
% }
% } else {
-% if ( $pkg->{susp} ) {
+% if ( $cust_pkg->get('susp') ) {
<!-- #status: suspended -->
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#FF9900"><B>Suspended</B>&nbsp;</FONT></TD>
- <% pkg_datestr($pkg,'susp',$conf) %>
+ <% pkg_datestr($cust_pkg, 'susp', $conf) %>
</TR>
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#FF9900" SIZE="-2">
- <% $pkg->{reason} %>
+ <% $cust_pkg->last_reason ? $cust_pkg->last_reason->reason : '' %>
</FONT></TD>
</TR>
-% unless ( $pkg->{setup} ) {
+% unless ( $cust_pkg->get('setup') ) {
<TR>
@@ -193,24 +189,24 @@ Current packages
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
- <% pkg_datestr($pkg, 'setup',$conf) %>
+ <% pkg_datestr($cust_pkg, 'setup', $conf) %>
</TR>
% }
-% if ( $pkg->{'last_bill'} ) {
+% if ( $cust_pkg->get('last_bill') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
- <% pkg_datestr($pkg, 'last_bill',$conf) %>
+ <% pkg_datestr($cust_pkg, 'last_bill', $conf) %>
</TR>
% }
<!-- # next bill ?? -->
-% if ( $pkg->{'expire'} ) {
+% if ( $cust_pkg->get('expire') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Expires&nbsp;</TD>
- <% pkg_datestr($pkg, 'expire',$conf) %>
+ <% pkg_datestr($cust_pkg, 'expire', $conf) %>
</TR>
% }
@@ -220,11 +216,11 @@ Current packages
<FONT SIZE=-1>
% if ( $curuser->access_right('Unsuspend customer package') ) {
- (&nbsp;<% pkg_unsuspend_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
% }
% if ( $curuser->access_right('Cancel customer package') ) {
- (&nbsp;<% pkg_cancel_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
% }
</FONT>
@@ -232,9 +228,9 @@ Current packages
</TR>
% } else {
<!-- #status: active -->
-% unless ( $pkg->{setup} ) {
+% unless ( $cust_pkg->get('setup') ) {
<!-- #not setup -->
-% unless ( $pkg->{'freq'} ) {
+% unless ( $part_pkg->freq ) {
<TR>
@@ -246,7 +242,7 @@ Current packages
<FONT SIZE=-1>
% if ( $curuser->access_right('Cancel customer package immediately') ) {
- (&nbsp;<% pkg_cancel_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
% }
</FONT>
@@ -256,12 +252,12 @@ Current packages
<TR>
- <TD COLSPAN=<%$colspan%>>Not&nbsp;yet&nbsp;billed&nbsp;(<% $billed_or_prepaid %>&nbsp;<% myfreq($pkg->{part_pkg}) %>)</TD>
+ <TD COLSPAN=<%$colspan%>>Not&nbsp;yet&nbsp;billed&nbsp;(<% $billed_or_prepaid %>&nbsp;<% myfreq($part_pkg) %>)</TD>
</TR>
% }
% } else {
<!-- #setup -->
-% unless ( $pkg->{freq} ) {
+% unless ( $part_pkg->freq ) {
<TR>
@@ -270,58 +266,58 @@ Current packages
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Billed&nbsp;</TD>
- <% pkg_datestr($pkg,'setup',$conf) %>
+ <% pkg_datestr($cust_pkg, 'setup', $conf) %>
</TR>
% } else {
<TR>
- <TD COLSPAN=<%$colspan%>><FONT COLOR="#00CC00"><B>Active</B></FONT>,&nbsp;<% $billed_or_prepaid %>&nbsp;<% myfreq($pkg->{part_pkg}) %></TD>
+ <TD COLSPAN=<%$colspan%>><FONT COLOR="#00CC00"><B>Active</B></FONT>,&nbsp;<% $billed_or_prepaid %>&nbsp;<% myfreq($part_pkg) %></TD>
</TR>
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
- <% pkg_datestr($pkg, 'setup',$conf) %>
+ <% pkg_datestr($cust_pkg, 'setup', $conf) %>
</TR>
% }
% }
-% if ( $pkg->{'last_bill'} ) {
+% if ( $cust_pkg->get('last_bill') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
- <% pkg_datestr($pkg, 'last_bill',$conf) %>
+ <% pkg_datestr($cust_pkg, 'last_bill', $conf) %>
</TR>
% }
-% if ( $pkg->{'next_bill'} ) {
+% if ( $cust_pkg->get('bill') ) { #next bill
<TR>
<TD WIDTH="<%$width%>" ALIGN="right"><% $next_bill_or_prepaid_until %>&nbsp;</TD>
- <% pkg_datestr($pkg, 'next_bill',$conf) %>
+ <% pkg_datestr($cust_pkg, 'bill', $conf) %>
</TR>
% }
-% if ( $pkg->{'expire'} ) {
+% if ( $cust_pkg->get('expire') ) {
<TR>
<TD WIDTH="<%$width%>" ALIGN="right">Expires&nbsp;</TD>
- <% pkg_datestr($pkg, 'expire',$conf) %>
+ <% pkg_datestr($cust_pkg, 'expire', $conf) %>
</TR>
% }
-% if ( $pkg->{freq} ) {
+% if ( $part_pkg->freq ) {
<TR>
<TD COLSPAN=<%$colspan%>>
<FONT SIZE=-1>
% if ( $curuser->access_right('Suspend customer package') ) {
- (&nbsp;<% pkg_suspend_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
% }
% if ( $curuser->access_right('Cancel customer package immediately') ) {
- (&nbsp;<% pkg_cancel_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
% }
% if ( $curuser->access_right('Cancel customer package later') ) {
- (&nbsp;<% pkg_expire_link($pkg) %>&nbsp;)
+ (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
% }
<FONT>
@@ -338,46 +334,49 @@ Current packages
<TD CLASS="inv" BGCOLOR="<% $bgcolor %>">
<TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
-% foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
+% #foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
+% foreach my $part_svc ( $cust_pkg->part_svc ) {
-% foreach my $service (@{$svcpart->{services}}) {
+% #foreach my $service (@{$svcpart->{services}}) {
+% foreach my $cust_svc ( @{ $part_svc->cust_pkg_svc } ) {
<TR>
- <TD ALIGN="right" VALIGN="top"><%svc_link($svcpart,$service)%></TD>
- <TD STYLE="padding-bottom:0px"><B><%svc_label_link($svcpart,$service)%></B></TD>
+ <TD ALIGN="right" VALIGN="top"><% FS::UI::Web::svc_link($m, $part_svc, $cust_svc) %></TD>
+ <TD STYLE="padding-bottom:0px"><B><% FS::UI::Web::svc_label_link($m, $part_svc, $cust_svc) %></B></TD>
</TR>
- <TR>
- <TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">
-
-% if ( $curuser->access_right('Recharge customer service')
-% && ($svcpart->{'svcdb'} eq 'svc_acct')
-% && ($service->{seconds} ne ''
-% || $service->{upbytes} ne ''
-% || $service->{downbytes} ne ''
-% || $service->{totalbytes} ne '' )
+ <TR>
+ <TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">
+
+% if ( $curuser->access_right('Recharge customer service')
+% && $cust_svc->svcdb eq 'svc_acct'
+% && ( $cust_svc->svc_x->seconds ne ''
+% || $cust_svc->svc_x->upbytes ne ''
+% || $cust_svc->svc_x->downbytes ne ''
+% || $cust_svc->svc_x->totalbytes ne ''
+% )
% ) {
- (&nbsp;<%svc_recharge_link($service)%>&nbsp;)
-% }
+ (&nbsp;<%svc_recharge_link($cust_svc)%>&nbsp;)
+% }
</FONT></TD>
<TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">
-% if ( $curuser->access_right('Unprovision customer service') ) {
- (&nbsp;<%svc_unprovision_link($service)%>&nbsp;)
-% }
+% if ( $curuser->access_right('Unprovision customer service') ) {
+ (&nbsp;<%svc_unprovision_link($cust_svc)%>&nbsp;)
+% }
</FONT></TD>
</TR>
% }
-% if ( ! $pkg->{'cancel'}
+% if ( ! $cust_pkg->get('cancel')
% && $curuser->access_right('Provision customer service')
-% && $svcpart->{count} < $svcpart->{quantity}
+% && $part_svc->num_avail
% ) {
<TR>
<TD COLSPAN=2 ALIGN="center" STYLE="padding-bottom:4px;padding-top:0px">
- <B><% svc_provision_link($pkg, $svcpart, $conf, $curuser) %></B>
+ <B><% svc_provision_link($cust_pkg, $part_svc, $conf, $curuser) %></B>
</TD>
</TR>
@@ -414,104 +413,33 @@ Current packages
% } else {
% $method = 'all_pkgs';
% }
-%
-% foreach my $cust_pkg ( $cust_main->$method() ) {
-%
-% my $part_pkg = $cust_pkg->part_pkg;
-%
-% my %pkg = ();
-%
-% #to get back to the original object... should use it in the first place!!
-% $pkg{cust_pkg} = $cust_pkg;
-% $pkg{part_pkg} = $part_pkg;
-%
-% $pkg{pkgnum} = $cust_pkg->pkgnum;
-% $pkg{pkg} = $part_pkg->pkg;
-% $pkg{pkgpart} = $part_pkg->pkgpart;
-% $pkg{comment} = $part_pkg->getfield('comment');
-% $pkg{freq} = $part_pkg->freq;
-% $pkg{setup} = $cust_pkg->getfield('setup');
-% $pkg{last_bill} = $cust_pkg->getfield('last_bill');
-% $pkg{next_bill} = $cust_pkg->getfield('bill');
-% $pkg{susp} = $cust_pkg->getfield('susp');
-% $pkg{expire} = $cust_pkg->getfield('expire');
-% $pkg{cancel} = $cust_pkg->getfield('cancel');
-% $pkg{reason} = $cust_pkg->last_reason->reason if $cust_pkg->last_reason;
-%
-%
-% my %svcparts = map {
-% $_->svcpart => {
-% $_->part_svc->hash,
-% 'quantity' => $_->quantity,
-% 'count' => $cust_pkg->num_cust_svc($_->svcpart),
-% #'services' => [],
-% };
-% } $part_pkg->pkg_svc;
-%
-% foreach my $cust_svc ( $cust_pkg->cust_svc ) {
-% #warn "svcnum ". $cust_svc->svcnum. " / svcpart ". $cust_svc->svcpart. "\n";
-% my $svc = {
-% 'svcnum' => $cust_svc->svcnum,
-% 'label' => ($cust_svc->label)[1],
-% $cust_svc->svc_x->hash,
-% };
-%
-% #false laziness with above, to catch extraneous services. whole
-% #damn thing should be OO...
-% my $svcpart = ( $svcparts{$cust_svc->svcpart} ||= {
-% $cust_svc->part_svc->hash,
-% 'quantity' => 0,
-% 'count' => $cust_pkg->num_cust_svc($cust_svc->svcpart),
-% #'services' => [],
-% } );
-%
-% push @{$svcpart->{services}}, $svc;
-%
-% }
-%
-% $pkg{svcparts} = [ values %svcparts ];
-%
-% push @packages, \%pkg;
-%
-% }
-%
-% return \@packages;
%
+% [ $cust_main->$method() ];
%}
-%
-%sub svc_link {
-%
-% my ($svcpart, $svc) = (shift,shift) or return '';
-% return qq!<A HREF="${p}view/$svcpart->{svcdb}.cgi?$svc->{svcnum}">$svcpart->{svc}</A>!;
-%
-%}
-%
-%sub svc_label_link {
-%
-% my ($svcpart, $svc) = (shift,shift) or return '';
-% return qq!<A HREF="${p}view/$svcpart->{svcdb}.cgi?$svc->{svcnum}">$svc->{label}</A>!;
-%
-%}
-%
+%
%sub svc_provision_link {
-% my ($pkg, $svcpart, $conf, $curuser) = @_;
-% ( my $svc_nbsp = $svcpart->{svc} ) =~ s/\s+/&nbsp;/g;
-% my $num_left = $svcpart->{quantity} - $svcpart->{count};
-% my $pkgnum_svcpart = "pkgnum$pkg->{pkgnum}-svcpart$svcpart->{svcpart}";
-%
+% my ($cust_pkg, $part_svc, $conf, $curuser) = @_;
+% ( my $svc_nbsp = $part_svc->svc ) =~ s/\s+/&nbsp;/g;
+% my $num_avail = $part_svc->num_avail;
+% my $pkgnum_svcpart = "pkgnum=". $cust_pkg->pkgnum. ';'.
+% "svcpart=". $part_svc->svcpart;
% my $url;
-% if ( $svcpart->{svcdb} eq 'svc_external'
+% if ( $part_svc->svcdb eq 'svc_external' #could be generalized
% && $conf->exists('svc_external-skip_manual')
% ) {
-% $url = "${p}edit/process/$svcpart->{svcdb}.cgi?".
-% "pkgnum=$pkg->{pkgnum}&".
-% "svcpart=$svcpart->{svcpart}";
+% $url = "${p}edit/process/". $part_svc->svcdb. ".cgi?$pkgnum_svcpart";
% } else {
-% $url = "${p}edit/$svcpart->{svcdb}.cgi?$pkgnum_svcpart";
+% $url = FS::UI::Web::svc_url(
+% 'm' => $m,
+% 'action' => 'edit',
+% 'part_svc' => $part_svc,
+% 'query' => $pkgnum_svcpart,
+% );
+% #$url = "${p}edit/$svcpart->{svcdb}.cgi?$pkgnum_svcpart";
% }
%
% my $link = qq!<A CLASS="provision" HREF="$url">!.
-% "Provision&nbsp;$svc_nbsp&nbsp;($num_left)</A>";
+% "Provision&nbsp;$svc_nbsp&nbsp;($num_avail)</A>";
% if ( $conf->exists('legacy_link')
% && $curuser->access_right('View/link unlinked services')
% )
@@ -519,39 +447,20 @@ Current packages
% $link .= '<BR>'.
% qq!<A CLASS="provision" HREF="${p}misc/link.cgi?!.
% qq!$pkgnum_svcpart">!.
-% "Link&nbsp;to&nbsp;legacy&nbsp;$svc_nbsp&nbsp;($num_left)</A>";
+% "Link&nbsp;to&nbsp;legacy&nbsp;$svc_nbsp&nbsp;($num_avail)</A>";
% }
% $link;
%}
%
%sub svc_unprovision_link {
-% my $svc = shift or return '';
-% qq!<A HREF="javascript:areyousure('${p}misc/unprovision.cgi?$svc->{svcnum}',!.
-% qq!'Permanently unprovision and delete this service?')">Unprovision</A>!;
-%}
-%
-%sub svc_recharge_link {
-% my $svc = shift or return '';
-%
-% qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}misc/recharge_svc.html?svcnum=$svc->{svcnum}', 392, 336, 'recharge_svc_popup' ), CAPTION, 'Recharge service $svc->{svcnum}', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Recharge</A>!;
-%}
-%
-%# This should be generalized to use config options to determine order.
-%sub pkgsort_pkgnum_cancel {
-% if ($a->{cancel} and $b->{cancel}) {
-% return ($a->{pkgnum} <=> $b->{pkgnum});
-% } elsif ($a->{cancel} or $b->{cancel}) {
-% return (-1) if ($b->{cancel});
-% return (1) if ($a->{cancel});
-% return (0);
-% } else {
-% return($a->{pkgnum} <=> $b->{pkgnum});
-% }
+% my $cust_svc = shift or return '';
+% qq!<A HREF="javascript:areyousure('${p}misc/unprovision.cgi?!. $cust_svc->svcnum.
+% qq!', 'Permanently unprovision and delete this service?')">Unprovision</A>!;
%}
%
%sub pkg_datestr {
-% my($pkg, $field, $conf) = @_ or return '';
-% return '&nbsp;' unless $pkg->{$field};
+% my($cust_pkg, $field, $conf) = @_ or return '';
+% return '&nbsp;' unless $cust_pkg->get($field);
% my $format = '<TD align="left"><B>%b</B></TD>'.
% '<TD align="right"><B>&nbsp;%o,</B></TD>'.
% '<TD align="right"><B>&nbsp;%Y</B></TD>';
@@ -561,48 +470,68 @@ Current packages
% '<TD ALIGN="left"><B>%M</B></TD>'.
% '<TD ALIGN="left"><B>&nbsp;%P</B></TD>'
% if $conf->exists('cust_pkg-display_times');
-% ( my $strip = time2str($format, $pkg->{$field}) ) =~ s/ (\d)/$1/g;
+% my $strip = time2str($format, $cust_pkg->get($field) );
+% $strip =~ s/ (\d)/$1/g;
% $strip;
%}
%
-%sub pkg_change_link {
-% my $pkg = shift or return '';
-% return qq!<a href="${p}misc/change_pkg.cgi?$pkg->{pkgnum}">!.
-% qq!Change&nbsp;package</a>!;
+%sub pkg_change_link { pkg_link('misc/change_pkg', 'Change&nbsp;package', @_ ); }
+%sub pkg_suspend_link { pkg_link('misc/susp_pkg', 'Suspend', @_ ); }
+%sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg', 'Unsuspend', @_ ); }
+%sub pkg_expire_link { pkg_link('misc/expire_pkg', 'Cancel&nbsp;later', @_ ); }
+%sub pkg_dates_link { pkg_link('edit/REAL_cust_pkg', 'Edit&nbsp;dates', @_ ); }
+%
+%sub pkg_cancel_link { pkg_popup_link( 'misc/cancel_pkg.html?method=cancel',
+% 'Cancel&nbsp;now',
+% 'Cancel',
+% @_
+% );
+% }
+%sub pkg_expire_link { pkg_popup_link( 'misc/cancel_pkg.html?method=expire',
+% 'Cancel&nbsp;later',
+% 'Expire', #"Cancel package $num later"
+% @_
+% );
+% }
+%
+%sub svc_recharge_link { svc_popup_link( 'misc/recharge_svc.html',
+% 'Recharge',
+% 'Recharge',
+% @_
+% );
+% }
+%
+%sub pkg_link {
+% my($action, $label, $cust_pkg) = @_;
+% return '' unless $cust_pkg;
+% qq!<a href="${p}misc/$action.cgi?!. $cust_pkg->pkgnum. qq!">$label</a>!;
%}
%
-%sub pkg_suspend_link {
-% my $pkg = shift or return '';
-% qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}misc/cancel_pkg.html?method=suspend&pkgnum=$pkg->{pkgnum}', 392, 336, 'suspend_pkg_popup' ), CAPTION, 'Suspend package $pkg->{pkgnum}', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Suspend</A>!;
+%sub pkg_popup_link {
+% my($action, $label, $actionlabel, $cust_pkg) = @_;
+% $action .= '&pkgnum='. $cust_pkg->pkgnum;
+% $actionlabel .= ' package '. $cust_pkg->pkgnum;
+% popup_link($action, $label, $actionlabel);
%}
%
-%sub pkg_unsuspend_link {
-% my $pkg = shift or return '';
-% return qq!<a href="${p}misc/unsusp_pkg.cgi?$pkg->{pkgnum}">Unsuspend</a>!;
+%sub svc_popup_link {
+% my($action, $label, $actionlabel, $cust_svc) = @_;
+% $action .= '?svcnum='. $cust_svc->svcnum;
+% $actionlabel .= ' service '. $cust_svc->svcnum;
+% popup_link($action, $label, $actionlabel);
%}
%
-%sub pkg_cancel_link {
-% my $pkg = shift or return '';
-%
-% qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}misc/cancel_pkg.html?method=cancel&pkgnum=$pkg->{pkgnum}', 392, 336, 'cancel_pkg_popup' ), CAPTION, 'Cancel package $pkg->{pkgnum}', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Cancel now</A>!;
-%}
-%
-%sub pkg_expire_link {
-% my $pkg = shift or return '';
-% qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('${p}misc/cancel_pkg.html?method=expire&pkgnum=$pkg->{pkgnum}', 392, 336, 'expire_pkg_popup' ), CAPTION, 'Expire package $pkg->{pkgnum}', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">Cancel later</A>!;
-%}
-%
-%sub pkg_dates_link {
-% my $pkg = shift or return '';
-% qq!<A HREF="${p}edit/REAL_cust_pkg.cgi?$pkg->{pkgnum}">Edit&nbsp;dates</A>!;
+%sub popup_link {
+% my($action, $label, $actionlabel) = @_;
+% qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('$p$action', 392, 336, 'pkg_or_svc_action_popup' ), CAPTION, '$actionlabel', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">$label</A>!;
%}
%
%sub pkg_customize_link {
-% my $pkg = shift or return '';
-% my $custnum = shift;
-% qq!<A HREF="${p}edit/part_pkg.cgi?keywords=$custnum;clone=$pkg->{pkgpart};!.
-% qq!pkgnum=$pkg->{pkgnum}">Customize</A>!;
+% my $cust_pkg = shift or return '';
+% my $custnum = $cust_pkg->custnum;
+% qq!<A HREF="${p}edit/part_pkg.cgi?!.
+% "keywords=$custnum;".
+% "clone=". $cust_pkg->part_pkg->pkgpart. ';'.
+% "pkgnum=". $cust_pkg->pkgnum.
+% qq!">Customize</A>!;
%}
-%
-%
-
diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html
index 35434632e..7b8df3a74 100644
--- a/httemplate/view/elements/svc_Common.html
+++ b/httemplate/view/elements/svc_Common.html
@@ -12,6 +12,9 @@
% # if not specified all columns (except for the primary key) will be viewable
% # 'fields' => [
% # ]
+% #
+% # # defaults to "edit/$table.cgi?", will have svcnum appended
+% # 'edit_url' =>
%
% my(%opt) = @_;
%
@@ -21,9 +24,15 @@
% #|| [ grep { $_ ne 'svcnum' } dbdef->table($table)->columns ];
% || [ grep { $_ ne 'svcnum' } fields($table) ];
%
-% my($query) = $cgi->keywords;
-% $query =~ /^(\d+)$/;
-% my $svcnum = $1;
+% my $svcnum;
+% if ( $cgi->param('svcnum') ) {
+% $cgi->param('svcnum') =~ /^(\d+)$/ or die "unparsable svcnum";
+% $svcnum = $1;
+% } else {
+% my($query) = $cgi->keywords;
+% $query =~ /^(\d+)$/ or die "no svcnum";
+% $svcnum = $1;
+% }
% my $svc_x = qsearchs( $opt{'table'}, { 'svcnum' => $svcnum } )
% or die "Unknown svcnum $svcnum in ". $opt{'table'}. " table\n";
%
@@ -69,7 +78,8 @@
Service #<B><% $svcnum %></B>
-| <A HREF="<%$p%>edit/<% $opt{'table'} %>.cgi?<%$svcnum%>">Edit this <% $label %></A>
+% my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?';
+| <A HREF="<%$url%><%$svcnum%>">Edit this <% $label %></A>
<BR>
<% ntable("#cccccc") %><TR><TD><% ntable("#cccccc",2) %>