File Coverage

blib/lib/ACH/Builder.pm
Criterion Covered Total %
statement 18 213 8.4
branch 0 48 0.0
condition 0 60 0.0
subroutine 6 41 14.6
pod 29 31 93.5
total 53 393 13.4


line stmt bran cond sub pod time code
1             package ACH::Builder;
2              
3 1     1   34513 use strict;
  1         2  
  1         25  
4 1     1   6 use warnings;
  1         2  
  1         30  
5 1     1   4 no warnings 'uninitialized';
  1         5  
  1         35  
6              
7 1     1   836 use POSIX qw( ceil strftime );
  1         7867  
  1         5  
8 1     1   1280 use Carp qw( carp croak );
  1         2  
  1         45  
9 1     1   828 use Encode qw( encode );
  1         10884  
  1         3319  
10              
11             our $VERSION = '0.23';
12              
13             =pod
14              
15             =head1 NAME
16              
17             ACH::Builder - Tools for building ACH (Automated Clearing House) files
18              
19             =head1 SYNOPSIS
20              
21             use ACH::Builder;
22              
23             my $ach = ACH::Builder->new( {
24             # Required
25             company_id => '11-111111',
26             company_name => 'MY COMPANY',
27             entry_description => 'TV-TELCOM',
28             destination => '123123123',
29             destination_name => 'COMMERCE BANK',
30             origination => '12312311',
31             origination_name => 'MYCOMPANY',
32              
33             # Optional
34             company_note => 'BILL',
35             effective_date => '130903',
36             allow_unbalanced_file => 1,
37             } );
38              
39             # load some sample records
40             my @samples = $ach->sample_detail_records;
41              
42             # build file header record
43             $ach->make_file_header_record;
44              
45             # build batch for web entries
46             $ach->set_entry_class_code( 'WEB' );
47             $ach->make_batch( \@samples );
48              
49             # build batch for telephone entries
50             $ach->set_entry_class_code( 'TEL' );
51             $ach->make_batch( \@samples );
52              
53             # build file control record
54             $ach->make_file_control_record;
55              
56             # add 9's filler records as needed
57             $ach->make_filler_records;
58              
59             print $ach->to_string;
60              
61             =head1 DESCRIPTION
62              
63             This module is tool to help construct ACH files, which are fixed-width
64             formatted files accpected by most banks. ACH (Automated Clearing House)
65             is an electronic banking network operating system in the United States.
66             ACH processes large volumes of both credit and debit transactions which
67             are originated in batches. Rules and regulations governing the ACH network
68             are established by the National Automated Clearing House Association
69             (NACHA) and the Federal Reserve (Fed).
70              
71             ACH credit transfers include direct deposit payroll payments and payments
72             to contractors and vendors. ACH debit transfers include consumer payments
73             on insurance premiums, mortgage loans, and other kinds of bills.
74              
75             =head1 CONFIGURATION
76              
77             The parameters below can be passed to the constructor C in a hashref.
78              
79             =head2 company_id
80              
81             Required. Your 10-digit company number; usually your federal tax ID.
82              
83             =head2 company_name
84              
85             Required. Your company name to appear on the receiver's statement; up to 16
86             characters.
87              
88             =head2 entry_description
89              
90             Required per batch. A brief description of the nature of the transactions.
91             This will appear on the receiver's bank statement. Maximum of 10 characters.
92              
93             =head2 destination
94              
95             Required per file. The 9-digit routing number for the destination bank.
96              
97             =head2 destination_name
98              
99             Optional per file. A 23-character string identifying the destination bank.
100              
101             =head2 origination
102              
103             Required per file. This will usually be the same as the C.
104              
105             =head2 origination_name
106              
107             Required per file. This will usually be the same as the C,
108             but note that it can be up to 23 characters long.
109              
110             =head2 originating_dfi
111              
112             Optional per file. This will usually be the first 8 positions of C,
113             but it can be set specifically if a certain originating Depository Financial
114             Institution is needed.
115              
116             =head2 company_note
117              
118             Optional per batch. For your own internal use. Maximum 20 characters.
119              
120             =head2 effective_date
121              
122             Optional per batch. Date in C format that the transactions should be posted.
123              
124             =head2 creation_date
125              
126             Optional per batch. Date in C format that the transactions were created on.
127             Useful when needing to re-create files exactly as they were originally created.
128             Defaults to current date.
129              
130             =head2 creation_time
131              
132             Optional per batch. Time in C format that the transactions were created at.
133             Useful when needing to re-create files exactly as they were originally created.
134             Defaults to current time.
135              
136             =head2 allow_unbalanced_file
137              
138             Optional per file. 1=True, 0=False. Allows for a file to contain debits and
139             credits that don't net to 0. The default is 0. 0 is useful for using the file
140             to transfer funds and 1 is useful when only doing debits (billing for services)
141             or credits (refunding transactions, distributing funds).
142              
143             =head1 DETAIL RECORD FORMAT
144              
145             The C function expects entry detail records in this format:
146              
147             {
148             customer_name => 'JOHN SMITH', # Maximum of 22 characters
149             customer_acct => '0000-0111111', # Maximum of 15 characters
150             amount => '2501', # In whole cents; this is $25.01
151             routing_number => '10010101', # 9 digits
152             bank_account => '103030030', # Maximum of 17 characters
153             transaction_code => '27',
154             entry_trace => 'ABCDE0000000001', # Optional trace number
155             addenda => [ # optional addenda entries
156             {
157             addendum_code => '05',
158             addendum_info => 'TEST INFO',
159             },
160             ],
161             }
162              
163             Only the following transaction codes are supported:
164              
165             22 - Deposit to checking account
166             27 - Debit from checking account
167             32 - Deposit to savings account
168             37 - Debit from savings account
169              
170             Rules for the C may vary. An example institution requires the
171             first 8 characters be the destination bank's routing number (excluding the
172             final checksum digit), and the next 7 characters be a zero-filled number
173             incrementing sequentially for each record.
174              
175             =head1 METHODS
176              
177             =head2 new({ company_id => '...', company_note ... })
178              
179             See above for configuration details. Note that the configuration parameter
180             names do not always match the names of the setter methods below.
181              
182             =cut
183              
184             sub new {
185 0     0 1   my ( $class, $vars ) = @_;
186              
187 0           my $self = {};
188 0           bless( $self, $class );
189              
190 0           $self->{__BATCH_COUNT__} = 0;
191 0           $self->{__ENTRY_COUNT__} = 0;
192 0           $self->{__ENTRY_HASH__} = 0;
193 0           $self->{__FILE_TOTAL_DEBIT__} = 0;
194 0           $self->{__FILE_TOTAL_CREDIT__} = 0;
195 0           $self->{__ACH_DATA__} = [];
196              
197             # Collapse given and default values
198 0   0       $self->set_service_class_code( $vars->{service_class_code} || 200);
199 0           $self->set_immediate_dest_name( $vars->{destination_name});
200 0           $self->set_immediate_origin_name( $vars->{origination_name});
201 0           $self->set_immediate_dest( $vars->{destination});
202 0           $self->set_immediate_origin( $vars->{origination});
203 0           $self->set_originating_dfi( $vars->{originating_dfi});
204              
205 0   0       $self->set_entry_class_code( $vars->{entry_class_code} || 'PPD');
206 0           $self->set_entry_description( $vars->{entry_description});
207 0           $self->set_company_id( $vars->{company_id});
208 0           $self->set_company_name( $vars->{company_name});
209 0           $self->set_company_note( $vars->{company_note});
210 0   0       $self->set_effective_date( $vars->{effective_date} || strftime( "%y%m%d", localtime( time + 86400 ) ));
211 0   0       $self->set_creation_date( $vars->{creation_date} || strftime( "%y%m%d", localtime( time ) ));
212 0   0       $self->set_creation_time( $vars->{creation_time} || strftime( "%H%M", localtime( time ) ));
213 0   0       $self->set_allow_unbalanced_file( $vars->{allow_unbalanced_file} || 0);
214              
215 0   0       $self->set_origin_status_code( $vars->{origin_status_code} || 1);
216 0   0       $self->set_file_id_modifier( $vars->{file_id_modifier} || 'A');
217 0   0       $self->set_record_size( $vars->{record_size} || 94);
218 0   0       $self->set_blocking_factor( $vars->{blocking_factor} || 10);
219 0   0       $self->set_format_code( $vars->{format_code} || 1);
220              
221 0           return( $self );
222             }
223              
224             =pod
225              
226             =head2 make_file_header_record( )
227              
228             Adds the file header record. This can only be called once and must be
229             called before any batches are added with C.
230              
231             =cut
232              
233             sub make_file_header_record {
234 0     0 1   my( $self ) = @_;
235              
236             # ach file header definition
237 0           my @def = qw(
238             record_type
239             priority_code
240             immediate_dest
241             immediate_origin
242             date
243             time
244             file_id_modifier
245             record_size
246             blocking_factor
247             format_code
248             immediate_dest_name
249             immediate_origin_name
250             reference_code
251             );
252              
253             my $data = {
254             record_type => 1,
255             priority_code => 1,
256             immediate_dest => $self->{__IMMEDIATE_DEST__},
257             immediate_origin => $self->{__IMMEDIATE_ORIGIN__},
258             date => $self->{__CREATION_DATE__},
259             time => $self->{__CREATION_TIME__},
260             file_id_modifier => $self->{__FILE_ID_MODIFIER__},
261             record_size => $self->{__RECORD_SIZE__},
262             blocking_factor => $self->{__BLOCKING_FACTOR__},
263             format_code => $self->{__FORMAT_CODE__},
264             immediate_dest_name => $self->{__IMMEDIATE_DEST_NAME__},
265             immediate_origin_name => $self->{__IMMEDIATE_ORIGIN_NAME__},
266 0           reference_code => '',
267             };
268              
269 0           push( @{ $self->ach_data() },
  0            
270             fixedlength( $self->format_rules, $data, \@def )
271             );
272             }
273              
274             =pod
275              
276             =head2 sample_detail_records( )
277              
278             Returns a list of sample records ready for C. See above for format details.
279              
280             =cut
281              
282             sub sample_detail_records {
283             return {
284 0     0 1   customer_name => 'JOHN SMITH',
285             customer_acct => '1234-0123456',
286             amount => '2501',
287             routing_number => '010010101',
288             bank_account => '103030030',
289             transaction_code => '27',
290             },
291             {
292             customer_name => 'ALICE VERYLONGNAMEGETSTRUNCATED',
293             customer_acct => 'verylongaccountgetstruncated',
294             amount => '2501',
295             routing_number => '010010401',
296             bank_account => '440030030',
297             transaction_code => '32',
298             },
299             ;
300             }
301              
302             =pod
303              
304             =head2 make_batch( @$records )
305              
306             Adds a batch of records to the file. You must have called
307             C before adding a batch to the file.
308              
309             =cut
310              
311             sub make_batch {
312 0     0 1   my ( $self, $records ) = @_;
313              
314 0 0 0       croak "Invalid or empty records for batch" unless ref $records eq 'ARRAY' && @$records;
315              
316 0           ++$self->{__BATCH_COUNT__};
317              
318             # reset the batch variables
319 0           $self->{__BATCH_TOTAL_DEBIT__} = 0;
320 0           $self->{__BATCH_TOTAL_CREDIT__} = 0;
321 0           $self->{__BATCH_ENTRY_COUNT__} = 0;
322 0           $self->{__BATCH_ENTRY_HASH__} = 0;
323              
324 0           $self->_make_batch_header_record();
325              
326 0           foreach my $record ( @$records ) {
327 0 0         croak 'Amount cannot be negative' if $record->{amount} < 0;
328              
329 0 0         if ($record->{transaction_code} =~ /^(27|37)$/) {
    0          
330 0 0         croak "Debits cannot be used with service_class_code 220" if $self->{__SERVICE_CLASS_CODE__} eq '220';
331 0           $self->{__BATCH_TOTAL_DEBIT__} += $record->{amount};
332 0           $self->{__FILE_TOTAL_DEBIT__} += $record->{amount};
333             } elsif ($record->{transaction_code} =~ /^(22|32)$/ ) {
334 0 0         croak "Credits cannot be used with service_class_code 220" if $self->{__SERVICE_CLASS_CODE__} eq '225';
335 0           $self->{__BATCH_TOTAL_CREDIT__} += $record->{amount};
336 0           $self->{__FILE_TOTAL_CREDIT__} += $record->{amount};
337             } else {
338 0           croak "Unsupported transaction_code '$record->{transaction_code}'";
339             }
340              
341             # modify batch values
342             # Hash is calculated without the checksum digit
343 0           $self->{__BATCH_ENTRY_HASH__} += substr $record->{routing_number}, 0, 8;
344 0           ++$self->{__BATCH_ENTRY_COUNT__};
345              
346             # modify file values
347 0           $self->{__ENTRY_HASH__} += substr $record->{routing_number}, 0, 8;
348 0           ++$self->{__ENTRY_COUNT__};
349              
350 0           $self->_make_detail_record( $record );
351 0           $self->_make_addenda_records( $record );
352             }
353              
354 0           $self->_make_batch_control_record();
355             }
356              
357             # For internal use only. Formats a detail record and adds it to the ACH data.
358             sub _make_detail_record {
359 0     0     my( $self, $record ) = @_;
360              
361 0           my @def = qw(
362             record_type
363             transaction_code
364             routing_number
365             bank_account
366             amount
367             customer_acct
368             customer_name
369             discretionary_data
370             addenda_indicator
371             entry_trace
372             );
373              
374             # default values for some fields
375 0   0       $record->{record_type} ||= 6;
376 0   0       $record->{discretionary_data} ||= '';
377             $record->{entry_trace} ||= substr($self->{__ORIGINATING_DFI__}, 0, 8)
378 0   0       . sprintf("%07s", $self->{__ENTRY_COUNT__}+1);
379 0   0       $record->{addenda} ||= [];
380 0 0 0       $record->{addenda_indicator} ||= @{$record->{addenda}} ? '1' : '0';
  0            
381              
382             # stash detail record
383 0           push( @{ $self->ach_data() },
  0            
384             fixedlength( $self->format_rules(), $record, \@def )
385             );
386             }
387              
388             # For internal use only. Makes the addenda record(s), if any, for the current
389             # detail.
390             sub _make_addenda_records
391             {
392 0     0     my( $self, $record ) = @_;
393              
394 0           my @def = qw(
395             record_type
396             addendum_code
397             addendum_info
398             addendum_sequence
399             entry_sequence
400             );
401              
402 0           my $addendum_sequence = 0;
403 0           for my $addendum (@{$record->{addenda}}) {
  0            
404 0           $addendum_sequence++;
405              
406             # default some fields
407 0   0       $addendum->{record_type} ||= '7';
408 0   0       $addendum->{addendum_sequence} ||= $addendum_sequence;
409 0   0       $addendum->{entry_sequence} ||= substr($record->{entry_trace}, -7);
410              
411             # add and count addenda record
412 0           push @{$self->ach_data}, fixedlength( $self->format_rules, $addendum, \@def );
  0            
413 0           $self->{__BATCH_ENTRY_COUNT__}++;
414 0           $self->{__ENTRY_COUNT__}++;
415             }
416             }
417              
418             # For internal use only. Starts a batch of detail records.
419             sub _make_batch_header_record {
420 0     0     my( $self ) = @_;
421              
422 0           my @def = qw(
423             record_type
424             service_class_code
425             company_name
426             company_note
427             company_id
428             entry_class_code
429             entry_description
430             date
431             effective_date
432             settlement_date
433             origin_status_code
434             origin_dfi_id
435             batch_number
436             );
437              
438             my $data = {
439             record_type => 5,
440             service_class_code => $self->{__SERVICE_CLASS_CODE__},
441             company_name => $self->{__COMPANY_NAME__},
442             company_note => $self->{__COMPANY_NOTE__},
443             company_id => $self->{__COMPANY_ID__},
444             entry_class_code => $self->{__ENTRY_CLASS_CODE__},
445             entry_description => $self->{__ENTRY_DESCRIPTION__},
446             date => $self->{__EFFECTIVE_DATE__},
447             effective_date => $self->{__EFFECTIVE_DATE__},
448             settlement_date => '',
449             origin_status_code => $self->{__ORIGIN_STATUS_CODE__},
450             origin_dfi_id => $self->{__ORIGINATING_DFI__},
451             batch_number => $self->{__BATCH_COUNT__},
452 0           authen_code => '',
453             bank_6 => '',
454             };
455              
456 0           push( @{ $self->ach_data() },
  0            
457             fixedlength( $self->format_rules(), $data, \@def )
458             );
459             }
460              
461             # For internal use only. Closes out a batch of detail records.
462             sub _make_batch_control_record {
463 0     0     my( $self ) = @_;
464              
465 0           my @def = qw(
466             record_type
467             service_class_code
468             entry_count
469             entry_hash
470             total_debit_amount
471             total_credit_amount
472             company_id
473             authen_code
474             bank_6
475             origin_dfi_id
476             batch_number
477             );
478              
479             my $data = {
480             record_type => 8,
481             service_class_code => $self->{__SERVICE_CLASS_CODE__},
482             company_id => $self->{__COMPANY_ID__},
483             origin_dfi_id => $self->{__ORIGINATING_DFI__},
484             batch_number => $self->{__BATCH_COUNT__},
485             authen_code => '',
486             bank_6 => '',
487             entry_hash => $self->{__BATCH_ENTRY_HASH__},
488             entry_count => $self->{__BATCH_ENTRY_COUNT__},
489             total_debit_amount => $self->{__BATCH_TOTAL_DEBIT__},
490             total_credit_amount => $self->{__BATCH_TOTAL_CREDIT__},
491 0           };
492              
493             # Truncate leftmost digits of entry hash
494 0 0         $data->{entry_hash} = substr($data->{entry_hash}, length($data->{entry_hash}) - 10, 10) if length($data->{entry_hash}) > 10;
495              
496 0           push( @{ $self->ach_data() },
  0            
497             fixedlength( $self->format_rules(), $data, \@def )
498             );
499             }
500              
501             =pod
502              
503             =head2 make_file_control_record( )
504              
505             Adds the file control record, finishing the file. This can only be called
506             once. Afterward, the ACH file can be retrieved in its entirety with C.
507              
508             =cut
509              
510             sub make_file_control_record {
511 0     0 1   my( $self ) = @_;
512              
513 0 0         unless ( $self->{__ALLOW_UNBALANCED_FILE__} ) {
514             croak "Detail records have unbalanced debits ($self->{__FILE_TOTAL_DEBIT__}) and credits ($self->{__FILE_TOTAL_CREDIT__})!"
515 0 0         unless $self->{__FILE_TOTAL_DEBIT__} eq $self->{__FILE_TOTAL_CREDIT__};
516             }
517              
518 0           my @def = qw(
519             record_type
520             batch_count
521             block_count
522             file_entry_count
523             entry_hash
524             total_debit_amount
525             total_credit_amount
526             bank_39
527             );
528              
529             my $data = {
530             record_type => 9,
531             batch_count => $self->{__BATCH_COUNT__},
532 0           block_count => ceil((scalar(@{ $self->{__ACH_DATA__} })+1)/$self->{__BLOCKING_FACTOR__}),
533             file_entry_count => $self->{__ENTRY_COUNT__},
534             entry_hash => $self->{__ENTRY_HASH__},
535             total_debit_amount => $self->{__FILE_TOTAL_DEBIT__},
536             total_credit_amount => $self->{__FILE_TOTAL_CREDIT__},
537 0           bank_39 => '',
538             };
539              
540             # Truncate leftmost digits of entry hash
541 0 0         $data->{entry_hash} = substr($data->{entry_hash}, length($data->{entry_hash}) - 10, 10) if length($data->{entry_hash}) > 10;
542              
543 0           push( @{ $self->ach_data() },
  0            
544             fixedlength( $self->format_rules(), $data, \@def )
545             );
546             }
547              
548             =pod
549              
550             =head2 make_filler_records( )
551              
552             Adds filler records (all 9's) as needed to fill out last block, so that the
553             total number of records is a multiple of 10.
554              
555             =cut
556              
557             sub make_filler_records
558             {
559 0     0 1   my $self = shift;
560 0           while (@{$self->ach_data} % $self->{__BLOCKING_FACTOR__} != 0) {
  0            
561 0           push @{$self->ach_data}, '9' x $self->{__RECORD_SIZE__};
  0            
562             }
563             }
564              
565              
566             =pod
567              
568             =head2 format_rules( )
569              
570             Returns a hash of ACH format rules. Used internally to generate the
571             fixed-width format required for output.
572              
573             =cut
574              
575             sub format_rules {
576 0     0 1   my( $self ) = @_;
577              
578             return( {
579 0           customer_name => '%-22.22s',
580             customer_acct => '%-15.15s',
581             amount => '%010.10s',
582             discretionary_data => '%-2.2s',
583             entry_trace => '%-15.15s',
584             addenda_indicator => '%01.1s',
585             trace_num => '%-15.15s',
586             transaction_code => '%-2.2s',
587             record_type => '%1.1s',
588             bank_account => '%-17.17s',
589             routing_number => '%09.9s',
590              
591             record_type => '%1.1s',
592              
593             priority_code => '%02.2s',
594             immediate_dest => '%10.10s',
595             immediate_origin => '%10.10s',
596             date => '%-6.6s',
597             time => '%-4.4s',
598             file_id_modifier => '%1.1s',
599             record_size => '%03.3s',
600             blocking_factor => '%02.2s',
601             format_code => '%1.1s',
602             immediate_dest_name => '%-23.23s',
603             immediate_origin_name => '%-23.23s',
604             reference_code => '%-8.8s',
605              
606             service_class_code => '%-3.3s',
607             company_name => '%-16.16s',
608             company_note => '%-20.20s',
609             company_id => '%-10.10s',
610             entry_class_code => '%-3.3s',
611             entry_description => '%-10.10s',
612             effective_date => '%-6.6s',
613             settlement_date => '%-3.3s', # for bank
614             origin_status_code => '%-1.1s', # for bank
615             origin_dfi_id => '%-8.8s', # for bank
616             batch_number => '%07.7s',
617              
618             addendum_code => '%-2.2s',
619             addendum_info => '%-80.80s',
620             addendum_sequence => '%04s',
621             entry_sequence => '%07s',
622              
623             entry_count => '%06s',
624             entry_hash => '%010s',
625             total_debit_amount => '%012s',
626             total_credit_amount => '%012s',
627             authen_code => '%-19.19s',
628             bank_6 => '%-6.6s',
629              
630             batch_count => '%06s',
631             block_count => '%06s',
632             file_entry_count => '%08s',
633             bank_39 => '%-39.39s',
634             } );
635             }
636              
637             # For internal use only. Formats a record according to format_rules.
638             # non-ASCII characters are replaced with a substitution characer ("?").
639             sub fixedlength {
640 0     0 0   my( $format, $data, $order ) = @_;
641              
642 0           my $fmt_string;
643 0           foreach my $field ( @$order ) {
644             croak "Format for the field $field was not defined"
645 0 0         unless defined $format->{$field};
646              
647             carp "data for $field is not defined"
648 0 0         unless defined $data->{$field};
649              
650 0   0       $data->{$field} ||= "";
651              
652 0           $fmt_string .= sprintf $format->{$field}, encode('ascii', $data->{$field}, Encode::FB_DEFAULT);
653             }
654              
655 0           return $fmt_string;
656             }
657              
658             =pod
659              
660             =head2 to_string([$line_term])
661              
662             Returns the built ACH file. $line_term is added to each line (default "\n")
663              
664             =cut
665              
666             sub to_string {
667 0     0 1   my ($self, $line_term) = @_;
668 0 0         $line_term = "\n" unless defined($line_term);
669 0           join('', map "$_$line_term", @{ $self->ach_data } );
  0            
670             }
671              
672             =pod
673              
674             =head2 ach_data( )
675              
676             Returns as an arrayref the formatted lines that will be turned into the ACH file.
677              
678             =cut
679              
680             sub ach_data {
681 0     0 1   my ( $self ) = shift;
682 0           $self->{__ACH_DATA__};
683             }
684              
685             =pod
686              
687             =head2 set_origin_status_code( $value )
688              
689             The code must be either:
690              
691             1 - Originator is a financial institution bound by the NACHA rules (the default)
692             2 - Originator is a federal agency not bound by the NACHA rules
693              
694             =cut
695              
696             sub set_origin_status_code {
697 0     0 1   my ( $self, $p ) = @_;
698 0 0 0       croak "Invalid origin_status_code" unless $p eq '1' || $p eq '2';
699 0           $self->{__ORIGIN_STATUS_CODE__} = $p;
700             }
701              
702             =pod
703              
704             =head2 set_format_code( $value )
705              
706             Of limited value. The only valid format code is I<1>, the default.
707              
708             =cut
709              
710             sub set_format_code {
711 0     0 1   my ( $self, $p ) = @_;
712 0 0         croak "format_code other than 1 is not supported" unless $p eq '1';
713 0           $self->{__FORMAT_CODE__} = $p;
714             }
715              
716             =pod
717              
718             =head2 set_blocking_factor( $value )
719              
720             Of limited value. The only valid blocking factor is I<10>, the default.
721              
722             =cut
723              
724             sub set_blocking_factor {
725 0     0 1   my ( $self, $p ) = @_;
726 0 0         croak "blocking_factor other than 10 is not supported" unless $p == 10;
727 0           $self->{__BLOCKING_FACTOR__} = $p;
728             }
729              
730             =pod
731              
732             =head2 set_record_size( $value )
733              
734             Of limited value. The only valid record size (characters per line) is I<94>, the default.
735              
736             =cut
737              
738             sub set_record_size {
739 0     0 1   my ( $self, $p ) = @_;
740 0 0         croak "record_size other than 94 is not supported" unless $p == 94;
741 0           $self->{__RECORD_SIZE__} = $p;
742             }
743              
744             =pod
745              
746             =head2 set_file_id_modifier( $value )
747              
748             A sequential alphanumeric value used to distinguish files submitted on the same day. The default is I.
749              
750             =cut
751              
752             sub set_file_id_modifier {
753 0     0 1   my ( $self, $p ) = @_;
754 0           check_length($p, 'file_id_modifier');
755 0           $self->{__FILE_ID_MODIFIER__} = $p;
756             }
757              
758             =pod
759              
760             =head2 set_immediate_origin_name( $value )
761              
762             The same as the C described above. This will usually be
763             your company name and is limited to 23 characters.
764              
765             =cut
766              
767             sub set_immediate_origin_name {
768 0     0 1   my ( $self, $p ) = @_;
769 0           check_length($p, 'immediate_origin_name');
770 0           $self->{__IMMEDIATE_ORIGIN_NAME__} = $p;
771             }
772              
773             =pod
774              
775             =head2 set_immediate_origin( $value )
776              
777             The same as the C described above. This will usually be your
778             federal tax ID number, in I<##-#######> format.
779              
780             =cut
781              
782             sub set_immediate_origin {
783 0     0 1   my ( $self, $p ) = @_;
784 0           check_length($p, 'immediate_origin');
785 0           $self->{__IMMEDIATE_ORIGIN__} = $p;
786 0           $self->{__ORIGINATING_DFI__} = substr $p, 0, 8;
787             }
788              
789             =pod
790              
791             =head2 set_originating_dfi( $value )
792              
793             The same as the C described above, Originating DFI
794             Identification. This will default to the first 8 positions of
795             C unless otherwise specified.
796              
797             =cut
798              
799             sub set_originating_dfi {
800 0     0 1   my ( $self, $p ) = @_;
801 0   0       $p ||= substr $self->{__IMMEDIATE_ORIGIN__}, 0, 8;
802 0           check_length($p, 'origin_dfi_id');
803 0           $self->{__ORIGINATING_DFI__} = $p;
804             }
805              
806             =pod
807              
808             =head2 set_immediate_dest_name( $value )
809              
810             The same as the C described above. This identifies the
811             destination bank that will be processing this file. Limited to 23
812             characters.
813              
814             =cut
815              
816             sub set_immediate_dest_name {
817 0     0 1   my ( $self, $p ) = @_;
818 0           check_length($p, 'immediate_dest_name');
819 0           $self->{__IMMEDIATE_DEST_NAME__} = $p;
820             }
821              
822             =pod
823              
824             =head2 set_immediate_dest( $value )
825              
826             The same as the C described above. This is the 9-digit routing
827             number of the destination bank.
828              
829             =cut
830              
831             sub set_immediate_dest {
832 0     0 1   my ( $self, $p ) = @_;
833 0           check_length($p, 'immediate_dest');
834 0           $self->{__IMMEDIATE_DEST__} = $p;
835             }
836              
837             =pod
838              
839             =head2 set_entry_description( $value )
840              
841             A brief description of the nature of the transactions. This will appear on
842             the receiver's bank statement. Maximum of 10 characters. This can be set
843             separately for each batch before C is called.
844              
845             =cut
846              
847             sub set_entry_description {
848 0     0 1   my ( $self, $p ) = @_;
849 0           check_length($p, 'entry_description');
850 0           $self->{__ENTRY_DESCRIPTION__} = $p;
851             }
852              
853             =pod
854              
855             =head2 set_entry_class_code( $value )
856              
857             The code must be one of:
858              
859             PPD - Prearranged Payments and Deposit entries for consumer items (the default)
860             CCD - Cash Concentration and Disbursement entries
861             CTX - Corporate Trade Exchange entries for corporate transactions
862             TEL - Telephone initiated entries
863             WEB - Authorization received via the Internet
864              
865             =cut
866              
867             sub set_entry_class_code {
868 0     0 1   my ( $self, $p ) = @_;
869 0           check_length($p, 'entry_class_code');
870 0           $self->{__ENTRY_CLASS_CODE__} = $p;
871             }
872              
873             =pod
874              
875             =head2 set_company_id( $value )
876              
877             Your 10-digit company number; usually your federal tax ID. This can be set
878             separately for each batch.
879              
880             =cut
881              
882             sub set_company_id {
883 0     0 1   my ( $self, $p ) = @_;
884 0           check_length($p, 'company_id');
885 0           $self->{__COMPANY_ID__} = $p;
886             }
887              
888             =pod
889              
890             =head2 set_company_name( $value )
891              
892             Required. Your company name to appear on the receiver's statement; up to 16
893             characters.
894              
895             =cut
896              
897             sub set_company_name {
898 0     0 1   my ( $self, $p ) = @_;
899 0           check_length($p, 'company_name');
900 0           $self->{__COMPANY_NAME__} = $p;
901             }
902              
903             =pod
904              
905             =head2 set_company_note( $value )
906              
907             An optional parameter for your internal use, limited to 20 characters.
908              
909             =cut
910              
911             sub set_company_note {
912 0     0 1   my ( $self, $p ) = @_;
913 0           check_length($p, 'company_note');
914 0           $self->{__COMPANY_NOTE__} = $p;
915             }
916              
917             =pod
918              
919             =head2 set_effective_date( $value )
920              
921             The date that transactions in this batch will be posted. The date should be
922             in I format. Defaults to tomorrow.
923              
924             =cut
925              
926             sub set_effective_date {
927 0     0 1   my ( $self, $p ) = @_;
928 0 0         croak "Invalid effective_date" unless $p =~ /^\d{6}$/;
929 0           check_length($p, 'effective_date');
930 0           $self->{__EFFECTIVE_DATE__} = $p;
931             }
932              
933             =pod
934              
935             =head2 set_creation_date( $value )
936              
937             The date that transactions in this batch were created. The date should be
938             in I format. Defaults to today.
939              
940             =cut
941              
942             sub set_creation_date {
943 0     0 1   my ( $self, $p ) = @_;
944 0 0         croak "Invalid creation_date" unless $p =~ /^\d{6}$/;
945 0           check_length($p, 'date');
946 0           $self->{__CREATION_DATE__} = $p;
947             }
948              
949             =pod
950              
951             =head2 set_creation_time( $value )
952              
953             The time that transactions in this batch were created. The time should be
954             in I format. Defaults to now.
955              
956             =cut
957              
958             sub set_creation_time {
959 0     0 1   my ( $self, $p ) = @_;
960 0 0         croak "Invalid creation_time" unless $p =~ /^\d{4}$/;
961 0           check_length($p, 'time');
962 0           $self->{__CREATION_TIME__} = $p;
963             }
964              
965             =pod
966              
967             =head2 set_allow_unbalanced_file( $value )
968              
969             Allow for a file's credits and debits to be unbalanced. Default is false.
970              
971             =cut
972              
973             sub set_allow_unbalanced_file {
974 0     0 1   my ( $self, $p ) = @_;
975 0           $self->{__ALLOW_UNBALANCED_FILE__} = $p;
976             }
977              
978             =pod
979              
980             =head2 set_service_class_code( $value )
981              
982             The code must be one of:
983              
984             200 - Mixed credits and debits (the default)
985             220 - Credits only
986             225 - Debits only
987              
988             =cut
989              
990             sub set_service_class_code {
991 0     0 1   my ( $self, $p ) = @_;
992 0 0         croak "Invalid service_class_code" unless $p =~ /^(200|220|225)$/;
993 0           $self->{__SERVICE_CLASS_CODE__} = $p;
994             }
995              
996             # For internal use only. Checks that the value for a field fits and warns if not.
997             sub check_length {
998 0     0 0   my ($p, $field) = @_;
999 0           my $rules = format_rules();
1000 0 0 0       carp "Field '$field' not found in format rules!" and return unless $rules->{$field};
1001 0           (my $length = $rules->{$field}) =~ s/^%-?0*(\d+).*/$1/;
1002 0 0 0       carp "Value '$p' for field $field will be truncated to '".sprintf($rules->{$field}, $p)."'!"
1003             and return 0 if length $p > $length;
1004 0           return 1;
1005             }
1006              
1007             =pod
1008              
1009             =head1 NOTES
1010              
1011             The ACH record format is officially documented in the NACHA I
1012             Rules & Guidelines> publication, which is not freely available. It can
1013             be purchased at: https://www.nacha.org/achrules
1014              
1015             ACH file structure:
1016              
1017             File Header
1018             Batch Header
1019             Entries
1020             Batch Control
1021             Batch Header
1022             Entries
1023             Batch Control
1024             File Control
1025              
1026             =head1 LIMITATIONS
1027              
1028             Only certain types of ACH transactions are supported (see the detail
1029             record format above).
1030              
1031             =head1 ENCODING
1032              
1033             The ACH file format only supports ASCII characters. All data is converted to
1034             ASCII using Encode::encode(). Any non-ASCII characters in the input are
1035             replaced with a substitution character ("?").
1036              
1037             =head1 AUTHOR
1038              
1039             Tim Keefer
1040              
1041             =head1 CONTRIBUTORS
1042              
1043             =over 4
1044              
1045             =item *
1046              
1047             Cameron Baustian
1048              
1049             =item *
1050              
1051             Steven N. Severinghaus
1052              
1053             =back
1054              
1055             =head1 COPYRIGHT
1056              
1057             Tim Keefer, Cameron Baustian
1058              
1059             =cut
1060              
1061             1;