File Coverage

blib/lib/Business/DK/PO.pm
Criterion Covered Total %
statement 90 90 100.0
branch 26 26 100.0
condition n/a
subroutine 19 19 100.0
pod 3 3 100.0
total 138 138 100.0


line stmt bran cond sub pod time code
1             package Business::DK::PO;
2              
3 7     7   158458 use strict;
  7         17  
  7         233  
4 7     7   36 use warnings;
  7         11  
  7         233  
5 7     7   4497 use integer;
  7         62  
  7         33  
6 7     7   220 use Carp qw(croak);
  7         10  
  7         537  
7 7     7   34 use vars qw($VERSION @EXPORT_OK);
  7         11  
  7         432  
8 7     7   154 use 5.006;
  7         21  
9              
10 7     7   31 use base qw(Exporter);
  7         7  
  7         1005  
11              
12             my @controlcifers = qw(2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1);
13              
14             $VERSION = '0.08';
15             @EXPORT_OK =
16             qw(calculate validate validatePO _argument _content _length _calculate_sum);
17              
18 7     7   38 use constant CONTROLCODE_LENGTH => 16;
  7         9  
  7         578  
19 7     7   35 use constant INVOICE_MINLENGTH => 1;
  7         8  
  7         436  
20 7     7   93 use constant INVOICE_MAXLENGTH => 15;
  7         12  
  7         390  
21 7     7   31 use constant MODULUS_OPERAND => 10;
  7         9  
  7         358  
22 7     7   34 use constant SUM_THRESHOLD => 9;
  7         8  
  7         4589  
23              
24             sub calculate {
25 17     17 1 5205 my ( $number, $maxlength, $minlength ) = @_;
26              
27 17 100       63 if ( !$minlength ) {
28 15         16 $minlength = INVOICE_MINLENGTH;
29             }
30              
31 17 100       26 if ( !$maxlength ) {
32 15         12 $maxlength = INVOICE_MAXLENGTH;
33             }
34              
35 17 100       30 if ( !$number ) {
36 1         3 _argument( $minlength, $maxlength );
37             }
38 16         25 _content($number);
39 16         29 _length( $number, $minlength, $maxlength );
40              
41 15         23 my $format = '%0' . $maxlength . 's';
42 15         44 $number = sprintf "$format", $number;
43              
44 15         21 my $sum = _calculate_sum($number);
45              
46 15         14 my $mod = $sum % MODULUS_OPERAND;
47 15         8 my $checkciffer = 0;
48              
49 15         14 $checkciffer = ( MODULUS_OPERAND - $mod );
50              
51 15         47 return ( $number . $checkciffer );
52             }
53              
54             ## no critic (RequireArgUnpacking)
55             sub validatePO {
56 8     8 1 160 return validate(@_);
57             }
58              
59             sub validate {
60 30     30 1 1531 my $controlnumber = shift;
61              
62 30 100       68 if ( !$controlnumber ) {
63 5         19 _argument(CONTROLCODE_LENGTH);
64             }
65 25         44 _content($controlnumber);
66 22         40 _length( $controlnumber, CONTROLCODE_LENGTH );
67              
68 18         30 my $sum = _calculate_sum($controlnumber);
69              
70 18 100       38 if ( $sum % MODULUS_OPERAND ) {
71 2         10 return 0;
72             }
73             else {
74 16         56 return 1;
75             }
76             }
77              
78             sub _argument {
79 9     9   1647 my ( $length, $maxlen ) = @_;
80              
81 9 100       31 if ($maxlen) {
    100          
82 2         43 croak
83             "function takes an argument of minimum: $length and maximum $maxlen digits";
84              
85             }
86             elsif ($length) {
87 6         100 croak "function takes an argument of $length digits";
88             }
89             else {
90 1         17 croak "function takes an argument";
91             }
92             }
93              
94             sub _content {
95 41     41   40 my $number = shift;
96              
97 41 100       183 if ( $number !~ /^\d*$/ ) {
98 3         37 croak "argument: $number must only contain digits";
99             }
100 38         40 return 1;
101             }
102              
103             sub _length {
104 40     40   1163 my ( $number, $length, $maxlen ) = @_;
105              
106 40 100       72 if ($maxlen) {
107 18 100       53 if ( length($number) < $length ) {
    100          
108 1         12 croak "argument: $number has to be $length digits long";
109              
110             }
111             elsif ( length($number) > $maxlen ) {
112 2         56 croak "argument: $number must be not more than $maxlen digits long";
113             }
114              
115             }
116             else {
117 22 100       58 if ( length($number) != $length ) {
118 4         50 croak "argument: $number has to be $length digits long";
119             }
120             }
121 33         36 return 1;
122             }
123              
124             sub _calculate_sum {
125 34     34   44 my $number = shift;
126              
127 34         38 my $sum = 0;
128 34         148 my @numbers = split( //, $number );
129              
130 34         83 for ( my $i = 0 ; $i < scalar(@numbers) ; $i++ ) {
131 512         336 my $tmpsum2 = 0;
132 512         536 my $tmpsum = $numbers[$i] * $controlcifers[$i];
133              
134 512 100       668 if ( $tmpsum > SUM_THRESHOLD ) {
135              
136             #TODO: address this construct
137             ## no critic (BuiltinFunctions::ProhibitVoidMap)
138 43         68 map( { $tmpsum2 += $_ } split( //, $tmpsum ) );
  86         102  
139 43         72 $tmpsum = $tmpsum2;
140             }
141 512         740 $sum += $tmpsum;
142             }
143              
144 34         82 return $sum;
145             }
146              
147             1;
148              
149             __END__