File Coverage

blib/lib/Business/NAB/BPAY/Remittance/File.pm
Criterion Covered Total %
statement 58 59 98.3
branch 8 10 80.0
condition n/a
subroutine 11 11 100.0
pod 2 2 100.0
total 79 82 96.3


line stmt bran cond sub pod time code
1             package Business::NAB::BPAY::Remittance::File;
2             $Business::NAB::BPAY::Remittance::File::VERSION = '0.03';
3             =head1 NAME
4              
5             Business::NAB::BPAY::Remittance::File
6              
7             =head1 SYNOPSIS
8              
9             use Business::NAB::BPAY::Remittance::File;
10              
11             my $File = Business::NAB::BPAY::Remittance::File->new_from_file(
12             "/path/to/bpay/payments/batch/file-brf.txt",
13             );
14              
15             # parse
16             my $Header = $File->header_record->[0];
17              
18             foreach my $File ( $File->detail_record->@* ) {
19             ...
20             }
21              
22             my $Trailer = $File->trailer_record->[0];
23              
24             # create
25             $File->to_file(
26             "/path/to/bpay/remittance/file_output.brf",
27             $separator, # defaults to "\r\n"
28             );
29              
30             =head1 DESCRIPTION
31              
32             Class for parsing / creating a NAB BPAY remittance/reporting file
33              
34             =cut;
35              
36 1     1   1154627 use strict;
  1         3  
  1         51  
37 1     1   7 use warnings;
  1         2  
  1         84  
38 1     1   8 use feature qw/ signatures /;
  1         2  
  1         191  
39 1     1   731 use autodie qw/ :all /;
  1         21932  
  1         4  
40 1     1   25680 use Carp qw/ croak /;
  1         3  
  1         106  
41              
42 1     1   716 use Moose;
  1         660257  
  1         11  
43             with 'Business::NAB::Role::AttributeContainer';
44             extends 'Business::NAB::FileContainer';
45              
46 1     1   10808 use Moose::Util::TypeConstraints;
  1         3  
  1         12  
47 1     1   3337 no warnings qw/ experimental::signatures /;
  1         3  
  1         81  
48              
49 1     1   21 use Business::NAB::BPAY::Remittance::File;
  1         3  
  1         991  
50              
51             # we have long namespaces and use them multiple times so have
52             # normalised them out into the $parent and @subclasses below
53             my $parent = 'Business::NAB::BPAY::Remittance::File';
54              
55             my @subclasses = (
56             qw/
57             HeaderRecord
58             DetailRecord
59             TrailerRecord
60             /
61             );
62              
63             =head1 ATTRIBUTES
64              
65             All attributes are ArrayRef[Obj] where Obj are of the Business::NAB::BPAY*
66             namespace:
67              
68             HeaderRecord
69             DetailRecord
70             TrailerRecord
71              
72             Convenience methods are available for trivial addition of new elements
73             to the arrays:
74              
75             $File->add_header_record( $HeaderRecord );
76             $File->add_detail_record( $DetailRecord );
77             $File->add_trailer_record( $TrailerRecord );
78              
79             =over
80              
81             =item header_record (ArrayRef[Obj])
82              
83             =item detail_record (ArrayRef[Obj])
84              
85             =item trailer_record (ArrayRef[Obj])
86              
87             =back
88              
89             =cut
90              
91             __PACKAGE__->load_attributes( $parent, @subclasses );
92              
93             =head1 METHODS
94              
95             =head2 new_from_file
96              
97             Returns a new instance of the class with attributes populated from
98             the result of parsing the passed file
99              
100             my $File = Business::NAB::BPAY::Remittance::File
101             ->new_from_file( $file_path );
102              
103             =cut
104              
105             sub new_from_file (
106 1         4 $class,
107 1         3 $file,
108 1         4 $class_parent = $parent, # undocumented as called by subclasses
109 1     1 1 3012 ) {
  1         2  
110              
111 1         82 my %sub_class_map = (
112             0 => 'HeaderRecord',
113             5 => 'DetailRecord',
114             9 => 'TrailerRecord',
115             );
116              
117 1 50       66 my $self = ref( $class ) ? $class : $class->new;
118              
119 1         13 return $self->SUPER::new_from_file(
120             $class_parent, $file, \%sub_class_map
121             );
122             }
123              
124             =head2 to_file
125              
126             Writes the file content to the passed file path:
127              
128             $File->to_file(
129             $file_path,
130             $separator, # defaults to "\r\n"
131             );
132              
133             =cut
134              
135             sub to_file (
136 3         11 $self,
137 3         28 $file,
138 3         9 $sep = "\r\n",
139 3     3 1 11905 ) {
  3         5  
140 3         23 open( my $fh, '>', $file );
141              
142 3         3164 print $fh $self->header_record->[ 0 ]->to_record . $sep;
143 3         24 print $fh $_->to_record . $sep foreach $self->detail_record->@*;
144              
145 3 100       23 if ( my $TrailerRecord = $self->trailer_record->[ 0 ] ) {
146 2         52 print $fh $TrailerRecord->to_record . $sep;
147             } else {
148              
149             my (
150 1         13 $number_of_error_corrections,
151             $amount_of_error_corrections,
152             $number_of_payments,
153             $amount_of_payments,
154             $number_of_reversals,
155             $amount_of_reversals,
156             ) = ( 0 ) x 6;
157              
158 1         7 foreach my $detail ( $self->detail_record->@* ) {
159              
160 12 100       47 if ( $detail->is_payment ) {
    100          
    50          
161 7         51 $number_of_payments++;
162 7         406 $amount_of_payments += $detail->amount;
163              
164             } elsif ( $detail->is_correction ) {
165 4         30 $number_of_error_corrections++;
166 4         234 $amount_of_error_corrections += $detail->amount;
167              
168             } elsif ( $detail->is_reversal ) {
169 1         9 $number_of_reversals++;
170 1         56 $amount_of_reversals += $detail->amount;
171              
172             } else {
173 0         0 croak(
174             "Unrecognised payment_instruction_type: "
175             . $detail->payment_instruction_type
176             );
177             }
178             }
179              
180 1         10 my $TrailerRecord = Business::NAB::BPAY::Remittance::File::TrailerRecord->new( {
181             'number_of_error_corrections' => $number_of_error_corrections,
182             'amount_of_error_corrections' => $amount_of_error_corrections,
183              
184             'number_of_payments' => $number_of_payments,
185             'amount_of_payments' => $amount_of_payments,
186              
187             'number_of_reversals' => $number_of_reversals,
188             'amount_of_reversals' => $amount_of_reversals,
189              
190             'biller_code' => $self->header_record->[ 0 ]->biller_code,
191              
192             'settlement_amount' => $amount_of_payments
193             - $amount_of_error_corrections
194             - $amount_of_reversals,
195             } );
196              
197 1         12 print $fh $TrailerRecord->to_record . $sep;
198             }
199              
200 3         19 close( $fh );
201              
202 3         2004 return 1;
203             }
204              
205             =head1 SEE ALSO
206              
207             L<Business::NAB::Types>
208              
209             L<Business::NAB::BPAY::Remittance::File::HeaderRecord>
210              
211             L<Business::NAB::BPAY::Remittance::File::DetailRecord>
212              
213             L<Business::NAB::BPAY::Remittance::File::TrailerRecord>
214              
215             =cut
216              
217             __PACKAGE__->meta->make_immutable;