RT# 82949 - changes section name from fees to pricing, better opiton
[freeside.git] / httemplate / edit / process / cust_main.cgi
index ff8be1a..baacd5e 100755 (executable)
@@ -1,11 +1,28 @@
 % if ( $error ) {
 %   $cgi->param('error', $error);
-%
-<% $cgi->redirect(popurl(2). "cust_main.cgi?". $cgi->query_string ) %>
+%   # workaround for create_uri_query's mangling of unicode characters,
+%   # false laziness with FS::Record::ut_coord
+%   use charnames ':full';
+%   for my $pre (qw(bill ship)) {
+%     foreach (qw( latitude longitude)) {
+%       my $coord = $cgi->param($pre.'_'.$_);
+%       $coord =~ s/\N{DEGREE SIGN}\s*$//;
+%       $cgi->param($pre.'_'.$_, $coord);
+%     }
+%   }
+%   my $query = $m->scomp('/elements/create_uri_query', 'secure'=>1);
+<% $cgi->redirect(popurl(2). "cust_main.cgi?$query" ) %>
 %
 % } else { 
 %
-<% $cgi->redirect(popurl(3). "view/cust_main.cgi?". $new->custnum) %>
+<% $cgi->redirect( -uri    => popurl(3). "view/cust_main.cgi?". $new->custnum,
+                   -cookie => CGI::Cookie->new(
+                     -name    => 'freeside_status',
+                     -value   => mt($freeside_status),
+                     -expires => '+5m',
+                   ),
+   )
+%>
 %
 % }
 <%once>
@@ -29,36 +46,18 @@ $cgi->param('tax','') unless defined $cgi->param('tax');
 
 $cgi->param('refnum', (split(/:/, ($cgi->param('refnum'))[0] ))[0] );
 
-my $payby = $cgi->param('payby');
-
-my %noauto = (
-  'CARD' => 'DCRD',
-  'CHEK' => 'DCHK',
-);
-$payby = $noauto{$payby}
-  if ! $cgi->param('payauto') && exists $noauto{$payby};
-
-$cgi->param('payby', $payby);
-
-if ( $payby ) {
-  if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
-      my $payinfo = $cgi->param('payinfo1'). '@';
-      $payinfo .= $cgi->param('payinfo3').'.' 
-            if $conf->config('echeck-country') eq 'CA';
-      $payinfo .= $cgi->param('payinfo2');
-      $cgi->param('payinfo',$payinfo);
-  }
-  $cgi->param('paydate',
-    $cgi->param( 'exp_month' ). '-'. $cgi->param( 'exp_year' ) );
-}
+#my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') );
+#push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
+#push @invoicing_list, 'FAX' if $cgi->param('invoicing_list_FAX');
+#$cgi->param('invoicing_list', join(',', @invoicing_list) );
 
-my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') );
-push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
-push @invoicing_list, 'FAX' if $cgi->param('invoicing_list_FAX');
-$cgi->param('invoicing_list', join(',', @invoicing_list) );
+my $agentnum = $cgi->param('agentnum');
 
 # is this actually used?  if so, we need to clone locations...
 # but I can't find anything that sets this parameter to a non-empty value
+# yes, fec48523d3cf056da08813f9b2b7d633b27aaf8d for #16582 is where it came in,
+# for "duplicate address checking for new customers".  afaict still in
+# edit/cust_main/bottomfixup.html (and working?)
 $cgi->param('duplicate_of_custnum') =~ /^(\d+)$/;
 my $duplicate_of = $1;
 
@@ -94,11 +93,16 @@ if ( ($cgi->param('same') || '') eq 'Y' ) {
 # but explicitly avoid setting ship_ fields
 
 my $new = new FS::cust_main ( {
-  map { ( $_, scalar($cgi->param($_)) ) } (fields('cust_main')),
-  map { ( "ship_$_", '' ) } (FS::cust_main->location_fields)
+  (map { ( $_, scalar($cgi->param($_)) ) } (fields('cust_main'))),
+  (map { ( "ship_$_", '' ) } (FS::cust_main->location_fields))
 } );
 
-$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($_)));
+}
+
+warn Dumper( $new ) if $DEBUG > 1;
 
 if ( $duplicate_of ) {
   # then negate all changes to the customer; the only change we should
@@ -117,7 +121,12 @@ if ( $cgi->param('no_credit_limit') ) {
   $new->setfield('credit_limit', '');
 }
 
-$new->tagnum( [ $cgi->param('tagnum') ] );
+#$new->tagnum( [ $cgi->param('tagnum') ] );
+my $params = $cgi->Vars;
+$new->tagnum( [
+  map { /^tagnum(\d+)/ && $1 }
+    grep { /^tagnum(\d+)/ && $cgi->param($_) } keys %$params
+] );
 
 $error ||= $new->set_national_id_from_cgi( $cgi );
 
@@ -174,9 +183,53 @@ if ( $curuser->access_right('Edit customer tax exemptions') ) {
   };
 }
 
+$options{'cust_payby_params'} = scalar($cgi->Vars);
+
+if ( $cgi->param('residential_commercial') eq 'Residential' ) {
+
+  my $email = $cgi->param('invoice_email') || '';
+  if ( length($email) == 0 and $conf->exists('cust_main-require_invoicing_list_email', $agentnum) ) {
+    $error = 'Email address required';
+  }
+
+  $options{'invoicing_list'} = [ split(/[,\s]+/, $email) ];
+  # XXX really should include the phone numbers in here also
+
+} else {
+
+  # contact UI is enabled
+  $options{'contact_params'} = scalar($cgi->Vars);
+
+  if ($conf->exists('cust_main-require_invoicing_list_email', $agentnum)) {
+    my $has_email = 0;
+    foreach my $prefix (grep /^contactnum\d+$/, $cgi->param) {
+      if ( length($cgi->param($prefix . '_emailaddress'))
+           and $cgi->param($prefix . '_invoice_dest') ) {
+        $has_email = 1;
+        last;
+      }
+    }
+    $error = "At least one contact must receive email invoices"
+      unless $has_email;
+  }
+
+}
+
+# kind of a hack, but some tax data vendors require a status and others
+# don't.
+my $vendor = $conf->config('tax_data_vendor');
+if ( $vendor eq 'avalara' or $vendor eq 'suretax' ) {
+  if ( ! $cgi->param('taxstatusnum') ) {
+    $error ||= 'Tax status required';
+  }
+}
+
 #perhaps this stuff should go to cust_main.pm
+my $freeside_status = '';
 if ( $new->custnum eq '' or $duplicate_of ) {
 
+  $freeside_status = 'Customer added';
+
   my $cust_pkg = '';
   my $svc;
 
@@ -280,7 +333,7 @@ if ( $new->custnum eq '' or $duplicate_of ) {
   }
   else {
     # create the customer
-    $error ||= $new->insert( \%hash, \@invoicing_list,
+    $error ||= $new->insert( \%hash,
                              %options,
                              prospectnum => scalar($cgi->param('prospectnum')),
                            );
@@ -298,69 +351,34 @@ if ( $new->custnum eq '' or $duplicate_of ) {
   
 } else { #create old record object
 
+  $freeside_status = 'Customer edited';
+
   my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } ); 
   $error ||= "Old record not found!" unless $old;
 
-  if ( length($old->paycvv) && $new->paycvv =~ /^\s*\*+\s*$/ ) {
-    $new->paycvv($old->paycvv);
-  }
   if ($new->ss =~ /xx/) {
     $new->ss($old->ss);
   }
   if ($new->stateid =~ /^xxx/) {
     $new->stateid($old->stateid);
   }
-  if ( $new->payby =~ /^(CARD|DCRD)$/
-       && (    $new->payinfo =~ /xx/
-            || $new->payinfo =~ /^\s*N\/A\s+\(tokenized\)\s*$/
-          )
-     )
-  {
-    $new->payinfo($old->payinfo);
-
-  } elsif ( $new->payby =~ /^(CHEK|DCHK)$/ && $new->payinfo =~ /xx/ ) {
-    #fix for #3085 "edit of customer's routing code only surprisingly causes
-    #nothing to happen...
-    # this probably won't do the right thing when we don't have the
-    # public key (can't actually get the real $old->payinfo)
-    my($new_account, $new_aba) = split('@', $new->payinfo);
-    my($old_account, $old_aba) = split('@', $old->payinfo);
-    $new_account = $old_account if $new_account =~ /xx/;
-    $new_aba     = $old_aba     if $new_aba     =~ /xx/;
-    $new->payinfo($new_account.'@'.$new_aba);
-  }
 
   if ( ! $conf->exists('cust_main-edit_signupdate') or
        ! $new->signupdate ) {
     $new->signupdate($old->signupdate);
   }
 
-  warn "$me calling $new -> replace( $old, \ @invoicing_list )" if $DEBUG;
+  warn "$me calling $new -> replace( $old )" if $DEBUG;
   local($FS::cust_main::DEBUG) = $DEBUG if $DEBUG;
   local($FS::Record::DEBUG)    = $DEBUG if $DEBUG;
 
   local($Data::Dumper::Sortkeys) = 1;
-  warn Dumper({ new => $new, old => $old }) if $DEBUG;
+  warn Dumper({ new => $new, old => $old, options => \%options}) if $DEBUG;
 
-  $error ||= $new->replace( $old, \@invoicing_list,
-                            %options,
-                          );
+  $error ||= $new->replace( $old, %options );
 
   warn "$me returned from replace" if $DEBUG;
   
 }
 
-unless ( $error ) { #XXX i guess i should be transactional... all in the insert
-                    # or replace call
-  my @contact_fields = qw( classnum first last title comment emailaddress );
-  foreach my $phone_type ( qsearch({table=>'phone_type', order_by=>'weight'}) ) {
-    push @contact_fields, 'phonetypenum'.$phone_type->phonetypenum;
-  }
-
-  $error = $new->process_o2m( 'table'  => 'contact',
-                              'fields' => \@contact_fields,
-                              'params' => scalar($cgi->Vars),
-                            );
-}
-
 </%init>