-- Deploy camper:process_payment_response to pg
-- requires: roles
-- requires: schema_camper
-- requires: redsys_response
-- requires: payment
-- requires: payment_redsys_response
-- requires: parse_price
-- requires: currency

begin;

set search_path to camper, public;

create or replace function process_payment_response(payment_slug uuid, response redsys_response) returns text as
$$
declare
	pid integer;
	next_status text;
begin
	if response.transaction_type <> 0 then
		raise invalid_parameter_value using message = response.transaction_type || ' is not a processable transaction type';
	end if;

	update payment
	set payment_status = case when response.response_code < 100 then 'completed' else 'failed' end
	  , updated_at = current_timestamp
	where slug = payment_slug
	  and payment_status in ('pending', 'failed')
	returning payment_id, payment_status
	into pid, next_status;

	if pid is null then
		return '';
	end if;

	insert into payment_redsys_response (
		  payment_id
		, response_code
		, date_time
		, secure_payment
		, transaction_type
		, amount
		, currency_code
		, order_number
		, authorization_code
		, merchant_code
		, terminal_number
		, error_code
	)
	select pid
	     , response.response_code
	     , response.date_time
	     , response.secure_payment
	     , response.transaction_type
	     , parse_price(response.amount, decimal_digits)
	     , response.currency_code
	     , response.order_number
	     , response.authorization_code
	     , response.merchant_code
	     , response.terminal_number
	     , response.error_code
	from currency
	where currency.currency_code = response.currency_code
	on conflict (payment_id) do update
	set response_code = excluded.response_code
	  , date_time = excluded.date_time
	  , secure_payment = excluded.secure_payment
	  , transaction_type = excluded.transaction_type
	  , amount = excluded.amount
	  , currency_code = excluded.currency_code
	  , order_number = excluded.order_number
	  , authorization_code = excluded.authorization_code
	  , merchant_code = excluded.merchant_code
	  , terminal_number = excluded.terminal_number
	  , error_code = excluded.error_code
	;

	return next_status;
end;
$$
	language plpgsql
;

revoke execute on function process_payment_response(uuid, redsys_response) from public;
grant execute on function process_payment_response(uuid, redsys_response) to guest;
grant execute on function process_payment_response(uuid, redsys_response) to employee;
grant execute on function process_payment_response(uuid, redsys_response) to admin;

commit;
