File Coverage

blib/lib/Business/AT/SSN.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Business::AT::SSN;
2              
3 1     1   15705 use Moose;
  0            
  0            
4             use DateTime;
5             use Try::Tiny;
6             our $VERSION = '0.91';
7              
8             # ABSTRACT: verify Austrian Social Securtiy numbers
9              
10             has 'ssn' => (isa => 'Str', is => 'rw');
11             has 'date_of_birth' => (isa => 'DateTime', is => 'rw', clearer => 'clear_dob',);
12             has 'error_messages' => (isa => 'ArrayRef', is => 'rw', clearer => 'clear' );
13              
14              
15             # this is the rare case where an example may be used as is
16             around BUILDARGS => sub {
17             my $orig = shift;
18             my $class = shift;
19              
20             if ( @_ == 1 && !ref $_[0] ) {
21             return $class->$orig( ssn => $_[0] );
22             }
23             else {
24             return $class->$orig(@_);
25             }
26             };
27              
28             __PACKAGE__->meta->make_immutable;
29              
30             sub checksum {
31             my $self = shift;
32             my @multiplicators = (3,7,9,0,5,8,4,2,1,6);
33             my @num = split('', $self->ssn);
34             my $i = 0;
35             my $sum = 0;
36             foreach my $d (@multiplicators) {
37             last unless defined $num[$i];
38             $sum += $d * $num[$i++];
39             }
40             return 1 unless $sum%11 == $num[3];
41             }
42              
43             sub get_dob {
44             my $self = shift;
45             my ($d, $m, $y) = $self->ssn =~ /^\d{4}(\d{2})(\d{2})(\d{2})$/;
46             my $now = DateTime->now;
47             # guess a year
48             $y = (($now->year) - ($y + 1900) < 100) ? $y + 1900 : $y + 2000;
49             try {
50             my $dt = DateTime->new(year => $y, month => $m, day => $d);
51             $self->date_of_birth( $dt );
52             return 1;
53             } catch {
54             $self->clear_dob;
55             return 0;
56             };
57             }
58              
59             sub is_valid {
60             my $self = shift;
61             die 'ssn not not set' unless $self->ssn;
62             my @error_messages;
63             push(@error_messages, 'Wrong length') if length($self->ssn) != 10;
64             push(@error_messages, 'Invalid characters') if $self->ssn =~ /\D/;
65             $self->error_messages(\@error_messages);
66             return 0 unless scalar @error_messages == 0;
67             # calculate checksum only if nothing else fails
68             $self->error_messages(\@error_messages);
69             push(@error_messages, 'Wrong checksum') if $self->checksum != 1;
70             return 0 unless scalar @error_messages == 0;
71             $self->get_dob;
72             return 1;
73             }
74              
75              
76              
77             1;
78             __END__