diff options
Diffstat (limited to 'FS')
| -rw-r--r-- | FS/FS/Conf.pm | 7 | ||||
| -rw-r--r-- | FS/FS/cust_bill.pm | 102 | ||||
| -rw-r--r-- | FS/FS/cust_main.pm | 129 | ||||
| -rw-r--r-- | FS/FS/pay_batch.pm | 27 | 
4 files changed, 163 insertions, 102 deletions
| diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 8bff460fe..93ecf30c7 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1227,6 +1227,13 @@ httemplate/docs/config.html    },    { +    'key'         => 'paymentforcedtobatch', +    'section'     => 'UI', +    'description' => 'Causes per customer payment entry to be forced to a batch processor rather than performed realtime.', +    'type'        => 'checkbox', +  }, + +  {      'key'         => 'svc_acct-notes',      'section'     => 'UI',      'description' => 'Extra HTML to be displayed on the Account View screen.', diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index d39e6ddc1..877d364e8 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -1434,107 +1434,9 @@ sub batch_card {    my ($self, %options) = @_;    my $cust_main = $self->cust_main; -  my $amount = sprintf("%.2f", $cust_main->balance - $cust_main->in_transit_payments); -  return '' unless $amount > 0; +  $options{invnum} = $self->invnum; -  if ($options{'realtime'}) { -    return $cust_main->realtime_bop( FS::payby->payby2bop($cust_main->payby), -                                     $amount, -                                     %options, -                                   ); -  } - -  my $oldAutoCommit = $FS::UID::AutoCommit; -  local $FS::UID::AutoCommit = 0; -  my $dbh = dbh; - -  $dbh->do("LOCK TABLE pay_batch IN SHARE ROW EXCLUSIVE MODE") -    or return "Cannot lock pay_batch: " . $dbh->errstr; - -  my %pay_batch = ( -    'status' => 'O', -    'payby'  => FS::payby->payby2payment($cust_main->payby), -  ); - -  my $pay_batch = qsearchs( 'pay_batch', \%pay_batch ); - -  unless ( $pay_batch ) { -    $pay_batch = new FS::pay_batch \%pay_batch; -    my $error = $pay_batch->insert; -    if ( $error ) { -      $dbh->rollback if $oldAutoCommit; -      die "error creating new batch: $error\n"; -    } -  } - -  my $old_cust_pay_batch = qsearchs('cust_pay_batch', { -      'batchnum' => $pay_batch->batchnum, -      'custnum'  => $cust_main->custnum, -  } ); - -  my $cust_pay_batch = new FS::cust_pay_batch ( { -    'batchnum' => $pay_batch->batchnum, -    'invnum'   => $self->getfield('invnum'),       # is there a better value? -                                                   # this field should be -						   # removed... -						   # cust_bill_pay_batch now -    'custnum'  => $cust_main->custnum, -    'last'     => $cust_main->getfield('last'), -    'first'    => $cust_main->getfield('first'), -    'address1' => $cust_main->address1, -    'address2' => $cust_main->address2, -    'city'     => $cust_main->city, -    'state'    => $cust_main->state, -    'zip'      => $cust_main->zip, -    'country'  => $cust_main->country, -    'payby'    => $cust_main->payby, -    'payinfo'  => $cust_main->payinfo, -    'exp'      => $cust_main->paydate, -    'payname'  => $cust_main->payname, -    'amount'   => $amount,                          # consolidating -  } ); -   -  $cust_pay_batch->paybatchnum($old_cust_pay_batch->paybatchnum) -    if $old_cust_pay_batch; - -  my $error; -  if ($old_cust_pay_batch) { -    $error = $cust_pay_batch->replace($old_cust_pay_batch) -  } else { -    $error = $cust_pay_batch->insert; -  } - -  if ( $error ) { -    $dbh->rollback if $oldAutoCommit; -    die $error; -  } - -  my $unapplied = $cust_main->total_credited + $cust_main->total_unapplied_payments + $cust_main->in_transit_payments; -  foreach my $cust_bill ($cust_main->open_cust_bill) { -    #$dbh->commit or die $dbh->errstr if $oldAutoCommit; -    my $cust_bill_pay_batch = new FS::cust_bill_pay_batch { -      'invnum' => $cust_bill->invnum, -      'paybatchnum' => $cust_pay_batch->paybatchnum, -      'amount' => $cust_bill->owed, -      '_date' => time, -    }; -    if ($unapplied >= $cust_bill_pay_batch->amount){ -      $unapplied -= $cust_bill_pay_batch->amount; -      next; -    }else{ -      $cust_bill_pay_batch->amount(sprintf ( "%.2f",  -                                   $cust_bill_pay_batch->amount - $unapplied )); -      $unapplied = 0; -    } -    $error = $cust_bill_pay_batch->insert; -    if ( $error ) { -      $dbh->rollback if $oldAutoCommit; -      die $error; -    } -  } - -  $dbh->commit or die $dbh->errstr if $oldAutoCommit; -  ''; +  $cust_main->batch_card(%options);  }  sub _agent_template { diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 1224c88da..708f014a8 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -3177,6 +3177,132 @@ sub realtime_refund_bop {  } +=item batch_card OPTION => VALUE... + +Adds a payment for this invoice to the pending credit card batch (see +L<FS::cust_pay_batch>), or, if the B<realtime> option is set to a true value, +runs the payment using a realtime gateway. + +=cut + +sub batch_card { +  my ($self, %options) = @_; + +  my $amount; +  if (exists($options{amount})) { +    $amount = $options{amount}; +  }else{ +    $amount = sprintf("%.2f", $self->balance - $self->in_transit_payments); +  } +  return '' unless $amount > 0; +   +  my $invnum = delete $options{invnum}; +  my $payby = $options{invnum} || $self->payby;  #dubious + +  if ($options{'realtime'}) { +    return $self->realtime_bop( FS::payby->payby2bop($self->payby), +                                $amount, +                                %options, +                              ); +  } + +  my $oldAutoCommit = $FS::UID::AutoCommit; +  local $FS::UID::AutoCommit = 0; +  my $dbh = dbh; + +  $dbh->do("LOCK TABLE pay_batch IN SHARE ROW EXCLUSIVE MODE") +    or return "Cannot lock pay_batch: " . $dbh->errstr; + +  my %pay_batch = ( +    'status' => 'O', +    'payby'  => FS::payby->payby2payment($payby), +  ); + +  my $pay_batch = qsearchs( 'pay_batch', \%pay_batch ); + +  unless ( $pay_batch ) { +    $pay_batch = new FS::pay_batch \%pay_batch; +    my $error = $pay_batch->insert; +    if ( $error ) { +      $dbh->rollback if $oldAutoCommit; +      die "error creating new batch: $error\n"; +    } +  } + +  my $old_cust_pay_batch = qsearchs('cust_pay_batch', { +      'batchnum' => $pay_batch->batchnum, +      'custnum'  => $self->custnum, +  } ); + +  foreach (qw( address1 address2 city state zip country payby payinfo paydate +               payname )) { +    $options{$_} = '' unless exists($options{$_}); +  } + +  my $cust_pay_batch = new FS::cust_pay_batch ( { +    'batchnum' => $pay_batch->batchnum, +    'invnum'   => $invnum || 0,                    # is there a better value? +                                                   # this field should be +                                                   # removed... +                                                   # cust_bill_pay_batch now +    'custnum'  => $self->custnum, +    'last'     => $self->getfield('last'), +    'first'    => $self->getfield('first'), +    'address1' => $options{address1} || $self->address1, +    'address2' => $options{address2} || $self->address2, +    'city'     => $options{city}     || $self->city, +    'state'    => $options{state}    || $self->state, +    'zip'      => $options{zip}      || $self->zip, +    'country'  => $options{country}  || $self->country, +    'payby'    => $options{payby}    || $self->payby, +    'payinfo'  => $options{payinfo}  || $self->payinfo, +    'exp'      => $options{paydate}  || $self->paydate, +    'payname'  => $options{payname}  || $self->payname, +    'amount'   => $amount,                         # consolidating +  } ); +   +  $cust_pay_batch->paybatchnum($old_cust_pay_batch->paybatchnum) +    if $old_cust_pay_batch; + +  my $error; +  if ($old_cust_pay_batch) { +    $error = $cust_pay_batch->replace($old_cust_pay_batch) +  } else { +    $error = $cust_pay_batch->insert; +  } + +  if ( $error ) { +    $dbh->rollback if $oldAutoCommit; +    die $error; +  } + +  my $unapplied = $self->total_credited + $self->total_unapplied_payments + $self->in_transit_payments; +  foreach my $cust_bill ($self->open_cust_bill) { +    #$dbh->commit or die $dbh->errstr if $oldAutoCommit; +    my $cust_bill_pay_batch = new FS::cust_bill_pay_batch { +      'invnum' => $cust_bill->invnum, +      'paybatchnum' => $cust_pay_batch->paybatchnum, +      'amount' => $cust_bill->owed, +      '_date' => time, +    }; +    if ($unapplied >= $cust_bill_pay_batch->amount){ +      $unapplied -= $cust_bill_pay_batch->amount; +      next; +    }else{ +      $cust_bill_pay_batch->amount(sprintf ( "%.2f",  +                                   $cust_bill_pay_batch->amount - $unapplied ));      $unapplied = 0; +    } +    $error = $cust_bill_pay_batch->insert; +    if ( $error ) { +      $dbh->rollback if $oldAutoCommit; +      die $error; +    } +  } + +  $dbh->commit or die $dbh->errstr if $oldAutoCommit; +  ''; +} +  =item total_owed  Returns the total owed for this customer on all invoices @@ -4882,6 +5008,9 @@ payinfo_masked false laziness with cust_pay.pm and cust_refund.pm  Birthdates rely on negative epoch values. +The payby for card/check batches is broken.  With mixed batching, bad +things will happen. +  =head1 SEE ALSO  L<FS::Record>, L<FS::cust_pkg>, L<FS::cust_bill>, L<FS::cust_credit> diff --git a/FS/FS/pay_batch.pm b/FS/FS/pay_batch.pm index 5a06ba603..c09753449 100644 --- a/FS/FS/pay_batch.pm +++ b/FS/FS/pay_batch.pm @@ -138,7 +138,7 @@ sub set_status {    $self->replace();  } -=item import results OPTION => VALUE, ... +=item import_results OPTION => VALUE, ...  Import batch results. @@ -162,6 +162,7 @@ sub import_results {    my $formatre;      # for Fixed.+    my @values;    my $begin_condition; +  my $pre_hook;    my $end_condition;    my $end_hook;    my $hook; @@ -340,7 +341,7 @@ sub import_results {      @fields = (        '',            # Name -      'paybatchnum', # ID:  Invoice number of the transaction +      'custnum'    , # ID:  Customer number of the transaction        'aba',         # ABA Number for the transaction        'payinfo',     # Bank Account Number for the transaction        '',            # Transaction Type:  27 - debit @@ -354,6 +355,20 @@ sub import_results {        '';      }; +    $pre_hook = sub { +      my $hash = shift; +      my @cust_pay_batch =    # this is dodgy, it works due to autoposting +        qsearch('cust_pay_batch', { 'custnum' => $hash->{'custnum'}+0,  +                                    'status'  => '' +                                  } ); +      if ( scalar(@cust_pay_batch) == 1 ) { +        $hash->{'paybatchnum'} = $cust_pay_batch[0]->paybatchnum; +      }else{ +        return "can't find batch payment for customer number " .$hash->{custnum}; +      } +      ''; +    }; +      $hook = sub {        my $hash = shift;        $hash->{'_date'} = time;  # got a better one? @@ -429,6 +444,14 @@ sub import_results {        $hash{$field} = $value;      } +    if ( defined($pre_hook) ) { +      my $error = &{$pre_hook}(\%hash); +      if ( $error ) { +        $dbh->rollback if $oldAutoCommit; +        return $error; +      } +    } +      if ( &{$end_condition}(\%hash) ) {        my $error = &{$end_hook}(\%hash, $total);        if ( $error ) { | 
