File Coverage

blib/lib/Business/BR/PIS.pm
Criterion Covered Total %
statement 28 36 77.7
branch 10 14 71.4
condition 2 3 66.6
subroutine 8 10 80.0
pod 0 5 0.0
total 48 68 70.5


line stmt bran cond sub pod time code
1            
2             package Business::BR::PIS;
3            
4 3     3   42635 use 5;
  3         9  
5 3     3   20 use strict;
  3         6  
  3         105  
6 3     3   17 use warnings;
  3         5  
  3         370  
7            
8             require Exporter;
9            
10             our @ISA = qw(Exporter);
11            
12             #our %EXPORT_TAGS = ( 'all' => [ qw() ] );
13             #our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
14             #our @EXPORT = qw();
15            
16             our @EXPORT_OK = qw( canon_pis format_pis parse_pis random_pis );
17             our @EXPORT = qw( test_pis );
18            
19             our $VERSION = '0.00_16';
20            
21 3     3   990 use Business::BR::Ids::Common qw(_dot _canon_id);
  3         7  
  3         1791  
22            
23             sub canon_pis {
24 206     206 0 399 return _canon_id(shift, size => 11);
25             }
26            
27            
28             # there is a subtle difference here between the return for
29             # for an input which is not 11 digits long (undef)
30             # and one that does not satisfy the check equations (0).
31             # Correct PIS numbers return 1.
32             sub test_pis {
33 206     206 0 1980 my $pis = canon_pis shift;
34 206 100       379 return undef if length $pis != 11;
35 205         527 my @pis = split '', $pis;
36 205         711 my $sum = _dot([qw(3 2 9 8 7 6 5 4 3 2 1)], \@pis) % 11;
37 205 100 66     1455 return ($sum==0 || $sum==1 && $pis[10]==0) ? 1 : 0;
38             }
39            
40             sub format_pis {
41 0     0 0 0 my $pis = canon_pis shift;
42 0         0 $pis =~ s/^(...)(.....)(..)(.).*/$1.$2.$3-$4/; # 999.99999.99-9
43 0         0 return $pis;
44             }
45            
46             sub parse_pis {
47 0     0 0 0 my $pis = canon_pis shift;
48 0         0 my ($base, $dv) = $pis =~ /(\d{10})(\d{1})/;
49 0 0       0 if (wantarray) {
50 0         0 return ($base, $dv);
51             }
52 0         0 return { base => $base, dv => $dv };
53             }
54            
55             # my $dv = _dv_pis('121.51144.13-7') # => $dv1 =
56             # my $dv = _dv_pis('121.51144.13-7', 0) # computes non-valid check digit
57             #
58             # computes the check digit of the candidate PIS number given as argument
59             # (only the first 10 digits enter the computation)
60             #
61             # In list context, it returns the check digit.
62             # In scalar context, it returns the complete PIS (base and check digits)
63             sub _dv_pis {
64 200     200   184 my $base = shift; # expected to be canon'ed already ?!
65 200 50       244 my $valid = @_ ? shift : 1;
66 200 100       244 my $dev = $valid ? 0 : 2; # deviation (to make PIS invalid)
67 200         751 my @base = split '', substr($base, 0, 10);
68 200         796 my $dv = (-_dot([qw(3 2 9 8 7 6 5 4 3 2)], \@base) + $dev) % 11 % 10;
69 200 50       479 return ($dv) if wantarray;
70 200         306 substr($base, 10, 1) = $dv;
71 200         508 return $base;
72             }
73            
74             # generates a random (correct or incorrect) PIS
75             # $pis = rand_pis();
76             # $pis = rand_pis($valid);
77             #
78             # if $valid==0, produces an invalid PIS.
79             sub random_pis {
80 200 100   200 0 64450 my $valid = @_ ? shift : 1; # valid PIS by default
81 200         829 my $base = sprintf "%010s?", int(rand(1E10)); # 10 dígitos
82 200         290 return scalar _dv_pis($base, $valid);
83             }
84            
85             1;
86            
87             __END__