=head1 NAME

Business::BatchPayment::Batch

=head1 DESCRIPTION

A Business::BatchPayment::Batch object represents a group of payment 
requests or confirmations (L<Business::BatchPayment::Item>) submitted
to a bank (or returned from a bank) as a batch.

=head1 ATTRIBUTES

=over 4

=item incoming - Flag for one-way batches.  The processor must set
this if the batch was originated by the gateway.

=item batch_id - Batch identifier.  The format is processor-specific
but usually must be a positive integer, if it's used at all.

Processor modules may include C<batch_id> in a reply batch ONLY if 
it is guaranteed to match the batch_id of a request batch AND all 
the items in the reply batch come from that request batch.  Otherwise, 
C<batch_id> must be undef.  It must always be undef when using one-way
(receive-only) workflow, since there are no request batches.

=item process_date - The intended processing date for a request batch.
If not set, it will default to the start of the next day; if that's  
not what you want, set it explicitly.

=item items - An arrayref of L<Business::BatchPayment::Item> objects
included in the batch.

=item num

If your processor uses C<format_header> and C<format_item>, this will 
be set to 0 by C<format_header> and incremented every time C<format_item>
is called.  Convenient for formats that require record numbers.

=back

=head1 METHODS

=over 4

=item totals

Returns a hash containing 'credit_count', 'credit_sum', 'payment_count', 
and 'payment_sum'.  These are the number of credits, sum of credit amounts,
number of payments, and sum of payment amounts.

=cut

package Business::BatchPayment::Batch;

use strict;
use Moose;
use Moose::Util::TypeConstraints;
use DateTime;

has incoming => (
  is => 'rw',
  isa => 'Bool',
);

has batch_id => (
  is => 'rw',
  isa => 'Str',
  default => '',
);

has items => (
  traits => ['Array'],
  is => 'rw',
  isa => 'ArrayRef[Business::BatchPayment::Item]',
  handles =>  {
    count     => 'count',
    elements  => 'elements',
    push      => 'push',
  },
  default => sub { [] },
);

class_type 'DateTime';

has process_date    => (
  is => 'rw',
  isa => 'DateTime',
  coerce => 1,
  default => sub {
#    warn "No batch process date set; assuming tomorrow.\n";
    DateTime->today->add(days => 1);
  },
);

has num => (
  is => 'rw',
  isa => 'Maybe[Int]',
);

sub totals {
  my $self = shift;
  my %totals = map {$_ => 0}
    qw(credit_count credit_sum payment_count payment_sum);
  foreach ($self->elements) {
    if ($_->action eq 'credit') {
      $totals{credit_count}++;
      $totals{credit_sum} += $_->amount;
    } elsif ( $_->action eq 'payment') {
      $totals{payment_count}++;
      $totals{payment_sum} += $_->amount;
    }
  }
  %totals;
}

1;
