File Coverage

blib/lib/Finance/Currency/Convert.pm
Criterion Covered Total %
statement 56 106 52.8
branch 5 26 19.2
condition 4 22 18.1
subroutine 11 16 68.7
pod 12 12 100.0
total 88 182 48.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # Copyright (C) 2000-2025, Jan Willamowius , https://www.willamowius.de/
4             # All rights reserved.
5             # This is free software; you can redistribute it and/or
6             # modify it under the same terms as Perl itself.
7             #
8              
9             package Finance::Currency::Convert;
10              
11 1     1   110627 use strict;
  1         2  
  1         27  
12 1     1   3 use warnings;
  1         1  
  1         39  
13 1     1   3 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         1198  
14              
15             require Exporter;
16             require AutoLoader;
17              
18             @ISA = qw(Exporter AutoLoader);
19             # Items to export into callers namespace by default. Note: do not export
20             # names by default without a very good reason. Use EXPORT_OK instead.
21             # Do not simply export all your public functions/methods/constants.
22             @EXPORT = qw(
23            
24             );
25             $VERSION = '2.12';
26              
27             my %EuroRates = (
28             BEF => {EUR=>0.0247899055505, BEF => 1},
29             DEM => {EUR=>0.511291881196, DEM => 1},
30             ESP => {EUR=>0.00601012104384, ESP => 1},
31             EUR => {ATS=>13.7603, BEF=>40.3399, DEM=>1.95583, EUR=>1, ESP=>166.386, FIM=>5.94573, FRF=>6.55957, GRD=>340.750, IEP=>.787564, ITL=>1936.27, LUF=>40.3399, NLG=>2.20371, PTE=>200.482, CYP=>0.585274, MTL=>0.429300, SIT=>239.640, SKK=>30.1260, EEK=>15.6466, LTL=>3.45303867403, LVL=>1.42287990894, HRK=>0.132722808415, BGN=>0.511291881196},
32             FRF => {EUR=>0.152449017237, FRF => 1},
33             GRD => {EUR=>0.00293470286134, GRD => 1},
34             IEP => {EUR=>1.26973807843, IEP => 1},
35             ITL => {EUR=>0.000516456899089, ITL => 1},
36             LUF => {EUR=>0.0247899055505, LUF => 1},
37             NLG => {EUR=>0.45378021609, NLG => 1},
38             ATS => {EUR=>0.0726728341679, ATS => 1},
39             PTE => {EUR=>0.00498797897068, PTE => 1},
40             FIM => {EUR=>0.168187926462, FIM => 1},
41             CYP => {EUR=>1.70860144137618, CYP => 1},
42             MTL => {EUR=>2.32937339855579, MTL => 1},
43             SIT => {EUR=>0.00417292605575029, SIT => 1},
44             SKK => {EUR=>0.0331939188740623, SKK => 1},
45             EEK => {EUR=>0.0639116485371, EEK => 1},
46             LTL => {EUR=>0.2896, LTL => 1},
47             LVL => {EUR=>0.7028, LVL => 1},
48             HRK => {EUR=>7.5345, HRK => 1},
49             BGN => {EUR=>1.95583, BGN => 1},
50             );
51              
52             sub new() {
53 1     1 1 167378 my $proto = shift;
54 1         2 my $ratesFile = shift; # optional
55 1   33     10 my $class = ref($proto) || $proto;
56 1         4 my $self = {};
57 1         4 $self->{CurrencyRates} = \%EuroRates;
58 1         6 $self->{RatesFile} = $ratesFile;
59 1         4 $self->{UserAgent} = "Finance::Currency::Convert $VERSION";
60 1         3 bless($self, $class);
61 1 50 33     5 $self->readRatesFile() if (defined($ratesFile) && (-e $self->{RatesFile}));
62 1         4 return $self;
63             }
64              
65             sub setRate() {
66 4     4 1 8 my $self = shift;
67 4         36 my $source = shift;
68 4         9 my $target = shift;
69 4         7 my $rate = shift;
70 4         14 $self->{CurrencyRates}{$source}{$target} = $rate;
71             }
72              
73             sub setRatesFile() {
74 1     1 1 990 my $self = shift;
75 1         4 $self->{RatesFile} = shift;
76 1 50       15 $self->readRatesFile() if (-e $self->{RatesFile});
77             }
78              
79             sub readRatesFile() {
80 0     0 1 0 my $self = shift;
81 0 0 0     0 if (!defined $self->{RatesFile} || !(-r $self->{RatesFile}) || !((-s $self->{RatesFile}) > 0)) {
      0        
82 0         0 warn("Can't read $self->{RatesFile}\n");
83 0         0 return;
84             }
85              
86 0 0 0     0 open(RATES, "<", $self->{RatesFile}) or ( warn("Can't read $self->{RatesFile}\n") and return );
87 0         0 while(local $_ = ) {
88 0         0 my ($source, $targetrates) = split(/\|/, $_);
89 0         0 foreach my $target (split(/\:/, $targetrates)) {
90 0         0 my @pieces = split(/\=/, $target);
91 0 0       0 if (scalar(@pieces) > 1) {
92 0         0 $self->setRate($source, $pieces[0], $pieces[1]);
93             }
94             }
95             }
96 0         0 close(RATES);
97             }
98              
99             sub writeRatesFile() {
100 1     1 1 3 my $self = shift;
101 1 50       6 return if (!defined $self->{RatesFile});
102              
103 1 50 0     4872 open(RATES, ">", $self->{RatesFile}) or ( warn("Can't access $self->{RatesFile}") and return );
104 1         5 foreach my $sourcerate (sort keys %{$self->{CurrencyRates}}) {
  1         20  
105 24         82 print RATES "$sourcerate|";
106 24         38 foreach my $targetrate (sort keys %{ $self->{CurrencyRates}{$sourcerate}}) {
  24         95  
107 68 50 33     521 if (exists($self->{CurrencyRates}{$sourcerate}{$targetrate})
      33        
108             && defined($self->{CurrencyRates}{$sourcerate}{$targetrate})
109             && $self->{CurrencyRates}{$sourcerate}{$targetrate} ne '') {
110 68         221 print RATES "$targetrate=" . $self->{CurrencyRates}{$sourcerate}{$targetrate} . ":";
111             }
112             }
113 24         52 print RATES "\n";
114             }
115 1         86 close(RATES);
116             }
117              
118             sub _getQuoteFetcher() {
119 0     0   0 my $self = shift;
120             # test if Finance::Quote is available
121 0         0 eval { require Finance::Quote; };
  0         0  
122 0 0       0 if ($@) {
123 0         0 warn "Finance::Quote not installed - can't use updateRates()\n";
124 0         0 return undef;
125             };
126             # test if Finance::Quote::CurrencyRates::ECB is available
127 0         0 my $ecbAvailable = 0;
128 0         0 eval { require Finance::Quote::CurrencyRates::ECB; };
  0         0  
129 0 0       0 if ($@) {
130 0         0 warn "Finance::Quote::CurrencyRates::ECB not installed\n";
131             } else {
132 0         0 $ecbAvailable = 1;
133             };
134             # get the exchange rates
135 0         0 my $q;
136 0 0       0 if ($ecbAvailable) {
137 0         0 $q = Finance::Quote->new(currency_rates => {order => ['ECB']});
138             } else {
139 0         0 $q = Finance::Quote->new();
140             }
141 0         0 $q->user_agent->agent($self->{UserAgent});
142 0         0 return $q;
143             }
144              
145             sub updateRates() {
146 0     0 1 0 my $self = shift;
147 0         0 my @CurrencyList = @_;
148 0         0 my $q = $self->_getQuoteFetcher();
149 0 0       0 return if (!defined($q));
150 0         0 foreach my $source (@CurrencyList) {
151 0         0 foreach my $target (sort keys %{ $self->{CurrencyRates}}) {
  0         0  
152 0         0 $self->setRate($source, $target, $q->currency($source, $target));
153             }
154             }
155 0         0 foreach my $source (sort keys %{ $self->{CurrencyRates}}) {
  0         0  
156 0         0 foreach my $target (@CurrencyList) {
157 0         0 $self->setRate($source, $target, $q->currency($source, $target));
158             }
159             }
160             }
161              
162             sub updateRate() {
163 0     0 1 0 my $self = shift;
164 0         0 my $source = shift;
165 0         0 my $target = shift;
166 0         0 my $q = $self->_getQuoteFetcher();
167 0 0       0 return if (!defined($q));
168             # get the exchange rate
169 0         0 $self->setRate($source, $target, $q->currency($source, $target));
170             }
171              
172             sub setUserAgent() {
173 0     0 1 0 my $self = shift;
174 0         0 $self->{UserAgent} = shift;
175             }
176              
177             sub rateAvailable {
178 3     3 1 400 my $self = shift;
179 3         7 my $source = shift;
180 3         6 my $target = shift;
181 3         18 return defined($self->{CurrencyRates}->{$source}{$target});
182             }
183              
184             sub convert() {
185 26     26 1 675 my $self = shift;
186 26         46 my $amount = shift;
187 26         45 my $source = shift;
188 26         41 my $target = shift;
189 26         146 return $amount * $self->{CurrencyRates}->{$source}{$target};
190             }
191              
192             sub convertFromEUR() {
193 10     10 1 19 my $self = shift;
194 10         20 my $amount = shift;
195 10         18 my $target = shift;
196 10         27 return $self->convert($amount, "EUR", $target);
197             }
198              
199             sub convertToEUR() {
200 12     12 1 3201 my $self = shift;
201 12         23 my $amount = shift;
202 12         22 my $source = shift;
203 12         37 return $self->convert($amount, $source, "EUR");
204             }
205              
206             1;
207              
208             __END__