project QadFinancials > class BAPMatching > method ValidateComponentPreAPMCInvoiceLegalDocument

Description

This procedure validates that the invoice amount and legal document amounts are the same.


Parameters


bdTotalInvoiceAmountLCinput-outputdecimal
bdTotalInvoiceAmountTCinput-outputdecimal
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BAPMatching.ValidateComponentPreAPMCInvoice


program code (program4/bapmatching.p)

/* ====================================================================================== *
 * Method       : ValidateComponentPreAPMCInvoiceLegalDocument                            *
 * Description  : This method does validation, that calculated supplier invoice amount    *
 *                has exactly the same amount as the legal document                       *
 *                                                                                        *
 * -------------------------------------------------------------------------------------- *
 * Parameters   : TotalInvoiceAmountLC                                                    *
 *                 
 * ====================================================================================== */
 
define variable doMfcCtrl as com.qad.fin.qaddb.mfc_ctrl. 
define variable doPocCtrl as com.qad.eefin.bmfgpurchasecontrol.PurchaseControlForLDSIRound.

 
MAIN_BLOCK:
do on error undo, throw:
    /* Pre-validation block */
    
    /* If Fiscal receiving is not activated, we have nothing to do */
    if not vlDomainIsFiscalConfirm
    then leave MAIN_BLOCK.


    /* ============================================================================================== *
     * Find fiscal receipt document, for which the invoice was created. We can take any of the        *
     * Receiver matching lines as they all belong to the same Legal document                          *
     * ============================================================================================== */
    find first t_sAPMatchingLn where
               t_sAPMatchingLn.tc_ParentRowid = t_sAPMatching.tc_Rowid and
               t_sAPMatchingLn.tc_Status     <> "D":U
               no-error.
    if not available t_sAPMatchingLn
    then leave MAIN_BLOCK.


    /* Get legal document identification being invoiced */
    if viBMFGLegalDocumentID = 0 or
       viBMFGLegalDocumentID = ?
    then do:
        <I-93 {bFcStartAndOpenInstance
             &ADD-TO-TRANSACTION   = "no"
             &CLASS                = "BMFGLegalDocument"}>
    end.
    else if not valid-handle(vhBMFGLegalDocumentInst)
    then do:
        <I-96 {bFcOpenInstance
             &CLASS           = "BMFGLegalDocument"}>
    end.
        
    
    <M-3 run GetLegalDocumentIDByPendingVoucher
       (input  t_sAPMatchingLn.PvoDomain (icPvoDomain), 
        input  t_sAPMatchingLn.PvoID (iiPvoId), 
        input  t_sAPMatchingLn.PvodLineID (iiPvodId), 
        output vcLgdDomain (ocLgdDomain), 
        output vcLgdSupplier (ocLgdSupplier), 
        output vcLgdNbr (ocLgdNbr), 
        output vtLgdEffDate (otLgdEffDate), 
        output viFcReturnSuper (oiReturnStatus)) in BMFGLegalDocument>
    if viFcReturnSuper < 0 or viFcReturnSuper > 0 and oiReturnStatus = 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper < 0 then leave MAIN_BLOCK.
    
    /* If legal document was not found, simply do nothing */
    if vcLgdDomain = "":U or vcLgdDomain = ?
    then leave MAIN_BLOCK.


    /* =============================================================================================== *
     * Let's calculate legal document amount, that we want to use for comparision with matched amount  *
     * =============================================================================================== */
     
    if (t_sAPMatching.tcCreditorCode <> '':U or  t_sAPMatching.tcCreditorCode <> ?) then assign vcInvoiceSupplier =  t_sAPMatching.tcCreditorCode.
    else assign vcInvoiceSupplier = vcLgdSupplier.
     
    <M-87 run GetLegalDocumentAmount
       (input  vcLgdDomain (icLgdDomain), 
        input  vcLgdNbr (icLgdNbr), 
        input  vcLgdSupplier (icLgdSupplier), 
        input  vtLgdEffDate (itLgdEffDate), 
        input  vcInvoiceSupplier (icInvSupplier), 
        output vdLgdTaxBaseLC (odLgdTaxBaseLC), 
        output vdLgdTaxLC (odLgdTaxLC), 
        output vdLgdTotalAmountLC (odLgdTotalAmountLC), 
        output viFcReturnSuper (oiReturnStatus)) in BMFGLegalDocument>
    if viFcReturnSuper < 0 or viFcReturnSuper > 0 and oiReturnStatus = 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper < 0 then leave MAIN_BLOCK.


    /* Compare calclulated supplier invoice amount based on receiver matching and legal document */
    if vdLgdTotalAmountLC <> bdTotalInvoiceAmountLC
    then do:

        /* When the invoice is in the Base currency, we have to create posting to eliminate this discrepancy */
        /* In case of foreign invoice, the posting is created automatically                                  */
        if t_sAPMatching.tcCurrencyCode = vcCompanyLC
        then do:
        
            assign vdBalanceLC = bdTotalInvoiceAmountLC - vdLgdTotalAmountLC.


            /* ========================================================================================== *
             * Retrieve GL account, where the discrepancy between the Legal document amount and current   *
             * Receiver matching amounts are posted                                                       *
             * ========================================================================================== */
            assign vcGLCode         = "":U
                   vcDivisionCode   = "":U
                   vcCostCentreCode = "":U
                   vcProjectCode    = "":U.
            
            
            GL_BLOCK:
            do on error undo, throw:
                /* if the AP setup requires to use Rounding GL account, let's use that */
                /* version is lower then 2015 */
                if viMfgProMajorVersionBAPM  < 3 /* Meaning eB3 */ or            
                   (viMfgProMajorVersionBAPM = 3 /* Meaning eB3 */ and             
                    viMfgProMinorVersionBAPM < 15 /* Meaning SP15 */) 
                then do:
                    doMfcCtrl = new com.qad.fin.qaddb.mfc_ctrl(vcDomainCode, {&LEGALDOCUMENTPOSTROUNDTO}).
                    if doMfcCtrl:available and
                       doMfcCtrl:mfc_char = {&LEGALDOCUMENTPOSTROUNDTO-APRATEVAR}
                    then assign vcPostRoundingDiffTo = {&LEGALDOCUMENTPOSTROUNDTO-APRATEVAR}.
                    else assign vcPostRoundingDiffTo = {&LEGALDOCUMENTPOSTROUNDTO-ROUND}.
                end. /* if viMfgProMajorVersionBAPM  > 3 */
                else do:
                    doPocCtrl = new com.qad.eefin.bmfgpurchasecontrol.PurchaseControlForLDSIRound(vcDomainCode).
                    if doPocCtrl:available and
                       doPocCtrl:poc_ers_round_gl = {&LEGALDOCUMENTPOSTROUNDTO-APRATEVAR}
                    then assign vcPostRoundingDiffTo = {&LEGALDOCUMENTPOSTROUNDTO-APRATEVAR}.
                    else assign vcPostRoundingDiffTo = {&LEGALDOCUMENTPOSTROUNDTO-ROUND}.
                end. /* else do */

                
                if vcPostRoundingDiffTo = {&LEGALDOCUMENTPOSTROUNDTO-ROUND}
                then do:
                    /* Get rounding account */
                    <Q-60 run GLBySystemTypeAndType (all) (Read) (NoCache)
                       (input ?, (GLCode)
                        input {&GLSYSTEMTYPE-ROUND}, (GLSystemTypeCode)
                        input ?, (GLId)
                        input {&GLTYPECODE-SYST}, (GLTypeCode)
                        input viCompanyId, (CompanyId)
                        input ?, (GlIsActive)
                        output dataset tqGLBySystemTypeAndType) in BGL>
                    
                    find tqGLBySystemTypeAndType where
                         tqGLBySystemTypeAndType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-ROUND} and
                         tqGLBySystemTypeAndType.tcGLTypeCode       = {&GLTYPECODE-SYST}
                         no-error.
                    if not available tqGLBySystemTypeAndType
                    then do :
                        assign vcMessage = #T-10'The system account for rounding differences has not been defined.':250(16626)T-10#.
                        <M-38 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-151043':U (icFcMsgNumber), 
                            input  '':U (icFcExplanation), 
                            input  '':U (icFcIdentification), 
                            input  '':U (icFcContext), 
                            output viFcReturnSuper (oiReturnStatus)) in BAPMatching>
                        assign oiReturnStatus = -1.
                        leave MAIN_BLOCK.
                    end. /* if not available tqGLBySystemTypeAndType */
                    
                    assign vcGLCode = tqGLBySystemTypeAndType.tcGLCode.
                    
                end. /* If use rounding account */
                else do: /* Use AP variance account */
                
                    /* Find the first Receiver matching line, that is used for correct AP rate variance retrieval */
                    find first t_sAPMatchingLn where  /* First try to find material line */
                               t_sAPMatchingLn.tc_ParentRowid             = t_sAPMatching.tc_Rowid             and
                               t_sAPMatchingLn.APMatchingLnPvodItemType   = {&APMATCHINGLNPVODITEMTYPE-NORMAL} and
                               t_sAPMatchingLn.APMatchingLnPvodIsLgCharge = false
                               no-error.
                    if not available t_sAPMatchingLn
                    then find first t_sAPMatchingLn where  /* Next try to find memo item line */
                                    t_sAPMatchingLn.tc_ParentRowid             = t_sAPMatching.tc_Rowid           and
                                    t_sAPMatchingLn.APMatchingLnPvodItemType   = {&APMATCHINGLNPVODITEMTYPE-MEMO} and
                                    t_sAPMatchingLn.APMatchingLnPvodIsLgCharge = false
                                    no-error.
                    if not available t_sAPMatchingLn
                    then find first t_sAPMatchingLn where  /* Get logistic charge line */
                                    t_sAPMatchingLn.tc_ParentRowid             = t_sAPMatching.tc_Rowid
                                    no-error.
                                    
                    /* if we still don't have any line, we are in trouble */
                    if not available t_sAPMatchingLn
                    then do:
                         assign vcMessage = #T-39'The system cannot find Receiver matching line for Rounding posting.':250(536061982)T-39#.
                        <M-77 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-422597':U (icFcMsgNumber), 
                            input  '':U (icFcExplanation), 
                            input  '':U (icFcIdentification), 
                            input  '':U (icFcContext), 
                            output viFcReturnSuper (oiReturnStatus)) in BAPMatching>
                        assign oiReturnStatus = -1.
                        leave MAIN_BLOCK. 
                    end.


                    /* Get Pending voucher details needed for retrieval of correct AP Rate variance account */
                    <Q-8 run PendingVoucherForMatchingAcc (all) (Read) (NoCache)
                       (input t_sAPMatchingLn.PvoDomain, (DomainCode)
                        input t_sAPMatchingLn.PvoID, (PvoID)
                        input t_sAPMatchingLn.PvodLineID, (PvodLineID)
                        output dataset tqPendingVoucherForMatchingAcc) in BMfgPendingVoucher>
                    find first tqPendingVoucherForMatchingAcc where 
                               tqPendingVoucherForMatchingAcc.tcpvo_domain   = t_sAPMatchingLn.PvoDomain and 
                               tqPendingVoucherForMatchingAcc.tipvo_id       = t_sAPMatchingLn.PvoID     and 
                               tqPendingVoucherForMatchingAcc.tipvod_id_line = t_sAPMatchingLn.PvodLineID
                               no-lock no-error.
                    if not available tqPendingVoucherForMatchingAcc
                    then do : 
                        assign oiReturnStatus  = -1
                               vcMsgAPMatching = #T-90'The system cannot submit the receiver matching. Internal error.':255(57568)T-90#
                               vcContext       = "Domain=&1|PvoId=&2|PvodLineId=&3"
                               vcContext       = substitute(vcContext, t_sAPMatchingLn.PvoDomain, t_sAPMatchingLn.PvoID, t_sAPMatchingLn.PvodLineID)
                               vcContext       = replace(vcContext, "|", chr(2)).
                        <M-79 run SetMessage
                           (input  vcMsgAPMatching (icMessage), 
                            input  '':U (icArguments), 
                            input  '':U (icFieldName), 
                            input  '':U (icFieldValue), 
                            input  'E':U (icType), 
                            input  3 (iiSeverity), 
                            input  '':U (icRowid), 
                            input  'qadfin-282958':U (icFcMsgNumber), 
                            input  '':U (icFcExplanation), 
                            input  '':U (icFcIdentification), 
                            input  vcContext (icFcContext), 
                            output viFcReturnSuper (oiReturnStatus)) in BAPMatching> 
                        Return.                    
                    end. /* if not available tqPendingVoucherForMatchingAcc */
                
                    /* Retrieve ap rate variance account for the receiver matching line */
                    <M-49 run GetGLPLVarRate
                       (input  if t_sAPMatchingLn.tcGLCode = '':U then t_sAPMatchingLn.APMatchingLnOpAllocCode else t_sAPMatchingLn.tcGLCode (icAPMatchingLnGLCode), 
                        input  t_sAPMatchingLn.tcDivisionCode (icAPMatchingLnDivCode), 
                        input  t_sAPMatchingLn.tcCostCentreCode (icAPMatchingLnCCCode), 
                        input  t_sAPMatchingLn.APMatchingLnIsVarGLPosting (ilAPMatchingLnIsVarGLPosting), 
                        input  t_sAPMatchingLn.APMatchingLnMatchQty (idAPMatchingLnMatchQty), 
                        input  t_sAPMatchingLn.APMatchingLnMatchUnitPrice (idAPMatchingLnMatchUnitPrice), 
                        input  t_sAPMatchingLn.APMatchingLnPvodCCCode (icAPMatchingLnPvodCCCode), 
                        input  t_sAPMatchingLn.APMatchingLnPvodCostMtdCur (icAPMatchingLnPvodCostMtdCur), 
                        input  t_sAPMatchingLn.APMatchingLnPvodCostMtdGL (icAPMatchingLnPvodCostMtdGL), 
                        input  t_sAPMatchingLn.APMatchingLnPvodDivCode (icAPMatchingLnPvodDivCode), 
                        input  t_sAPMatchingLn.APMatchingLnPvodGLCode (icAPMatchingLnPvodGLCode), 
                        input  t_sAPMatchingLn.APMatchingLnPvodIsLgCharge (ilAPMatchingLnPvodIsLgCharge), 
                        input  t_sAPMatchingLn.APMatchingLnPvodItem (icAPMatchingLnPvodItem), 
                        input  t_sAPMatchingLn.APMatchingLnPvodItemType (icAPMatchingLnPvodItemType), 
                        input  t_sAPMatchingLn.APMatchingLnPvodLgCharge (icAPMatchingLnPvodLgCharge), 
                        input  t_sAPMatchingLn.APMatchingLnPvodPrjCode (icAPMatchingLnPvodPrjCode), 
                        input  t_sAPMatchingLn.APMatchingLnPvodReceiptQty (idAPMatchingLnPvodReceiptQty), 
                        input  t_sAPMatchingLn.APMatchingLnPvodSite (icAPMatchingLnPvodSite), 
                        input  t_sAPMatchingLn.APMatchingLnPvodUnitPrice (idAPMatchingLnPvodUnitPrice), 
                        input  t_sAPMatchingLn.APMatchingLnVarRateTC (idAPMatchingLnVarRateTC), 
                        input  t_sAPMatchingLn.PvoDomain (icPvoDomain), 
                        input  t_sAPMatchingLn.PvoID (iiPvoId), 
                        input  t_sAPMatchingLn.PvodLineID (iiPvodLineID), 
                        input  t_sAPMatchingLn.APMatchingLnPvodOpAllocCode (icPvodOpAllocCode), 
                        input  t_sAPMatchingLn.APMatchingLnOpAllocCode (icOpAllocCode), 
                        input  tqPendingVoucherForMatchingAcc.tcpod_loc (icpod_loc), 
                        input  tqPendingVoucherForMatchingAcc.tipod_op (iipod_op), 
                        input  tqPendingVoucherForMatchingAcc.tcpod_wo_lot (icpod_wo_Lot), 
                        input  tqPendingVoucherForMatchingAcc.tcprh_site (icprh_site), 
                        input  tqPendingVoucherForMatchingAcc.tcprh_type (icprh_type), 
                        input  tqPendingVoucherForMatchingAcc.tcprh_vend (icprh_vend), 
                        input  tqPendingVoucherForMatchingAcc.tcpt_prod_line (icpt_prod_line), 
                        input  tqPendingVoucherForMatchingAcc.tcpt_site (icpt_site), 
                        input  tqPendingVoucherForMatchingAcc.tcpvo_order_type (icpvo_order_type), 
                        input  tqPendingVoucherForMatchingAcc.tcpvo_shipfrom (icpvo_shipfrom), 
                        input  tqPendingVoucherForMatchingAcc.tcpvo_shipto (icpvo_shipto), 
                        input  tqPendingVoucherForMatchingAcc.tcpvod_channel (icpvod_channel), 
                        input  tqPendingVoucherForMatchingAcc.tcpvod_shipto (icpvod_shipto), 
                        input  tqPendingVoucherForMatchingAcc.tcvd_type (icvd_type), 
                        output vcDummy (ocNormalRateVarGLCode), 
                        output vcDummy (ocNormalRateVarDivisionCode), 
                        output vcDummy (ocNormalRateVarCostCentreCode), 
                        output vcDummy (ocDiscrepancyGLCode), 
                        output vcDummy (ocDiscrepancyDivisionCode), 
                        output vcDummy (ocDiscrepancyCostCentreCode), 
                        output vcDummy (ocLogRateVarGLCode), 
                        output vcDummy (ocLogRateVarDivisionCode), 
                        output vcDummy (ocLogRateVarCostCentreCode), 
                        output vcDummy (ocPPVGLCode), 
                        output vcDummy (ocPPVDivCode), 
                        output vcDummy (ocPPVCCCode), 
                        output vcGLCode (ocRateVarGLCode), 
                        output vcDivisionCode (ocRateVarDivisionCode), 
                        output vcCostCentreCode (ocRateVarCostCentreCode), 
                        output viFcReturnSuper (oiReturnStatus)) in BAPMatching>
                    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
                    if viFcReturnSuper <  0 then return.
                    
                    assign vcProjectCode = t_sAPMatchingLn.APMatchingLnPvodPrjCode.
                    
                end. /* Use AP variance account */
            end. /* GL block */

            /* we have to check, whether retrieved "rounding" account is GL account or operational allocation code */
            /* in case of operational allocation code we have to retrieve the first GL account of the allocaiton   */
            /* code to which the rounding amount is posted to                                                      */
            <Q-43 assign vlFcQueryRecordsAvailable = GLPrim (NoCache)
               (input t_sAPMatching.Company_ID, (CompanyId)
                input vcGLCode, (GLCode)
                input ?, (GLId)) in BGL>
            if vlFcQueryRecordsAvailable = false
            then do:
                 empty temp-table tOpAllocCodeStruct.

                 assign vhFcComponent = ?.
                 <M-18 run GetAllocationAccountStructure
                    (input  t_sAPMatchingLn.PvoDomain (icDomainCode), 
                     input  vcGLCode (icAllocationCode), 
                     output tOpAllocCodeStruct (tAllocationStruct), 
                     output viFcReturnSuper (oiReturnStatus)) in BMfgAllocationAccount>

                 find first tOpAllocCodeStruct no-error.

                 if available tOpAllocCodeStruct
                 then assign vcGLCode         = tOpAllocCodeStruct.tcGLCode
                             vcDivisionCode   = tOpAllocCodeStruct.tcDivisionCode
                             vcCostCentreCode = tOpAllocCodeStruct.tcCostCentreCode
                             vcProjectCode    = tOpAllocCodeStruct.tcProjectCode.
            end. /*if vlFcQueryRecordsAvailable = false */
            
            /* return amount of the invoice based on legal document amount */
            assign bdTotalInvoiceAmountLC = vdLgdTotalAmountLC
                   bdTotalInvoiceAmountTC = vdLgdTotalAmountLC.
    
            /* Create additional posting line, where the difference is posted to */
            <M-57 run AddDetailLine
               (input  'APMatchingCost':U (icTable), 
                input  t_sAPMatching.tc_Rowid (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BAPMatching>
            if viFcReturnSuper < 0 or viFcReturnSuper > 0 and oiReturnStatus = 0 then assign oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0 then leave MAIN_BLOCK.
            
            assign tAPMatchingCost.tcCurrencyCode   = t_sAPMatching.tcCurrencyCode
                   tAPMatchingCost.tcGLCode         = vcGLCode
                   tAPMatchingCost.tcDivisionCode   = vcDivisionCode
                   tAPMatchingCost.tcCostCentreCode = vcCostCentreCode
                   tAPMatchingCost.tcProjectCode    = vcProjectCode
                   tAPMatchingCost.tdCreditLC       = if vdBalanceLC > 0 then vdBalanceLC   else 0
                   tAPMatchingCost.tdDebitLC        = if vdBalanceLC < 0 then - vdBalanceLC else 0
                   tAPMatchingCost.tdCreditTC       = if vdBalanceLC > 0 then vdBalanceLC   else 0
                   tAPMatchingCost.tdDebitTC        = if vdBalanceLC < 0 then - vdBalanceLC else 0.
                   
            create t_sAPMatchingCost.
            buffer-copy tAPMatchingCost to t_sAPMatchingCost.
        end. /* if vdLgdTotalAmountLC <> bdTotalInvoiceAmountLC */

        /* Foreign currecy invoice */
        else do:
            /* return amount of the invoice based on legal document amount */
            assign bdTotalInvoiceAmountLC = vdLgdTotalAmountLC.
        end. /* if t_sAPMatching.tcCurrencyCode = vcCompanyLC */
    end. /* if vdLgdTotalAmountLC <> bdTotalInvoiceAmountLC */
    
    finally:
        if valid-object(doMfcCtrl) then delete object doMfcCtrl no-error.
        if valid-object(doPocCtrl) then delete object doPocCtrl no-error.
    end finally.
end. /* MAIN_BLOCK */