summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Record.pm37
-rw-r--r--FS/FS/part_svc.pm5
-rwxr-xr-xFS/FS/part_virtual_field.pm14
-rw-r--r--httemplate/browse/router.cgi43
-rw-r--r--httemplate/edit/elements/part_svc_column.html2
-rw-r--r--httemplate/edit/elements/svc_Common.html3
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi5
-rw-r--r--httemplate/edit/process/part_virtual_field.html3
8 files changed, 85 insertions, 27 deletions
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index 2bffdc377..af8c10196 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -4,7 +4,7 @@ use strict;
use charnames ':full';
use vars qw( $AUTOLOAD @ISA @EXPORT_OK $DEBUG
%virtual_fields_cache
- $money_char $lat_lower $lon_upper
+ %virtual_fields_hash_cache $money_char $lat_lower $lon_upper
$me
$nowarn_identical $nowarn_classload
$no_update_diff $no_history $qsearch_qualify_columns
@@ -1621,6 +1621,41 @@ sub virtual_fields {
}
+=item virtual_fields_hash [ TABLE ]
+
+Returns a list of virtual field records as a hash defined for the table. This should not
+be exported, and should only be called as an instance or class method.
+
+=cut
+
+sub virtual_fields_hash {
+ my $self = shift;
+ my $table;
+ $table = $self->table or confess "virtual_fields called on non-table";
+
+ confess "Unknown table $table" unless dbdef->table($table);
+
+ return () unless dbdef->table('part_virtual_field');
+
+ unless ( $virtual_fields_hash_cache{$table} ) {
+ $virtual_fields_hash_cache{$table} = [];
+ my $concat = [ "'cf_'", "name" ];
+ my $select = concat_sql($concat).' as name, label, length';
+ my @vfields = qsearch({
+ select => $select,
+ table => 'part_virtual_field',
+ hashref => { 'dbtable' => $table, },
+ });
+
+ foreach (@vfields) {
+ push @{ $virtual_fields_hash_cache{$table} }, $_->{Hash};
+ }
+ }
+
+ @{$virtual_fields_hash_cache{$table}};
+
+}
+
=item process_batch_import JOB OPTIONS_HASHREF PARAMS
Processes a batch import as a queued JSRPC job
diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm
index b387085f5..7bf3d5aaf 100644
--- a/FS/FS/part_svc.pm
+++ b/FS/FS/part_svc.pm
@@ -708,6 +708,11 @@ sub _svc_defs {
warn "skipping disabled service FS::$mod" if $DEBUG;
next;
}
+
+ foreach ("FS::$mod"->virtual_fields_hash) {
+ $info->{'fields'}->{$_->{'name'}} = $_->{'label'};
+ }
+
$info{$mod} = $info;
}
}
diff --git a/FS/FS/part_virtual_field.pm b/FS/FS/part_virtual_field.pm
index 4e6d2e4bd..1df4984e1 100755
--- a/FS/FS/part_virtual_field.pm
+++ b/FS/FS/part_virtual_field.pm
@@ -62,6 +62,7 @@ Create a new record. To add the record to the database, see "insert".
sub table { 'part_virtual_field'; }
sub virtual_fields { () }
+sub virtual_fields_hash { () }
=item widget UI_TYPE MODE [ VALUE ]
@@ -84,19 +85,20 @@ VALUE (optional) is the current value of the field.
sub widget {
my $self = shift;
- my ($ui_type, $mode, $value) = @_;
+ my ($ui_type, $mode, $value, $header_col_type) = @_;
+ $header_col_type = 'TD' unless $header_col_type;
my $text;
my $label = $self->label || $self->name;
if ($ui_type eq 'HTML') {
if ($mode eq 'view') {
- $text = q!<TR><TD ALIGN="right">! . $label .
- q!</TD><TD BGCOLOR="#ffffff">! . $value .
+ $text = q!<TR><!.$header_col_type.q! ALIGN="right">! . $label .
+ q!</!.$header_col_type.q!><TD BGCOLOR="#ffffff">! . $value .
q!</TD></TR>! . "\n";
} elsif ($mode eq 'edit') {
- $text = q!<TR><TD ALIGN="right">! . $label .
- q!</TD><TD>!;
- $text .= q!<INPUT NAME="! . $self->name .
+ $text = q!<TR><!.$header_col_type.q! ALIGN="right">! . $label .
+ q!</!.$header_col_type.q!><TD>!;
+ $text .= q!<INPUT TYPE=text NAME="! . $self->name .
q!" VALUE="! . escapeHTML($value) . q!"!;
if ($self->length) {
$text .= q! SIZE="! . $self->length . q!"!;
diff --git a/httemplate/browse/router.cgi b/httemplate/browse/router.cgi
index 85512f8df..c7713f313 100644
--- a/httemplate/browse/router.cgi
+++ b/httemplate/browse/router.cgi
@@ -7,24 +7,9 @@
'extra_sql' => $extra_sql,
},
'count_query' => "SELECT count(*) from router $count_sql",
- 'header' => [ 'Router name',
- 'Address block(s)',
- 'IP addressing',
- 'Action',
- ],
- 'fields' => [ 'routername',
- sub { join( '<BR>', map { $_->NetAddr }
- shift->addr_block
- );
- },
- sub { shift->manual_addr ? 'Manual' : 'Automatic' },
- sub { 'Delete' },
- ],
- 'links' => [ [ "${p2}edit/router.cgi?", 'routernum' ],
- '',
- '',
- [ "${p}misc/delete-router.html?", 'routernum' ],
- ],
+ 'header' => [ @header_fields ],
+ 'fields' => [ @fields ],
+ 'links' => [ @links ],
'agent_virt' => 1,
'agent_null_right'=> "Broadband global configuration",
'agent_pos' => 1,
@@ -32,6 +17,8 @@
%>
<%init>
+use CGI qw(escapeHTML);
+
die "access denied"
unless $FS::CurrentUser::CurrentUser->access_right('Broadband configuration')
|| $FS::CurrentUser::CurrentUser->access_right('Broadband global configuration');
@@ -52,6 +39,26 @@ if ($cgi->param('hidecustomerrouters') eq '1') {
$cgi->delete('hidecustomerrouters');
}
+my @header_fields = ('Router name', 'Address block(s)', 'IP addressing');
+my @fields = ( 'routername',
+ sub { join( '<BR>', map { $_->NetAddr } shift->addr_block); },
+ sub { shift->manual_addr ? 'Manual' : 'Automatic' },
+ );
+my @links = ( [ "${p2}edit/router.cgi?", 'routernum' ],
+ '',
+ '',
+ );
+
+foreach (FS::router->virtual_fields_hash) {
+ push @header_fields, escapeHTML($_->{'label'});
+ push @fields, escapeHTML($_->{'name'});
+ push @links, '';
+}
+
+push @header_fields, 'Action';
+push @fields, sub { 'Delete' };
+push @links, [ "${p}misc/delete-router.html?", 'routernum' ];
+
my $count_sql = $extra_sql. ( $extra_sql =~ /WHERE/ ? ' AND' : 'WHERE' ).
$FS::CurrentUser::CurrentUser->agentnums_sql(
'null_right' => 'Broadband global configuration',
diff --git a/httemplate/edit/elements/part_svc_column.html b/httemplate/edit/elements/part_svc_column.html
index 1e1ff79ee..80d325e59 100644
--- a/httemplate/edit/elements/part_svc_column.html
+++ b/httemplate/edit/elements/part_svc_column.html
@@ -98,7 +98,7 @@ that field.
<TD ROWSPAN=2 CLASS="grid">
<INPUT NAME="<% $svcdb %>__<% $field %>_label"
STYLE="text-align: right"
- VALUE="<% $part_svc_column->columnlabel || $def->{'label'} |h %>">
+ VALUE="<% $part_svc_column->columnlabel || escapeHTML($def->{'label'}) |h %>">
</TD>
<TD ROWSPAN=1 CLASS="grid">
diff --git a/httemplate/edit/elements/svc_Common.html b/httemplate/edit/elements/svc_Common.html
index e1c309080..e5dc55979 100644
--- a/httemplate/edit/elements/svc_Common.html
+++ b/httemplate/edit/elements/svc_Common.html
@@ -227,7 +227,8 @@
$html .=
$svc_x->pvf($field)->widget( 'HTML',
'edit',
- $svc_x->getfield($field)
+ $svc_x->getfield($field),
+ 'TH'
);
}
}
diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi
index e3fa4e6f8..d277e17b1 100755
--- a/httemplate/edit/process/cust_main.cgi
+++ b/httemplate/edit/process/cust_main.cgi
@@ -113,6 +113,11 @@ my $new = new FS::cust_main ( {
$new->invoice_noemail( ($cgi->param('invoice_email') eq 'Y') ? '' : 'Y' );
+# add any virtual fields to the new cust_main record
+foreach ($new->virtual_fields) {
+ $new->setfield($_, scalar($cgi->param($_)));
+}
+
if ( $duplicate_of ) {
# then negate all changes to the customer; the only change we should
# make is to order a package, if requested
diff --git a/httemplate/edit/process/part_virtual_field.html b/httemplate/edit/process/part_virtual_field.html
index e734d9616..6a8008db7 100644
--- a/httemplate/edit/process/part_virtual_field.html
+++ b/httemplate/edit/process/part_virtual_field.html
@@ -42,6 +42,9 @@
my $act = 'add';
+## make cgi->param("name") lowercase
+$cgi->param('name' => lc $cgi->param('name'));
+
die "access denied"
unless $FS::CurrentUser::CurrentUser->access_right('Configuration');