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

View File

@ -10,9 +10,14 @@ $$
declare declare
result text; result text;
scale integer := 10^decimal_digits; scale integer := 10^decimal_digits;
sign text := '';
begin begin
if cents < 0 then
sign := '-';
cents = -cents;
end if;
result = cents::text; 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; end;
$$ $$
language plpgsql language plpgsql

View File

@ -5,7 +5,7 @@ reset client_min_messages;
begin; begin;
select plan(36); select plan(42);
set search_path to auth, numerus, public; 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('1.1', 3), 1100 );
select is( parse_price('0', 2), 0 ); select is( parse_price('0', 2), 0 );
select is( parse_price('0', 3), 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.01', 2), 1 );
select is( parse_price('0.001', 3), 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.1', 2), 10 );
select is( parse_price('0.01', 3), 10 ); select is( parse_price('0.01', 3), 10 );
select is( parse_price('1', 2), 100 ); 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('1', 3), 1000 );
select is( parse_price('23.23', 2), 2323 ); select is( parse_price('23.23', 2), 2323 );
select is( parse_price('23.23', 3), 23230 ); 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 throws_ok( $$ select parse_price('234.234', 2) $$ );
select is( parse_price('234.234', 3), 234234 ); select is( parse_price('234.234', 3), 234234 );
select throws_ok( $$ select parse_price('2345.2345', 2) $$ ); select throws_ok( $$ select parse_price('2345.2345', 2) $$ );

View File

@ -5,7 +5,7 @@ reset client_min_messages;
begin; begin;
select plan(23); select plan(29);
set search_path to numerus, public; 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(0, 3), '0.000' );
select is( to_price(1, 2), '0.01' ); select is( to_price(1, 2), '0.01' );
select is( to_price(1, 3), '0.001' ); 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, 2), '0.10' );
select is( to_price(10, 3), '0.010' ); select is( to_price(10, 3), '0.010' );
select is( to_price(100, 2), '1.00' ); 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, 3), '12345.678' );
select is( to_price(12345678, 4), '1234.5678' ); select is( to_price(12345678, 4), '1234.5678' );
select is( to_price(12345678, 5), '123.45678' ); 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 * select *
from finish(); from finish();