Fix to_price and parse_price for negative values

This commit is contained in:
jordi fita mas 2023-02-23 14:42:18 +01:00
parent 8dbf8ef2d0
commit 980db529f1
4 changed files with 27 additions and 4 deletions

View File

@ -11,7 +11,13 @@ declare
parts text[];
result int;
frac_part text;
sign int := 1;
begin
if price like '-%' Then
sign := -1;
price := substring(price from 2);
end if;
parts := string_to_array(price, '.');
if array_length(parts, 1) > 2 then
raise invalid_parameter_value using message = price || ' is not a valid price representation.';
@ -31,7 +37,7 @@ begin
result := result + frac_part::integer;
end if;
return result;
return sign * result;
end;
$$
language plpgsql

View File

@ -10,9 +10,14 @@ $$
declare
result text;
scale integer := 10^decimal_digits;
sign text := '';
begin
if cents < 0 then
sign := '-';
cents = -cents;
end if;
result = cents::text;
return (cents / scale)::text || '.' || to_char(mod(cents, scale), rpad('FM', decimal_digits + 2, '0'));
return sign || (cents / scale)::text || '.' || to_char(mod(cents, scale), rpad('FM', decimal_digits + 2, '0'));
end;
$$
language plpgsql

View File

@ -5,7 +5,7 @@ reset client_min_messages;
begin;
select plan(36);
select plan(42);
set search_path to auth, numerus, public;
@ -23,8 +23,12 @@ select is( parse_price('1.1', 2), 110 );
select is( parse_price('1.1', 3), 1100 );
select is( parse_price('0', 2), 0 );
select is( parse_price('0', 3), 0 );
select is( parse_price('-0', 2), 0 );
select is( parse_price('-0', 3), 0 );
select is( parse_price('0.01', 2), 1 );
select is( parse_price('0.001', 3), 1 );
select is( parse_price('-0.01', 2), -1 );
select is( parse_price('-0.001', 3), -1 );
select is( parse_price('0.1', 2), 10 );
select is( parse_price('0.01', 3), 10 );
select is( parse_price('1', 2), 100 );
@ -33,6 +37,8 @@ select is( parse_price('10', 2), 1000 );
select is( parse_price('1', 3), 1000 );
select is( parse_price('23.23', 2), 2323 );
select is( parse_price('23.23', 3), 23230 );
select is( parse_price('-23.23', 2), -2323 );
select is( parse_price('-23.23', 3), -23230 );
select throws_ok( $$ select parse_price('234.234', 2) $$ );
select is( parse_price('234.234', 3), 234234 );
select throws_ok( $$ select parse_price('2345.2345', 2) $$ );

View File

@ -5,7 +5,7 @@ reset client_min_messages;
begin;
select plan(23);
select plan(29);
set search_path to numerus, public;
@ -23,6 +23,8 @@ select is( to_price(0, 2), '0.00' );
select is( to_price(0, 3), '0.000' );
select is( to_price(1, 2), '0.01' );
select is( to_price(1, 3), '0.001' );
select is( to_price(-1, 2), '-0.01' );
select is( to_price(-1, 3), '-0.001' );
select is( to_price(10, 2), '0.10' );
select is( to_price(10, 3), '0.010' );
select is( to_price(100, 2), '1.00' );
@ -33,6 +35,10 @@ select is( to_price(12345678, 2), '123456.78' );
select is( to_price(12345678, 3), '12345.678' );
select is( to_price(12345678, 4), '1234.5678' );
select is( to_price(12345678, 5), '123.45678' );
select is( to_price(-12345678, 2), '-123456.78' );
select is( to_price(-12345678, 3), '-12345.678' );
select is( to_price(-12345678, 4), '-1234.5678' );
select is( to_price(-12345678, 5), '-123.45678' );
select *
from finish();