File Coverage

blib/lib/Finance/Bank/ABSA.pm
Criterion Covered Total %
statement 12 63 19.0
branch 0 18 0.0
condition n/a
subroutine 4 5 80.0
pod 0 1 0.0
total 16 87 18.3


line stmt bran cond sub pod time code
1             package Finance::Bank::ABSA;
2 1     1   15575 use strict;
  1         4  
  1         44  
3 1     1   7 use Carp;
  1         2  
  1         113  
4             our $VERSION = '0.03';
5 1     1   1243 use WWW::Mechanize;
  1         205888  
  1         45  
6 1     1   14 use HTML::TokeParser;
  1         1  
  1         707  
7              
8             sub check_ABSA_balance {
9 0     0 0   my ($class, %opts) = @_;
10 0           my @accounts;
11 0 0         croak "Must provide a security code" unless exists $opts{seccode};
12 0 0         croak "Must provide a banking id" unless exists $opts{bankingid};
13 0 0         croak "Must provide a password" unless exists $opts{mypassword};
14              
15 0           my $self = bless { %opts }, $class;
16              
17 0           my $agent = WWW::Mechanize->new();
18 0           $agent->get("https://vs1.absa.co.za/ibs/UserAuthentication.do");
19              
20             # Filling in the login form.
21 0           $agent->form("theForm");
22 0           $agent->field("AccessAccount", $opts{bankingid});
23 0           $agent->field("PIN", $opts{seccode});
24 0           $agent->click("button_processAuthenticate");
25 0 0         die unless ($agent->success);
26              
27 0           my @secletter = split(//, $opts{mypassword}); # put p/word into an array
28 0           $agent->form("AuthPasswordForm");
29              
30             # Now comes to trickery to only provide the requested chars of password
31             # Need to determine which of the input fields are class jc-pwdDgt
32             # as input fields with class jc-pwdDgtDis aren't required for login
33             # This is in order to not need to provide the whole password over the Net!
34 0 0         my $testpwdDgt = HTML::TokeParser->new(\$agent->content) or die "$!";
35 0           $testpwdDgt->get_tag("form");
36              
37             # Go to first input field in form.
38 0           my $pwdToken = $testpwdDgt->get_tag("input");
39 0           while ( $pwdToken->[1]{name} =~ /pwdDgt(\d+)/ ) # Step through all pwdDgt fields only
40             # Setting $1 to the pwdDgt number
41             {
42 0 0         if ( $pwdToken->[1]{class} eq "jc-pwdDgt" ) { # AHA - they want this char!
43 0           $agent->field($pwdToken->[1]{name}, @secletter[$1]);
44             }
45 0           $pwdToken = $testpwdDgt->get_tag("input");
46             }
47              
48 0           $agent->click("button_processAuthPassword");
49 0 0         die unless ($agent->success);
50              
51             # Now we have the data, we need to parse it. This is fragile.
52 0           my $content = $agent->{content};
53 0           my ($split1, $split2) = split /\Balance Enquiries/, $content;
54 0           my ($content, $split2) = split /Click on the account number for a statement/, $split2;
55              
56 0 0         my $stream = HTML::TokeParser->new(\$content) or die "$!";
57 0           $stream->get_tag("table");
58 0           $stream->get_tag("tr");
59 0           $stream->get_tag("tr");
60 0           $stream->get_tag("tr");
61              
62 0           while (my $token = $stream->get_tag("tr")) {
63 0           $token = $stream->get_tag("td");
64 0 0         if ($token->[1]{width} eq "5") {
65 0           $stream->get_tag("td");
66 0           my $accountname = $stream->get_trimmed_text("/td");
67 0           $stream->get_tag("td");
68 0           my $accountnumber = $stream->get_trimmed_text("/td");
69 0           $stream->get_tag("td");
70 0           my $accountbalance = $stream->get_trimmed_text("/td");
71 0           my @strarray = split(//, $accountbalance);
72 0           $stream->get_tag("td");
73 0           my $accountavailable = $stream->get_trimmed_text("/td");
74              
75             # Octal 240 is used from HTML3.2 spec to replace  
76             # See Entities.pm under your perl vendor tree
77             # I choose to replace it here to easily/correctly cater for later formatting.
78 0           $accountbalance =~ s/[, ]/./g;
79 0           $accountbalance =~ s/\240//g;
80 0           $accountavailable =~ s/[, ]/./g;
81 0           $accountavailable =~ s/\240//g;
82 0           $accountname =~ s/\240//g;
83              
84 0           push @accounts, {
85             balance => $accountbalance,
86             name => $accountname,
87             available => $accountavailable,
88             account => $accountnumber
89             };
90             }
91             }
92 0           return @accounts;
93             }
94              
95             1;
96             __END__