Lines 1512-1549
Return the best guess at what the actual price is from a price field.
Link Here
|
1512 |
|
1512 |
|
1513 |
sub MungeMarcPrice { |
1513 |
sub MungeMarcPrice { |
1514 |
my ( $price ) = @_; |
1514 |
my ( $price ) = @_; |
1515 |
|
|
|
1516 |
return unless ( $price =~ m/\d/ ); ## No digits means no price. |
1515 |
return unless ( $price =~ m/\d/ ); ## No digits means no price. |
1517 |
|
1516 |
# Look for the currency symbol and the normalized code of the active currency, if it's there, |
1518 |
## Look for the currency symbol of the active currency, if it's there, |
1517 |
my $active_currency = C4::Budgets->GetCurrency(); |
1519 |
## start the price string right after the symbol. This allows us to prefer |
1518 |
my $symbol = $active_currency->{'symbol'}; |
1520 |
## this native currency price over other currency prices, if possible. |
1519 |
my $isocode = $active_currency->{'isocode'}; |
1521 |
my $active_currency = C4::Context->dbh->selectrow_hashref( 'SELECT * FROM currency WHERE active = 1', {} ); |
1520 |
my $localprice; |
1522 |
my $symbol = quotemeta( $active_currency->{'symbol'} ); |
1521 |
if ( $symbol ) { |
1523 |
if ( $price =~ m/$symbol/ ) { |
1522 |
my @matches =($price=~ / |
1524 |
my @parts = split(/$symbol/, $price ); |
1523 |
\s? |
1525 |
$price = $parts[1]; |
1524 |
( # start of capturing parenthesis |
1526 |
} |
1525 |
(?: |
1527 |
|
1526 |
(?:[\p{Sc}\p{L}\/.]){1,4} # any character from Currency signs or Letter Unicode categories or slash or dot within 1 to 4 occurrences : call this whole block 'symbol block' |
1528 |
## Grab the first number in the string ( can use commas or periods for thousands separator and/or decimal separator ) |
1527 |
|(?:\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 4 occurrences : call this whole block 'digits block' |
1529 |
( $price ) = $price =~ m/([\d\,\.]+[[\,\.]\d\d]?)/; |
1528 |
) |
1530 |
|
1529 |
\s?\p{Sc}?\s? # followed or not by a whitespace. \p{Sc}?\s? are for cases like '25$ USD' |
1531 |
## Split price into array on periods and commas |
1530 |
(?: |
1532 |
my @parts = split(/[\,\.]/, $price); |
1531 |
(?:[\p{Sc}\p{L}\/.]){1,4} # followed by same block as symbol block |
1533 |
|
1532 |
|(?:\d+[\p{P}\s]?){1,4} # or by same block as digits block |
1534 |
## If the last grouping of digits is more than 2 characters, assume there is no decimal value and put it back. |
1533 |
) |
1535 |
my $decimal = pop( @parts ); |
1534 |
\s? # followed or not by a whitespace |
1536 |
if ( length( $decimal ) > 2 ) { |
1535 |
) # end of capturing parenthesis |
1537 |
push( @parts, $decimal ); |
1536 |
(?:\p{P}|\z) # followed by a punctuation sign or by the end of the string |
1538 |
$decimal = ''; |
1537 |
/gx); |
1539 |
} |
1538 |
|
1540 |
|
1539 |
if ( @matches ) { |
1541 |
$price = join('', @parts ); |
1540 |
foreach ( @matches ) { |
1542 |
|
1541 |
$localprice = $_ and last if index($_, $isocode)>=0; |
1543 |
if ( $decimal ) { |
1542 |
} |
1544 |
$price .= ".$decimal"; |
1543 |
if ( !$localprice ) { |
|
|
1544 |
foreach ( @matches ) { |
1545 |
$localprice = $_ and last if $_=~ /(^|[^\p{Sc}\p{L}\/])\Q$symbol\E([^\p{Sc}\p{L}\/]|\z)/; |
1546 |
} |
1547 |
} |
1548 |
} |
1549 |
$price=$localprice; |
1550 |
if ($price) { |
1551 |
# eliminate symbol/isocode, space and any final dot from the string |
1552 |
$price =~ s/[\p{Sc}\p{L}\/ ]|\.$//g; |
1553 |
# remove comma,dot when used as separators from hundreds |
1554 |
$price =~s/[\,\.](\d{3})/$1/g; |
1555 |
# convert comma to dot to ensure correct display of decimals if existing |
1556 |
$price =~s/,/./; |
1557 |
} |
1545 |
} |
1558 |
} |
1546 |
|
|
|
1547 |
return $price; |
1559 |
return $price; |
1548 |
} |
1560 |
} |
1549 |
|
1561 |
|