File Coverage

blib/lib/Business/FR/RIB.pm
Criterion Covered Total %
statement 58 59 98.3
branch 11 14 78.5
condition 5 8 62.5
subroutine 13 13 100.0
pod 7 7 100.0
total 94 101 93.0


line stmt bran cond sub pod time code
1             package Business::FR::RIB;
2 2     2   58061 use Math::BigInt;
  2         59767  
  2         11  
3 2     2   36716 use strict;
  2         3  
  2         77  
4              
5             BEGIN {
6 2     2   11 use Exporter ();
  2         10  
  2         46  
7 2     2   13 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  2         4  
  2         266  
8 2     2   4 $VERSION = '0.05';
9 2         36 @ISA = qw(Exporter);
10             #Give a hoot don't pollute, do not export more than needed by default
11 2         5 @EXPORT = qw();
12 2         4 @EXPORT_OK = qw();
13 2         1381 %EXPORT_TAGS = ();
14             }
15              
16             ########################################################################
17              
18             =head1 NAME
19              
20             Business::FR::RIB - Verify French RIB (Releve d'Identite Bancaire)
21              
22             =head1 VERSION
23              
24             Version 0.05
25              
26             =head1 SYNOPSIS
27              
28             use Business::FR::RIB;
29             my $object = Business::FR::RIB->new('1234567890DWFACEOFBOE08');
30             print "RIB valid" if $object->is_valid();
31              
32             =head1 DESCRIPTION
33              
34             This module determines whether a French RIB (Releve d'Identite Bancaire)
35             is well-formed.
36              
37             Please note that there is no way to determine whether a RIB is linked to
38             a true bank account without using it or asking the bank.
39              
40             =head1 METHODS
41              
42             =cut
43              
44             ########################################################################
45              
46             sub _check_rib {
47 5     5   10 my ($class, $rib) = @_;
48              
49 5         13 $rib =~ s/\s+//g;
50              
51 5 100       27 return '' if($rib !~ m/^\d{10}[\da-zA-Z]{11}(\d{2})$/);
52              
53             # check the RIB key
54 3 50 33     42 return '' if($1 > 97 || $1 < 1);
55              
56 3         14 return $rib;
57             }# sub _check_rib
58              
59             ########################################################################
60              
61             =head2 new
62              
63             Usage : my $object = Business::FR::RIB->new();
64             Purpose : Constructor
65             Returns : A Business::FR::RIB object
66             Argument : The new constructor optionally takes a RIB string
67              
68             =cut
69              
70             ########################################################################
71              
72             sub new {
73 3     3 1 912 my ($class, $rib) = @_;
74              
75 3         12 my $self = bless \$rib, $class;
76              
77 3   100     20 $rib ||= '';
78 3         13 $rib = $self->_check_rib($rib);
79              
80 3         10 return $self;
81             }# sub new
82              
83             ########################################################################
84              
85             =head2 is_valid
86              
87             Usage : $object->is_valid();
88             Purpose : Check if the RIB is well-formed
89             Returns : 1 or 0
90             Argument : Optionally take the RIB string as argument
91             Comment : Please note that there is no way to determine
92             : whether a RIB is linked to a true bank account
93             : without using it or asking the bank.
94              
95             =cut
96              
97             ########################################################################
98              
99             sub is_valid {
100 3     3 1 8 my $self = shift;
101 3         5 my $rib = shift;
102              
103 3 100       11 $$self = $self->_check_rib($rib) if($rib);
104              
105 3         7 my $cbanque = $self->get_code_banque();
106 3         8 my $cguichet = $self->get_code_guichet();
107 3         5 my $nocompte = $self->get_no_compte();
108 3         7 my $clerib = $self->get_cle_rib();
109              
110 3         46 my %letter_substitution = ("A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5, "F" => 6, "G" => 7, "H" => 8, "I" => 9,
111             "J" => 1, "K" => 2, "L" => 3, "M" => 4, "N" => 5, "O" => 6, "P" => 7, "Q" => 8, "R" => 9,
112             "S" => 2, "T" => 3, "U" => 4, "V" => 5, "W" => 6, "X" => 7, "Y" => 8, "Z" => 9);
113 3         5 my $tabcompte = "";
114              
115 3         4 my $len = length($nocompte);
116 3 50       7 return 0 if ($len != 11);
117              
118 3         7 for (my $i = 0; $i < $len; $i++) {
119 33         31 my $car = substr($nocompte, $i, 1);
120 33 50       53 if ($car !~ m/^\d$/) {
121 33         38 my $b = $letter_substitution{uc($car)};
122 33         75 my $c = ( $b + 2**(($b - 10)/9) ) % 10;
123 33         74 $tabcompte .= $c;
124             } else {
125 0         0 $tabcompte .= $car;
126             }
127             }
128 3         5 my $int = "$cbanque$cguichet$tabcompte$clerib";
129 3 100 66     26 return (length($int) >= 21 && Math::BigInt->new($int)->bmod(97) == 0) ? 1 : 0;
130             }# sub valid_rib
131              
132             ########################################################################
133              
134             =head2 rib
135              
136             Usage : $object->rib();
137             Purpose : Get and optionnally or set the object's RIB
138             Returns : The RIB
139             Argument : The rib method optionally takes a RIB string
140              
141             =cut
142              
143             ########################################################################
144              
145             sub rib {
146 2     2 1 2 my $self = shift;
147 2         3 my $rib = shift;
148              
149 2 100       7 $$self = $self->_check_rib($rib) if ($rib);
150              
151 2         8 return $$self;
152             }# sub rib
153              
154             ########################################################################
155              
156             =head2 get_code_banque
157              
158             Usage : $object->get_code_banque();
159             Returns : The bank code
160              
161             =cut
162              
163             ########################################################################
164              
165             sub get_code_banque {
166 4     4 1 6 my $self = shift;
167              
168 4         11 return substr($$self, 0, 5);
169             }# sub get_code_banque
170              
171             ########################################################################
172              
173             =head2 get_code_guichet
174              
175             Usage : $object->get_code_guichet();
176             Returns : The counter code
177              
178             =cut
179              
180             ########################################################################
181              
182             sub get_code_guichet {
183 4     4 1 6 my $self = shift;
184              
185 4         10 return substr($$self, 5, 5);
186             }# sub get_code_guichet
187              
188             ########################################################################
189              
190             =head2 get_no_compte
191              
192             Usage : $object->get_no_compte();
193             Returns : The RIB account number
194              
195             =cut
196              
197             ########################################################################
198              
199             sub get_no_compte {
200 4     4 1 5 my $self = shift;
201              
202 4         11 return substr($$self, 10, 11);
203             }# sub get_no_compte
204              
205             ########################################################################
206              
207             =head2 get_cle_rib
208              
209             Usage : $object->get_cle_rib();
210             Returns : The RIB key
211              
212             =cut
213              
214             ########################################################################
215              
216             sub get_cle_rib {
217 4     4 1 6 my $self = shift;
218              
219 4         10 return substr($$self, 21,2);
220             }# sub get_cle_rib
221              
222             ########################################################################
223              
224             =head1 BUGS and SUPPORT
225              
226             You can find documentation for this module with the perldoc command.
227              
228             perldoc Business::FR::RIB
229              
230             Bugs and feature requests will be tracked at RT:
231              
232             http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Business-FR-RIB
233             bug-business-fr-rib at rt.cpan.org
234              
235             The latest source code can be browsed and fetched at:
236              
237             https://dev.fiat-tux.fr/projects/business-fr-rib
238             git clone git://fiat-tux.fr/Business-FR-RIB.git
239              
240             You can also look for information at:
241              
242             =over 4
243              
244             =item * RT: CPAN's request tracker
245              
246             L
247              
248             =item * AnnoCPAN: Annotated CPAN documentation
249              
250             L
251              
252             =item * CPAN Ratings
253              
254             L
255              
256             =item * Search CPAN
257              
258             L
259              
260             =back
261              
262             =head1 AUTHOR
263              
264             Luc DIDRY
265             CPAN ID: LDIDRY
266             ldidry@cpan.org
267             http://www.fiat-tux.fr/
268              
269             =head1 COPYRIGHT
270              
271             This program is free software; you can redistribute
272             it and/or modify it under the same terms as Perl itself.
273              
274             The full text of the license can be found in the
275             LICENSE file included with this module.
276              
277              
278             =head1 SEE ALSO
279              
280             perl(1).
281              
282             =cut
283              
284             1;