Merge branch 'master' of git.freeside.biz:/home/git/Business-BatchPayment
authorIvan Kohler <ivan@freeside.biz>
Thu, 12 Feb 2015 23:15:45 +0000 (15:15 -0800)
committerIvan Kohler <ivan@freeside.biz>
Thu, 12 Feb 2015 23:15:45 +0000 (15:15 -0800)
1  2 
BatchPayment/Item.pm

diff --combined BatchPayment/Item.pm
@@@ -31,7 -31,7 +31,7 @@@ Item TO the account identified by the P
  
  =cut
  
 -enum 'Action' => qw(payment credit);
 +enum 'Action' => [qw(payment credit)];
  coerce 'Action', from 'Str', via { lc $_ };
  has action => (
    is  => 'rw',
@@@ -49,7 -49,7 +49,7 @@@ and if set on the Processor object, thi
  =cut
  
  # are we okay with these names?
 -enum 'PaymentType' => qw( CC ECHECK );
 +enum 'PaymentType' => [qw( CC ECHECK )];
  has payment_type => ( is  => 'rw', isa => 'PaymentType' );
  
  =item amount
@@@ -106,6 -106,10 +106,10 @@@ Company name
  Billing address fields.  Credit card processors may use these (especially
  zip) for authentication.
  
+ =item phone
+ Customer phone number.
  =cut
  
  has [ qw(
    state
    country
    zip
+   phone
  ) ] => ( is => 'rw', isa => 'Str', default => '' );
  
  =back
  
  =item process_date
  
- The date requested for processing.
+ The date requested for processing.  This is meaningful only if the 
+ processor allows different processing dates for items in the same 
+ batch.
  
  =item invoice_number
  
@@@ -193,7 -200,54 +200,54 @@@ Credit card expiration, MMYY format
  =cut
  
  has card_number     => ( is => 'rw', isa => 'Str' );
- has expiration      => ( is => 'rw', isa => 'Str' );
+ has ['expiration_month', 'expiration_year'] => ( is => 'rw', isa => 'Int' );
+ sub expiration {
+   # gets/sets expiration_month and _year in MMYY format
+   my $self = shift;
+   my $arg = shift;
+   if ( $arg ) {
+     # well, we said it's in MMYY format
+     my ($m, $y) = _parse_expiration($arg);
+     $self->expiration_month($m);
+     $self->expiration_year($y);
+   }
+   return sprintf('%02d/%02d',
+     $self->expiration_month,
+     $self->expiration_year % 2000);
+ }
+ sub _parse_expiration {
+   my $arg = shift;
+   if ( $arg =~ /^(\d\d)(\d\d)$/ ) {
+     return ($1, 2000 + $2);
+   } elsif ( $arg =~ /^(\d\d?)\W(\d\d)$/ ) {
+     return ($1, 2000 + $2);
+   } elsif ( $arg =~ /^(\d\d?)\W(\d\d\d\d)$/ ) {
+     return ($1, $2);
+   } elsif ( $arg =~ /^(\d\d?)\W\d\d?\W(\d\d\d\d)$/) {
+     return ($1, $3);
+   } else {
+     die "can't parse expiration date '$arg'";
+   }
+ }
+ sub payinfo {
+   # gets/sets either the card number, or the account number + routing code
+   # depending on the payment type
+   my $self = shift;
+   if ( $self->payment_type eq 'CC' ) {
+     $self->card_number(@_);
+   } elsif ( $self->payment_type eq 'ECHECK' ) {
+     my $arg = shift;
+     if ( $arg ) {
+       $arg =~ /^(\d+)@(\d+)$/ or die "Validation failed for payinfo";
+       $self->account_number($1);
+       $self->routing_code($2);
+     }
+     return ($self->account_number . '@' . $self->routing_code);
+   }
+ }
  
  =back
  
@@@ -256,6 -310,28 +310,28 @@@ account again
  The message returned by the gateway.  This may contain a value even 
  if the payment was successful (use C<approved> to determine that.)
  
+ =item failure_status
+ A normalized failure status, from the following list:
+ =over 4
+ =item expired
+ =item nsf (non-sufficient funds / credit limit)
+ =item stolen
+ =item pickup
+ =item blacklisted
+ =item inactive
+ =item decline (other card/transaction declines)
+ =back
  =back
  
  =cut
@@@ -271,8 -347,28 +347,28 @@@ has [qw
    assigned_token
  )] => ( is => 'rw', isa => 'Str');
  
+ enum FailureStatus => qw(
+   expired
+   nsf
+   stolen
+   pickup
+   blacklisted
+   inactive
+   decline
+ );
+ has failure_status  => ( is => 'rw', isa => 'Maybe[FailureStatus]' );
  has check_number => ( is => 'rw', isa => 'Int' );
  
+ around 'BUILDARGS' => sub {
+   my ($orig, $self, %args) = @_;
+   if ( $args{expiration} ) {
+     @args{'expiration_month', 'expiration_year'} =
+       _parse_expiration($args{expiration}); 
+   }
+   $self->$orig(%args);
+ };
  __PACKAGE__->meta->make_immutable;
  
  1;