@accounter/server
Version:
Accounter GraphQL server
162 lines (147 loc) • 7.27 kB
JavaScript
export default {
name: '2025-07-14T14-35-02.swift-multiple-currencies-handle.sql',
run: ({ sql }) => sql `
create or replace function accounter_schema.insert_poalim_swift_transaction_handler() returns trigger
language plpgsql
as
$$
DECLARE
merged_id UUID;
account_id_var UUID;
owner_id_var UUID;
charge_id_var UUID = NULL;
instructed_amount NUMERIC;
value_date_amount NUMERIC;
transaction_amount NUMERIC;
fee_amount NUMERIC;
currency_code accounter_schema.currency;
instructed_currency_code accounter_schema.currency;
value_date_currency_code accounter_schema.currency;
exchange_rate NUMERIC;
transaction_id_var UUID = NULL;
BEGIN
-- extract amount
BEGIN
instructed_amount := CASE
WHEN NEW.swift_currency_instructed_amount_33b <> ' ' THEN REPLACE(
RIGHT(NEW.swift_currency_instructed_amount_33b,
LENGTH(NEW.swift_currency_instructed_amount_33b) - 3), ',',
'.')::NUMERIC END;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid instructed amount for SWIFT. got: [%]; error: %', NEW.swift_currency_instructed_amount_33b, SQLERRM;
END;
BEGIN
value_date_amount := CASE
WHEN NEW.swift_value_date_currency_amount_32a <> ' ' THEN REPLACE(
RIGHT(NEW.swift_value_date_currency_amount_32a,
LENGTH(NEW.swift_value_date_currency_amount_32a) - 9), ',',
'.')::NUMERIC END;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid value date amount for SWIFT. got: [%]; error: %', NEW.swift_value_date_currency_amount_32a, SQLERRM;
END;
transaction_amount := COALESCE(instructed_amount, value_date_amount);
-- extract currency
BEGIN
instructed_currency_code := CASE
WHEN NEW.swift_currency_instructed_amount_33b <> ' '
THEN LEFT(NEW.swift_currency_instructed_amount_33b, 3)::accounter_schema.currency
END;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid instructed currency for SWIFT transaction. got: [%]; error: %', NEW.swift_currency_instructed_amount_33b, SQLERRM;
END;
BEGIN
value_date_currency_code := CASE
WHEN NEW.swift_value_date_currency_amount_32a <> ' '
THEN RIGHT(LEFT(NEW.swift_value_date_currency_amount_32a,
9), 3)::accounter_schema.currency END;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid value date currency for SWIFT transaction. got: [%]; error: %', NEW.swift_value_date_currency_amount_32a, SQLERRM;
END;
currency_code := COALESCE(instructed_currency_code, value_date_currency_code);
-- handle multiple currencies
BEGIN
exchange_rate := CASE
WHEN NEW.swift_exchange_rate_36 <> ' '
THEN REPLACE(NEW.swift_exchange_rate_36, ',', '.')::NUMERIC END;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid exchange rate format in SWIFT fields. Got this: [%]; Error: %', NEW.swift_exchange_rate_36, SQLERRM;
END;
-- handle multiple currencies
IF (instructed_amount IS NOT NULL AND value_date_currency_code <> instructed_currency_code) THEN
IF (exchange_rate IS NULL) THEN
RAISE EXCEPTION 'Invalid SWIFT transaction: multiple currencies without exchange rate. instructed amount: [%]; value date amount: [%]; exchange rate: [%]; Error: %', NEW.swift_currency_instructed_amount_33b, NEW.swift_value_date_currency_amount_32a, NEW.swift_exchange_rate_36, SQLERRM;
END IF;
transaction_amount := ROUND(instructed_amount * exchange_rate, 2);
END IF;
fee_amount := transaction_amount - value_date_amount;
IF (fee_amount > 0) THEN
-- Create merged raw transactions record:
INSERT INTO accounter_schema.transactions_raw_list (poalim_swift_id)
VALUES (NEW.id)
RETURNING id INTO merged_id;
-- get account and owner IDs
SELECT INTO account_id_var, owner_id_var id,
owner
FROM accounter_schema.financial_accounts
WHERE account_number = NEW.account_number::TEXT;
IF (account_id_var IS NULL) THEN
RAISE EXCEPTION 'Account not found for account number: %', NEW.account_number;
END IF;
-- check if matching charge exists for source:
SELECT t.charge_id
INTO charge_id_var
FROM (SELECT formatted_value_date, event_details, id, currency, event_amount
FROM accounter_schema.poalim_foreign_account_transactions) AS s
LEFT JOIN accounter_schema.transactions_raw_list tr
ON COALESCE(tr.poalim_ils_id, tr.poalim_foreign_id) = s.id
LEFT JOIN accounter_schema.transactions t
ON tr.id = t.source_id
WHERE t.charge_id IS NOT NULL
AND s.formatted_value_date = NEW.formatted_start_date
AND currency_code = s.currency
AND (s.event_details LIKE '%' || TRIM(LEFT(NEW.charge_party_name, 13)) || '%'
AND NEW.amount::NUMERIC = s.event_amount)
OR (transaction_amount * -1 = s.event_amount);
-- if no match, create new charge
IF (charge_id_var IS NULL) THEN
INSERT INTO accounter_schema.charges (owner_id)
VALUES (owner_id_var)
RETURNING id INTO charge_id_var;
END IF;
-- create new transaction for fee
INSERT INTO accounter_schema.transactions (account_id, charge_id, source_id, source_description, currency,
event_date, debit_date, amount, current_balance, business_id, is_fee,
source_reference, counter_account, source_origin, origin_key)
VALUES (account_id_var,
charge_id_var,
merged_id,
CONCAT_WS(' ',
'Swift Fee:',
NEW.charge_party_name,
NEW.reference_number,
NEW.swift_remittance_information_70
),
currency_code,
NEW.formatted_start_date::DATE,
NEW.formatted_start_date::DATE,
fee_amount * -1,
0,
NULL,
TRUE,
NEW.reference_number,
'SWIFT',
'POALIM',
NEW.id)
RETURNING id INTO transaction_id_var;
END IF;
RETURN NEW;
END
$$;
`,
};
//# sourceMappingURL=2025-07-14T14-35-02.swift-multiple-currencies-handle.js.map