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   17250 use Moose;
  0            
  0            
4             use DateTime;
5             use Try::Tiny;
6             our $VERSION = '0.92';
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__
79              
80             =encoding utf-8
81              
82             =head1 NAME
83              
84             Business::AT::SSN
85              
86             =head1 SYNOPSIS
87              
88             use Business::AT::SSN;
89              
90             =head1 DESCRIPTION
91              
92             Business::AT::SSN checks Austrian social security numbers (Sozialversicherungsnummer)
93             for wellformed-ness according to
94             https://www.sozialversicherung.at/portal27/portal/ecardportal/content/contentWindow?&contentid=10008.551806&action=b&cacheability=PAGE
95              
96             if possible (not all SSNs contain a valid date) it also creates a DateTime Object with the
97             date of birth
98              
99             =head1 METHODS
100            
101             =over 4
102            
103             =item my $obj = Business::AT::SSN->new([$ssn])
104            
105             The new constructor optionally takes a ssn number
106            
107             =item $obj->ssn([$ssn])
108            
109             if no argument is given, it returns the current ssn number.
110             if an argument is provided, it will set the ssn number.
111            
112             =item $obj->is_valid()
113            
114             Returns true if the ssn number is valid.
115            
116             =item $obj->date_of_birth
117              
118             Returns the date of birth as a DateTime object
119              
120             =item $array_ref = $obj->error_messages
121              
122             Returns a array ref of error messages after calling is_valid
123              
124             =back
125            
126             =head1 AUTHOR
127              
128             Mark Hofstetter E<lt>mark@hofstetter.atE<gt>
129              
130             =head1 COPYRIGHT
131              
132             Copyright 2014- Mark Hofstetter
133              
134             =head1 LICENSE
135              
136             This library is free software; you can redistribute it and/or modify
137             it under the same terms as Perl itself.
138              
139             =head1 SEE ALSO
140              
141             =cut