Description
if the posting is completely in foreign currency, and the posting is balanced in TC, then it also must be balanced in LC and CC
Parameters
oiReturnStatus | output | integer | Return status of the method. |
Internal usage
QadFinancials
program code (program8/bopenitemadjustment.p)
/* =============================================================================================== */
/* The overall goal of this method is to make sure that when the posting is balanced in TC and not */
/* yet balanced in LC or CC, we try to automate as much the balancing of the posting in LC and CC */
/* We will automatically create additional posting-lines with only an amount in LC or CC filled */
/* and this can either be on a realised-gain/loss acocunt either on a rouding account */
/* */
/* Note that at this time, the posting can already contain some postinglines with only an amount */
/* in LC or CC and a currency of LC or CC; such lines could have already been added to the posting */
/* my the methods that have made the movement on the invoices as when making the last movement on */
/* an invoice it can happen that a rouding line is added to completely set the LC- or CC-balance */
/* to zero. */
/* We will not taken these posting-lines into account for deciding if a posting only uses a single */
/* currency but of course we count them for getting the LC- or CC-balance of the posting */
/* */
/* **********Case 1: */
/* All the items being matched in the posting have the same Transaction Currency and the trx nets */
/* to 0 in TC, and all the items have the same exchange rate to the target currency (BC or SC). In */
/* this case, the only cause of this difference can be rounding, so the difference must be posted */
/* to the system rounding difference account. */
/* **********Case 2: */
/* All the items being matched in the posting have the same Transaction Currency and the trx nets */
/* to 0 in TC, and there are at least 2 different exchange rates. In this case, even though, */
/* technically, part of the difference could be due to rounding, most of it will be a realised */
/* exchange gain or loss. It is considered acceptable to post all of the difference to either the */
/* system Realized Exchange Gain or Realized Exchange Loss account, depending on whether the */
/* difference is a Credit or Debit posting respectively. This approach has been discussed with a */
/* number of other business analysts and qualified accountants. */
/* =============================================================================================== */
/* ======================================= */
/* Excpetion handling and initialiasations */
/* ======================================= */
assign oiReturnStatus = -98
viLocalReturnStatus = 0
vcOIAdjCurrencyCode = "":U
vlIsSameCurrency = true.
/* ========================================================== */
/* Actions are only needed in case all OIAdj have the same TC */
/* and when the LC or CC differs from that currency */
/* ========================================================== */
for each tOIAdj :
if vcOIAdjCurrencyCode = "":U
then assign vcOIAdjCurrencyCode = tOIAdj.tcInvoiceCurrencyCode.
if tOIAdj.tcInvoiceCurrencyCode <> vcOIAdjCurrencyCode
then do:
assign vlIsSameCurrency = false.
leave.
end. /* if tOIAdj.tcInvoiceCurrencyCode <> vcOIAdjCurrencyCode */
end. /* For each tOIAd */
assign vlIsSameCurrency = vlIsSameCurrency and
(vcOIAdjCurrencyCode <> vcCompanyLC or
vcOIAdjCurrencyCode <> vcCompanyCC).
if vlIsSameCurrency <> true
then do :
assign oiReturnStatus = 0.
Return.
end. /* if vlIsSameCurrency <> true */
/* ================= */
/* Start major block */
/* ================= */
AUOTBALANCINGBLOCK: DO:
/* ================================================================================ */
/* Get the Deb/Cred values from the posting - Instance of BJE is already Opened etc */
/* ================================================================================ */
<M-47 run GetPostingAmountAndCurrency
(input viMainPostingID (iiPostingID),
output vcCurrencyCodeInPosting (ocCurrencyCode),
output vdTCLCExchangeRateInPosting (odTCLCExchangeRate),
output vdTCLCExchangeScaleInPosting (odTCLCExchangeScale),
output vdTCCCExchangeRateInPosting (odTCCCExchangeRate),
output vdTCCCExchangeScaleInPosting (odTCCCExchangeScale),
output vdPostingAmountDebitTC (odPostingAmountDebitTC),
output vdPostingAmountCreditTC (odPostingAmountCreditTC),
output vdPostingAmountDebitLC (odPostingAmountDebitLC),
output vdPostingAmountCreditLC (odPostingAmountCreditLC),
output vdPostingAmountDebitCC (odPostingAmountDebitCC),
output vdPostingAmountCreditCC (odPostingAmountCreditCC),
output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
if viFcReturnSuper <> 0
then assign viLocalReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave AUOTBALANCINGBLOCK.
/* ========================================================================================= */
/* If the posting holds posting-lines with different currencies (exception for the lines */
/* where no TC-amount is filled) then we will stop this method without raising an error */
/* ========================================================================================= */
if vcCurrencyCodeInPosting = "":U or vcCurrencyCodeInPosting = ? /* this means multiple currencies are used in the posting */
then do :
assign viLocalReturnStatus = 0.
Leave AUOTBALANCINGBLOCK.
end. /* if vcCurrencyCodeInPosting = "":U or vcCurrencyCodeInPosting = ? /* this means multiple currencies are used in the posting */ */
/* ================================================================================== */
/* If the posting is not yet balanced in TC then no further actions are needed here */
/* as the validations of the posting-class itself will hanlde all the required checks */
/* ================================================================================== */
if vdPostingAmountDebitTC - vdPostingAmountCreditTC <> 0
then Leave AUOTBALANCINGBLOCK.
/* =============================================================================================== */
/* LC */
/* All lines in the posting have the same currency (exception for the lines where no TC-amount */
/* is filled) and the posting is balanced in TC but not in LC Then; */
/* - Post the LC-difference to a rouding account in case all the posting-lines (exception for the */
/* lines where no TC-amount is filled) have the same exchange rate and scale */
/* - Post the LC-difference to a gain-loss account in case the posting-lines (where a TC-amount is */
/* filled) have different exchange-rates/scales */
/* Amount to post: Abs(Debit-Credit) */
/* Deb/Cred: if single-exch-rate-scale */
/* then if Debit-Credit > 0 */
/* then post amount to Credit and on rouding-account */
/* else post amount to Debit and on rouding-account */
/* else if Debit-Credit > 0 */
/* then post amount to Credit and on a Gain-acc */
/* else post amount to Debit and on a Loss-acc */
/* =============================================================================================== */
if vdPostingAmountDebitLC - vdPostingAmountCreditLC <> 0
then do :
/* =========================== */
/* Get the amount to be posted */
/* =========================== */
if vdPostingAmountDebitLC - vdPostingAmountCreditLC > 0
then assign vdDebitLC = 0
vdCreditLC = absolute(vdPostingAmountDebitLC - vdPostingAmountCreditLC).
else assign vdDebitLC = absolute(vdPostingAmountDebitLC - vdPostingAmountCreditLC)
vdCreditLC = 0.
/* ============================================================ */
/* Get either a gain-loss-account, either the rounding-account */
/* ============================================================ */
if vdTCLCExchangeRateInPosting = 0 or
vdTCLCExchangeScaleInPosting = 0 /* This means not all rates/scales on the posting-lines were the same */
then do :
if vdCreditLC > 0
then do :
<Q-16 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-EXCHANGEREALPROFIT}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find tqGLByGLSystemType where
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST} and
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-EXCHANGEREALPROFIT}
no-lock no-error.
if not available tqGLByGLSystemType
then do:
assign vcMsgOIAdj = trim(substitute(#T-93'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(144169476)T-93#,{&GLSYSTEMTYPE-EXCHANGEREALPROFIT-TR}))
viLocalReturnStatus = -3.
<M-61 run SetMessage
(input vcMsgOIAdj (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-237744':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* if vdCreditLC > 0 */
else do :
<Q-14 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-EXCHANGEREALLOSS}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find tqGLByGLSystemType where
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST} and
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-EXCHANGEREALLOSS}
no-lock no-error.
if not available tqGLByGLSystemType
then do:
assign vcMsgOIAdj = trim(substitute(#T-68'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(144169476)T-68#,{&GLSYSTEMTYPE-EXCHANGEREALLOSS-TR}))
viLocalReturnStatus = -3.
<M-44 run SetMessage
(input vcMsgOIAdj (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-509521':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* else if vdCreditLC > 0 */
end. /* if vdTCLCExchangeRateInPosting = 0 or */
else do :
<Q-98 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-ROUND}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find first tqGLByGLSystemType where
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-ROUND} and
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST}
no-error.
if not available tqGLByGLSystemType
then do :
assign vcMsgOIAdj = trim(substitute(#T-22'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(26431060)T-22#,{&GLSYSTEMTYPE-ROUND-TR}))
viLocalReturnStatus = -3.
<M-25 run SetMessage
(input vcOIAdjCurrencyCode (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-282906':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* else if vdTCLCExchangeRateInPosting = 0 or */
/* ====================================================== */
/* Create the additional posting-line with only LC filled */
/* ====================================================== */
empty temp-table tDefaultSafsFromOIAdj.
<M-82 run AddStandardPosting
(input vcMainPostingTcRowid (icPostingtcRowid),
input vcGLCode (icGLCode),
input ? (icDivisionCode),
input ? (icCostCentreCode),
input ? (icCostCentreText),
input ? (icProjectCode),
input ? (icProjectText),
input ? (icIntercoBusinessRelationCode),
input vcCurrencyCodeInPosting (icCurrencyCode),
input 0 (idDebitTC),
input vdDebitLC (idDebitLC),
input 0 (idDebitCC),
input 0 (idDebitPC),
input 0 (idCreditTC),
input vdCreditLC (idCreditLC),
input 0 (idCreditCC),
input 0 (idCreditPC),
input 0 (idQty),
input ? (icLineText),
input ? (icSafText),
input tDefaultSafsFromOIAdj (tDefaultSafs),
input {&EXCHANGERATETYPE-ACCOUNTING} (icExchangeRateType),
input 1 (idExchangeRate),
input 1 (idExchangeRateScale),
input 1 (idPostingLineCCRate),
input 1 (idPostingLineCCScale),
output viDummyPostingLineID (oiPostingLineId),
input ? (iiSafStructureId),
input ? (icSafStructureCode),
input ? (icAllocationKey),
input false (ilLinkedCrCyDaemonReqExists),
output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
if viFcReturnSuper <> 0
then assign viLocalReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave AUOTBALANCINGBLOCK.
end. /* if vdPostingAmountDebitLC - vdPostingAmountCreditLC <> 0 */
/* =============================================================================================== */
/* CC */
/* All lines in the posting have the same currency (exception for the lines where no TC-amount */
/* is filled) and the posting is balanced in TC but not in CC Then; */
/* - Post the CC-difference to a rouding account in case all the posting-lines (exception for the */
/* lines where no TC-amount is filled) have the same exchange rate and scale */
/* - Post the CC-difference to a gain-loss account in case the posting-lines (where a TC-amount is */
/* filled) have different exchange-rates/scales */
/* Amount to post: Abs(Debit-Credit) */
/* Deb/Cred: if single-exch-rate-scale */
/* then if Debit-Credit > 0 */
/* then post amount to Credit and on rouding-account */
/* else post amount to Debit and on rouding-account */
/* else if Debit-Credit > 0 */
/* then post amount to Credit and on a Gain-acc */
/* else post amount to Debit and on a Loss-acc */
/* =============================================================================================== */
if vdPostingAmountDebitCC - vdPostingAmountCreditCC <> 0
then do :
/* =========================== */
/* Get the amount to be posted */
/* =========================== */
if vdPostingAmountDebitCC - vdPostingAmountCreditCC > 0
then assign vdDebitCC = 0
vdCreditCC = absolute(vdPostingAmountDebitCC - vdPostingAmountCreditCC).
else assign vdDebitCC = absolute(vdPostingAmountDebitCC - vdPostingAmountCreditCC)
vdCreditCC = 0.
/* ============================================================ */
/* Get either a gain-loss-account, either the rounding-account */
/* ============================================================ */
if vdTCCCExchangeRateInPosting = 0 or
vdTCCCExchangeScaleInPosting = 0 /* This means not all rates/scales on the posting-lines were the same */
then do :
if vdCreditCC > 0
then do :
<Q-24 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-EXCHANGEREALPROFIT}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find tqGLByGLSystemType where
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST} and
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-EXCHANGEREALPROFIT}
no-lock no-error.
if not available tqGLByGLSystemType
then do:
assign vcMsgOIAdj = trim(substitute(#T-91'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(144169476)T-91#,{&GLSYSTEMTYPE-EXCHANGEREALPROFIT-TR}))
viLocalReturnStatus = -3.
<M-2 run SetMessage
(input vcMsgOIAdj (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-317983':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* if vdCreditCC > 0 */
else do :
<Q-57 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-EXCHANGEREALLOSS}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find tqGLByGLSystemType where
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST} and
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-EXCHANGEREALLOSS}
no-lock no-error.
if not available tqGLByGLSystemType
then do:
assign vcMsgOIAdj = trim(substitute(#T-79'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(144169476)T-79#,{&GLSYSTEMTYPE-EXCHANGEREALLOSS-TR}))
viLocalReturnStatus = -3.
<M-76 run SetMessage
(input vcMsgOIAdj (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-767089':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* else if vdCreditCC > 0 */
end. /* if vdTCCCExchangeRateInPosting = 0 or */
else do :
<Q-78 run GLByGLSystemType (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input {&GLSYSTEMTYPE-ROUND}, (GLSystemTypeCode)
input {&GLTYPECODE-SYST}, (GlTypeCode)
input ?, (GlIsDivisionAccount)
output dataset tqGLByGLSystemType) in BGL >
find first tqGLByGLSystemType where
tqGLByGLSystemType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-ROUND} and
tqGLByGLSystemType.tcGLTypeCode = {&GLTYPECODE-SYST}
no-error.
if not available tqGLByGLSystemType
then do :
assign vcMsgOIAdj = trim(substitute(#T-49'Unable to balance the posting in base-currency as we cannot find the system-account of type &1.':255(26431060)T-49#,{&GLSYSTEMTYPE-ROUND-TR}))
viLocalReturnStatus = -3.
<M-21 run SetMessage
(input vcOIAdjCurrencyCode (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-366321':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BOpenItemAdjustment>
Leave AUOTBALANCINGBLOCK.
end. /* if not available tqGLByGLSystemType */
assign vcGLCode = tqGLByGLSystemType.tcGLCode.
end. /* else if vdTCCCExchangeRateInPosting = 0 or */
/* ====================================================== */
/* Create the additional posting-line with only CC filled */
/* ====================================================== */
empty temp-table tDefaultSafsFromOIAdj.
<M-10 run AddStandardPosting
(input vcMainPostingTcRowid (icPostingtcRowid),
input vcGLCode (icGLCode),
input ? (icDivisionCode),
input ? (icCostCentreCode),
input ? (icCostCentreText),
input ? (icProjectCode),
input ? (icProjectText),
input ? (icIntercoBusinessRelationCode),
input vcCurrencyCodeInPosting (icCurrencyCode),
input 0 (idDebitTC),
input 0 (idDebitLC),
input vdDebitCC (idDebitCC),
input 0 (idDebitPC),
input 0 (idCreditTC),
input 0 (idCreditLC),
input vdCreditCC (idCreditCC),
input 0 (idCreditPC),
input 0 (idQty),
input ? (icLineText),
input ? (icSafText),
input tDefaultSafsFromOIAdj (tDefaultSafs),
input {&EXCHANGERATETYPE-ACCOUNTING} (icExchangeRateType),
input 1 (idExchangeRate),
input 1 (idExchangeRateScale),
input 1 (idPostingLineCCRate),
input 1 (idPostingLineCCScale),
output viDummyPostingLineID (oiPostingLineId),
input ? (iiSafStructureId),
input ? (icSafStructureCode),
input ? (icAllocationKey),
input false (ilLinkedCrCyDaemonReqExists),
output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
if viFcReturnSuper <> 0
then assign viLocalReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave AUOTBALANCINGBLOCK.
end. /* if vdPostingAmountDebitCC - vdPostingAmountCreditCC <> 0 */
END. /* AUOTBALANCINGBLOCK */
/* ==================================================== */
/* Exception handling - Capture the returnestatus */
/* ==================================================== */
assign oiReturnStatus = viLocalReturnStatus.