File Coverage

blib/lib/Finance/Currency/Convert/DnB.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Finance::Currency::Convert::DnB;
2 1     1   21248 use strict;
  1         2  
  1         37  
3 1     1   7 use warnings;
  1         1  
  1         25  
4 1     1   6 use Exporter;
  1         11  
  1         109  
5             our @ISA = qw/Exporter/;
6             our @EXPORT = qw/currency update_currency currencies/;
7             our $VERSION = '0.2';
8              
9             our $currency;
10 1     1   6 use File::Spec;
  1         2  
  1         30  
11 1     1   468 use XML::Simple;
  0            
  0            
12             use LWP::Simple;
13             use Slurp;
14              
15             sub update_currency {
16             my $filename = File::Spec->tmpdir() . "/currency_list_" . ((defined $>) ? $> : "") . ".xml";
17             #only download XML twice a day
18             if (!-e $filename || time()-43200 < -M $filename || $_[0]) {
19             is_success ($_=getstore('http://www.dnbnor.no/portalfront/datafiles/miscellaneous/csv/kursliste_ws.xml', $filename))
20             or die 'Failed to get list of currencies; http error code: ' . $_;
21              
22             }
23              
24             my $content = slurp $filename;
25             $currency = XMLin($content, KeyAttr => ["kode"]);
26             }
27              
28             sub currencies {
29             update_currency;
30             sort keys %{$currency->{valutakurs}}
31             }
32              
33             sub currency {
34             my ($amount, $from, $to, $decimals) = @_;
35             $decimals = 2 unless defined $decimals;
36             update_currency;
37              
38             map {
39             my $res;
40             my $from_currency = $currency->{valutakurs}->{$from}->{overforsel}->{midtkurs} / $currency->{valutakurs}->{$from}->{enhet} if ($from ne "NOK");
41             my $to_currency = $currency->{valutakurs}->{$_}->{overforsel}->{midtkurs} / $currency->{valutakurs}->{$_}->{enhet} if ($_ ne "NOK");
42            
43             foreach my $amount ( (ref($amount) eq 'ARRAY') ? @$amount : $amount ) {
44             if ($_ eq "NOK") {
45             $res += $amount * $from_currency;
46             }
47             elsif ($from eq "NOK") {
48             $res += $amount / $to_currency;
49             }
50             else {
51             $res += $amount * $from_currency / $to_currency;
52             }
53             }
54             $res = sprintf('%.' . $decimals . 'f', $res);
55             ($to) ? return $res : $_ => $res
56             } ($to) ? $to : keys %{$currency->{valutakurs}}
57             }
58              
59             1;
60              
61             =head1 NAME
62              
63             Finance::Currency::Convert::DnB - convert currencies with up to date currencies from dnbnor.no
64              
65             =head1 SYNOPSIS
66              
67             use Finance::Currency::Convert::DnB;
68            
69             #get results with default number of decimals which is 2
70             $result = currency 20, "NOK", "GBP";
71             #3 decimals
72             $result = currency 20, "NOK", "GBP", 3;
73              
74             #convert several numbers
75             $result = currency \@values, "NOK", "GBP";
76             $result = currency [20, 50, 35], "NOK", "GBP";
77              
78             #store all results in a hash
79             my %all_currencies = currency 20, "NOK";
80             print "20 NOK in $_ is $all_currencies{$_}\n" foreach (keys %all_currencies);
81              
82             #get a list of available currencies
83             my @currencies = currencies;
84              
85             =head1 DESCRIPTION
86              
87             Finance::Currency::Convert::DnB uses a XML list from dnbnor.no to convert currencies. Caches XML list in a temporary file for quick access.
88              
89             =head1 AVAILABLE METHODS
90              
91             =head2 currency
92              
93             $result = convert 20, "NOK", "GBP", 2;
94             Amount can also be an array reference, and it will return a total of all elements.
95             If conversion currency is excluded, it will return a hash with all results for all currencies.
96             If number of decimals is excluded, if will default to 2 decimals.
97              
98             =head2 currencies
99              
100             Returns a list of available currencies sorted alphabetically.
101              
102             =head2 update_currency
103              
104             This is an internal function called automatically to update currencies. It is done automatically if the cache is non-existing or if it is older than 12 hours. You can force updating by calling it with a true argument.
105              
106             =cut