project QadFinancials > class BCInvoice > method UpdateCInvoiceFromAPM

Description

Update supplier invoice total amount and tax details based on data entered in Receive? matching


Parameters


iiCompanyIdinputinteger
iiCInvoiceIdinputinteger
iiCInvoiceRegistrationNrinputinteger
idCInvoiceTotalAmountinputdecimal
idCInvoiceTotalAmountLCinputdecimal
tApiCInvoiceVatinputtemp-tableInput temp-table for the taxes of the invoice
tApiCInvoiceWHTinputtemp-tableInput temp-table for the WHT of the invoice
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BAPMatching.ValidateComponentPreAPMCInvoice
method BCInvoice.ApiUpdateCInvoiceFromAPM


program code (program9/bcinvoice.p)

/* =================================================================================================== */
/* Method      : UpdateCInvoiceFromAPM                                                                 */
/* Desc        : Update supplier invoice total amount and tax details based on data entered in         */
/*               receiver matching                                                                     */
/* --------------------------------------------------------------------------------------------------- */
/* Params:  (I)  CompanyId              Company                                                        */
/*          (I)  CInvoiceId             Invoice ID                                                     */
/*          (I)  CInvoiceRegistrationNr Invoice registration number                                    */
/*          (I)  CInvoiceTotalAmount    Total Invoice amount                                           */
/*          (I)  ApiCInvoiceVat         VAT details of the invoice                                     */
/* =================================================================================================== */

assign oiReturnStatus = -98.

/* =================================================================================================== */
/* Normalize input parameters                                                                          */
/* =================================================================================================== */
if iiCInvoiceId             = ? then assign iiCInvoiceId             = 0.
if iiCInvoiceRegistrationNr = ? then assign iiCInvoiceRegistrationNr = 0.
if idCinvoiceTotalAmount    = ? then assign idCinvoiceTotalAmount    = 0.
if iiCompanyId              = ? then assign iiCompanyId              = viCompanyId.

/* =================================================================================================== */
/* Validate input parameters                                                                           */
/* =================================================================================================== */
if iiCInvoiceId = 0 and
   (iiCompanyId = 0 or iiCInvoiceRegistrationNr = 0)
then do:
    assign vcContext = 'iiCInvoiceId=&1|iiCompanyId=&2|iiCInvoiceRegistrationNr=&3':U
           vcContext = replace(vcContext, '|':U, chr(2))
           vcContext = substitute(vcContext, iiCInvoiceId, iiCompanyId, iiCInvoiceRegistrationNr). 
    <M-11 run SetMessage
       (input  #T-11'You have not entered all the mandatory values.':255(63250)T-11# (icMessage), 
        input  '':U (icArguments), 
        input  '':U (icFieldName), 
        input  '':U (icFieldValue), 
        input  'S':U (icType), 
        input  3 (iiSeverity), 
        input  '':U (icRowid), 
        input  'QadFin-8418':U (icFcMsgNumber), 
        input  '':U (icFcExplanation), 
        input  '':U (icFcIdentification), 
        input  vcContext (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    assign oiReturnStatus = -1.
    return.
end.

/* =================================================================================================== */
/* Search invoice                                                                                      */
/* =================================================================================================== */
if iiCInvoiceId <> 0
then find first tCInvoice where
                tCInvoice.CInvoice_ID = iiCInvoiceId
                no-error.
else find first tCInvoice where
                tCInvoice.Company_ID             = iiCompanyId and
                tCInvoice.CInvoiceRegistrationNr = iiCInvoiceRegistrationNr
                no-error.
if not available tCInvoice
then do:
    /* check with prim query if the invoice exists, if not, give error */
    /* if no error, then dataload */
    <M-1 run DataLoad
       (input  '':U (icRowids), 
        input  string(iiCInvoiceId) (icPkeys), 
        input  '':U (icObjectIds), 
        input  '':U (icFreeform), 
        input  true (ilKeepPrevious), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper <  0
    then do:
        assign vcMessage = trim(substitute(#T-8'Data could not be loaded: unable to load the supplier invoice (&1).':100(69147)T-8#, string(iiCInvoiceId))).
        <M-2 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  '':U (icFieldName), 
            input  '':U (icFieldValue), 
            input  'E':U (icType), 
            input  1 (iiSeverity), 
            input  '':U (icRowid), 
            input  'QadFin-8415':U (icFcMsgNumber), 
            input  '':U (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
        return.
    end.
end.

find first tCInvoice where
           tCInvoice.CInvoice_ID = iiCInvoiceId
           no-error.
if not available tCInvoice
then do:
    assign vcMessage = trim(substitute(#T-9'Invalid supplier invoice: &1.':255(1108)T-9#,string(iiCInvoiceId))).
    <M-3 run SetMessage
       (input  vcMessage (icMessage), 
        input  '':U (icArguments), 
        input  '':U (icFieldName), 
        input  '':U (icFieldValue), 
        input  'E':U (icType), 
        input  1 (iiSeverity), 
        input  '':U (icRowid), 
        input  'QadFin-8416':U (icFcMsgNumber), 
        input  '':U (icFcExplanation), 
        input  '':U (icFcIdentification), 
        input  '':U (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    assign oiReturnStatus = -1.
    return.
end.

/* =========================================================================================================== *
 * FIN-1677 - Currently receiver matching can update supplier invoice only when all taxes on receiver matching *
 *            are on the line level. If they are on header level, then incorrect calculation would happend and *
 *            taxes were not correclty posted (therefore block it for now, until this is fully implemented     *
 * =========================================================================================================== */
if tCInvoice.CInvoiceIsInitialStatus 
then do:
    for each tApiCInvoiceVat where
             tApiCInvoiceVat.CInvoice_ID = iiCInvoiceId:
        <Q-18 assign vlFcQueryRecordsAvailable = MfgTaxCodeByTaxCode (NoCache)
           (input tApiCInvoiceVat.tcVatCode, (TaxCode)
            input tApiCInvoiceVat.tcDomainCode, (DomainCode)
            input ?, (DiscountAtPayment)
            input No, (IsTaxByLine)) in BMfgTaxCode >
        if vlFcQueryRecordsAvailable <> false and tCInvoice.CInvoiceIsTaxable
        then do:
        /* raise error and stop processing */
            assign vcMessage      = trim(substitute(#T-20'It is not allowed to do this because the tax used indicates that calculations are done on the invoice total and not on the lines. Please go to the invoice itself to modify the invoice and/or tax amounts.':255(999890791)T-20#))
                   oiReturnStatus = -1.
            <M-19 run SetMessage
               (input  vcMessage (icMessage), 
                input  '':U (icArguments), 
                input  '':U (icFieldName), 
                input  '':U (icFieldValue), 
                input  'E':U (icType), 
                input  1 (iiSeverity), 
                input  '':U (icRowid), 
                input  'QadFin-9619':U:U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BCInvoice>    
            return.
        end. /* if vlFcQueryRecordsAvailable <> false */
    end. /* for each tApiCInvoiceVat where */
end. /* if tCInvoice.CInvoiceIsInitialStatus  */    
     
/* fill the original */
if tCInvoice.CInvoiceType = {&INVOICETYPE-INVOICE} or 
   tCInvoice.CInvoiceType = {&INVOICETYPE-INVOICECORRECTION}
then assign tCInvoice.tdCInvoiceOriginalTC     = idCinvoiceTotalAmount
            tCInvoice.tdCInvoiceOriginalLC     = <M-28 GetAmountPreferencingExpected
                                                    (input  idCInvoiceTotalAmountLC (idExpectedAmount), 
                                                     input  tCInvoice.tdCInvoiceOriginalTC * tCInvoice.CInvoiceExchangeRate * tCInvoice.CInvoiceRateScale (idCalculatedAmount), 
                                                     input  viCompanyLCId (iiCurrencyId)) in BCInvoice>
            tCInvoice.CInvoiceOriginalDebitTC  = 0
            tCInvoice.CInvoiceOriginalDebitLC  = 0
            tCInvoice.CInvoiceOriginalCreditTC = tCInvoice.tdCInvoiceOriginalTC
            tCInvoice.CInvoiceOriginalCreditLC = tCInvoice.tdCInvoiceOriginalLC.
else assign tCInvoice.tdCInvoiceOriginalTC     = - idCinvoiceTotalAmount
            tCInvoice.tdCInvoiceOriginalLC     = <M-39 GetAmountPreferencingExpected
                                                    (input  - idCInvoiceTotalAmountLC (idExpectedAmount), 
                                                     input  tCInvoice.tdCInvoiceOriginalTC * tCInvoice.CInvoiceExchangeRate * tCInvoice.CInvoiceRateScale (idCalculatedAmount), 
                                                     input  viCompanyLCId (iiCurrencyId)) in BCInvoice>
            tCInvoice.CInvoiceOriginalDebitTC  = tCInvoice.tdCInvoiceOriginalTC
            tCInvoice.CInvoiceOriginalDebitLC  = tCInvoice.tdCInvoiceOriginalLC
            tCInvoice.CInvoiceOriginalCreditTC = 0
            tCInvoice.CInvoiceOriginalCreditLC = 0.

assign tCInvoice.CInvoiceIsTaxExcluded    = false
       tCInvoice.tc_Status                = (if tCInvoice.tc_Status = "":U  then "C":U  else tCInvoice.tc_Status).
    
/* Update cc amounts */
if viCompanyCCId <> 0 and
   viCompanyCCId <> ?
then do:
    if tCInvoice.tcCurrencyCode = vcCompanyCC
    then assign tCInvoice.CInvoiceOriginalDebitCC  = tCInvoice.CInvoiceOriginalDebitTC
                tCInvoice.CInvoiceOriginalCreditCC = tCInvoice.CInvoiceOriginalCreditTC.
    else if vlDomainIsStatutory = false
    then assign tCInvoice.CInvoiceOriginalDebitCC  = tCInvoice.CInvoiceOriginalDebitLC
                tCInvoice.CInvoiceOriginalCreditCC = tCInvoice.CInvoiceOriginalCreditLC.
    else do:
        <M-64 run GetExRateByEntityInvoiceFlag
           (input  tCInvoice.CInvoiceDate (itCInvoiceDate), 
            input  tCInvoice.CInvoicePostingDate (itCInvoicePostingDate), 
            input  0 (iiFromCurrencyId), 
            input  tCInvoice.tcCurrencyCode (icFromCurrencyCode), 
            input  viCompanyCCId (iiToCurrencyId), 
            input  vcCompanyCC (icToCurrencyCode), 
            input  0 (iiExchangeRateTypeId), 
            input  {&EXCHANGERATETYPE-STATUTORY} (icExchangeRateTypeCode), 
            output vdCInvoiceCCExchangeRate (odCInvoiceExchangeRate), 
            output vdCInvoiceCCRateScale (odCInvoiceRateScale), 
            output viFcReturnSuper (oiReturnStatus)) in BCInvoice>

        if viFcReturnSuper < 0 or oiReturnStatus  = 0
        then assign oiReturnStatus = viFcReturnSuper.

        assign tCInvoice.CInvoiceOriginalDebitCC  = <M-13 RoundAmount
                                                       (input  tCInvoice.CInvoiceOriginalDebitTC * vdCInvoiceCCExchangeRate * vdCInvoiceCCRateScale (idUnroundedAmount), 
                                                        input  viCompanyCCId (iiCurrencyID), 
                                                        input  vcCompanyCC (icCurrencyCode)) in business>
               tCInvoice.CInvoiceOriginalCreditCC = <M-14 RoundAmount
                                                       (input  tCInvoice.CInvoiceOriginalCreditTC * vdCInvoiceCCExchangeRate * vdCInvoiceCCRateScale (idUnroundedAmount), 
                                                        input  viCompanyCCId (iiCurrencyID), 
                                                        input  vcCompanyCC (icCurrencyCode)) in business>.
    end. /* else do: */
end. /* if viCompanyCCId <> 0 and */

/* fill balance fields */
assign vdOldBalanceDebitTC  = tCInvoice.CInvoiceBalanceDebitTC
       vdOldBalanceCreditTC = tCInvoice.CInvoiceBalanceCreditTC.

assign tCInvoice.CInvoiceBalanceDebitTC     = tCInvoice.CInvoiceOriginalDebitTC
       tCInvoice.CInvoiceBalanceDebitLC     = tCInvoice.CInvoiceOriginalDebitLC
       tCInvoice.CInvoiceBalanceDebitCC     = tCInvoice.CInvoiceOriginalDebitCC
       tCInvoice.CInvoiceBalanceCreditTC    = tCInvoice.CInvoiceOriginalCreditTC
       tCInvoice.CInvoiceBalanceCreditLC    = tCInvoice.CInvoiceOriginalCreditLC
       tCInvoice.CInvoiceBalanceCreditCC    = tCInvoice.CInvoiceOriginalCreditCC
       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.tdCInvoiceOriginalAmount   = tCInvoice.CInvoiceBalanceTC
       tCInvoice.tdCInvoiceOpenAmount       = tCInvoice.CInvoiceBalanceTC
       tCInvoice.tdCInvoiceOriginalAmountLC = tCInvoice.CInvoiceBalanceLC
       tCInvoice.tdCInvoiceOpenAmountLC     = tCInvoice.CInvoiceBalanceLC.

<M-70 run DefaultValuesPaymentCondition
   (input  tCInvoice.tcNormalPaymentConditionCode (icPaymentConditionCode), 
    input  tCInvoice.NormalPaymentCondition_ID (iiPaymentConditionID), 
    input  tCInvoice.CInvoiceDate (itCInvoiceDate), 
    input  tCInvoice.tc_Rowid (icCInvoiceRowID), 
    input  tCInvoice.tdCInvoiceOriginalTC (idCInvoiceOriginalTC), 
    input  tCInvoice.tcCurrencyCode (icCurrencyCode), 
    input  tCInvoice.CInvoiceIsTaxExcluded (ilCInvoiceIsTaxExcluded), 
    input   tCInvoice.tcNormalPaymentConditionType (icPaymentConditionPaymentType), 
    input  ? (icPaymentConditionPeriodType), 
    input  ? (itPaymentConditionBaseDate), 
    input  ? (iiPaymentConditionDaysMonths), 
    input  ? (iiPaymentConditionSupplDays), 
    input  ? (iiPaymentConditionBaseDays), 
    input  ? (iiPaymentConditionDueDays), 
    input  ? (icPaymentConditionDescript), 
    input  ? (idPaymentConditionPercentage), 
    input  ? (icPaymentConditionPdtypediscount), 
    input  ? (iiPaymentConditionDayMthsDisc), 
    input  ? (iiPaymentConditionSupDaysDisc), 
    output vcDummyCode (ocPaymentConditionPaymentType), 
    output vtDummyDate (otCInvoiceDueDate), 
    output vtDummyDate (otCInvoiceDiscountDueDate), 
    output tApiCInvoiceStage (tApiCInvoiceStage), 
    output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    
if viFcReturnSuper < 0 or oiReturnStatus  = 0
then assign oiReturnStatus = viFcReturnSuper.

<M-5 run UpdateCInvoiceBankToPayTC
   (input  iiCInvoiceId (iiCInvoiceId), 
    input  vdOldBalanceDebitTC (idOldBalanceDebitTC), 
    input  vdOldBalanceCreditTC (idOldBalanceCreditTC), 
    input  tCInvoice.CInvoiceBalanceDebitTC - vdOldBalanceDebitTC (idMovementAmountDebitTC), 
    input  tCInvoice.CInvoiceBalanceCreditTC - vdOldBalanceCreditTC (idMovementAmountCreditTC), 
    input  ? (iiBankNumber_ID), 
    output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper <  0
then do:
    assign vcMessage      = trim(substitute(#T-10'An internal error occurred when updating the bank records of the supplier invoice.':255(69195)T-10#,string(iiCInvoiceId))).
    <M-6 run SetMessage
       (input  vcMessage (icMessage), 
        input  '':U (icArguments), 
        input  '':U (icFieldName), 
        input  '':U (icFieldValue), 
        input  'E':U (icType), 
        input  1 (iiSeverity), 
        input  '':U (icRowid), 
        input  'QadFin-8417':U (icFcMsgNumber), 
        input  '':U (icFcExplanation), 
        input  '':U (icFcIdentification), 
        input  '':U (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    return.
end.

/* delete old tax records, and create new one */
for each tCInvoiceVat where
         tCInvoiceVat.tc_ParentRowid  = tCInvoice.tc_Rowid :
    if tCInvoiceVat.tc_Status = "N":U
    then delete tCInvoiceVat.
    else assign tCInvoiceVat.tc_Status = "D":U.
end. /* for each tCInvoiceVat where */

/* create new tax records */
for each tApiCInvoiceVat:
    <M-7 run AddDetailLine
       (input  'CInvoiceVat':U (icTable), 
        input  tCInvoice.tc_Rowid (icParentRowid), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper <  0 then return.
    buffer-copy tApiCInvoiceVat 
                except CInvoiceVat_ID CInvoice_ID tc_rowid tc_ParentRowid tc_status 
                to tCInvoiceVat.
    /* Make sure the sign of the NonRecTaxAmtTC is correct regardless the value the caller passes in */
    if tCInvoice.CInvoiceType = {&INVOICETYPE-INVOICE} or 
       tCInvoice.CInvoiceType = {&INVOICETYPE-CREDITNOTE}
    then assign tCInvoiceVat.CInvoiceVatNonRecTaxAmtTC = absolute(tCInvoiceVat.CInvoiceVatNonRecTaxAmtTC).
    else assign tCInvoiceVat.CInvoiceVatNonRecTaxAmtTC = absolute(tCInvoiceVat.CInvoiceVatNonRecTaxAmtTC) * -1.    
end. /* for each tApiCInvoiceVat */

/* delete old WHT records, and create new one */
for each tCInvoiceWHT where
         tCInvoiceWHT.tc_ParentRowid = tCInvoice.tc_Rowid:
    if tCInvoiceWHT.tc_Status = "N":U
    then delete tCInvoiceWHT.
    else assign tCInvoiceWHT.tc_Status = "D":U.
end. /* for each tCInvoiceWHT where */

/* create new WHT records */
for each tApiCInvoiceWHT :
    <M-16 run AddDetailLine
       (input  'CInvoiceWHT':U (icTable), 
        input  tCInvoice.tc_Rowid (icParentRowid), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper <  0 then return.
    buffer-copy tApiCInvoiceWHT
            except CInvoiceWHT_ID CInvoice_ID tc_rowid tc_ParentRowid tc_status 
            to tCInvoiceWHT.
end. /* for each tApiCInvoiceWHT */

/* is Taxable, is WHT */
assign tCInvoice.CInvoiceIsTaxable = if can-find (first tCInvoiceVat where 
                                                        tCInvoiceVat.tc_ParentRowid  = tCInvoice.tc_Rowid and 
                                                        tCInvoiceVat.tc_Status      <> "D":U              and
                                                        tCInvoiceVat.TxtyTaxType    <> {&VATTAXTYPE-NONTAX})
                                     then true
                                     else false                                 
       tCInvoice.CInvoiceIsWHT     = if can-find (first tCInvoiceWHT where 
                                                        tCInvoiceWHT.tc_ParentRowid  = tCInvoice.tc_Rowid and 
                                                        tCInvoiceWHT.tc_Status      <> "D":U)
                                     then true
                                     else false.

/* Even there are no taxes, supplier invoice has to have at least one tax line created */
if tCInvoice.CInvoiceIsTaxable = false and
   not can-find(first tCInvoiceVat where 
                      tCInvoiceVat.tc_ParentRowid  = tCInvoice.tc_Rowid and 
                      tCInvoiceVat.tc_Status      <> "D":U)
then do:
    <M-81 run DefaultValuesTax
       (input  tCInvoice.tc_Rowid (icCInvoiceRowid), 
        input  tCInvoice.CInvoice_ID (iiCInvoiceId), 
        input  tCInvoice.tcCurrencyCode (icCurrencyCode), 
        input  tCInvoice.CInvoiceReference (icDocumentReference), 
        input  tCInvoice.CInvoiceTaxPointDate (itTaxPointDate), 
        input  tCInvoice.tcShipFromTaxZone (icShipFromTaxZone), 
        input  tCInvoice.tcShipToTaxZone (icShipToTaxZone), 
        input  tCInvoice.tcShipFromTaxClass (icTxclTaxClass), 
        input  tCInvoice.tcShipFromTaxUsage (icTxuTaxUsage), 
        input  tCInvoice.tdCInvoiceOriginalTC (idInvoiceAmountTC), 
        input  tCInvoice.CInvoiceExchangeRate (idExchangeRate), 
        input  tCInvoice.CInvoiceRateScale (idExchangeRateScale), 
        input  tCInvoice.tcNormalPaymentConditionCode (icPaymentConditionCode), 
        input  tCInvoice.CInvoicePostingDate (itPostingDate), 
        input  tCInvoice.CInvoiceIsTaxable (ilTaxable), 
        input  can-find(first tCInvoiceWht where tCInvoiceWht.tc_ParentRowId = tCInvoice.tc_RowId) (ilCreditorIsWht), 
        input  tCInvoice.CInvoiceType (icInvoiceType), 
        input  tCInvoice.tlShipToAddressIsTaxInCity (ilShipToAddressIsTaxInCity), 
        input  tCInvoice.CInvoiceVatExchangeRate (idVatExchangeRate), 
        input  tCInvoice.CInvoiceVatRateScale (idVatRateScale), 
        input  tCInvoice.CInvoiceIsLogisticMatching (ilIsLogisticMatching), 
        output vcDummy (ocTxenvTaxEnv), 
        input  tCInvoice.CInvoiceIsTaxExcluded (ilCInvoiceIsTaxExcluded), 
        input  tCInvoice.CInvoiceDate (itCInvoiceDate), 
        input  tCInvoice.CInvoiceCCRate (idCCExchangeRate), 
        input  tCInvoice.CInvoiceCCScale (idCCExchangeRateScale), 
        input  ? (iiShipToAddressID), 
        input  ? (iiShipFromAddressID), 
        input  tCInvoice.tcCreditorCode (icCreditorCode), 
        output viFcReturnSuper (oiReturnStatus)) in BCInvoice>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper <  0 then return.
end.

                   
/* =================================================================================================== */
/* Return                                                                                              */
/* =================================================================================================== */
if oiReturnStatus = -98 then assign oiReturnStatus = 0.