numerus/deploy/parse_price@v1.sql

54 lines
1.4 KiB
PL/PgSQL

-- Deploy numerus:parse_price to pg
-- requires: schema_public
begin;
set search_path to numerus, public;
create or replace function parse_price(price text, decimal_digits integer) returns integer as
$$
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.';
end if;
result := parts[1]::integer;
for d in 1..decimal_digits loop
result := result * 10;
end loop;
if array_length(parts, 1) = 2 then
frac_part := rtrim(parts[2], '0');
if length(frac_part) > decimal_digits then
raise invalid_parameter_value using message = price || ' has too many digits in the fraction part.';
end if;
frac_part := rpad(frac_part, decimal_digits, '0');
result := result + frac_part::integer;
end if;
return sign * result;
end;
$$
language plpgsql
immutable;
comment on function parse_price(text, integer) is
'Converts the string representation of a price in decimal form to cents, according to the number of decimal digits passed.';
revoke execute on function parse_price(text, integer) from public;
grant execute on function parse_price(text, integer) to invoicer;
grant execute on function parse_price(text, integer) to admin;
commit;