File Coverage

blib/lib/Finance/Currency/Convert/BChile.pm
Criterion Covered Total %
statement 55 85 64.7
branch 9 34 26.4
condition 2 9 22.2
subroutine 12 12 100.0
pod 7 7 100.0
total 85 147 57.8


line stmt bran cond sub pod time code
1             package Finance::Currency::Convert::BChile;
2              
3 7     7   485791 use warnings;
  7         73  
  7         238  
4 7     7   42 use strict;
  7         17  
  7         140  
5              
6 7     7   34 use Carp;
  7         13  
  7         512  
7              
8             =head1 NAME
9              
10             Finance::Currency::Convert::BChile - Currency conversion module
11             between Chilean Pesos (CLP) and USA Dollars (USD).
12              
13             =head1 VERSION
14              
15             Version 0.06
16              
17             =cut
18              
19             $Finance::Currency::Convert::BChile::VERSION = '0.06';
20              
21 7     7   5286 use LWP::UserAgent;
  7         334936  
  7         273  
22 7     7   3836 use HTML::TokeParser;
  7         74649  
  7         6709  
23              
24             # As of 2013-07-24, bcentral.cl uses an iframe in homepage and
25             # feeds values from another URL
26             my $BCENTRAL_URL = 'http://si3.bcentral.cl/indicadoresvalores/secure/indicadoresvalores.aspx';
27             my $DEFAULT_UA = 'Finance::Currency::Convert::BChile perl module';
28              
29             =head1 SYNOPSIS
30              
31             Currency conversion module between Chilean Pesos (CLP) and USA
32             Dollars (USD). The conversion rate is obtained from the official
33             source in Chile: the central bank "Banco Central de Chile", from
34             their webpage http://www.bcentral.cl
35              
36             use Finance::Currency::Convert::BChile;
37              
38             my $conversor = Finance::Currency::Convert::BChile->new();
39             $conversor->update;
40             print $conversor->CLP2USD(20170);
41              
42             =head1 FUNCTIONS
43              
44             =head2 new
45              
46             Creates a new Finance::Currency::Convert::BChile object.
47             Initializes the web robot. You can pass a user agent string
48             as a parameter.
49              
50             =cut
51              
52             sub new {
53 6     6 1 452 my ($this, @args) = @_;
54              
55 6   33     57 my $class = ref($this) || $this;
56              
57 6   33     41 my $ua_string = $args[0] || $DEFAULT_UA;
58              
59 6         17 my $self = {};
60 6         16 bless $self, $class;
61              
62 6 50       39 $self->{'ua'} = LWP::UserAgent->new
63             or croak "Unable to create user agent";
64 6         17930 $self->{'ua'}->agent($ua_string);
65              
66 6         438 $self->{'dolar'} = '';
67 6         17 $self->{'fecha'} = '';
68              
69 6         21 return $self;
70             }
71              
72             =head2 update
73              
74             Obtains the data from bcentral page.
75             You can pass a fake value as a parameter. In this case there's no
76             update from bcentral site.
77              
78             =cut
79              
80             sub update {
81 5     5 1 23 my $self = shift;
82 5         12 my $simulate = shift;
83              
84 5 50       17 if ($simulate) {
85 5         10 $self->{'dolar'} = $simulate;
86 5         12 $self->{'fecha'} = 'UNKNOWN';
87              
88 5         13 return 1;
89             }
90              
91 0         0 my $response = $self->{'ua'}->get($BCENTRAL_URL);
92              
93 0 0       0 unless ($response->is_success) {
94 0         0 carp "Unable to get page: " . $response->status_line;
95              
96 0         0 $self->{'dolar'} = '';
97 0         0 $self->{'fecha'} = '';
98 0         0 return 0;
99             }
100              
101 0 0       0 my $p = HTML::TokeParser->new(\$response->content)
102             or croak "Unable to parse response: $!";
103              
104 0         0 my ($dolar, $fecha);
105              
106 0         0 while (my $token = $p->get_tag("div")) {
107 0 0       0 next unless $token->[1]{id} eq 'ind-dia';
108              
109 0         0 while (my $token2 = $p->get_tag("p")) {
110 0 0       0 next unless $token2->[1]{class} eq 'published-date';
111 0         0 last;
112             }
113 0         0 while (my $token2 = $p->get_tag("span")) {
114 0 0       0 next unless $token2->[1]{id} eq 'Lbl_fecha';
115 0         0 last;
116             }
117 0         0 $fecha = $p->get_text;
118              
119 0         0 while (my $token2 = $p->get_tag("span")) {
120 0 0       0 next unless $token2->[1]{id} eq 'RptListado_ctl03_lbl_valo';
121 0         0 $dolar = $p->get_text;
122 0         0 last;
123             }
124             }
125              
126 0 0 0     0 return 0 unless $dolar and $fecha;
127 0 0       0 return 0 unless $dolar =~ /^\d+[,.]{0,1}\d+$/;
128              
129 0         0 $self->{'dolar'} = $dolar;
130 0         0 $self->{'fecha'} = $fecha;
131              
132 0         0 return 1;
133             }
134              
135             =head2 date
136              
137             Return the date obtained from Banco Central's site.
138             There's no formatting at all.
139              
140             =cut
141              
142             sub date {
143 1     1 1 4 my $self = shift;
144              
145 1         19 return $self->{'fecha'};
146             }
147              
148             =head2 dollarValue
149              
150             Return the value of 1 dollar in CLP.
151             There's no formatting.
152              
153             =cut
154              
155             sub dollarValue {
156 1     1 1 4 my $self = shift;
157              
158 1         14 return $self->{'dolar'};
159             }
160              
161             =head2 rate
162              
163             Return the rate of transforming CLP in USD.
164             If there's no value data, return -1
165              
166             =cut
167              
168             sub rate {
169 2     2 1 8 my $self = shift;
170              
171 2         19 my $valor = $self->{'dolar'};
172              
173             # Changing decimal separator
174 2         7 $valor =~ s/,/./;
175              
176 2 50       7 return -1 unless $valor;
177 2 50       13 return -1 unless $valor =~ /^\d+[,.]{0,1}\d+$/;
178              
179 2 50       9 return -1 unless $valor >= 0;
180              
181 2         11 return 1 / $valor;
182             }
183              
184             =head2 CLP2USD
185              
186             Convert the amount received as parameter (CLP) to USD,
187             rounded at two decimals.
188             Returns -1 on error.
189              
190             =cut
191              
192             sub CLP2USD {
193 1     1 1 13 my $self = shift;
194 1         5 my $pesos = shift;
195              
196 1 50       8 if ($pesos !~ /^\d+$/) {
197 0         0 carp "Argument to CLP2USD must be an integer";
198 0         0 return -1;
199             }
200              
201 1         3 my $rate = $self->rate;
202 1 50       4 return -1 unless $rate >= 0;
203              
204 1         26 return sprintf("%.2f", $pesos * $rate);
205             }
206              
207             =head2 USD2CLP
208              
209             Convert the amount received as parameter (USD) to CLP,
210             rounded as integer (no decimals).
211             Returns -1 on error.
212              
213             =cut
214              
215             sub USD2CLP {
216 1     1 1 3 my $self = shift;
217 1         2 my $dolares = shift;
218              
219 1 50       14 if ($dolares !~ /^\d+(\.\d{0,2}){0,1}$/) {
220 0         0 carp "Wrong format in argument to USD2CLP";
221 0         0 return -1;
222             }
223              
224 1         3 my $valor = $self->{'dolar'};
225              
226             # Changing decimal separator
227 1         2 $valor =~ s/,/./;
228              
229 1 50       6 return -1 unless $valor >= 0;
230              
231 1         7 return sprintf("%.0f", $dolares * $valor);
232             }
233              
234             =head1 AUTHOR
235              
236             Hugo Salgado, C<< >>
237              
238             =head1 BUGS
239              
240             Please report any bugs or feature requests to C<~huguei/perl-Finance-Currency-Convert-BChile@todo.sr.ht>, or through
241             the web interface at L. I will be notified, and then you'll
242             automatically be notified of progress on your bug as I make changes.
243              
244             =head1 SUPPORT
245              
246             You can find documentation for this module with the perldoc command.
247              
248             perldoc Finance::Currency::Convert::BChile
249              
250              
251             You can also look for information at:
252              
253             =over 4
254              
255             =item * sourcehut's request tracker
256              
257             L
258              
259             =item * CPAN Ratings
260              
261             L
262              
263             =item * Search CPAN
264              
265             L
266              
267             =back
268              
269             =head1 SEE ALSO
270              
271             HTML::TokeParser
272             LWP::UserAgent
273              
274             =cut
275              
276             =head1 TERMS OF USE
277              
278             The data obtained from bcentral site is under this policy:
279             http://www.bcentral.cl/sitio/condiciones-uso.htm
280              
281             No liability is accepted by the author for abuse or miuse of
282             the software herein. Use of this software is only permitted under
283             the terms stipulated by bcentral.cl.
284              
285             =cut
286              
287             =head1 ACKNOWLEDGEMENTS
288              
289             This module was built for NIC Chile (http://www.nic.cl), who
290             granted its liberation as free software.
291              
292             =head1 COPYRIGHT & LICENSE
293              
294             Copyright 2020 Hugo Salgado, all rights reserved.
295              
296             This program is free software; you can redistribute it and/or modify it
297             under the same terms as Perl itself.
298              
299             =cut
300              
301             1; # End of Finance::Currency::Convert::BChile