File Coverage

blib/lib/Business/TW/TSIB/CStorePayment.pm
Criterion Covered Total %
statement 61 61 100.0
branch 3 6 50.0
condition 4 9 44.4
subroutine 12 12 100.0
pod 3 3 100.0
total 83 91 91.2


line stmt bran cond sub pod time code
1             package Business::TW::TSIB::CStorePayment;
2              
3 3     3   21819 use warnings;
  3         4  
  3         114  
4 3     3   19 use strict;
  3         5  
  3         123  
5 3     3   1895 use Business::TW::TSIB::CStorePayment::Entry;
  3         8  
  3         23  
6 3     3   1330 use DateTime;
  3         262099  
  3         964  
7              
8             =head1 NAME
9              
10             Business::TW::TSIB::CStorePayment - Module for Taishin Bank Convenient Store Payment Management
11              
12             =cut
13              
14             our $VERSION = '0.04';
15              
16             =head1 SYNOPSIS
17              
18             use Business::TW::TSIB::CStorePayment;
19             my $csp = Business::TW::TSIB::CStorePayment->new({ corp_code => 'CPCU' });
20             my @bar = $csp->generate( { due => DateTime->new( year => 2007, month => 4, day => 2 ),
21             collect_until => DateTime->new( year => 2007, month => 4, day => 2 ),
22             amount => 3900,
23             ar_id => '20892' } );
24              
25             # render the code39 barcode with GD::Barcode
26             my @png = map { GD::Barcode::Code39->new("*$_*")->plot->png } @bar;
27              
28             # parse summary from file handler
29             my $entries = Business::TW::TSIB::CStorePayment->parse_summary($fh);
30              
31             # entries is arrayref of Business::TW::TSIB::CStorePayment::Entry objects,
32              
33             =head1 DESCRIPTION
34              
35             This module provides utility functions for the convenient store
36             payment collection service by TSIB (Taishin International Bank,
37             Taiwan).
38              
39             =head1 METHODS
40              
41             =head2 new( { corp_code => $corp_code} )
42              
43             Initialize the payment collection context with C provided
44             by TSIB.
45              
46             =cut
47              
48             sub new {
49 2     2 1 5 my $class = shift;
50 2         4 my $args = shift;
51 2         5 my $self = {};
52 2 50       15 die("No Given Corperation Code") if ( ! exists( $args->{corp_code} ));
53              
54 2         8 $self->{corp_code} = $args->{corp_code};
55              
56 2         11 return bless $self , $class;
57             }
58              
59             =head2 $csp->generate( $args )
60              
61             Generate bar codes for the given arguments. Returns a list of 3
62             strings that are to be printed as barcode. $args is a hash ref and
63             must contain:
64              
65             =over
66              
67             =item due
68              
69             A L object for due day of the payment.
70              
71             =item collect_until
72              
73             A L object for last collection date, default to C.
74              
75             =item amount
76              
77             The expected amount of the transaction.
78              
79             =item ar_id
80              
81             The arbitary account receivable identifier.
82              
83             =back
84              
85             =cut
86              
87             sub generate {
88 2     2 1 785 my $self = shift;
89 2         5 my $args = shift;
90              
91 2 50       4 map { die("No Given $_") if ( !exists( $args->{$_} ) ) } qw/due amount ar_id/;
  6         24  
92              
93 2   33     108 $args->{collect_until} ||= $args->{due};
94 2         77 my $bar1 = sprintf("%02d%02d%02d", $args->{due}->year-1911, $args->{due}->month, $args->{due}->day) . '627';
95 2         46 my $bar2 = $self->{corp_code}.sprintf("%0".(16 - length($self->{corp_code}))."s", $args->{ar_id});
96 2         8 my $bar3 = sprintf("%02d%02d", $args->{collect_until}->month, $args->{collect_until}->day).'00'.sprintf("%09d", $args->{amount});
97              
98 2         23 my $checksum = $self->_compute_checksum($bar1, $bar2, $bar3);
99 2         7 substr($bar3, 4, 2, $checksum);
100 2         9 return ($bar1, $bar2, $bar3);
101             }
102              
103 3     3   27 use List::Util qw(sum);
  3         6  
  3         375  
104 3     3   20 use List::MoreUtils qw(apply part);
  3         12  
  3         1989  
105              
106             sub _compute_checksum {
107 4     4   1779 my $self = shift;
108 4     12   54 my (@bar) = apply { tr/A-Z/1-91-92-9/ }@_;
  12         29  
109 4         18 my $str = $bar[0].'0'.$bar[1].$bar[2];
110 4         8 my $i = 0;
111 4     164   90 my @sum = map { (sum @$_) % 11 } part { $i++ % 2 } split //, $str;
  8         91  
  164         203  
112 4   33     53 $sum[0] = { 0 => 'A', '10' => 'B' } -> { $sum[0] } || $sum[0];
113 4   66     27 $sum[1] = { 0 => 'X', '10' => 'Y' } -> { $sum[1] } || $sum[1];
114 4         26 return join('', @sum);
115             }
116              
117             =head2 $self->parse_summary($fh)
118              
119             Parse CStore Payment file
120              
121             =cut
122              
123             sub parse_summary {
124 1     1 1 2039 my $self = shift;
125 1         18 my $fh = shift;
126              
127             # format:
128              
129             # debit date (8)
130             # paid date (8)
131             # payment id (16)
132             # amount (9)
133             # due (4)
134             # collection agent (8)
135             # payee account (14)
136              
137              
138 1         4 my @entries;
139 1         7 while (<$fh>) {
140 5         7 chomp;
141 5 50       11 next unless length $_;
142 5         4 my %cols;
143              
144             @cols{
145 5         38 qw/
146             debit_date
147             paid_date
148             payment_id
149             amount
150             due
151             collection_agent
152             payee_account/
153             }
154             = (
155             m/
156             (.{8}) # debit date
157             (.{8}) # paid date
158             (.{16}) # payment id
159             (.{9}) # amount
160             (.{4}) # due
161             (.{8}) # collection agent
162             (.{14}) # payee account
163             /x
164             );
165              
166             # trim
167 5         16 map { $cols{$_} =~ s/\s*$//g; $cols{$_} =~ s/^\s*//g; } keys %cols;
  35         129  
  35         93  
168              
169 5         12 $cols{amount} = int($cols{amount});
170              
171 5         25 my $entry = Business::TW::TSIB::CStorePayment::Entry->new( \%cols );
172 5         64 push @entries, $entry;
173             }
174 1         4 return \@entries;
175             }
176              
177             =head1 AUTHOR
178              
179             Chia-liang Kao, C<< >> ,
180              
181             =head1 BUGS
182              
183             Please report any bugs or feature requests to
184             C, or through the web interface at
185             L.
186             I will be notified, and then you'll automatically be notified of progress on
187             your bug as I make changes.
188              
189             =head1 SUPPORT
190              
191             You can find documentation for this module with the perldoc command.
192              
193             perldoc Business::TW::TSIB::CStorePayment
194              
195             You can also look for information at:
196              
197             =over 4
198              
199             =item * AnnoCPAN: Annotated CPAN documentation
200              
201             L
202              
203             =item * CPAN Ratings
204              
205             L
206              
207             =item * RT: CPAN's request tracker
208              
209             L
210              
211             =item * Search CPAN
212              
213             L
214              
215             =back
216              
217             =head1 ACKNOWLEDGEMENTS
218              
219             =head1 COPYRIGHT & LICENSE
220              
221             Copyright 2007 AIINK co., ltd, all rights reserved.
222              
223             This program is free software; you can redistribute it and/or modify it
224             under the same terms as Perl itself.
225              
226             =cut
227              
228              
229              
230              
231              
232             1; # End of Business::TW::TSIB::CStorePayment