File Coverage

blib/lib/Business/IBAN.pm
Criterion Covered Total %
statement 80 104 76.9
branch 13 32 40.6
condition 4 11 36.3
subroutine 13 17 76.4
pod 0 8 0.0
total 110 172 63.9


line stmt bran cond sub pod time code
1             package Business::IBAN;
2              
3             require 5.005_62;
4 1     1   28328 use Math::BigInt;
  1         33522  
  1         6  
5 1     1   20265 use strict;
  1         3  
  1         39  
6 1     1   4 use vars qw($VERSION @errors);
  1         8  
  1         67  
7              
8             $VERSION = '0.06';
9              
10             # error codes
11 1     1   5 use constant IBAN_CTR => 0;
  1         1  
  1         45  
12 1     1   5 use constant IBAN_BBAN => 1;
  1         1  
  1         34  
13 1     1   4 use constant IBAN_ISO => 2;
  1         2  
  1         63  
14 1     1   5 use constant IBAN_FORMAT => 3;
  1         2  
  1         36  
15 1     1   4 use constant IBAN_FORMAT2 => 4;
  1         1  
  1         37  
16 1     1   5 use constant IBAN_INVALID => 5;
  1         2  
  1         1018  
17              
18             sub new {
19 1     1 0 13 my ($class) = @_;
20 1         3 my $self = {};
21 1         3 bless $self, $class;
22 1         3 return $self;
23             } ## end sub new
24             # --------------------------------------
25             sub getIBAN {
26 1     1 0 11 my ($self, $args) = @_;
27 1         3 my $iso = uc $args->{ISO};
28 1         3 my $bban = $args->{BBAN};
29 1         3 my $bic = $args->{BIC};
30 1         2 my $ac = $args->{AC};
31 1         6 delete $self->{ERRORS};
32 1 50       4 push @{$self->{ERRORS}}, IBAN_CTR unless $iso ;
  0         0  
33 1 50 33     11 push @{$self->{ERRORS}}, IBAN_BBAN unless $bban || ($bic && $ac);
  0   33     0  
34 1 50       4 return if $self->{ERRORS};
35 1 50       4 $iso =~ tr/A-Za-z//cd if $iso;
36 1 50       4 $bban =~ tr/A-Za-z09//cd if $bban;
37 1 50       8 $ac =~ tr/A-Za-z09//cd if $ac;
38              
39 1 50       17 return unless $iso;
40 1         3 $iso = uc $iso;
41 1         3 $args->{CV} = $iso;
42 1         6 $args->{CV} =~ s/([A-Z])/(ord $1)-55/eg;
  2         8  
43 1         2 my $no;
44 1         3 $args->{ISO} = $iso;
45 1         3 for ($iso) {
46 1 50       10 m/^DE$/ and $no = $self->iban_de($args), last;
47 0         0 $no = $self->iban_unspec($args);
48             }
49 1         4 return $no;
50             }
51             # --------------------------------------
52             sub iban_de {
53 1     1 0 2 my $self = shift;
54 1         3 my $args = shift;
55 1   33     12 $args->{BBAN} ||= sprintf "%08s%010s", $args->{BIC},$args->{AC};
56 1         4 my $no = sprintf "%018s%4s00", $args->{BBAN}, $args->{CV};
57 1         16 my $tmp = $no % 97;
58 1         12 my $bigint = Math::BigInt->new($no);
59 1         136 my $mod = sprintf "%2d", 98 - ($bigint % 97);
60 1         392 substr($no,-6,6) = "";
61 1         5 $no = 'IBAN '.$args->{ISO}.$mod.$no;
62 1         4 return $no;
63             }
64             # --------------------------------------
65             sub iban_unspec {
66 0     0 0 0 my $self = shift;
67 0         0 my $args = shift;
68 0 0       0 push @{$self->{ERRORS}}, IBAN_BBAN unless $args->{BBAN};
  0         0  
69 0 0       0 return if $self->{ERRORS};
70 0         0 my $no = sprintf "%s%4s00", $args->{BBAN}, $args->{CV};
71 0         0 my $bigint = Math::BigInt->new($no);
72 0         0 my $mod = 98 - ($bigint % 97);
73 0         0 substr($no,-6,6) = "";
74 0         0 $no = 'IBAN '.$args->{ISO}.$mod.$no;
75 0         0 return $no;
76             }
77             # --------------------------------------
78             sub getError {
79 0 0   0 0 0 return unless $_[0]->{ERRORS};
80 0         0 return @{$_[0]->{ERRORS}};
  0         0  
81             }
82             # --------------------------------------
83             sub printError {
84 0 0   0 0 0 return unless $_[0]->{ERRORS};
85 0         0 print "$errors[$_]\n" for @{$_[0]->{ERRORS}};
  0         0  
86             }
87             # --------------------------------------
88             sub country {
89 0     0 0 0 return $_[0]->{COUNTRY};
90             }
91             # --------------------------------------
92             sub valid {
93 2     2 0 678 my ($self, $ib) = @_;
94 2         5 delete $self->{ERRORS};
95             # remove spaces
96 2         4 $ib =~ tr/ //d;
97             # invalid characters
98             #(push @{$self->{ERRORS}}, IBAN_FORMAT2), return if $ib =~ tr/A-Za-z0-9//c;
99 2         30 $ib =~ s/^IBAN//i;
100 2 50       9 push @{$self->{ERRORS}}, IBAN_FORMAT unless $ib =~ m/^[A-Z][A-Z]/i;
  0         0  
101 2 50       6 return if $self->{ERRORS};
102 2         5 my $iso = substr $ib, 0, 2, "";
103 2         8 $iso =~ s/([A-Z])/(ord $1)-55/eg;
  4         11  
104 2         5 my $check = substr $ib, 0, 2, "";
105             # convert alpha characters to their ascii code
106 2         3 $ib =~ s/([A-Z])/(ord $1)-55/eg;
  0         0  
107             # iban still contains characters which are not numbers!
108 2 50       7 (push @{$self->{ERRORS}}, IBAN_FORMAT2), return if $ib =~ tr/0-9//c;
  0         0  
109 2         3 $ib .= "$iso$check";
110 2         7 $ib = Math::BigInt->new($ib);
111 2 100 50     76 push @{$self->{ERRORS}}, IBAN_INVALID and return unless ($ib % 97)==1;
  1         241  
112 1         214 return 1;
113             }
114             # --------------------------------------
115              
116             @errors = (
117             "No Country or Iso-Code supplied",
118             "No BBAN (Bank-Number) or Bank Identifier and Accountnumber supplied",
119             "Could not find country",
120             "IBAN must contain two-letter ISO-Code at the beginning",
121             "IBAN must only contain only alphanumerics after the ISO-code",
122             "IBAN is invalid",
123             );
124              
125             1;
126             __END__