[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FX gains/losses in bulk payment postings
- Subject: FX gains/losses in bulk payment postings
- From: Erik Huelsmann <..hidden..>
- Date: Sun, 22 Jan 2012 13:48:32 +0100
Hi Chris,
As discussed, I'm moving forward on updating payment_bulk_post() to
account for possible fx gains/losses.
Below you'll find the patch I have prepared, which loads correctly and
should work. However, while testing, I found that the bulk-payment
entry screen doesn't ask me for an FX rate when there isn't one
already entered for the posting date specified - when the currency
doesn't equal the default currency, of course.
>From what I understand, you're quite familiar with that code, so, if
you could do the UI bit and let me know if I should commit my patch,
that would be great!
After the UI bit is done, I can continue further testing on the backend.
Bye,
Erik.
Index: modules/Payment.sql
===================================================================
--- modules/Payment.sql (revision 4280)
+++ modules/Payment.sql (working copy)
@@ -480,7 +480,8 @@
t_exchangerate := in_exchangerate;
END IF;
- CREATE TEMPORARY TABLE bulk_payments_in (id int, amount numeric);
+ CREATE TEMPORARY TABLE bulk_payments_in
+ (id int, amount numeric, fxrate numeric, gain_loss_accno int);
select id into t_ar_ap_id from chart where accno = in_ar_ap_accno;
select id into t_cash_id from chart where accno = in_cash_accno;
@@ -495,18 +496,46 @@
in_transactions[out_count][2]);
END LOOP;
-
IF in_account_class = 1 THEN
t_cash_sign := 1;
ELSE
t_cash_sign := -1;
END IF;
+ IF (in_curr IS NULL OR in_curr = t_currs[0]) THEN
+ UPDATE bulk_payments_in
+ SET fxrate = 1;
+ ELSE
+ UPDATE bulk_payments_in bpi
+ SET fxrate =
+ (SELECT CASE WHEN in_account_class = 1 THEN sell
+ ELSE buy
+ END
+ FROM exchangerate e
+ JOIN (SELECT * FROM ar
+ UNION
+ SELECT * FROM ap) a
+ ON (e.transdate = a.transdate
+ AND e.curr = a.curr)
+ WHERE a.id = bpi.id);
+ UPDATE bulk_payments_in bpi
+ SET gain_loss_accno =
+ (SELECT value::int FROM defaults
+ WHERE setting_key = 'fxgain_accno_id')
+ WHERE ((t_exchangerate - bpi.fxrate) * t_cash_sign) < 0;
+ UPDATE bulk_payments_in
+ SET gain_loss_accno = (SELECT value::int FROM defaults
+ WHERE setting_key = 'fxloss_accno_id')
+ WHERE ((t_exchangerate - bpi.fxrate) * t_cash_sign) > 0;
+ -- explicitly leave zero gain/loss accno_id entries at NULL
+ -- so we have an easy check for which
+ END IF;
+
-- Insert cash side
INSERT INTO acc_trans
(trans_id, chart_id, amount, approved,
voucher_id, transdate, source)
- SELECT id, t_cash_id, amount * t_cash_sign * t_exchangerate,
+ SELECT id, t_cash_id, amount * t_cash_sign * fxrate,
CASE WHEN t_voucher_id IS NULL THEN true
ELSE false END,
t_voucher_id, in_payment_date, in_source
@@ -517,14 +546,25 @@
(trans_id, chart_id, amount, approved,
voucher_id, transdate, source)
SELECT id, t_ar_ap_id,
- amount * -1 * t_cash_sign * t_exchangerate,
+ amount * -1 * t_cash_sign * fxrate,
CASE WHEN t_voucher_id IS NULL THEN true
ELSE false END,
t_voucher_id, in_payment_date, in_source
FROM bulk_payments_in where amount <> 0;
- -- ### BUG: Where's the FX gain/loss part for FX postings??
+ -- Insert fx gain/loss effects, if applicable
+ INSERT INTO acc_trans
+ (trans_id, chart_id, amount, approved,
+ voucher_id, transdate, source)
+ SELECT id, gain_loss_accno,
+ amount * -1 * t_cash_sign * (t_exchangerate - fxrate),
+ CASE WHEN t_voucher_id IS NULL THEN true
+ ELSE false END,
+ t_voucher_id, in_payment_date, in_source
+ FROM bulk_payments_in
+ WHERE amount <> 0 AND gain_loss_accno IS NOT NULL;
+
DROP TABLE bulk_payments_in;
perform unlock_all();
return out_count;