File Coverage

blib/lib/Finance/Bank/AllianceAndLeicester.pm
Criterion Covered Total %
statement 12 67 17.9
branch 0 32 0.0
condition 0 3 0.0
subroutine 4 5 80.0
pod 1 1 100.0
total 17 108 15.7


line stmt bran cond sub pod time code
1             package Finance::Bank::AllianceAndLeicester;
2              
3 1     1   22404 use strict;
  1         2  
  1         32  
4 1     1   6 use Carp;
  1         1  
  1         84  
5 1     1   1780 use HTML::TokeParser;
  1         15062  
  1         31  
6 1     1   1270 use WWW::Mechanize;
  1         271740  
  1         778  
7              
8             our $VERSION = '1.03';
9              
10             sub check_balance {
11              
12             # Get the inputs, and perform sanity checking.
13 0     0 1   my ($class, %opts) = @_;
14 0 0         croak 'Must provide a customer ID' unless exists $opts{customerid};
15 0 0         croak 'Must provide memorable information' unless exists $opts{memorable};
16 0 0         croak 'Must provide a unique phrase' unless exists $opts{phrase};
17 0 0         croak 'Must provide a PIN code' unless exists $opts{pin};
18 0 0         croak 'Customer ID should be 8 digits' unless $opts{customerid} =~ /^\d{8}$/;
19 0 0         croak 'PIN code should be 5 digits' unless $opts{pin} =~ /^\d{5}$/;
20              
21             # Initialise the output array.
22 0           my @accounts;
23              
24             # Submit the customer ID.
25 0           my $agent = WWW::Mechanize->new();
26 0           $agent->get('https://www.mybank.alliance-leicester.co.uk/index.asp');
27 0           $agent->submit_form(fields => {txtCustomerID => $opts{customerid}},
28             form_name => 'login');
29 0 0         croak 'Login failed' unless $agent->success();
30              
31             # Submit the memorable information, if necessary.
32 0 0         if ($agent->form_name('frmChangePIN')) {
33             # We've got an extra step to perform.
34 0           $agent->submit_form(fields => {txtMemDetail => $opts{memorable}},
35             form_name => 'frmChangePIN');
36 0 0         croak 'Failed to submit memorable data' unless $agent->success();
37             }
38              
39             # Check we have got the correct unique phrase.
40 0           my $content = $agent->content;
41 0 0         my $stream = HTML::TokeParser->new(\$content) or die $!;
42 0           for (my $a=0; $a < 5; $a++) {
43 0           $stream->get_tag('span');
44             }
45 0           my $phrase = $stream->get_trimmed_text('/span');
46              
47 0 0         croak 'Unique phrase mismatch' unless (lc($phrase) eq lc($opts{phrase}));
48              
49             # Submit the PIN number.
50 0           $agent->submit_form(fields => {txtCustomerPIN => $opts{pin}},
51             form_name => 'frmPM4point1');
52 0 0         croak 'Failed to submit PIN' unless $agent->success();
53              
54             # Check for login errors.
55 0           $content = $agent->content;
56 0 0         $stream = HTML::TokeParser->new(\$content) or die $!;
57 0           while (my $token = $stream->get_tag('div')) {
58 0 0 0       if ($token->[1]{'id'} && $token->[1]{'id'} eq 'error') {
59 0           my $error = $stream->get_trimmed_text('/div');
60 0           croak "Error during login: $error\n";
61 0           last; # This is just silly.
62             }
63             }
64              
65             # Save this data to parse later.
66 0           $content = $agent->{content};
67              
68             # We have the data we need, so let's log out.
69 0           $agent->get('https://www.mybank.alliance-leicester.co.uk/' .
70             'login/calls/logout.asp');
71              
72             # Begin parsing the HTML.
73 0 0         $stream = HTML::TokeParser->new(\$content) or die $!;
74 0           $stream->get_tag('tr');
75              
76 0           while (my $token = $stream->get_tag('tr')) {
77              
78 0           my($balance, $name, $overdraft, $account, $available_balance);
79              
80             # Get the account name and number.
81 0           $token = $stream->get_tag('td');
82 0           $name = $stream->get_trimmed_text('/td');
83 0           $name =~ s/\s(\d+)$//;
84 0           $account = $1;
85              
86             # Get the balance.
87 0           $stream->get_tag('td');
88 0           $balance = $stream->get_trimmed_text('/td');
89              
90             # Get the overdraft limit.
91 0           $stream->get_tag('td');
92 0           $overdraft = $stream->get_trimmed_text('/td');
93              
94             # Fix up the overdraft amount to zero, if there is no overdraft available.
95 0 0         $overdraft = 0 if ($overdraft eq 'n/a');
96              
97             # Get the available balance.
98 0           $stream->get_tag('td');
99 0           $available_balance = $stream->get_trimmed_text('/td');
100              
101             # Strip pounds signs from balances.
102 0           $balance =~ s/^\x{00A3}//;
103 0           $overdraft =~ s/^\x{00A3}//;
104 0           $available_balance =~ s/^\x{00A3}//;
105              
106             # Strip Comma ',' from balances.
107 0           $balance =~ s/\,//g;
108 0           $overdraft =~ s/\,//g;
109 0           $available_balance =~ s/\,//g;
110              
111             # Add to list of accounts to return.
112 0           push(@accounts, {balance => $balance,
113             name => $name,
114             overdraft => $overdraft,
115             account => $account,
116             available_balance => $available_balance});
117             }
118              
119 0           return @accounts;
120             }
121              
122             1;
123              
124             __END__