+# 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
+ # make is to order a package, if requested
+ $new = qsearchs('cust_main', { 'custnum' => $duplicate_of })
+ # this should never happen
+ or die "nonexistent existing customer (custnum $duplicate_of)";
+}
+
+for my $pre (qw(bill ship)) {
+ $new->set($pre.'_location', $locations{$pre});
+ $new->set($pre.'_locationnum', $locations{$pre}->locationnum);
+}
+
+if ( $cgi->param('no_credit_limit') ) {
+ $new->setfield('credit_limit', '');
+}
+
+#$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 );
+
+my %usedatetime = ( 'birthdate' => 1,
+ 'spouse_birthdate' => 1,
+ 'anniversary_date' => 1,
+ );
+
+foreach my $dfield (qw(
+ signupdate birthdate spouse_birthdate anniversary_date
+)) {
+
+ if ( $cgi->param($dfield) && $cgi->param($dfield) =~ /^([ 0-9\-\/]{0,10})$/) {
+
+ my $value = $1;
+ my $parsed = '';
+
+ if ( exists $usedatetime{$dfield} && $usedatetime{$dfield} ) {
+
+ my $format = $conf->config('date_format') || "%m/%d/%Y";
+ my $parser = DateTime::Format::Strptime->new( pattern => $format,
+ time_zone => 'floating',
+ );
+ my $dt = $parser->parse_datetime($value);
+ if ( $dt ) {
+ $parsed = $dt->epoch;
+ } else {
+ $error ||= "Invalid $dfield: $value";
+ }
+
+ } else {
+
+ $parsed = parse_datetime($value)
+ or $error ||= "Invalid $dfield: $value";
+
+ }
+
+ $new->setfield( $dfield, $parsed );
+ $cgi->param( $dfield, $parsed );
+
+ }
+
+}
+
+$new->setfield('paid', $cgi->param('paid') )
+ if $cgi->param('paid');
+
+my %options = ();
+if ( $curuser->access_right('Edit customer tax exemptions') ) {
+ my @exempt_groups = grep /\S/, $conf->config('tax-cust_exempt-groups');
+ my @tax_exempt = grep { $cgi->param("tax_$_") eq 'Y' } @exempt_groups;
+ $options{'tax_exemption'} = {
+ map { $_ => scalar($cgi->param("tax_$_".'_num')) } @tax_exempt
+ };
+}
+
+$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';
+ }