<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[FrontAccounting forum — Realized FX not posted when a PO prepayment is moved to the invoice]]></title>
	<link rel="self" href="https://frontaccounting.com/punbb/extern.php?action=feed&amp;tid=10747&amp;type=atom" />
	<updated>2026-11-02T14:06:43Z</updated>
	<generator>PunBB</generator>
	<id>https://frontaccounting.com/punbb/viewtopic.php?id=10747</id>
		<entry>
			<title type="html"><![CDATA[Realized FX not posted when a PO prepayment is moved to the invoice]]></title>
			<link rel="alternate" href="https://frontaccounting.com/punbb/viewtopic.php?pid=43899#p43899" />
			<content type="html"><![CDATA[<p>Claude Assisted.</p><p>Version: FrontAccounting 2.4.19 and 2.4.20 (same code in both)</p><p>Summary<br />When an advance payment allocated to a Purchase Order is transferred to the<br />supplier invoice on invoice entry, the exchange difference between the payment<br />rate and the invoice rate is never posted. The supplier sub-ledger shows the<br />invoice fully settled, but GL Accounts Payable keeps the FX difference as a<br />residual balance. Normal allocations (Allocate Supplier Payments) post the FX<br />correctly; only the PO-prepayment path is affected.</p><p>Steps to reproduce (home currency CAD, supplier in USD)<br />1. Purchase Order Entry: USD supplier, date 11/01, 1,000.00 USD.<br />2. Supplier payment dated 11/01, 1,000.00 USD at rate 1.30; allocate it to the PO<br />&nbsp; &nbsp;(the PO is only offered for allocation before it is received).<br />3. Receive the PO on 11/02.<br />4. Enter the supplier invoice for that delivery dated 11/03 at rate 1.40.</p><p>Expected<br />The invoice GL shows an exchange variation pair for the advance:<br />&nbsp; Dr Accounts Payable 100.00 / Cr Exchange Variances 100.00<br />&nbsp; (1,000 x (1.40 - 1.30)), and GL AP for the supplier nets to zero.</p><p>Actual<br />No exchange variation is posted. The invoice is fully allocated in the<br />sub-ledger, but GL AP for the supplier is left at Cr 100.00.</p><p>Cause<br />add_supp_invoice() (purchasing/includes/db/invoice_db.inc) moves the PO<br />allocations with get_po_prepayments() -&gt; reallocate_payments() -&gt;<br />allocate_payment(). allocate_payment() only rewrites supp_allocations and the<br />alloc totals; it never calls exchange_variation(), unlike<br />allocation_cart::write().</p><p>Suggested fix<br />After reallocate_payments() in add_supp_invoice(), for supplier invoices, call<br />exchange_variation() for each allocation now pointing at the new invoice,<br />using the payment&#039;s own date (as allocation_cart::write() does):</p><p>&nbsp; if ($trans_type == ST_SUPPINVOICE &amp;&amp; empty($GLOBALS[&#039;no_exchange_variations&#039;])) {<br />&nbsp; &nbsp; &nbsp; $res = db_query(&quot;SELECT a.trans_type_from, a.trans_no_from, a.amt, t.tran_date<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &quot;.TB_PREF.&quot;supp_allocations a<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JOIN &quot;.TB_PREF.&quot;supp_trans t ON t.type=a.trans_type_from<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND t.trans_no=a.trans_no_from AND t.supplier_id=a.person_id<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE a.trans_type_to=&quot;.ST_SUPPINVOICE.&quot; AND a.trans_no_to=&quot;.db_escape($invoice_id).&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND a.person_id=&quot;.db_escape($supp_trans-&gt;supplier_id));<br />&nbsp; &nbsp; &nbsp; while ($a = db_fetch($res))<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($a[&#039;trans_type_from&#039;] != ST_JOURNAL)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exchange_variation($a[&#039;trans_type_from&#039;], $a[&#039;trans_no_from&#039;],<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ST_SUPPINVOICE, $invoice_id, sql2date($a[&#039;tran_date&#039;]),<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a[&#039;amt&#039;], PT_SUPPLIER);<br />&nbsp; }</p><p>Note for invoice re-entry (edit): the invoice gets a new number and existing<br />allocations are moved the same way. FX previously booked on the payment side<br />(memo &quot;Supplier Invoice &lt;old no&gt;&quot;) is not removed by void_transaction(), so a<br />complete fix should remove the old pair&#039;s FX before re-posting. Related: the<br />allocation re-save duplicate FX issue below makes this worse.</p>]]></content>
			<author>
				<name><![CDATA[andijani]]></name>
				<uri>https://frontaccounting.com/punbb/profile.php?id=20111</uri>
			</author>
			<updated>2026-11-02T14:06:43Z</updated>
			<id>https://frontaccounting.com/punbb/viewtopic.php?pid=43899#p43899</id>
		</entry>
</feed>
