Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / UI / Web.pm
index ccba1de..6655f27 100644 (file)
@@ -113,16 +113,16 @@ sub svc_url {
     if $DEBUG;
   if ( $opt{m}->interp->comp_exists("/$opt{action}/$svcdb.cgi") ) {
     $url = "$svcdb.cgi?";
+  } elsif ( $opt{m}->interp->comp_exists("/$opt{action}/$svcdb.html") ) {
+    $url = "$svcdb.html?";
   } else {
-
     my $generic = $opt{action} eq 'search' ? 'cust_svc' : 'svc_Common';
 
     $url = "$generic.html?svcdb=$svcdb;";
     $url .= 'svcnum=' if $query =~ /^\d+(;|$)/ or $query eq '';
   }
 
-  import FS::CGI 'rooturl'; #WTF!  why is this necessary
-  my $return = rooturl(). "$opt{action}/$url$query";
+  my $return = FS::CGI::rooturl(). "$opt{action}/$url$query";
 
   $return = qq!<A HREF="$return">! if $opt{ahref};
 
@@ -170,7 +170,8 @@ sub svc_export_links {
 }
 
 sub parse_lt_gt {
-  my($cgi, $field) = @_;
+  my($cgi, $field) = (shift, shift);
+  my $table = ( @_ && length($_[0]) ) ? shift.'.' : '';
 
   my @search = ();
 
@@ -188,7 +189,7 @@ sub parse_lt_gt {
 
       my $num = $1;
       $num =~ s/[\,\s]+//g;
-      my $search = "$field $op{$op} $num";
+      my $search = "$table$field $op{$op} $num";
       push @search, $search;
 
       warn "found ${field}_$op field; adding search element $search\n"
@@ -205,6 +206,7 @@ sub parse_lt_gt {
 # cust_main report subroutines
 ###
 
+=over 4
 
 =item cust_header [ CUST_FIELDS_VALUE ]
 
@@ -225,46 +227,53 @@ sub cust_header {
 
   my %header2method = (
     'Customer'                 => 'name',
-    'Cust. Status'             => 'ucfirst_cust_status',
+    'Cust. Status'             => 'cust_status_label',
     '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) 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',
-    '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?
+    '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',
-    '(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',
+    '(bill) Latitude'          => 'bill_latitude',
+    '(bill) Longitude'         => 'bill_longitude',
     '(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',
+    '(service) Latitude'       => 'ship_latitude',
+    '(service) Longitude'      => 'ship_longitude',
     'Invoicing email(s)'       => 'invoicing_list_emailonly_scalar',
     'Payment Type'             => 'payby',
     'Current Balance'          => 'current_balance',
+    'Agent Cust#'              => 'agent_custid',
   );
   $header2method{'Cust#'} = 'display_custnum'
     if $conf->exists('cust_main-default_agent_custid');
@@ -322,6 +331,14 @@ sub cust_header {
   @cust_header;
 }
 
+sub cust_sort_fields {
+  cust_header(@_) if( @_ or !@cust_fields );
+  #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.
@@ -337,19 +354,26 @@ sub cust_sql_fields {
   my @fields = qw( last first company );
 #  push @fields, map "ship_$_", @fields;
 
-  cust_header(@_);
+  cust_header(@_) if( @_ or !@cust_fields );
   #inefficientish, but tiny lists and only run once per page
 
   my @location_fields;
-  foreach my $field (qw( address1 address2 city state zip )) {
+  foreach my $field (qw( address1 address2 city state zip latitude longitude )) {
     foreach my $pre ('bill_','ship_') {
       if ( grep { $_ eq $pre.$field } @cust_fields ) {
         push @location_fields, $pre.'location.'.$field.' AS '.$pre.$field;
       }
     }
   }
-  
-  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 = ();
@@ -470,6 +494,7 @@ element.
 
 sub cust_fields_subs {
   my $unlinked_warn = 0;
+
   return map { 
     my $f = $_;
     if ( $unlinked_warn++ ) {
@@ -556,6 +581,19 @@ sub cust_aligns {
   }
 }
 
+=item cust_links
+
+Returns an array of links to view/cust_main.cgi, for use with cust_fields.
+
+=cut
+
+sub cust_links {
+  my $link = [ FS::CGI::rooturl().'view/cust_main.cgi?', 'custnum' ];
+
+  return map { $_ eq 'cust_status_label' ? '' : $link }
+    @cust_fields;
+}
+
 =item is_mobile
 
 Utility function to determine if the client is a mobile browser.
@@ -569,7 +607,11 @@ sub is_mobile {
   }
   return 0;
 }
-    
+
+=back
+
+=cut
+
 ###
 # begin JSRPC code...
 ###
@@ -676,14 +718,9 @@ sub start_job {
   #too slow to insert all the cgi params as individual args..,?
   #my $error = $queue->insert('_JOB', $cgi->Vars);
   
-  #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
+  #rely on FS::queue smartness to freeze/encode the param hash
 
-  my $error = $job->insert( '_JOB', encode_base64(nfreeze(\%param)) );
+  my $error = $job->insert( '_JOB', \%param );
 
   if ( $error ) {