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   286704 use strict;
  9         45  
  9         254  
4 9     9   45 use warnings;
  9         17  
  9         247  
5 9     9   46 use vars qw($VERSION @EXPORT_OK);
  9         16  
  9         455  
6 9     9   49 use Carp qw(croak);
  9         17  
  9         455  
7 9     9   4600 use Params::Validate qw(validate_pos SCALAR OBJECT ARRAYREF );
  9         82470  
  9         680  
8 9     9   4719 use Readonly;
  9         36348  
  9         469  
9 9     9   168 use 5.008; #5.8.0
  9         34  
10              
11 9     9   52 use base qw(Exporter);
  9         19  
  9         1236  
12              
13             $VERSION = '0.12';
14             @EXPORT_OK = qw(validate validateCVR generate _calculate_sum);
15              
16 9     9   59 use constant MODULUS_OPERAND => 11;
  9         19  
  9         506  
17 9     9   99 use constant MAX_CVRS => 9090908;
  9         22  
  9         413  
18 9     9   50 use constant VALID => 1;
  9         25  
  9         445  
19 9     9   55 use constant INVALID => 0;
  9         37  
  9         5247  
20              
21             Readonly my @controlcifers => qw(2 7 6 5 4 3 2 1);
22              
23             sub validateCVR {
24 7     7 1 266 return validate(shift);
25             }
26              
27             sub validate {
28 140     140 1 440 my ($controlnumber) = @_;
29              
30 140         1395 validate_pos( @_, { type => SCALAR, regex => qr/^\d{8}$/ } );
31              
32 129         992 my $sum = _calculate_sum( $controlnumber, \@controlcifers );
33              
34 129 100       232 if ( $sum % MODULUS_OPERAND ) {
35 109         196 return INVALID;
36             } else {
37 20         61 return VALID;
38             }
39             }
40              
41             sub _calculate_sum {
42 129     129   203 my ( $number, $controlcifers ) = @_;
43              
44 129         1018 validate_pos( @_,
45             { type => SCALAR, regex => qr/^\d+$/ },
46             { type => ARRAYREF },
47             );
48              
49 129         1067 my $sum = 0;
50 129         351 my @numbers = split //smx, $number;
51              
52 129         269 for ( my $i = 0; $i < scalar @numbers; $i++ ) {
53 1032         5651 $sum += $numbers[$i] * $controlcifers->[$i];
54             }
55 129         762 return $sum;
56             }
57              
58             sub generate {
59 8     8 1 261 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         30 my ( $self, $amount, $seed ) = @array;
66              
67 8 100 100     51 if ( defined $self and $self =~ m/\d+/ ) {
68 2         4 $seed = $amount;
69 2         3 $amount = $self;
70             }
71              
72 8         13 my @cvrs;
73             my $cvr;
74              
75 8 100       14 if ( $amount > MAX_CVRS ) {
76 1         16 croak 'The amount requested exceeds the maximum possible valid CVRs ('
77             . MAX_CVRS . ')';
78             }
79              
80 7         9 my $count = $amount;
81 7         12 while ($count) {
82 113         228 $cvr = sprintf '%08d', $seed;
83 113 100       186 if ( validate($cvr) ) {
84 9         15 push @cvrs, $cvr;
85 9         10 $count--;
86             }
87 113         175 $seed++;
88             }
89              
90 7 100       11 if (wantarray) {
91 2         12 return @cvrs;
92             } else {
93 5 100       11 if ( $amount == 1 ) {
94 3         12 return $cvr;
95             } else {
96 2         10 return \@cvrs;
97             }
98             }
99             }
100              
101             1;
102              
103             __END__