Merge branch 'master' of git.freeside.biz:/home/git/Business-BatchPayment
[Business-BatchPayment.git] / BatchPayment / Item.pm
index f93f5b3..c719efc 100644 (file)
@@ -106,6 +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(
@@ -119,6 +123,7 @@ has [ qw(
   state
   country
   zip
+  phone
 ) ] => ( is => 'rw', isa => 'Str', default => '' );
 
 =back
@@ -129,7 +134,9 @@ has [ qw(
 
 =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 @@ 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 @@ 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 @@ 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;