RT# 82092 - custom fields now save and fixed so name label is displayed insted of...
authorChristopher Burger <burgerc@freeside.biz>
Tue, 19 Feb 2019 19:42:25 +0000 (14:42 -0500)
committerChristopher Burger <burgerc@freeside.biz>
Tue, 19 Feb 2019 19:42:25 +0000 (14:42 -0500)
FS/FS/Record.pm
FS/FS/part_svc.pm
FS/FS/part_virtual_field.pm
httemplate/browse/router.cgi
httemplate/edit/cust_main/basics.html
httemplate/edit/elements/part_svc_column.html
httemplate/edit/elements/svc_Common.html
httemplate/edit/process/cust_main.cgi
httemplate/edit/process/part_virtual_field.html
httemplate/view/cust_main/misc.html

index b24b69e..f4bf2a2 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 use charnames ':full';
 use vars qw( $AUTOLOAD
              %virtual_fields_cache %fk_method_cache $fk_table_cache
-             $money_char $lat_lower $lon_upper
+             %virtual_fields_hash_cache $money_char $lat_lower $lon_upper
              $use_placeholders
            );
 use Carp qw(carp cluck croak confess);
@@ -1811,6 +1811,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
index 49854f7..a565ee4 100644 (file)
@@ -707,6 +707,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;
 
       # all svc_* modules are required to have h_svc_* modules for invoice
index 0011ec6..63712b7 100755 (executable)
@@ -59,6 +59,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 ]
 
@@ -81,19 +82,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!"!;
index 85512f8..c7713f3 100644 (file)
@@ -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',
index 97313aa..b45523f 100644 (file)
 </SCRIPT>
 
 % foreach my $field ($cust_main->virtual_fields) {
-    <% $cust_main->pvf($field)->widget('HTML', 'edit',$cust_main->getfield($field)) %>
+    <% $cust_main->pvf($field)->widget('HTML', 'edit',$cust_main->getfield($field), 'TH') %>
 % }
 
 %# tags
index bdbce7c..075f15e 100644 (file)
@@ -97,7 +97,7 @@ my %communigate_fields = (
     <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">
index e1c3090..e5dc559 100644 (file)
                        $html .=
                          $svc_x->pvf($field)->widget( 'HTML',
                                                       'edit', 
-                                                      $svc_x->getfield($field)
+                                                      $svc_x->getfield($field),
+                                                      'TH'
                                                     );
                      }
                    }
index e1a5bc6..baacd5e 100755 (executable)
@@ -97,6 +97,11 @@ my $new = new FS::cust_main ( {
   (map { ( "ship_$_", '' ) } (FS::cust_main->location_fields))
 } );
 
+# add any virtual fields to the new cust_main record
+foreach ($new->virtual_fields) {
+  $new->setfield($_, scalar($cgi->param($_)));
+}
+
 warn Dumper( $new ) if $DEBUG > 1;
 
 if ( $duplicate_of ) {
index e734d96..6a8008d 100644 (file)
@@ -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');
 
index cb465f5..d2deae2 100644 (file)
 % }
 
 % foreach (sort { $a cmp $b } $cust_main->virtual_fields) {
-    <% $cust_main->pvf($_)->widget('HTML', 'view', $cust_main->getfield($_)) %>
+    <% $cust_main->pvf($_)->widget('HTML', 'view', $cust_main->getfield($_), 'TH') %>
 % }
 
 </TABLE>