FS RT #27208 - adding Mobile phone to FS::ConfDefaults::cust_fields_avail and related...
[freeside.git] / FS / FS / UI / Web.pm
index 91d2034..fba4a45 100644 (file)
@@ -6,7 +6,7 @@ use Exporter;
 use Carp qw( confess );
 use HTML::Entities;
 use FS::Conf;
 use Carp qw( confess );
 use HTML::Entities;
 use FS::Conf;
-use FS::Misc::DateTime qw( parse_datetime );
+use FS::Misc::DateTime qw( parse_datetime day_end );
 use FS::Record qw(dbdef);
 use FS::cust_main;  # are sql_balance and sql_date_balance in the right module?
 
 use FS::Record qw(dbdef);
 use FS::cust_main;  # are sql_balance and sql_date_balance in the right module?
 
@@ -32,16 +32,16 @@ sub parse_beginning_ending {
   my $beginning = 0;
   if ( $cgi->param($prefix.'begin') =~ /^(\d+)$/ ) {
     $beginning = $1;
   my $beginning = 0;
   if ( $cgi->param($prefix.'begin') =~ /^(\d+)$/ ) {
     $beginning = $1;
-  } elsif ( $cgi->param($prefix.'beginning') =~ /^([ 0-9\-\/]{1,64})$/ ) {
+  } elsif ( $cgi->param($prefix.'beginning') =~ /^([ 0-9\-\/\:]{1,64})$/ ) {
     $beginning = parse_datetime($1) || 0;
   }
 
   my $ending = 4294967295; #2^32-1
   if ( $cgi->param($prefix.'end') =~ /^(\d+)$/ ) {
     $ending = $1 - 1;
     $beginning = parse_datetime($1) || 0;
   }
 
   my $ending = 4294967295; #2^32-1
   if ( $cgi->param($prefix.'end') =~ /^(\d+)$/ ) {
     $ending = $1 - 1;
-  } elsif ( $cgi->param($prefix.'ending') =~ /^([ 0-9\-\/]{1,64})$/ ) {
-    #probably need an option to turn off the + 86399
-    $ending = parse_datetime($1) + 86399;
+  } elsif ( $cgi->param($prefix.'ending') =~ /^([ 0-9\-\/\:]{1,64})$/ ) {
+    $ending = parse_datetime($1);
+    $ending = day_end($ending) unless $ending =~ /:/;
   }
 
   ( $beginning, $ending );
   }
 
   ( $beginning, $ending );
@@ -229,39 +229,41 @@ sub cust_header {
     'Cust#'                    => 'custnum',
     'Name'                     => 'contact',
     'Company'                  => 'company',
     'Cust#'                    => 'custnum',
     'Name'                     => 'contact',
     'Company'                  => 'company',
+
+    # obsolete but might still be referenced in configuration
     '(bill) Customer'          => 'name',
     '(service) Customer'       => 'ship_name',
     '(bill) Name'              => 'contact',
     '(service) Name'           => 'ship_contact',
     '(bill) Company'           => 'company',
     '(service) Company'        => 'ship_company',
     '(bill) Customer'          => 'name',
     '(service) Customer'       => 'ship_name',
     '(bill) Name'              => 'contact',
     '(service) Name'           => 'ship_contact',
     '(bill) Company'           => 'company',
     '(service) Company'        => 'ship_company',
+    '(bill) Day phone'         => 'daytime',
+    '(bill) Night phone'       => 'night',
+    '(bill) Fax number'        => 'fax',
+    'Customer'                 => 'name',
     'Address 1'                => 'bill_address1',
     'Address 2'                => 'bill_address2',
     'City'                     => 'bill_city',
     'State'                    => 'bill_state',
     'Zip'                      => 'bill_zip',
     'Address 1'                => 'bill_address1',
     'Address 2'                => 'bill_address2',
     'City'                     => 'bill_city',
     'State'                    => 'bill_state',
     'Zip'                      => 'bill_zip',
-    'Country'                  => 'country_full',
+    'Country'                  => 'bill_country_full',
     'Day phone'                => 'daytime', # XXX should use msgcat, but how?
     'Night phone'              => 'night',   # XXX should use msgcat, but how?
     'Day phone'                => 'daytime', # XXX should use msgcat, but how?
     'Night phone'              => 'night',   # XXX should use msgcat, but how?
+    'Mobile phone'             => 'mobile',  # XXX should use msgcat, but how?
     'Fax number'               => 'fax',
     '(bill) Address 1'         => 'bill_address1',
     '(bill) Address 2'         => 'bill_address2',
     '(bill) City'              => 'bill_city',
     '(bill) State'             => 'bill_state',
     '(bill) Zip'               => 'bill_zip',
     'Fax number'               => 'fax',
     '(bill) Address 1'         => 'bill_address1',
     '(bill) Address 2'         => 'bill_address2',
     '(bill) City'              => 'bill_city',
     '(bill) State'             => 'bill_state',
     '(bill) Zip'               => 'bill_zip',
-    '(bill) Country'           => 'country_full',
-    '(bill) Day phone'         => 'daytime', # XXX should use msgcat, but how?
-    '(bill) Night phone'       => 'night',   # XXX should use msgcat, but how?
-    '(bill) Fax number'        => 'fax',
+    '(bill) Country'           => 'bill_country_full',
     '(service) Address 1'      => 'ship_address1',
     '(service) Address 2'      => 'ship_address2',
     '(service) City'           => 'ship_city',
     '(service) State'          => 'ship_state',
     '(service) Zip'            => 'ship_zip',
     '(service) Country'        => 'ship_country_full',
     '(service) Address 1'      => 'ship_address1',
     '(service) Address 2'      => 'ship_address2',
     '(service) City'           => 'ship_city',
     '(service) State'          => 'ship_state',
     '(service) Zip'            => 'ship_zip',
     '(service) Country'        => 'ship_country_full',
-    '(service) Day phone'      => 'ship_daytime', # XXX should use msgcat, how?
-    '(service) Night phone'    => 'ship_night',   # XXX should use msgcat, how?
-    '(service) Fax number'     => 'ship_fax',
     'Invoicing email(s)'       => 'invoicing_list_emailonly_scalar',
     'Payment Type'             => 'payby',
     'Current Balance'          => 'current_balance',
     'Invoicing email(s)'       => 'invoicing_list_emailonly_scalar',
     'Payment Type'             => 'payby',
     'Current Balance'          => 'current_balance',
@@ -322,6 +324,14 @@ sub cust_header {
   @cust_header;
 }
 
   @cust_header;
 }
 
+sub cust_sort_fields {
+  cust_header(@_);
+  #inefficientish, but tiny lists and only run once per page
+
+  map { $_ eq 'custnum' ? 'custnum' : '' } @cust_fields;
+
+}
+
 =item cust_sql_fields [ CUST_FIELDS_VALUE ]
 
 Returns a list of fields for the SELECT portion of an SQL query.
 =item cust_sql_fields [ CUST_FIELDS_VALUE ]
 
 Returns a list of fields for the SELECT portion of an SQL query.
@@ -348,8 +358,15 @@ sub cust_sql_fields {
       }
     }
   }
       }
     }
   }
-  
-  push @fields, 'payby' if grep { $_ eq 'payby'} @cust_fields;
+  foreach my $pre ('bill_','ship_') {
+    if ( grep { $_ eq $pre.'country_full' } @cust_fields ) {
+      push @location_fields, $pre.'locationnum';
+    }
+  }
+
+  foreach my $field (qw(daytime night mobile fax payby)) {
+    push @fields, $field if (grep { $_ eq $field } @cust_fields);
+  }
   push @fields, 'agent_custid';
 
   my @extra_fields = ();
   push @fields, 'agent_custid';
 
   my @extra_fields = ();
@@ -378,6 +395,9 @@ Otherwise, this function will assume the field is named "custnum".  If the
 argument isn't present at all, the join will just say "USING (custnum)", 
 which might work.
 
 argument isn't present at all, the join will just say "USING (custnum)", 
 which might work.
 
+As a special case, if TABLE is 'cust_main', only the joins to cust_location
+will be returned.
+
 LOCATION_TABLE is an optional table name to use for joining ship_location,
 in case your query also includes package information and you want the 
 "service address" columns to reflect package addresses.
 LOCATION_TABLE is an optional table name to use for joining ship_location,
 in case your query also includes package information and you want the 
 "service address" columns to reflect package addresses.
@@ -392,11 +412,12 @@ sub join_cust_main {
   ($location_table, $locationnum) = split(/\./, $location_table);
   $locationnum ||= 'locationnum';
 
   ($location_table, $locationnum) = split(/\./, $location_table);
   $locationnum ||= 'locationnum';
 
-  my $sql = ' LEFT JOIN cust_main ';
+  my $sql = '';
   if ( $cust_table ) {
   if ( $cust_table ) {
-    $sql .= "ON (cust_main.custnum = $cust_table.$custnum)";
+    $sql = " LEFT JOIN cust_main ON (cust_main.custnum = $cust_table.$custnum)"
+      unless $cust_table eq 'cust_main';
   } else {
   } else {
-    $sql .= "USING (custnum)";
+    $sql = " LEFT JOIN cust_main USING (custnum)";
   }
 
   if ( !@cust_fields or grep /^bill_/, @cust_fields ) {
   }
 
   if ( !@cust_fields or grep /^bill_/, @cust_fields ) {
@@ -468,23 +489,26 @@ sub cust_fields_subs {
   my $unlinked_warn = 0;
   return map { 
     my $f = $_;
   my $unlinked_warn = 0;
   return map { 
     my $f = $_;
-    if( $unlinked_warn++ ) {
+    if ( $unlinked_warn++ ) {
+
       sub {
         my $record = shift;
       sub {
         my $record = shift;
-        if( $record->custnum ) {
-          $record->$f(@_);
-        }
-        else {
+        if ( $record->custnum ) {
+          encode_entities( $record->$f(@_) );
+        } else {
           '(unlinked)'
         };
           '(unlinked)'
         };
-      }
-    } 
-    else {
+      };
+
+    } else {
+
       sub {
         my $record = shift;
       sub {
         my $record = shift;
-        $record->$f(@_) if $record->custnum;
-      }
+        $record->custnum ? encode_entities( $record->$f(@_) ) : '';
+      };
+
     }
     }
+
   } @cust_fields;
 }
 
   } @cust_fields;
 }
 
@@ -574,7 +598,7 @@ use vars qw($DEBUG);
 use Carp;
 use Storable qw(nfreeze);
 use MIME::Base64;
 use Carp;
 use Storable qw(nfreeze);
 use MIME::Base64;
-use JSON;
+use JSON::XS;
 use FS::UID qw(getotaker);
 use FS::Record qw(qsearchs);
 use FS::queue;
 use FS::UID qw(getotaker);
 use FS::Record qw(qsearchs);
 use FS::queue;
@@ -671,6 +695,10 @@ sub start_job {
   
   #warn 'froze string of size '. length(nfreeze(\%param)). " for job args\n"
   #  if $DEBUG;
   
   #warn 'froze string of size '. length(nfreeze(\%param)). " for job args\n"
   #  if $DEBUG;
+  #
+  #  XXX FS::queue::insert knows how to do this.
+  #  not changing it here because that requires changing it everywhere else,
+  #  too, but we should eventually fix it
 
   my $error = $job->insert( '_JOB', encode_base64(nfreeze(\%param)) );
 
 
   my $error = $job->insert( '_JOB', encode_base64(nfreeze(\%param)) );
 
@@ -719,10 +747,7 @@ sub job_status {
     @return = ( 'error', $job ? $job->statustext : $jobnum );
   }
 
     @return = ( 'error', $job ? $job->statustext : $jobnum );
   }
 
-  #to_json(\@return);  #waiting on deb 5.0 for new JSON.pm?
-  #silence the warning though
-  my $to_json = JSON->can('to_json') || JSON->can('objToJson');
-  &$to_json(\@return);
+  encode_json \@return;
 
 }
 
 
 }