File Coverage

blib/lib/Business/DK/CVR.pm
Criterion Covered Total %
statement 69 69 100.0
branch 12 12 100.0
condition 3 3 100.0
subroutine 16 16 100.0
pod 3 3 100.0
total 103 103 100.0


line stmt bran cond sub pod time code
1             package Business::DK::CVR;
2              
3 9     9   324396 use strict;
  9         50  
  9         274  
4 9     9   45 use warnings;
  9         18  
  9         259  
5 9     9   46 use vars qw($VERSION @EXPORT_OK);
  9         16  
  9         475  
6 9     9   52 use Carp qw(croak);
  9         17  
  9         479  
7 9     9   5076 use Params::Validate qw(validate_pos SCALAR OBJECT ARRAYREF );
  9         86610  
  9         703  
8 9     9   4910 use Readonly;
  9         36529  
  9         460  
9 9     9   169 use 5.008; #5.8.0
  9         35  
10              
11 9     9   55 use base qw(Exporter);
  9         25  
  9         1245  
12              
13             $VERSION = '0.11';
14             @EXPORT_OK = qw(validate validateCVR generate _calculate_sum);
15              
16 9     9   68 use constant MODULUS_OPERAND => 11;
  9         18  
  9         494  
17 9     9   97 use constant MAX_CVRS => 9090908;
  9         23  
  9         436  
18 9     9   57 use constant VALID => 1;
  9         23  
  9         456  
19 9     9   55 use constant INVALID => 0;
  9         41  
  9         5500  
20              
21             Readonly my @controlcifers => qw(2 7 6 5 4 3 2 1);
22              
23             sub validateCVR {
24 7     7 1 335 return validate(shift);
25             }
26              
27             sub validate {
28 140     140 1 533 my ($controlnumber) = @_;
29              
30 140         1692 validate_pos( @_, { type => SCALAR, regex => qr/^\d{8}$/ } );
31              
32 129         1211 my $sum = _calculate_sum( $controlnumber, \@controlcifers );
33              
34 129 100       282 if ( $sum % MODULUS_OPERAND ) {
35 109         275 return INVALID;
36             } else {
37 20         69 return VALID;
38             }
39             }
40              
41             sub _calculate_sum {
42 129     129   246 my ( $number, $controlcifers ) = @_;
43              
44 129         1159 validate_pos( @_,
45             { type => SCALAR, regex => qr/^\d+$/ },
46             { type => ARRAYREF },
47             );
48              
49 129         1276 my $sum = 0;
50 129         406 my @numbers = split //smx, $number;
51              
52 129         317 for ( my $i = 0; $i < scalar @numbers; $i++ ) {
53 1032         6915 $sum += $numbers[$i] * $controlcifers->[$i];
54             }
55 129         924 return $sum;
56             }
57              
58             sub generate {
59 8     8 1 310 my @array = validate_pos( @_,
60             { type => OBJECT | SCALAR, optional => 1 },
61             { type => SCALAR, optional => 1, default => 1 },
62             { type => SCALAR, optional => 1, default => 1 },
63             );
64              
65 8         35 my ( $self, $amount, $seed ) = @array;
66              
67 8 100 100     53 if ( defined $self and $self =~ m/\d+/ ) {
68 2         5 $seed = $amount;
69 2         3 $amount = $self;
70             }
71              
72 8         17 my @cvrs;
73             my $cvr;
74              
75 8 100       17 if ( $amount > MAX_CVRS ) {
76 1         19 croak 'The amount requested exceeds the maximum possible valid CVRs ('
77             . MAX_CVRS . ')';
78             }
79              
80 7         12 my $count = $amount;
81 7         14 while ($count) {
82 113         285 $cvr = sprintf '%08d', $seed;
83 113 100       181 if ( validate($cvr) ) {
84 9         20 push @cvrs, $cvr;
85 9         14 $count--;
86             }
87 113         207 $seed++;
88             }
89              
90 7 100       15 if (wantarray) {
91 2         18 return @cvrs;
92             } else {
93 5 100       10 if ( $amount == 1 ) {
94 3         18 return $cvr;
95             } else {
96 2         16 return \@cvrs;
97             }
98             }
99             }
100              
101             1;
102              
103             __END__