File Coverage

blib/lib/Finance/OFX/UserAgent.pm
Criterion Covered Total %
statement 24 79 30.3
branch 0 14 0.0
condition 0 3 0.0
subroutine 8 19 42.1
pod 8 11 72.7
total 40 126 31.7


line stmt bran cond sub pod time code
1             # Filename: UserAgent.pm
2             #
3             # OFX Interface for interacting with a Financial Institution server
4             #
5             # Created January 30, 2008 Brandon Fosdick
6             #
7             # Copyright 2008 Brandon Fosdick (BSD License)
8             #
9             # $Id: UserAgent.pm,v 1.2 2008/03/04 04:22:27 bfoz Exp $
10              
11             package Finance::OFX::UserAgent;
12              
13 1     1   9 use strict;
  1         2  
  1         33  
14 1     1   5 use warnings;
  1         1  
  1         36  
15              
16             our $VERSION = '2';
17              
18 1     1   634 use Finance::OFX::Parse;
  1         16  
  1         32  
19 1     1   950 use Finance::OFX::Response;
  1         4  
  1         31  
20 1     1   1333 use Data::GUID;
  1         33871  
  1         8  
21 1     1   2673 use LWP;
  1         22289  
  1         117  
22 1     1   2725 use POSIX qw(strftime);
  1         11206  
  1         7  
23              
24 1         1580 use constant DEFAULT_OPTIONS =>
25             {
26             'ofxVersion' => '100',
27             'ofxAppID' => 'QWIN',
28             'ofxAppVer' => '0900',
29             'userID' => 'anonymous00000000000000000000000',
30             'userPass' => 'anonymous00000000000000000000000',
31 1     1   1609 };
  1         2  
32              
33             sub new
34             {
35 0     0 1   my ($this, %options) = @_;
36 0   0       my $class = ref($this) || $this;
37 0           my $self = {};
38 0           bless $self, $class;
39              
40             # Initialization
41 0           $self->{Institution} = delete $options{Institution};
42 0           $self->{ofxVersion} = delete $options{ofxVersion};
43 0           $self->{ofxAppID} = delete $options{ofxAppID};
44 0           $self->{ofxAppVer} = delete $options{ofxAppVer};
45 0           $self->{userID} = delete $options{userID};
46 0           $self->{userPass} = delete $options{userPass};
47              
48             # Defaults
49 0           for( keys %{DEFAULT_OPTIONS()} )
  0            
50             {
51 0 0         $self->{$_} = DEFAULT_OPTIONS()->{$_} unless defined $self->{$_};
52             }
53              
54 0           $self->{ua} = LWP::UserAgent->new(%options);
55              
56 0           return $self;
57             }
58              
59             sub account_info
60             {
61 0     0 1   my $s = shift;
62              
63 0           my $r = $s->request('
64            
65             '.$s->sonrq.'
66            
67            
68            
69             '.(Data::GUID->new()->as_string).'
70            
71             19700101
72            
73            
74             ');
75 0           return $s->{response} = Finance::OFX::Response->from_http_response($r);
76             }
77              
78             sub statement
79             {
80 0     0 1   my ($s, $acct, %options) = @_;
81 0           my $start = delete $options{start};
82 0           my $end = delete $options{end};
83 0           my $transactions = delete $options{transactions};
84              
85 0 0         my $r = $s->request('
    0          
    0          
86             '.$s->sonrq.'
87            
88            
89            
90             '.(Data::GUID->new()->as_string).'
91             '.$acct->bankacctfrom().'
92             '.
93             ($start ?
94             ''.strftime('%Y%m%d%H%M%S', gmtime($start))."[0:UTC]\n" : '').
95             ($end ?
96             ''.strftime('%Y%m%d%H%M%S', gmtime($end))."[0:UTC]\n" : '').'
97             '.($transactions ? 'Y' : 'N').'
98            
99            
100            
101             ');
102              
103 0           return $s->{response} = Finance::OFX::Response->from_http_response($r);
104             }
105              
106             sub profile
107             {
108 0     0 1   my $s = shift;
109              
110 0           my $request = HTTP::Request->new(POST => ${$s->{Institution}}->url);
  0            
111 0           $request->content_type('application/x-ofx');
112 0           $request->content($s->header().
113             '
114            
115             '.$s->sonrq.'
116            
117            
118            
119             '.(Data::GUID->new()->as_string).'
120            
121             NONE
122 0           '.${$s->{Institution}}->date.'
123            
124            
125            
126             ');
127              
128 0           print $request->as_string;
129 0           my $r = $s->request($request);
130 0           return $s->{response} = Finance::OFX::Response->from_http_response($r);
131             }
132              
133             # --- Getters and Setters ---
134              
135             sub institution
136             {
137 0     0 1   my $s = shift;
138 0 0         $s->{Institution} = shift if scalar @_;
139 0           $s->{Institution};
140             }
141              
142             sub response
143             {
144 0     0 1   my $s = shift;
145 0           $s->{response};
146             }
147              
148             sub user_id
149             {
150 0     0 1   my $s = shift;
151 0 0         $s->{userID} = shift if scalar @_;
152 0           $s->{userID};
153             }
154              
155             sub user_pass
156             {
157 0     0 1   my $s = shift;
158 0 0         $s->{userPass} = shift if scalar @_;
159 0           $s->{userPass};
160             }
161              
162             # --- Internal use only ---
163              
164             # Returns an OFX header appropriate for the protocol version in use
165             sub header
166             {
167 0     0 0   my $s = shift;
168              
169 0           'OFXHEADER:100
170             DATA:OFXSGML
171             VERSION:102
172             SECURITY:NONE
173             ENCODING:USASCII
174             CHARSET:1252
175             COMPRESSION:NONE
176             OLDFILEUID:NONE
177             NEWFILEUID:NONE'."\n\n"
178             }
179              
180             sub request
181             {
182 0     0 0   my ($s, $content) = @_;
183 0           my $r = HTTP::Request->new(POST => $s->{Institution}->url);
184 0           $r->content_type('application/x-ofx');
185 0           $r->content($s->header().''.$content.'');
186             # print "request: ", $r->as_string, "\n\n---\n\n";
187 0           return $s->{ua}->request($r);
188             }
189              
190             # Returns a SONRQ block
191             sub sonrq
192             {
193 0     0 0   my $s = shift;
194 0           my $t = strftime('%Y%m%d%H%M%S[%z:%Z]', localtime);
195 0           $t =~ s/00:/:/; # Fix the %z format
196              
197 0           '
198             '.$t.'
199             '.$s->{userID}.'
200             '.$s->{userPass}.'
201             '.$s->{Institution}->language.'
202            
203             '.$s->{Institution}->org.'
204             '.$s->{Institution}->fid.'
205            
206             '.$s->{ofxAppID}.'
207             '.$s->{ofxAppVer}.'
208             '
209             }
210              
211             1;
212              
213             __END__