project QadFinancials > class BCInvoice > method CreateCInvoiceMovements
Description
This method will first load all invoices linked to the movements or stages that got passed to the method.
Create the postingline on the control account and add the movement record.
Also update the balance fields and status fields of the invoices.
This method will also balance the LC and CC amounts of the invoice, when the invoice gets balanced in TC.
Parameters
| tMovement | input-output | temp-table | Movement records wherefor a cinvoicemovement record must be created |
| tCInvoiceStageUpdates | input | temp-table | |
| biBJournalEntryId | input-output | integer | Journal Entry ID |
| ilClearData | input | logical | ClearData; pass true in case you want BCinvoice to start from scratch |
| itPaymentTaxPointDate | input | date | Tax Point Date of Payment |
| ilIsCallFromBankingEntryOrOIAdj | input | logical | |
| oiReturnStatus | output | integer | Return status of the method. |
Internal usage
QadFinancials
program code (program7/bcinvoice.p)
if ilIsCallFromBankingEntryOrOIAdj = ?
then assign ilIsCallFromBankingEntryOrOIAdj = false.
/* ======================================================= */
/* Default the payment tax point date when it's left empty */
/* ======================================================= */
if itPaymentTaxPointDate = ? then assign itPaymentTaxPointDate = today.
/* ====================================================================== */
/* first clear the instance, otherwise problems when you execute it twice */
/* ====================================================================== */
if ilClearData
then do:
<M-1 run ClearData (output oiReturnStatus (oiReturnStatus)) in BCInvoice>
if oiReturnStatus < 0 then return.
empty temp-table tCInvoiceIDsForQCrossCompany.
empty temp-table tPostingLinesForQCrossCompany.
end. /* if ilClearData */
/* =============================================== */
/* check if there is one movement record available */
/* =============================================== */
find first tMovement no-error.
if not available tMovement
then do:
assign oiReturnStatus = -1.
<M-18 run SetMessage
(input trim(#T-44'You must define the input for the method that creates activity on supplier invoices.':255(1203)T-44#) (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'QADFIN-679':U (icFcMsgNumber),
input '' (icFcExplanation),
input '' (icFcIdentification),
input '' (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
return.
end. /* if not available tMovement */
/* ====================================================== */
/* Empty the temp-table used for calling BQCrossCyPosting */
/* Record created in CreateCInvoiceMovementsCrossCyExt */
/* ====================================================== */
empty temp-table tNewQCrossCyPostingTable.
empty temp-table tInvoicesToUpdate.
assign vcListCInvoiceIds = "":U.
/* ============================================ */
/* start and/or open the journal entry instance */
/* ============================================ */
assign viBJournalEntryCIID = biBJournalEntryId.
if viBJournalEntryCIId = 0 or viBJournalEntryCIId = ?
then do:
<I-40 {bFcStartAndOpenInstance
&ADD-TO-TRANSACTION = "true"
&CLASS = "BJournalEntry"}>
assign vlBJEIsStartedFromCI = true.
end. /* if viBJournalEntryCIId = 0 or viBJournalEntryCIId = ? */
else do:
<I-41 {bFcOpenInstance
&CLASS = "BJournalEntry"}>
end. /* else do: */
/* ==================================================== */
/* Get the list of ID's to load and do some validations */
/* ==================================================== */
<M-67 run CreateCInvoiceMovementsIDS
(input-output tMovement (tMovement),
input tCInvoiceStageUpdates (tCInvoiceStageUpdates),
output tInvoicesToUpdate (tInvoicesToUpdate),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
/* ====================================================== */
/* close the journal entry instance when an error occured */
/* ====================================================== */
if oiReturnStatus < 0
then do:
<I-42 {bFcCloseInstance
&CLASS = "BJournalEntry"}>
return.
end. /* if oiReturnStatus < 0 */
/* ========================================================= */
/* Add CInvoice_ID's from the stage updates to the load list */
/* ========================================================= */
for each tCInvoiceStageUpdates:
find first tCInvoice where
tCInvoice.CInvoice_ID = tCInvoiceStageUpdates.tiCInvoice_Id
no-error.
if not available tCInvoice and
not can-find (first tNewQCrossCyPostingTable where
tNewQCrossCyPostingTable.CInvoice_ID = tCInvoiceStageUpdates.tiCInvoice_Id)
then do:
/* assign vcListCInvoiceIds = if vcListCInvoiceIds = "":U
then string(tCInvoiceStageUpdates.tiCInvoice_Id)
else if lookup(string(tCInvoiceStageUpdates.tiCInvoice_Id), vcListCInvoiceIds,chr(4)) = 0
then vcListCInvoiceIds + chr(4) + string (tCInvoiceStageUpdates.tiCInvoice_Id)
else vcListCInvoiceIds.*/
if not can-find(first tInvoicesToUpdate where tInvoicesToUpdate.tiCInvoiceID = tCInvoiceStageUpdates.tiCInvoice_Id)
then do:
create tInvoicesToUpdate.
assign tInvoicesToUpdate.tiCInvoiceID = tCInvoiceStageUpdates.tiCInvoice_Id.
end.
end.
end. /* for each tCInvoiceStageUpdates: */
/* ================================================================================================ */
/* Load the Invoices that are related to the movement- and stagedrecords we got as input parameters */
/* ================================================================================================ */
for each tInvoicesToUpdate:
if vcListCInvoiceIds = '':U
then assign vcListCInvoiceIds = string(tInvoicesToUpdate.tiCInvoiceID).
else assign vcListCInvoiceIds = vcListCInvoiceIds + chr(4) + string(tInvoicesToUpdate.tiCInvoiceID).
/* if vcListCInvoiceIds > 10000, load the data to prevent vcListPostingIDsToLoad to get out of 32K limit */
if length(vcListCInvoiceIds , "CHARACTER") > 10000
then do :
/* If we do a DataLoad here then vlFcDataValidated will be set to false again. */
/* When this method is called from a sub-method of BCInvoice:AdditionalUpdates then we only want to create a movement on the linked invoice. */
/* As all data in this flow has already been validated, we consider it to be okay to save the linked invoice without validating that invoice */
/* To avoid we get error 'BLF-308: Data to save () has not been validated", we will manually assign vlFcDataValidated to true after the DataLoad if it was already true before the DataLoad */
assign vlPreviousFcDataValidated = vlFcDataValidated.
<M-34 run DataLoad
(input '':U (icRowids),
input vcListCInvoiceIds (icPkeys),
input '':U (icObjectIds),
input '' (icFreeform),
input yes (ilKeepPrevious),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if vlPreviousFcDataValidated = true
then assign vlFcDataValidated = true.
/* ====================================================================== */
/* close the journal entry instance when an error occured during the load */
/* ====================================================================== */
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if oiReturnStatus < 0
then do:
<I-43 {bFcCloseInstance
&CLASS = "BJournalEntry"}>
return.
end. /* if oiReturnStatus < 0 */
assign vcListCInvoiceIds = '':U.
end. /* if length(vcListCInvoiceIds , "CHARACTER") > 10000 */
end.
if vcListCInvoiceIds <> ''
then do :
/* If we do a DataLoad here then vlFcDataValidated will be set to false again. */
/* When this method is called from a sub-method of BCInvoice:AdditionalUpdates then we only want to create a movement on the linked invoice. */
/* As all data in this flow has already been validated, we consider it to be okay to save the linked invoice without validating that invoice */
/* To avoid we get error 'BLF-308: Data to save () has not been validated", we will manually assign vlFcDataValidated to true after the DataLoad if it was already true before the DataLoad */
assign vlPreviousFcDataValidated = vlFcDataValidated.
<M-84 run DataLoad
(input '':U (icRowids),
input vcListCInvoiceIds (icPkeys),
input '':U (icObjectIds),
input '' (icFreeform),
input yes (ilKeepPrevious),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if vlPreviousFcDataValidated = true
then assign vlFcDataValidated = true.
/* ====================================================================== */
/* close the journal entry instance when an error occured during the load */
/* ====================================================================== */
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if oiReturnStatus < 0
then do:
<I-52 {bFcCloseInstance
&CLASS = "BJournalEntry"}>
return.
end. /* if oiReturnStatus < 0 */
assign vcListCInvoiceIds = '':U.
end. /* if vcListCInvoiceIds <> '' */
empty temp-table tCInvoiceVatDelayDelta.
/* =========================================================== */
/* check if the Movement came from Unconfirm Payment selection */
/* Set the vlIsPaySelUnconfirm data item - CA767022 */
/* =========================================================== */
<I-89 {bFcOpenInstance
&CLASS = "Session"}>
<M-2 run GetLogicalValue
(input 'PaySelUnconfirm':U (icName),
output vlIsPaySelUnconfirm (olValue),
output viFcReturnSuper (oiReturnStatus)) in Session>
/* set the value back to null in case it will affect furtuer normal payment selection */
if vlIsPaySelUnconfirm <> ?
then do:
<M-83 run SetLogicalValue
(input 'PaySelUnconfirm':U (icName),
input ? (ilValue),
output viFcReturnSuper (oiReturnStatus)) in Session>
end. /* if vlIsPaySelUnconfirm <> ? */
FOREACHTMOVEMENTBLOCK : DO :
for each tMovement
/* first the one with false, after that the one with true */
by tMovement.tlMovementIsAboutWHT:
/* ================================= */
/* get the invoice for this movement */
/* ================================= */
find first tCInvoice where
tCInvoice.CInvoice_ID = tMovement.tiCInvoiceId and
tCInvoice.Company_ID = viCompanyId no-error.
if not available tCInvoice
then next.
/* ============================================================================== */
/* Make sure, we are skiping creation of the movements for Cross-company invoices */
/* ============================================================================== */
if can-find (first tNewQCrossCyPostingTable where
tNewQCrossCyPostingTable.CInvoice_ID = tMovement.tiCInvoiceId)
then next.
/* ========================================================================================== */
/* Check, if this is the last payment of the invoice, in this case complete LC and CC balance */
/* has to be taken for the movement */
/* ========================================================================================== */
assign vlIsLastPayment =
(tCInvoice.CInvoiceBalanceCreditTC = tMovement.tdAmountDebitTC and tMovement.tdAmountDebitTC <> 0 or
tCInvoice.CInvoiceBalanceDebitTC = tMovement.tdAmountCreditTC and tMovement.tdAmountCreditTC <> 0).
/* ========================================================================================== */
/* Check if this is the reopening of the invoice to full invoice amount (like payment undo) */
/* ========================================================================================== */
assign vlIsFullReopen =
tMovement.tlIsUndoPayment and
((tCInvoice.CInvoiceBalanceCreditTC + tMovement.tdAmountCreditTC = tCInvoice.CInvoiceOriginalCreditTC and tMovement.tdAmountCreditTC <> 0) or
(tCInvoice.CInvoiceBalanceDebitTC + tMovement.tdAmountDebitTC = tCInvoice.CInvoiceOriginalDebitTC and tMovement.tdAmountDebitTC <> 0)).
/* =============================== */
/* Calculate the LC and CC amounts */
/* =============================== */
if tMovement.tlMovementIsAboutWHT <> true
then do :
/* ========================= */
/* Fill in LC and CC Amounts */
/* ========================= */
if tCInvoice.CInvoiceCurrency_ID = viCompanyLCId or
tCInvoice.tcCurrencyCode = vcCompanyLC
then assign vdDebitLC = tMovement.tdAmountDebitTC
vdCreditLC = tMovement.tdAmountCreditTC.
else if vlIsLastPayment /* Last payment of the invoice */
then assign vdDebitLC = tCInvoice.CInvoiceBalanceCreditLC
vdCreditLC = tCInvoice.CInvoiceBalanceDebitLC.
else if vlIsFullReopen /* Full reopening of the invoice */
then assign vdDebitLC = tCInvoice.CInvoiceOriginalDebitLC - tCInvoice.CInvoiceBalanceDebitLC
vdCreditLC = tCInvoice.CInvoiceOriginalCreditLC - tCInvoice.CInvoiceBalanceCreditLC.
else /* Special exchange rate is to be used - e. g. Expense Notes */
if (tMovement.tdAmountCreditLC <> 0 and
tMovement.tdAmountCreditLC <> ?) or
(tMovement.tdAmountDebitLC <> 0 and
tMovement.tdAmountDebitLC <> ?)
then assign vdDebitLC = <M-61 RoundAmount
(input tMovement.tdAmountDebitLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>
vdCreditLC = <M-62 RoundAmount
(input tMovement.tdAmountCreditLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>.
else assign vdDebitLC = <M-63 RoundAmount
(input tMovement.tdAmountDebitTC * tCInvoice.CInvoiceExchangeRate * tCInvoice.CinvoiceRateScale (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>
vdCreditLC = <M-64 RoundAmount
(input tMovement.tdAmountCreditTC * tCInvoice.CInvoiceExchangeRate * tCInvoice.CinvoiceRateScale (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>.
if tCInvoice.CInvoiceCurrency_ID = viCompanyCCId or
tCInvoice.tcCurrencyCode = vcCompanyCC
then assign vdDebitCC = tMovement.tdAmountDebitTC
vdCreditCC = tMovement.tdAmountCreditTC.
else if vlDomainIsStatutory = false
then assign vdDebitCC = vdDebitLC
vdCreditCC = vdCreditLC.
else if vlIsLastPayment /* Last payment of the invoice */
then assign vdDebitCC = tCInvoice.CInvoiceBalanceCreditCC
vdCreditCC = tCInvoice.CInvoiceBalanceDebitCC.
else if vlIsFullReopen /* Full reopening of the invoice */
then assign vdDebitCC = tCInvoice.CInvoiceOriginalDebitCC - tCInvoice.CInvoiceBalanceDebitCC
vdCreditCC = tCInvoice.CInvoiceOriginalCreditCC - tCInvoice.CInvoiceBalanceCreditCC.
else /* Special exchange rate is to be used - e. g. Expense Notes */
if (tMovement.tdAmountCreditCC <> 0 and
tMovement.tdAmountCreditCC <> ?) or
(tMovement.tdAmountDebitCC <> 0 and
tMovement.tdAmountDebitCC <> ?)
then assign vdDebitCC = <M-39 RoundAmount
(input tMovement.tdAmountDebitCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>
vdCreditCC = <M-91 RoundAmount
(input tMovement.tdAmountCreditCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>.
else assign vdDebitCC = <M-51 RoundAmount
(input tMovement.tdAmountDebitTC * tCInvoice.CInvoiceCCRate * tCInvoice.CInvoiceCCScale (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>
vdCreditCC = <M-49 RoundAmount
(input tMovement.tdAmountCreditTC * tCInvoice.CInvoiceCCRate * tCInvoice.CInvoiceCCScale (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BApplicationProperty>.
end. /* if tMovement.tlMovementIsAboutWHT <> true */
else do:
/* ================================= */
/* Fill in LC and CC Amounts for WHT */
/* ================================= */
if tCInvoice.CInvoiceCurrency_ID = viCompanyLCId or
tCInvoice.tcCurrencyCode = vcCompanyLC
then assign vdDebitLC = tMovement.tdAmountDebitTC
vdCreditLC = tMovement.tdAmountCreditTC.
else if (tMovement.tdAmountCreditLC <> 0 and
tMovement.tdAmountCreditLC <> ?) or
(tMovement.tdAmountDebitLC <> 0 and
tMovement.tdAmountDebitLC <> ?)
then assign vdDebitLC = <M-95 RoundAmount
(input tMovement.tdAmountDebitLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>
vdCreditLC = <M-22 RoundAmount
(input tMovement.tdAmountCreditLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>.
else do :
if tMovement.tdRateTCLC = 0 or
tMovement.tdScaleTCLC = ? or
tMovement.tdRateTCLC = 0 or
tMovement.tdScaleTCLC = ?
then do :
assign oiReturnStatus = -1
vcmessage = trim(#T-78'Internal error: The input-record for the invoice-movement does not hold a proper rate fot the base-currency.':255(570834916)T-78#).
<M-37 run SetMessage
(input vcMessage (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-469759':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
Leave FOREACHTMOVEMENTBLOCK.
end. /* if tMovement.tdRateTCLC = 0 or */
assign vdDebitLC = <M-576 RoundAmount
(input tMovement.tdAmountDebitTC * tMovement.tdRateTCLC * tMovement.tdScaleTCLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>
vdCreditLC = <M-545 RoundAmount
(input tMovement.tdAmountCreditTC * tMovement.tdRateTCLC * tMovement.tdScaleTCLC (idUnroundedAmount),
input viCompanyLCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>.
end. /* else do */
if tCInvoice.CInvoiceCurrency_ID = viCompanyCCId or
tCInvoice.tcCurrencyCode = vcCompanyCC
then assign vdDebitCC = tMovement.tdAmountDebitTC
vdCreditCC = tMovement.tdAmountCreditTC.
else if (tMovement.tdAmountCreditCC <> 0 and
tMovement.tdAmountCreditCC <> ?) or
(tMovement.tdAmountDebitCC <> 0 and
tMovement.tdAmountDebitCC <> ?)
then assign vdDebitCC = <M-12 RoundAmount
(input tMovement.tdAmountDebitCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>
vdCreditCC = <M-13 RoundAmount
(input tMovement.tdAmountCreditCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>.
else do :
if tMovement.tdRateTCCC = 0 or
tMovement.tdScaleTCCC = ? or
tMovement.tdRateTCCC = 0 or
tMovement.tdScaleTCCC = ?
then do :
assign oiReturnStatus = -1
vcmessage = trim(#T-5'Internal error: The input-record for the invoice-movement does not hold a proper rate fot the statutory-currency.':255(198000521)T-5#).
<M-56 run SetMessage
(input vcMessage (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-871039':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
Leave FOREACHTMOVEMENTBLOCK.
end. /* if tMovement.tdRateTCCC = 0 or */
assign vdDebitCC = <M-6 RoundAmount
(input tMovement.tdAmountDebitTC * tMovement.tdRateTCCC * tMovement.tdScaleTCCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>
vdCreditCC = <M-54 RoundAmount
(input tMovement.tdAmountCreditTC * tMovement.tdRateTCCC * tMovement.tdScaleTCCC (idUnroundedAmount),
input viCompanyCCId (iiCurrencyID),
input ? (icCurrencyCode)) in BCInvoice>.
end. /* else do : */
end. /* else do: */
/* ===================================================================================================== */
/* If tMovement is marked as WHT then we should not post on the control-account but on the different GLs */
/* specified in CInvoiceWHT. We will call a separate submethod that will create the related postings */
/* ===================================================================================================== */
if tMovement.tlMovementIsAboutWHT = true
then do :
<M-38 run CreateCInvoiceMovementsWHT
(input tMovement.tdAmountDebitTC (idDebitTC),
input tMovement.tdAmountCreditTC (idCreditTC),
input vdDebitLC (idDebitLC),
input vdCreditLC (idCreditLC),
input vdDebitCC (idDebitCC),
input vdCreditCC (idCreditCC),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper <> 0
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave FOREACHTMOVEMENTBLOCK.
end. /* if tMovement.tlMovementIsAboutWHT = true */
else do :
/* ============================================================================================================= */
/* if the current invoice is 'STAGED', we should check if at least one tCinvoiceStageUpdates record is available */
/* If not, then we have no payment records for the stages yet, which means we should create them. */
/* ============================================================================================================= */
if tCInvoice.tcNormalPaymentConditionType = {&PAYMENTCONDITIONPAYMENTTYPE-STAGED}
then do:
find first tCInvoiceStageUpdates where
tCinvoiceStageUpdates.tiCInvoice_ID = tCInvoice.CInvoice_ID
no-error.
if tMovement.tiPostingLine_ID <> 0 and
tMovement.tiPostingLine_ID <> ? and
not available (tCinvoiceStageUpdates)
then do:
<Q-86 run PostingByPostingLineId (all) (Read) (NoCache)
(input tCInvoice.Company_ID, (CompanyId)
input tMovement.tiPostingLine_ID, (PostingLineId)
output dataset tqPostingByPostingLineId) in BPosting>
for first tqPostingByPostingLineId:
<M-35 run CreateCInvoiceStageUpdate
(input tCinvoice.Cinvoice_ID (iiCinvoiceID),
input tqPostingByPostingLineId.ttPostingDate (itPaymentDate),
input tMovement.tdAmountDebitTC - tMovement.tdAmountCreditTC (idMovementAmount),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
end. /* for first tqPostingByPostingLineId: */
end. /* if tMovement.tiPostingLine_ID <> 0 and */
end. /* if tCInvoice.tcNormalPaymentConditionType = {&PAYMENTCONDITIONPAYMENTTYPE-STAGED} */
/* ================================================================================================= */
/* Get the IntercompanyCode linked to this BusinessRelation. This IntercoCode is used in the Posting */
/* ================================================================================================= */
assign vcBusinessRelationCode = tCInvoice.tcBusinessRelationCode
vcBusinessRelationInterCoCode = "":U.
if vcBusinessRelationCode <> "":U
then do:
<Q-47 run BusinessRelationByIDCodeIC (all) (Read) (Cache)
(input ?, (BusinessRelationID)
input vcBusinessRelationCode, (BusinessRelationCode)
input ?, (BusinessRelationIntercoCode)
input ?, (BusinessRelationIsActive)
output dataset tqBusinessRelationByIDCodeIC) in BBusinessRelation>
find first tqBusinessRelationByIDCodeIC no-error.
if available tqBusinessRelationByIDCodeIC
then assign vcBusinessRelationInterCoCode = tqBusinessRelationByIDCodeIC.tcBusinessRelationICCode.
end. /* if vcBusinessRelationCode <> "":U */
/* =================== */
/* get control account */
/* =================== */
<Q-30 run GLById (all) (Read) (Cache)
(input viCompanyId, (CompanyId)
input tCInvoice.ControlGL_ID, (GLId)
output dataset tqGLById) in BGL>
find first tqGLById where tqGLById.tiGL_ID = tCInvoice.ControlGL_ID no-error.
if not available tqGLById
then do:
assign oiReturnStatus = -1
vcmessage = trim(#T-21'The system could not find a supplier control account record.':255(771986882)T-21#).
<M-9 run SetMessage
(input vcMessage (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'qadfin-407283':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
leave FOREACHTMOVEMENTBLOCK.
end. /* end of if not available tqGLById */
/* ========================= */
/* get division profile info */
/* ========================= */
if tqGLById.tlGLIsDivisionAccount and
tMovement.tcGLAccountDivisionCode = "":U
then do:
<Q-74 run GetDivisionFromProfile (all) (Read) (NoCache)
(input tCInvoice.Company_ID, (CompanyId)
input tqGLById.tiDivisionProfile_ID, (DivisionProfileId)
output dataset tqDivisionFromProfile) in BProfile >
find first tqDivisionFromProfile no-error.
if not available tqDivisionFromProfile
then do:
assign oiReturnStatus = -3.
<M-75 run SetMessage
(input #T-49'The sub-account profile of the Supplier Control account is not defined.':150(894249329)T-49# (icMessage),
input '':U (icArguments),
input '':U (icFieldName),
input '':U (icFieldValue),
input 'E':U (icType),
input 3 (iiSeverity),
input '':U (icRowid),
input 'QadFin-6771':U (icFcMsgNumber),
input '':U (icFcExplanation),
input '':U (icFcIdentification),
input '':U (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
leave FOREACHTMOVEMENTBLOCK.
end. /* if not available tqDivisionFromProfile */
end. /* end of if tqGLById.tlGLIsDivisionAccount and tDIMovement.tcGLAccountDivisionCode = "":U */
assign vcDivisionCode= if tqGLById.tlGLIsDivisionAccount
then if tMovement.tcGLAccountDivisionCode = "":U
then if tCInvoice.tcDivisionCode = "":U and
available tqDivisionFromProfile
then tqDivisionFromProfile.tcDivisionCode
else tCInvoice.tcDivisionCode
else tMovement.tcGLAccountDivisionCode
else "":U.
/* ==================== */
/* Get the CreditorType */
/* ==================== */
<Q-53 run SupplierForSICACreate (all) (Read) (Cache)
(input tCInvoice.Company_ID, (CompanyId)
input tCInvoice.Creditor_ID, (CreditorId)
input tCInvoice.tcCreditorCode, (CreditorCode)
output dataset tqSupplierForSICACreate) in BCreditor>
find tqSupplierForSICACreate where
tqSupplierForSICACreate.tcCreditorCode = tCInvoice.tcCreditorCode
no-error.
if available tqSupplierForSICACreate
then assign vcCreditorTypeCode = tqSupplierForSICACreate.tcCreditorTypeCode.
else assign vcCreditorTypeCode = '':U.
/* ============================================= */
/* Create the postingline on the control account */
/* ============================================= */
empty temp-table tDefaultSafsCI.
create tDefaultSafsCI.
assign tDefaultSafsCI.tcSafConceptCode = {&SAFCONCEPT-SUPPLIERTYPE}
tDefaultSafsCI.tcSafCode = vcCreditorTypeCode.
<M-14 run AddControlPosting
(input tMovement.tcPostingRowId (icPostingtcRowid),
input tqGLById.tcGLCode (icGLCode),
input vcDivisionCode (icDivisionCode),
input vcBusinessRelationInterCoCode (icIntercoBusinessRelationCode),
input tCInvoice.tcCurrencyCode (icCurrencyCode),
input tMovement.tdAmountDebitTC (idDebitTC),
input vdDebitLC (idDebitLC),
input vdDebitCC (idDebitCC),
input tMovement.tdAmountCreditTC (idCreditTC),
input vdCreditLC (idCreditLC),
input vdCreditCC (idCreditCC),
input (if length(tMovement.tcPostingText,'CHARACTER':U) = 0 then tCInvoice.CInvoiceCIText else tMovement.tcPostingText) (icText),
input tCInvoice.Creditor_ID (iiMasterId),
input tMovement.tiCInvoiceId (iiTransactionId),
input if tCInvoice.CInvoiceExchangeRate = 0 then 1 else tCInvoice.CInvoiceExchangeRate (idExchangeRate),
input if tCInvoice.CinvoiceRateScale = 0 then 1 else tCInvoice.CinvoiceRateScale (idExchangeRateScale),
input if tCInvoice.CInvoiceCCRate = 0 then 1 else tCInvoice.CInvoiceCCRate (idPostingLineCCRate),
input if tCInvoice.CInvoiceCCScale = 0 then 1 else tCInvoice.CInvoiceCCScale (idPostingLineCCScale),
input '':U (icAllocationKey),
input tCInvoice.tcCostCentreCode (icCostCentreCode),
input tCInvoice.tcProjectCode (icProjectCode),
input tDefaultSafsCI (tDefaultSafs),
output tMovement.tiPostingLine_ID (oiPostingLineId),
input false (ilLinkedCrCyDaemonReqExists),
output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave FOREACHTMOVEMENTBLOCK.
/* ======================= */
/* Create CInvoiceMovement */
/* ======================= */
if not can-find(first tCInvoiceMovement where
tCInvoiceMovement.tc_ParentRowid = tCInvoice.tc_Rowid and
tCInvoiceMovement.PostingLine_ID = tMovement.tiPostingLine_ID)
then do:
<M-25 run AddDetailLine
(input 'CInvoiceMovement':U (icTable),
input tCInvoice.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if oiReturnStatus < 0 then Leave FOREACHTMOVEMENTBLOCK.
assign tCInvoiceMovement.CInvoice_ID = tMovement.tiCInvoiceId
tCInvoiceMovement.PostingLine_Id = tMovement.tiPostingLine_ID
tCInvoiceMovement.CInvoiceMovementDiscountTC = tMovement.tdMovementDiscountTC
tCInvoiceMovement.CInvoiceMovementType = {&MOVEMENTTYPE-MOVEMENT}.
/* ============================= */
/* update the bank records first */
/* ============================= */
<M-32 run UpdateCInvoiceBankToPayTC
(input tMovement.tiCInvoiceId (iiCInvoiceId),
input tCInvoice.CInvoiceBalanceDebitTC (idOldBalanceDebitTC),
input tCInvoice.CInvoiceBalanceCreditTC (idOldBalanceCreditTC),
input tMovement.tdAmountDebitTC (idMovementAmountDebitTC),
input tMovement.tdAmountCreditTC (idMovementAmountCreditTC),
input tMovement.tiBankNumber_ID (iiBankNumber_ID),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave FOREACHTMOVEMENTBLOCK.
/* ========================================================================================== */
/* create delayed tax posting lines and undo the tax posting lines for the payments if needed */
/* ========================================================================================== */
<M-80 run CreateCInvoiceMovementsDelTax
(input ilIsCallFromBankingEntryOrOIAdj (ilIsCallFromBankingEntryOrOIAdj),
input-output tCInvoiceVatDelayDelta (tCInvoiceVatDelayDelta),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then Leave FOREACHTMOVEMENTBLOCK.
/* ====================================================================================== */
/* Update balance fields; if the originalbalance-Credit was filled then all updates of */
/* the balance will be on the credit fields allthough the CInvoice record can have linked */
/* posting-lines with an amount filled on the debit-side of the posting. */
/* -------------------------------------------------------------------------------------- */
/* CuccBal NewBal Posting (=tDIMov) BalanceChange */
/* 100Cr 80Cr 20Db -20Cr */
/* 100Cr 110Cr 10Cr 10Cr */
/* 100Db 70Db 30Cr -30Db */
/* 100Db 140Db 40Db 40Db */
/* ================================================ */
if tCInvoice.CInvoiceOriginalDebitTC <> ? and tCInvoice.CInvoiceOriginalDebitTC <> 0
then assign tCInvoice.CInvoiceBalanceDebitTC = tCInvoice.CInvoiceBalanceDebitTC - tMovement.tdAmountCreditTC + tMovement.tdAmountDebitTC
tCInvoice.CInvoiceBalanceDebitLC = tCInvoice.CInvoiceBalanceDebitLC - vdCreditLC + vdDebitLC
tCInvoice.CInvoiceBalanceDebitCC = tCInvoice.CInvoiceBalanceDebitCC - vdCreditCC + vdDebitCC.
else assign tCInvoice.CInvoiceBalanceCreditTC = tCInvoice.CInvoiceBalanceCreditTC - tMovement.tdAmountDebitTC + tMovement.tdAmountCreditTC
tCInvoice.CInvoiceBalanceCreditLC = tCInvoice.CInvoiceBalanceCreditLC - vdDebitLC + vdCreditLC
tCInvoice.CInvoiceBalanceCreditCC = tCInvoice.CInvoiceBalanceCreditCC - vdDebitCC + vdCreditCC.
assign tCInvoice.CInvoiceBalanceTC = tCInvoice.CInvoiceBalanceDebitTC - tCInvoice.CInvoiceBalanceCreditTC
tCInvoice.CInvoiceBalanceLC = tCInvoice.CInvoiceBalanceDebitLC - tCInvoice.CInvoiceBalanceCreditLC
tCInvoice.CInvoiceBalanceCC = tCInvoice.CInvoiceBalanceDebitCC - tCInvoice.CInvoiceBalanceCreditCC
tCInvoice.CInvoiceIsOpen = (tCInvoice.CInvoiceBalanceTC <> 0 or tCInvoice.CInvoiceBalanceLC <> 0 or tCInvoice.CInvoiceBalanceCC <> 0)
tCInvoice.tc_Status = (if tCInvoice.tc_Status = "":U then "C":U else tCInvoice.tc_Status)
tCInvoice.CInvoiceIsSelected = if vlIsPaySelUnconfirm = true then true else false.
end. /* if not can-find(first tCInvoiceMovement where */
end. /* Not if tMovement.tlMovementIsAboutWHT = true */
/* ========================================================================== */
/* Update the HoldAmount of the invoice if it was provided in the input table */
/* ========================================================================== */
if tMovement.tdCInvoiceHoldAmountTC <> ?
then assign tCInvoice.CInvoiceHoldAmountTC = tMovement.tdCInvoiceHoldAmountTC
tCInvoice.tc_Status = (if tCInvoice.tc_Status = "":U then "C":U else tCInvoice.tc_Status).
end. /* for each tmovement */
END. /* FOREACHTMOVEMENTBLOCK */
/* ================================================================================================= */
/* Create one postingline to reverse existing delayed tax account and one for the normal tax account */
/* Update the existing tax records of the invoice. */
/* ================================================================================================= */
if can-find(first tCInvoiceVatDelayDelta)
then do:
<M-16 run UpdateCInvoiceVatDelay
(input tCInvoiceVatDelayDelta (tCInvoiceVatDelayDelta),
input ? (iiBJournalEntryID),
input ? (ihBJournalEntryHandle),
output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0 then return.
end. /* if can-find(first tMoveDelTax) */
/* ============================ */
/* Update CInvoiceStage Records */
/* ============================ */
for each tMovement
break by tMovement.tiCInvoiceId:
if first-of(tMovement.tiCInvoiceId)
then do:
for each tCInvoiceStageUpdates where
tCInvoiceStageUpdates.tiCInvoice_ID = tMovement.tiCInvoiceId and
(tCInvoiceStageUpdates.tc_Status <> "":U or tMovement.tlIsUndoPayment):
find first tCInvoiceStage where
tCInvoiceStage.CInvoiceStage_ID = tCinvoiceStageUpdates.CInvoiceStage_ID
no-error.
if available tCinvoiceStage
then do:
if tMovement.tlIsUndoPayment
then assign tCInvoiceStage.CInvoiceStageAmtAppliedTC = tCInvoiceStage.CInvoiceStageAmtAppliedTC - tCinvoiceStageUpdates.CDocInvoiceXrefStageAlloTC.
else assign tCInvoiceStage.CInvoiceStageAmtAppliedTC = tCInvoiceStage.CInvoiceStageAmtAppliedTC + tCinvoiceStageUpdates.CDocInvoiceXrefStageAlloTC.
assign tCinvoiceStage.tc_Status = (if tCInvoiceStage.tc_Status = "":U then "C":U else tCInvoiceStage.tc_Status).
end.
end. /* for each tCInvoiceStageUpdates where */
end. /* if first-of(tMovement.tiCInvoiceId) */
end. /* end of update CinvoiceStage records */
/* ========================================================================================================= */
/* Normally we would here close the communication to BJournalEntry but we will not do it for performance */
/* reasons as this way the Commit of the transaction does not have to re-open the instance to commit it. */
/* And in all other scenario's the instance of the class ill be closed by the de-activiate procedure of the */
/* appserver that is executed after each call to the appserver */
/* ========================================================================================================= */
if oiReturnStatus < 0
then do:
/* Stop external instances */
<M-76 run StopExternalInstances
(output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
return.
end.
/* State the ID */
assign biBJournalEntryId = viBJournalEntryCIID.
/* ========================================================================== */
/* Create Q-CrossCompany postings that will be picked up later-on by a daemon */
/* ========================================================================== */
if can-find (first tNewQCrossCyPostingTable)
then do :
if viBQCrossCyPostingID = 0 or viBQCrossCyPostingID = ?
then do:
<I-57 {bFcStartAndOpenInstance
&ADD-TO-TRANSACTION = "true"
&CLASS = "BQCrossCyPosting"}>
end. /* if viBQCrossCyPostingID = 0 */
else do:
<I-58 {bFcOpenInstance
&CLASS = "BQCrossCyPosting"}>
end. /* if viBQCrossCyPostingID <> 0 */
<M-59 run ApiCreateQCrossCyPosting
(input tNewQCrossCyPostingTable (tNewQCrossCyPosting),
output viExternalReturn (oiReturnStatus)) in BQCrossCyPosting>
/* ========================================================================================================= */
/* Normally we would here close BQCrossCyPosting but we will not do it for performance */
/* reasons as this way the Commit of the transaction does not have to re-open the instance to commit it. */
/* And in all other scenario's the instance of the class ill be closed by the de-activiate procedure of the */
/* appserver that is executed after each call to the appserver */
/* ========================================================================================================= */
if viExternalReturn <> 0 then assign oiReturnStatus = viExternalReturn.
if oiReturnStatus < 0
then return.
end. /* if can-find (first tNewQCrossCyPostingTable) */