X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_main.pm;h=8e098488290cf1c40cdfd511d2c4d5f873550dd4;hb=5d089cbe4980f7c9c25b83e164099b22bc59eead;hp=ee70deaa610bdf059fd4c585128f0d69a2bb4037;hpb=768ab093771b3305a67c9d929b461ef777ecdad8;p=freeside.git diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index ee70deaa6..8e0984882 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -31,7 +31,7 @@ use Business::CreditCard 0.28; use FS::UID qw( dbh driver_name ); use FS::Record qw( qsearchs qsearch dbdef regexp_sql ); use FS::Cursor; -use FS::Misc qw( generate_ps do_print money_pretty ); +use FS::Misc qw( generate_ps do_print money_pretty card_types ); use FS::Msgcat qw(gettext); use FS::CurrentUser; use FS::TicketSystem; @@ -468,7 +468,8 @@ sub insert { $self->auto_agent_custid() if $conf->config('cust_main-auto_agent_custid') && ! $self->agent_custid; - my $error = $self->SUPER::insert; + my $error = $self->check_payinfo_cardtype + || $self->SUPER::insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; #return "inserting cust_main record (transaction rolled back): $error"; @@ -1354,6 +1355,14 @@ sub replace { || $old->payby =~ /^(CHEK|DCHK)$/ && $self->payby =~ /^(CHEK|DCHK)$/ ) && ( $old->payinfo eq $self->payinfo || $old->paymask eq $self->paymask ); + if ( $self->payby =~ /^(CARD|DCRD)$/ + && $old->payinfo ne $self->payinfo + && $old->paymask ne $self->paymask ) + { + my $error = $self->check_payinfo_cardtype; + return $error if $error; + } + return "Invoicing locale is required" if $old->locale && ! $self->locale @@ -2092,6 +2101,25 @@ sub check { $self->SUPER::check; } +sub check_payinfo_cardtype { + my $self = shift; + + return '' unless $self->payby =~ /^(CARD|CHEK)$/; + + my $payinfo = $self->payinfo; + $payinfo =~ s/\D//g; + + return '' if $payinfo =~ /^99\d{14}$/; #token + + my %bop_card_types = map { $_=>1 } values %{ card_types() }; + my $cardtype = cardtype($payinfo); + + return "$cardtype not accepted" unless $bop_card_types{$cardtype}; + + ''; + +} + =item replace_check Additional checks for replace only. @@ -2174,7 +2202,7 @@ sub cust_contact { Returns all payment methods (see L) for this customer. If one or more PAYBY are specified, returns only payment methods for specified PAYBY. -Does not validate PAYBY--do not pass tainted values. +Does not validate PAYBY. =cut @@ -2186,7 +2214,7 @@ sub cust_payby { 'hashref' => { 'custnum' => $self->custnum }, 'order_by' => "ORDER BY payby IN ('CARD','CHEK') DESC, weight ASC", }; - $search->{'extra_sql'} = ' AND payby IN ( ' . join(',', map { "'$_'" } @payby) . ' ) ' + $search->{'extra_sql'} = ' AND payby IN ( ' . join(',', map { dbh->quote($_) } @payby) . ' ) ' if @payby; qsearch($search); @@ -4407,8 +4435,10 @@ sub payment_history { Saves a new cust_payby for this customer, replacing an existing entry only in select circumstances. Does not validate input. -If auto is specified, marks this as the customer's primary method (weight 1) -and changes existing primary methods for that payby to secondary methods (weight 2.) +If auto is specified, marks this as the customer's primary method, or the +specified weight. Existing payment methods have their weight incremented as +appropriate. + If bill_location is specified with auto, also sets location in cust_main. Will not insert complete duplicates of existing records, or records in which the @@ -4420,39 +4450,77 @@ blanks when replacing. Accepts the following named parameters: -payment_payby - either CARD or CHEK +=over 4 + +=item payment_payby + +either CARD or CHEK + +=item auto + +save as an automatic payment type (CARD/CHEK if true, DCRD/DCHK if false) + +=item weight + +optional, set higher than 1 for secondary, etc. + +=item payinfo + +required -auto - save as an automatic payment type (CARD/CHEK if true, DCRD/DCHK if false) +=item paymask -payinfo - required +optional, but should be specified for anything that might be tokenized, will be preserved when replacing -paymask - optional, but should be specified for anything that might be tokenized, will be preserved when replacing +=item payname -payname - required +required -payip - optional, will be preserved when replacing +=item payip -paydate - CARD only, required +optional, will be preserved when replacing -bill_location - CARD only, required, FS::cust_location object +=item paydate -paystart_month - CARD only, optional, will be preserved when replacing +CARD only, required -paystart_year - CARD only, optional, will be preserved when replacing +=item bill_location -payissue - CARD only, optional, will be preserved when replacing +CARD only, required, FS::cust_location object -paycvv - CARD only, only used if conf cvv-save is set appropriately +=item paystart_month -paytype - CHEK only +CARD only, optional, will be preserved when replacing -paystate - CHEK only +=item paystart_year + +CARD only, optional, will be preserved when replacing + +=item payissue + +CARD only, optional, will be preserved when replacing + +=item paycvv + +CARD only, only used if conf cvv-save is set appropriately + +=item paytype + +CHEK only + +=item paystate + +CHEK only + +=back =cut #The code for this option is in place, but it's not currently used # -# replace - existing cust_payby object to be replaced (must match custnum) +# =item replace +# +# existing cust_payby object to be replaced (must match custnum) # stateid/stateid_state/ss are not currently supported in cust_payby, # might not even work properly in 4.x, but will need to work here if ever added @@ -4483,8 +4551,7 @@ sub save_cust_payby { @check_existing = qw( CHEK DCHK ); } - # every automatic payment type added here will be marked primary - $new->set( 'weight' => $opt{'auto'} ? 1 : '' ); + $new->set( 'weight' => $opt{'auto'} ? $opt{'weight'} : '' ); # basic fields $new->payinfo($opt{'payinfo'}); # sets default paymask, but not if it's already tokenized @@ -4578,7 +4645,7 @@ PAYBYLOOP: # if we got this far, we're definitely replacing $old = $cust_payby; last PAYBYLOOP; - } + } #PAYBYLOOP } if ($old) { @@ -4621,7 +4688,8 @@ PAYBYLOOP: last unless $cust_payby->payby !~ /^D/; last if $cust_payby->weight > 1; next if $new->custpaybynum eq $cust_payby->custpaybynum; - $cust_payby->set( 'weight' => 2 ); + next if $cust_payby->weight < ($opt{'weight'} || 1); + $cust_payby->weight( $cust_payby->weight + 1 ); my $error = $cust_payby->replace; if ( $error ) { $dbh->rollback if $oldAutoCommit; @@ -5482,6 +5550,20 @@ sub _upgrade_data { #class method } + # at the time we do this, also migrate paytype into cust_pay_batch + # so that batches that are open before the migration can still be + # processed + my @cust_pay_batch = qsearch('cust_pay_batch', { + 'custnum' => $cust_main->custnum, + 'payby' => 'CHEK', + 'paytype' => '', + }); + foreach my $cust_pay_batch (@cust_pay_batch) { + $cust_pay_batch->set('paytype', $cust_main->get('paytype')); + my $error = $cust_pay_batch->replace; + die "$error (setting cust_pay_batch.paytype)" if $error; + } + $cust_main->complimentary('Y') if $cust_main->payby eq 'COMP'; $cust_main->invoice_attn( $cust_main->payname )