View | Details | Raw Unified | Return to bug 9593
Collapse All | Expand All

(-)a/C4/Biblio.pm (-33 / +71 lines)
Lines 1465-1472 sub GetMarcPrice { Link Here
1465
    for my $field ( $record->field(@listtags) ) {
1465
    for my $field ( $record->field(@listtags) ) {
1466
        for my $subfield_value  ($field->subfield($subfield)){
1466
        for my $subfield_value  ($field->subfield($subfield)){
1467
            #check value
1467
            #check value
1468
            $subfield_value = MungeMarcPrice( $subfield_value );
1468
            my $rate;
1469
            return $subfield_value if ($subfield_value);
1469
            ($subfield_value,$rate) = MungeMarcPrice( $subfield_value );
1470
            if ($subfield_value) {
1471
                ( $subfield_value ) = $subfield_value =~ m/(\d[\d\,\. ]*\d{0,2})/;
1472
                # remove comma,dot or space when used as separators from hundreds
1473
                $subfield_value =~s/[\,\. ](\d{3})/$1/g;
1474
                # convert comma to dot to ensure correct display of decimals if existing
1475
                $subfield_value =~s/,/./;
1476
                # convert to active currency if necessary
1477
                $subfield_value/= $rate if $rate;
1478
                return $subfield_value;
1479
            }
1470
        }
1480
        }
1471
    }
1481
    }
1472
    return 0; # no price found
1482
    return 0; # no price found
Lines 1479-1517 Return the best guess at what the actual price is from a price field. Link Here
1479
1489
1480
sub MungeMarcPrice {
1490
sub MungeMarcPrice {
1481
    my ( $price ) = @_;
1491
    my ( $price ) = @_;
1482
1483
    return unless ( $price =~ m/\d/ ); ## No digits means no price.
1492
    return unless ( $price =~ m/\d/ ); ## No digits means no price.
1484
1493
    # Look for the currency symbol and the normalized code of the active currency, if it's there,
1485
    ## Look for the currency symbol of the active currency, if it's there,
1494
    my @currencies= C4::Budgets->GetCurrencies();
1486
    ## start the price string right after the symbol. This allows us to prefer
1495
    my $symbol;
1487
    ## this native currency price over other currency prices, if possible.
1496
    my $isocode;
1488
    my $active_currency = C4::Context->dbh->selectrow_hashref( 'SELECT * FROM currency WHERE active = 1', {} );
1497
    my $rate;
1489
    my $symbol = quotemeta( $active_currency->{'symbol'} );
1498
    my $localprice;
1490
    if ( $price =~ m/$symbol/ ) {
1499
    my @altercurrencies;
1491
        my @parts = split(/$symbol/, $price );
1500
    foreach my $cur ( @currencies ) {
1492
        $price = $parts[1];
1501
        if ( $cur->{'active'} ) {
1493
    }
1502
            $symbol = $cur->{'symbol'};
1494
1503
            $isocode = $cur->{'isocode'};
1495
    ## Grab the first number in the string ( can use commas or periods for thousands separator and/or decimal separator )
1504
        } else {
1496
    ( $price ) = $price =~ m/([\d\,\.]+[[\,\.]\d\d]?)/;
1505
            push @altercurrencies, {symbol=>$cur->{'symbol'},isocode=>$cur->{'isocode'},rate=>$cur->{'rate'},};
1497
1506
        }
1498
    ## Split price into array on periods and commas
1507
    }
1499
    my @parts = split(/[\,\.]/, $price);
1508
1500
1509
    if ( $symbol ) {
1501
    ## If the last grouping of digits is more than 2 characters, assume there is no decimal value and put it back.
1510
        my @matches =($price=~ /
1502
    my $decimal = pop( @parts );
1511
            \s?
1503
    if ( length( $decimal ) > 2 ) {
1512
            (                          # start of capturing parenthesis
1504
        push( @parts, $decimal );
1513
            (?:
1505
        $decimal = '';
1514
            (?:\p{Sc}|[a-zA-Z]){1,3}   # currency sign (unicode propriety) or alphabetical character whitin 1 to 3 occurrences (block 1)
1506
    }
1515
            |(?:\d+[\p{P}\s]?){1,4}    # or else at least one digit followed or not by a punctuation sign or whitespace, all theese within 1 to 3 occurrences (block 2)
1507
1516
            )
1508
    $price = join('', @parts );
1517
            \s?\p{Sc}?\s?                       # followed or not by a whitespace
1509
1518
            (?:
1510
    if ( $decimal ) {
1519
            (?:\p{Sc}|[a-zA-Z]){1,3}  # followed by same block as block 1
1511
     $price .= ".$decimal";
1520
            |(?:\d+[\p{P}\s]?){1,4}    # or by same block as block 2
1521
            )
1522
            #
1523
            #~ (?:\s[A-Z]{3})?
1524
            \s?              # followed or not by 3 alphabetical uppercase character (= isocode for price like '3$ USD')
1525
            )?                          # end of capturing parenthesis
1526
            (?:\p{P}|\z)            # followed by a punctuation sign, a whitespace or by the end of the string
1527
            /gx);
1528
1529
1530
        if ( @matches ) {
1531
            foreach ( @matches ) {
1532
                    $localprice = $_ and last if index($_, $isocode)>=0;
1533
            }
1534
            if ( !$localprice ) {
1535
                foreach ( @matches ) {
1536
                        $localprice = $_ and last  if $_=~ /(^|[^A-Za-z\p{Sc}])\Q$symbol\E([^A-Za-z\p{Sc}]|\z)/;
1537
                }
1538
            }
1539
            if ( !$localprice and @altercurrencies ) {
1540
                foreach my $match ( @matches ) {
1541
                    foreach my $alter ( @altercurrencies ) {
1542
                        $localprice = $match and $rate=$alter->{rate} and last if index($match, $alter->{isocode})>=0;
1543
                        my $altsymbol = $alter->{symbol};
1544
                        $localprice = $match and $rate=$alter->{rate} and last if $match=~ /(^|[^A-Za-z\p{Sc}])\Q$altsymbol\E([^A-Za-z\p{Sc}]|\z)/;
1545
                    }
1546
                    last if $localprice;
1547
                }
1548
            }
1549
        }
1550
        $price=$localprice;
1512
    }
1551
    }
1513
1552
    return ($price,$rate);
1514
    return $price;
1515
}
1553
}
1516
1554
1517
1555
(-)a/admin/currency.pl (-2 / +5 lines)
Lines 185-190 sub add_validate { Link Here
185
    my $rec = {
185
    my $rec = {
186
        rate     => $input->param('rate'),
186
        rate     => $input->param('rate'),
187
        symbol   => $input->param('symbol') || q{},
187
        symbol   => $input->param('symbol') || q{},
188
        isocode  => $input->param('isocode') || q{},
188
        active   => $input->param('active') || 0,
189
        active   => $input->param('active') || 0,
189
        currency => $input->param('currency'),
190
        currency => $input->param('currency'),
190
    };
191
    };
Lines 198-217 sub add_validate { Link Here
198
        {}, $input->param('currency') );
199
        {}, $input->param('currency') );
199
    if ($row_count) {
200
    if ($row_count) {
200
        $dbh->do(
201
        $dbh->do(
201
q|UPDATE currency SET rate = ?, symbol = ?, active = ? WHERE currency = ? |,
202
q|UPDATE currency SET rate = ?, symbol = ?, isocode = ?, active = ? WHERE currency = ? |,
202
            {},
203
            {},
203
            $rec->{rate},
204
            $rec->{rate},
204
            $rec->{symbol},
205
            $rec->{symbol},
206
            $rec->{isocode},
205
            $rec->{active},
207
            $rec->{active},
206
            $rec->{currency}
208
            $rec->{currency}
207
        );
209
        );
208
    } else {
210
    } else {
209
        $dbh->do(
211
        $dbh->do(
210
q|INSERT INTO currency (currency, rate, symbol, active) VALUES (?,?,?,?) |,
212
q|INSERT INTO currency (currency, rate, symbol, isocode, active) VALUES (?,?,?,?,?) |,
211
            {},
213
            {},
212
            $rec->{currency},
214
            $rec->{currency},
213
            $rec->{rate},
215
            $rec->{rate},
214
            $rec->{symbol},
216
            $rec->{symbol},
217
            $rec->{isocode},
215
            $rec->{active}
218
            $rec->{active}
216
        );
219
        );
217
220
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 588-593 DROP TABLE IF EXISTS `currency`; Link Here
588
CREATE TABLE `currency` (
588
CREATE TABLE `currency` (
589
  `currency` varchar(10) NOT NULL default '',
589
  `currency` varchar(10) NOT NULL default '',
590
  `symbol` varchar(5) default NULL,
590
  `symbol` varchar(5) default NULL,
591
  `isocode` varchar(5) default NULL,
591
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
592
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
592
  `rate` float(15,5) default NULL,
593
  `rate` float(15,5) default NULL,
593
  `active` tinyint(1) default NULL,
594
  `active` tinyint(1) default NULL,
(-)a/installer/data/mysql/updatedatabase.pl (+7 lines)
Lines 6771-6776 if ( CheckVersion($DBversion) ) { Link Here
6771
   SetVersion ($DBversion);
6771
   SetVersion ($DBversion);
6772
}
6772
}
6773
6773
6774
$DBversion = "3.11.00.XXX";
6775
if ( CheckVersion($DBversion) ) {
6776
    $dbh->do("ALTER TABLE currency ADD isocode VARCHAR(5) default NULL AFTER symbol;");
6777
    print "Upgrade to $DBversion done (Added isocode to the currency table)\n";
6778
    SetVersion($DBversion);
6779
}
6780
6774
6781
6775
=head1 FUNCTIONS
6782
=head1 FUNCTIONS
6776
6783
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/currency.tt (-3 / +14 lines)
Lines 24-29 Link Here
24
        if (f.symbol.value.length==0) {
24
        if (f.symbol.value.length==0) {
25
            _alertString += _("- Symbol missing") + "\n";
25
            _alertString += _("- Symbol missing") + "\n";
26
        }
26
        }
27
        if (f.isocode.value.length==0) {
28
            _alertString += _("- Iso code missing") + "\n";
29
        }
27
        if (_alertString.length==0) {
30
        if (_alertString.length==0) {
28
            document.Aform.submit();
31
            document.Aform.submit();
29
        } else {
32
        } else {
Lines 72-78 Link Here
72
<div id="bd">
75
<div id="bd">
73
    <div id="yui-main">
76
    <div id="yui-main">
74
    <div class="yui-b">
77
    <div class="yui-b">
75
78
<div class="message dialog"><p style="text-align:justify" >You can define here a currency that will be picked rather than the default one ( that says the first in the price zone ) during the importation process from a staged file
79
whenever the price data is provided under different currencies.<br/>For this purpose, you must check the active box.
80
The symbol may be the pure currency sign or a string in which it's included ( like '$US' ).<br />
81
If the active currency cannot be found in the string price, then, others currencies likely to be present in this list are searched and the first found will be used to provide a local price throughout conversion.<br/>
82
Beware that the active currency had to be enabled only if necessary.</p></div>
76
[% IF ( else ) %]
83
[% IF ( else ) %]
77
<div id="toolbar" class="btn-toolbar">
84
<div id="toolbar" class="btn-toolbar">
78
    <a class="btn btn-small" id="newcurrency" href="[% script_name %]?op=add_form"><i class="icon-plus"></i> New currency</a>
85
    <a class="btn btn-small" id="newcurrency" href="[% script_name %]?op=add_form"><i class="icon-plus"></i> New currency</a>
Lines 107-113 Link Here
107
            <label for="symbol">Symbol: </label>
114
            <label for="symbol">Symbol: </label>
108
            <input type="text" name="symbol" id="symbol" size="5" maxlength="5" value="[% symbol %]" />
115
            <input type="text" name="symbol" id="symbol" size="5" maxlength="5" value="[% symbol %]" />
109
        </li>
116
        </li>
110
117
        <li>
118
            <label for="isocode">Iso code: </label>
119
            <input type="text" name="isocode" id="isocode" size="5" maxlength="5" value="[% isocode %]" />
120
        </li>
111
        <li>
121
        <li>
112
            <span class="label">Last updated: </span>[% timestamp %]
122
            <span class="label">Last updated: </span>[% timestamp %]
113
        </li>
123
        </li>
Lines 187-192 Link Here
187
            <th>Currency</th>
197
            <th>Currency</th>
188
            <th>Rate</th>
198
            <th>Rate</th>
189
            <th>Symbol</th>
199
            <th>Symbol</th>
200
            <th>Iso code</th>
190
            <th>Last updated</th>
201
            <th>Last updated</th>
191
            <th>Active</th>
202
            <th>Active</th>
192
            <th colspan="2">Actions&nbsp;</th>
203
            <th colspan="2">Actions&nbsp;</th>
Lines 200-205 Link Here
200
            <td>[% loo.currency %]</td>
211
            <td>[% loo.currency %]</td>
201
            <td>[% loo.rate %]</td>
212
            <td>[% loo.rate %]</td>
202
            <td>[% loo.symbol |html %]</td>
213
            <td>[% loo.symbol |html %]</td>
214
            <td>[% loo.isocode |html %]</td>
203
            <td>[% loo.timestamp %]</td>
215
            <td>[% loo.timestamp %]</td>
204
            <td style="color:green;">[% IF ( loo.active ) %]✓[% END %]</td>
216
            <td style="color:green;">[% IF ( loo.active ) %]✓[% END %]</td>
205
            <td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.currency %]">Edit</a></td>
217
            <td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.currency %]">Edit</a></td>
206
- 

Return to bug 9593