Code used to settle posted payment journal transaction against the sales invoice
// <summary>
/// Settle payment journal (which still has balance) against sales invoice. Each payment journal is make for one sales order only.
/// No payment is made for multiple order. If balance is available after settle, leave the balance as there might be another invoice
/// not comes in yet for the same order. This periodic job will settle against them when the invoice is in.
/// </summary>
/// <param name = "_contract"></param>
public void processSettlement(AG_CustSalesPaymSettlementDataContract _contract)
{
RefRecId paymLedgerJournalTransRefRecId = _contract.parmPaymLedgerJournalTransRecId();
boolean showInfoLog = _contract.parmShowInfoLog();
LedgerJournalTable paymLedgerJournalTable;
LedgerJournalTrans paymLedgerJournalTrans;
CustTransOpen paymCustTransOpen, custTransOpen;
CustTrans paymCustTrans;
//Loop through all payment journal which still has open balance
while select paymLedgerJournalTable
where paymLedgerJournalTable.Posted == NoYes::Yes
join paymLedgerJournalTrans
where paymLedgerJournalTrans.JournalNum == paymLedgerJournalTable.JournalNum
&& ((!paymLedgerJournalTransRefRecId) //If specific payment journal line is provided, get that only,
|| (paymLedgerJournalTrans.RecId == paymLedgerJournalTransRefRecId)) //else, get all lines (which satisfy other query criteria)
join paymCustTrans
where paymCustTrans.Voucher == paymLedgerJournalTrans.Voucher
&& paymCustTrans.RecId == paymLedgerJournalTrans.CustTransId
&& paymCustTrans.TransType == LedgerTransType::Payment
join paymCustTransOpen
where paymCustTransOpen.RefRecId == paymCustTrans.RecId
{
AG_CustSalesPaymSettlementService::settleByPaymJourTrans(paymLedgerJournalTrans, showInfoLog);
}
}
public static void settleByPaymJourTrans(LedgerJournalTrans _paymLedgerJournalTrans, boolean _showInfoLog)
{
boolean useLegacyMethod = false;
CustTable custTable;
LedgerJournalTrans paymLedgerJournalTrans;
CustTransOpen invCustTransOpen, paymCustTransOpen, custTransOpen;
CustTrans invCustTrans, paymCustTrans;
CustInvoiceJour custInvoiceJour;
SpecTransManager manager;
CustVendTransData custVendTransData;
//Given the payment LedgerJournalTrans, find the related CustTrans which has CustTransOpen
select firstonly paymLedgerJournalTrans
where paymLedgerJournalTrans.RecId == _paymLedgerJournalTrans.RecId
join paymCustTrans
where paymCustTrans.Voucher == paymLedgerJournalTrans.Voucher
&& paymCustTrans.RecId == paymLedgerJournalTrans.CustTransId
&& paymCustTrans.TransType == LedgerTransType::Payment
join paymCustTransOpen
where paymCustTransOpen.RefRecId == paymCustTrans.RecId;
//Find the related invoice to be settled against the payment journal in the query above
select firstonly invCustTrans
where invCustTrans.AccountNum == paymCustTrans.AccountNum
&& invCustTrans.MCRPaymOrderID == paymCustTrans.MCRPaymOrderID
&& invCustTrans.TransType == LedgerTransType::Sales
join invCustTransOpen
where invCustTransOpen.RefRecId == invCustTrans.RecId;
custTable = CustTable::find(paymCustTrans.AccountNum);
try
{
ttsbegin;
if(paymCustTransOpen && invCustTransOpen)
{
//Legacy code for settlement --------------------------------------------------------------------------------------------------------
if(useLegacyMethod)
{
//Create an object of the CustVendTransData class with the invoice transaction as parameter and mark it for settlement
custVendTransData = CustVendTransData::construct(invCustTrans);
custVendTransData.markForSettlement(custTable);
//Create an object of the CustVendTransData class with the payment transaction as parameter and mark it for settlement
custVendTransData = CustVendTransData::construct(paymCustTrans);
custVendTransData.markForSettlement(custTable);
// Settle all transactions marked for settlement for this customer
CustTrans::settleTransact(custTable, null, true, SettleDatePrinc::DaysDate, systemdateget());
}
//New code for settlement -----------------------------------------------------------------------------------------------------------
else
{
//Mark for settlement
SpecTransExecutionContext specTransExecutionContext = SpecTransExecutionContext::newFromSource(custTable);
SpecTransManager specTransManager = SpecTransManager::construct(specTransExecutionContext.parmSpecContext());
Amount settleAmount = invCustTransOpen.AmountCur;
//Prevent over settle
if(settleAmount > (-paymCustTransOpen.AmountCur))
settleAmount = (-paymCustTransOpen.AmountCur);
//Payment
specTransManager.insert(paymCustTransOpen.DataAreaId,
paymCustTransOpen.TableId,
paymCustTransOpen.RecId,
-settleAmount,
paymCustTrans.CurrencyCode);
//Invoice
specTransManager.insert(invCustTransOpen.DataAreaId,
invCustTransOpen.TableId,
invCustTransOpen.RecId,
settleAmount,
invCustTrans.CurrencyCode);
//Settle
if(CustTrans::settleTransaction(specTransExecutionContext, CustTransSettleTransactionParameters::construct()))
{
if(_showInfoLog)
info(strFmt("@AG:AG_SettlementCompletedFor", invCustTrans.MCRPaymOrderID, invCustTrans.Invoice, settleAmount)); //Label: Settlement completed for Sales order %1, Invoice %2, Amount %3
}
}
}
ttscommit;
}
catch
{
error(strFmt("@AG:AG_SettlementForPaymentJournalLineFailed", _paymLedgerJournalTrans.RecId, _paymLedgerJournalTrans.accountDisplay())); //label: Settlement for payment journal line is unsuccessful (RecId: %1, Account: %2)
}
}