project QadFinancials > class BDInvoice > method ApiStdMaintainTTInitialDefaulting

Description

ApiStdMaintainTTInitialDefaulting;
This method is called when creating an invoice through an API right before the processing of the input.
This method can be used to default field values to the incoming dataset prior to the acctual processing.

Standard defaulting in this method :

• Default Company_ID with the current company you are logged on to
• Default DInvoiceType with INVOICE
• Default DInvoiceDIText with DInvoiceDescription.
• Default DInvoicePostingDate with DInvoiceDate (and vice-versa so one of them is mandatory).
• Default DInvoiceTaxPointDate with DInvoicePostingDate
• Default DInvoicePostingYear and DInvoicePostingPeriod based upon DInvoicePostingDate
• Default DInvoiceShipToCode and tcSoldToDebtorCode with the DebtorCode
• Default all ShipTo-related fields on the invoice based upon the customer
• Default all ShipFrom-related fields on the invoice based upon the operational-details of the customer
• Default Invoice-status with the default invoice-status of the customer
• Default following fields based upon the invoice-type and the associated default profiles of the customer; ControlGLCode, DivisionCode, CostCentreCode and ProjectCode
• Default Daybook based upon the invoice-type and the daybooks defined in the application
• Default NormalPaymentConditionCode with the defaults of the customer
• Default DInvoiceDueDate and DInvoiceDiscountDueDate based upon a non-staged NormalPaymentConditionCode and DInvoiceDate
• Default complete DInvoiceBank and DInvoiceBankPayCode in case no DInvoiceBank was specified
• Default the VatCurrency with the currency of the invoice
• Default the VatExchangeRate with 1 in case the VatCurrency equals the InvoiceCurrency
• Default the VatExchangeRate with the InvoiceExchangeRate in case the VatCurrency equals the base-currency of the Company
• Default DInvoiceVat.tcDomainCode with the domain of the current company
• Default DInvoiceVat.tcVatInOut with OUTPUT
• Default DInvoiceVat.DInvoiceVatSequence with 1
• Default following fields based upon the VatCode and the Domain related to the Company: DInvoiceVatIsUpdAllow, DInvoiceVatIsAbsRet, DInvoiceVatIsAccrRcpUs, DInvoiceVatIsRevCharge and DInvoiceVatIsSuspDel
• Replace unknown-values with an empty-string for these fields in DInvoiceVat: TxuTaxUsage, TxenvTaxEnv and TxclTaxCls
• Default the Taxable flag on the invoice-level based on the same flag on the DInvoiceVat-records
• Default following fields with their normal default-value in case they have the unknown-value: DInvoiceIsExternal, DInvoiceIsWithBankl, DInvoiceIsWithDeduction, DInvoiceIsTaxExcluded, DInvoiceCreationDate, DInvoiceIsDiscTaxAtInv, DInvoiceIsDiscTaxAtPaym, DInvoiceIsVatDelay, DInvoiceNonDiscAmtTC, DInvoiceNonDiscAmtCC, DInvoiceNonDiscAmtLC, DInvoiceOriginalCreditLC, DInvoiceOriginalCreditTC, DInvoiceOriginalDebitLC, DInvoiceOriginalDebitTC, DInvoiceVatBaseCreditLC, DInvoiceVatBaseCreditTC, DInvoiceVatBaseDebitLC, DInvoiceVatBaseDebitTC, DInvoiceVatCreditLC, DInvoiceVatCreditTC, DInvoiceVatDebitLC, DInvoiceVatDebitTC, DInvoiceBalanceDebitLC, DInvoiceBalanceCreditLC, DInvoiceBalanceDebitTC, DInvoiceBalanceCreditTC, DInvoiceBalanceLC, DInvoiceBalanceTC and DInvoiceBalanceCC


Parameters


oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BDInvoice.ApiStdMaintainTT
method BDInvoice.StdMaintainTT


program code (program9/bdinvoice.p)

    
    /* Additional logging in the CTLog */
    publish "Logging.BusinessCode":U  ("START-SUB,General-Initiliasation":U,"":U).
    
    /* ============================================================================================================= */
    /* Add an include in here so we can easily trace the methods that do direct db-access (or via dynamic querying)  */
    /* As in this method a lot of different tables are accessed we do not specify the complete list here in the call */
    /* ============================================================================================================= */
    <I-2 {READDIRECTDBACCESS
         &READTABLENAMES = "Plenty of Finacials and Operational tables"}>
    
    /* ============================================================================== */
    /* Notes:                                                                         */
    /*  0. In this method we will ony do the defaulting that applies to the Invoice   */
    /*     only (and not the associated Posting). The defaulting that applies to the  */
    /*     Invoice should be written in BDInvoiceJournalEntry                         */
    /*  1. No records are available at the moment this method is entered              */
    /*  2. The records that need to be extended are tApi-tables (eg tApiDInvoice)     */
    /*  3. Exception handling is done via progress itself (on error undo throw)       */
    /*  4. Database is accessed directly and variables are defined manually to:       */
    /*        A. Come to a proper performance                                         */
    /*        B. Ease downgradability                                                 */
    /*        C. Ease installations on released products: This complete peice of code */
    /*           can be copied into the 'before' hook of the parent-method of this    */
    /*           method by using the customization-technology that we have in the Fin */
    /*  Addition: Note that only Financial-tables can be accessed directly - for      */ 
    /*            Operational tables we will have to use dynamic queries!             */ 
    /* ============================================================================== */
    
    
    /* We are naming these manual defined variable with an X to avoid interactions with the normaly defined method-data-items */
    define variable viXDebtorSharedSetID          as  integer no-undo. 
    define variable viXGLSharedSetID              as  integer no-undo. 
    define variable viXDivisionSharedSetID        as  integer no-undo. 
    define variable viXCostCentreSharedSetID      as  integer no-undo. 
    define variable viXProjectSharedSetID         as  integer no-undo. 
    define variable viXJournalSharedSetID         as  integer no-undo.
    define variable viXGLProfileID                as  integer no-undo.
    define variable viXDivisionProfileID          as  integer no-undo.
    define variable viXCostCentreProfileID        as  integer no-undo.
    define variable viXProjectProfileID           as  integer no-undo.
    define variable viXGLIsDivisionAccount        as  logical no-undo.
    define variable viXGLIsCostCentreAccount      as  logical no-undo.
    define variable viXGLIsProjectAccount         as  logical no-undo.
    define variable vcXDomainCode                 as  character no-undo.
    define variable vcXSalesGLCode                as  character no-undo.
    define variable vcXPaymentConditionPeriodType as  character no-undo.
    define variable vtXPaymentConditionBaseDate   as  date no-undo.
    define variable viXPaymentConditionDaysMonths as  integer no-undo.
    define variable viXPaymentConditionSupplDays  as  integer no-undo.
    define variable viXPaymentConditionBaseDays   as  integer no-undo.
    define variable viXPaymentConditionDueDays    as  integer no-undo.
    define variable viXPaymentConditionDayMthDisc as  integer no-undo.
    define variable viXPaymentConditionSupDayDisc as  integer no-undo.
    define variable vcXPaymentConditionpDiscType  as  character no-undo.
    define variable vtXPaymentConditionStartDate  as  date no-undo.
    define variable viXBankNumberID               as  integer no-undo.
    define variable viXbXBankNumberID             as  integer no-undo.
    define variable viXBankPayFormatID            as  integer no-undo.
    define buffer   bXBankNumber                  for BankNumber.
    define buffer   bXCurrency                    for Currency. 
    define variable vhXQueryCmMstr                as  handle no-undo.
    define variable vhXBufferCmMstr               as  handle no-undo.
    define variable vhXBufferLsMstr               as  handle no-undo.
    define variable vhXBufferSiMstr               as  handle no-undo.
    define variable vhXBufferAdMstr               as  handle no-undo.
    define variable vhXBufferTx2Mstr              as  handle no-undo.
    define variable vhXQueryTx2Mstr               as  handle no-undo.
    /* Initialise the object-handles for queries and buffers */
    CREATE BUFFER vhXBufferCmMstr      FOR TABLE "cm_mstr".
    CREATE BUFFER vhXBufferLsMstr      FOR TABLE "ls_mstr".
    CREATE BUFFER vhXBufferSiMstr      FOR TABLE "si_mstr".
    CREATE BUFFER vhXBufferAdMstr      FOR TABLE "ad_mstr".
    CREATE QUERY vhXQueryCmMstr.
    vhXQueryCmMstr:Set-Buffers(vhXBufferCmMstr,vhXBufferSiMstr,vhXBufferLsMstr,vhXBufferAdMstr).      
    CREATE BUFFER vhXBufferTx2Mstr          FOR TABLE "tx2_mstr".
    CREATE QUERY vhXQueryTx2Mstr.
    vhXQueryTx2Mstr:Set-Buffers(vhXBufferTx2Mstr).
    
    /* Additional logging in the CTLog */
    publish "Logging.BusinessCode":U  ("END-SUB,General-Initiliasation":U,"":U).
    
    /* ====================================================== */
    /* Go through all invoices as only new-mode is supported  */
    /* ====================================================== */
    for each tApiDInvoice on error undo, throw :
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("START-SUB,Invoice-Initiliasation":U,"":U).
        
        /* ================================================================================================= */
        /* Avoid unkown-values as this is not allowed although some interfaces (like QXtend) do pass in this */
        /* ================================================================================================= */
        assign tApiDInvoice.DInvoiceIsExternal        = no    when tApiDInvoice.DInvoiceIsExternal        = ?
               tApiDInvoice.DInvoiceIsWithBank        = yes   when tApiDInvoice.DInvoiceIsWithBank        = ?
               tApiDInvoice.DInvoiceIsWithDeduction   = yes   when tApiDInvoice.DInvoiceIsWithDeduction   = ?
               tApiDInvoice.DInvoiceIsTaxExcluded     = no    when tApiDInvoice.DInvoiceIsTaxExcluded     = ?
               tApiDInvoice.DInvoiceCreationDate      = today when tApiDInvoice.DInvoiceCreationDate      = ?
               tApiDInvoice.DInvoiceIsDiscTaxAtInv    = no    when tApiDInvoice.DInvoiceIsDiscTaxAtInv    = ?
               tApiDInvoice.DInvoiceIsDiscTaxAtPaym   = no    when tApiDInvoice.DInvoiceIsDiscTaxAtPaym   = ?
               tApiDInvoice.DInvoiceIsVatDelay        = no    when tApiDInvoice.DInvoiceIsVatDelay        = ?
               tApiDInvoice.DInvoiceNonDiscAmtTC      = 0     when tApiDInvoice.DInvoiceNonDiscAmtTC      = ?
               tApiDInvoice.DInvoiceNonDiscAmtCC      = 0     when tApiDInvoice.DInvoiceNonDiscAmtCC      = ?
               tApiDInvoice.DInvoiceNonDiscAmtLC      = 0     when tApiDInvoice.DInvoiceNonDiscAmtLC      = ?
               tApiDInvoice.DInvoiceOriginalCreditLC  = 0     when tApiDInvoice.DInvoiceOriginalCreditLC  = ?
               tApiDInvoice.DInvoiceOriginalCreditTC  = 0     when tApiDInvoice.DInvoiceOriginalCreditTC  = ?
               tApiDInvoice.DInvoiceOriginalDebitLC   = 0     when tApiDInvoice.DInvoiceOriginalDebitLC   = ?
               tApiDInvoice.DInvoiceOriginalDebitTC   = 0     when tApiDInvoice.DInvoiceOriginalDebitTC   = ?
               tApiDInvoice.DInvoiceVatBaseCreditLC   = 0     when tApiDInvoice.DInvoiceVatBaseCreditLC   = ?
               tApiDInvoice.DInvoiceVatBaseCreditTC   = 0     when tApiDInvoice.DInvoiceVatBaseCreditTC   = ?
               tApiDInvoice.DInvoiceVatBaseDebitLC    = 0     when tApiDInvoice.DInvoiceVatBaseDebitLC    = ?
               tApiDInvoice.DInvoiceVatBaseDebitTC    = 0     when tApiDInvoice.DInvoiceVatBaseDebitTC    = ?
               tApiDInvoice.DInvoiceVatCreditLC       = 0     when tApiDInvoice.DInvoiceVatCreditLC       = ?
               tApiDInvoice.DInvoiceVatCreditTC       = 0     when tApiDInvoice.DInvoiceVatCreditTC       = ?
               tApiDInvoice.DInvoiceVatDebitLC        = 0     when tApiDInvoice.DInvoiceVatDebitLC        = ?
               tApiDInvoice.DInvoiceVatDebitTC        = 0     when tApiDInvoice.DInvoiceVatDebitTC        = ?
               tApiDInvoice.DInvoiceBalanceDebitLC    = 0     when tApiDInvoice.DInvoiceBalanceDebitLC    = ?
               tApiDInvoice.DInvoiceBalanceCreditLC   = 0     when tApiDInvoice.DInvoiceBalanceCreditLC   = ?
               tApiDInvoice.DInvoiceBalanceDebitTC    = 0     when tApiDInvoice.DInvoiceBalanceDebitTC    = ?
               tApiDInvoice.DInvoiceBalanceCreditTC   = 0     when tApiDInvoice.DInvoiceBalanceCreditTC   = ?
               tApiDInvoice.DInvoiceBalanceLC         = 0     when tApiDInvoice.DInvoiceBalanceLC         = ?
               tApiDInvoice.DInvoiceBalanceTC         = 0     when tApiDInvoice.DInvoiceBalanceTC         = ?
               tApiDInvoice.DInvoiceBalanceCC         = 0     when tApiDInvoice.DInvoiceBalanceCC         = ?.
        
        /* ================================================= */
        /* Fill in tApiDInvoice.tc_Rowid when not specified  */
        /* Default Company_ID and InvoiceType on the Invoice */
        /* ================================================= */
        if tApiDInvoice.tc_Rowid = "":U or 
           tApiDInvoice.tc_Rowid = ?
        then assign tApiDInvoice.tc_Rowid = string(rowid(tApiDInvoice)).
        if tApiDInvoice.Company_ID = ? or
           tApiDInvoice.Company_ID = 0
        then assign tApiDInvoice.Company_ID = viCompanyID.
        if tApiDInvoice.DInvoiceType = ? or 
           tApiDInvoice.DInvoiceType = "":U
        then assign tApiDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE}. /* INVOICE */
        
        /* =================================== */
        /* Get the DomainCode and SharedSetIDs */
        /* =================================== */
        For each Company where 
                 Company.Company_ID = tApiDInvoice.Company_ID
                 no-lock ,
            first Domains of Company no-lock,
            each CompanySharedSet of Company no-lock
            on error undo, throw :
            Assign vcXDomainCode = Domains.DomainCode.
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-DEBTOR} /* DEBTORE */
                     no-lock 
                     on error undo, throw :
                assign viXDebtorSharedSetID  = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-GL} /* GL */
                     no-lock 
                     on error undo, throw :
                assign viXGLSharedSetID = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-DIVISION} /* DIVISION */
                     no-lock 
                     on error undo, throw :
                assign viXDivisionSharedSetID = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-PROJECT} /* PROJECT */
                     no-lock 
                     on error undo, throw :
                assign viXProjectSharedSetID = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-COSTCENTRE} /* COSTCENTRE */
                     no-lock 
                     on error undo, throw :
                assign viXCostCentreSharedSetID = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
            For each SharedSet of CompanySharedSet where 
                     SharedSet.SharedSetTypeCode = {&SHAREDSETTYPE-JOURNAL} /* JOURNAL */
                     no-lock 
                     on error undo, throw :
                assign viXJournalSharedSetID = SharedSet.SharedSet_ID.
            end. /* For each SharedSet of CompanySharedSet where */
        end. /* For each Company where */  
        if vcXDomainCode           = "":U or 
           vcXDomainCode           = ? or 
           viXDebtorSharedSetID    = 0 or 
           viXDebtorSharedSetID    = ? or 
           viXGLSharedSetID        = 0 or 
           viXGLSharedSetID        = ? or 
           viXDivisionSharedSetID  = 0 or 
           viXDivisionSharedSetID  = ? or 
           viXJournalSharedSetID   = 0 or 
           viXJournalSharedSetID   = ? 
        then Return. /* If this missing then further defaulting makes no sense */
        
        /* ================================================================ */
        /* Default InvoicePostingDate, InvoiceDate and InvoiceTaxPointDate  */
        /* Default InvoiceDescription and DInvoiceDIText                    */
        /* ================================================================ */
        if tApiDInvoice.DInvoiceDate        = ? and 
           tApiDInvoice.DInvoicePostingDate = ? 
        then assign tApiDinvoice.DInvoiceDate = today.
        if tApiDInvoice.DInvoicePostingDate  = ? and 
           tApiDInvoice.DInvoiceDate        <> ? 
        then assign tApiDInvoice.DInvoicePostingDate = tApiDInvoice.DInvoiceDate.
        if tApiDInvoice.DInvoiceDate         = ? and 
           tApiDInvoice.DInvoicePostingDate <> ? 
        then assign tApiDInvoice.DInvoiceDate = tApiDInvoice.DInvoicePostingDate.
        if tApiDInvoice.DInvoiceTaxPointDate  = ? and 
           tApiDInvoice.DInvoicePostingDate  <> ? 
        then assign tApiDInvoice.DInvoiceTaxPointDate = tApiDInvoice.DInvoicePostingDate. 
        if tApiDinvoice.DInvoiceDescription = "":U or 
           tApiDinvoice.DInvoiceDescription = ? 
        then assign tApiDinvoice.DInvoiceDescription = substring((if tApiDInvoice.tcDebtorCode <> "":U and 
                                                                           tApiDInvoice.tcDebtorCode <> ?
                                                                        then tApiDinvoice.tcDebtorCode + " ":U 
                                                                        else "":U) +
                                                                       (if tApiDInvoice.DInvoicePostingDate <> ?
                                                                        then string(tApiDInvoice.DInvoicePostingDate) + " ":U 
                                                                        else "":U) + 
                                                                       string(tApiDInvoice.DInvoiceOriginalDebitTC - tApiDInvoice.DInvoiceOriginalCreditTC) + " ":U + 
                                                                       tApiDInvoice.tcCurrencyCode 
                                                                       ,1,40,"character":U).
        if tApiDInvoice.DInvoiceDIText = "":U or 
           tApiDinvoice.DInvoiceDIText = ? 
        then assign tApiDinvoice.DInvoiceDIText = tApiDInvoice.DInvoiceDescription.
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Invoice-Initiliasation":U,"":U).
        publish "Logging.BusinessCode":U  ("START-SUB,Period-Defaulting":U,"":U).
        
        /* =========================================================== */
        /* Default AccountingYearPeriod based upon DInvoicePostingDate */
        /* =========================================================== */
        if tApiDInvoice.DInvoicePostingDate <> ? and 
           (tApiDInvoice.DInvoicePostingYear = 0 or 
            tApiDInvoice.DInvoicePostingYear = ?) and 
           (tApiDInvoice.DInvoicePostingPeriod = 0 or 
            tApiDInvoice.DInvoicePostingPeriod = ?)
        then do :
            Release Period no-error.
            Find Period where 
                 Period.Company_ID                 = tApiDInvoice.Company_ID          and 
                 Period.PeriodStartDate           <= tApiDInvoice.DInvoicePostingDate and 
                 Period.PeriodEndDate             >= tApiDInvoice.DInvoicePostingDate and 
                 Period.PeriodTypeCode             = {&PERIODTYPECODE-NORMAL}         and /* NORM */
                 Period.PeriodIsPostingGLAllowed   = true                             and
                 Period.PeriodIsPostingPurchAllow  = true 
                 no-lock no-error.
            if not available Period 
            then Find Period where 
                      Period.Company_ID                 = tApiDInvoice.Company_ID          and 
                      Period.PeriodStartDate           <= tApiDInvoice.DInvoicePostingDate and 
                      Period.PeriodEndDate             >= tApiDInvoice.DInvoicePostingDate and 
                      Period.PeriodIsPostingGLAllowed   = true                             and
                      Period.PeriodIsPostingPurchAllow  = true 
                      no-lock no-error.
            if available Period
            then assign tApiDInvoice.DInvoicePostingYear   = Period.PeriodYear
                        tApiDInvoice.DInvoicePostingPeriod = Period.PeriodPeriod.
        end. /* if tApiDInvoice.DInvoicePostingDate <> ? and */               
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Period-Defaulting":U,"":U).
        publish "Logging.BusinessCode":U  ("START-SUB,Ship-From-To":U,"":U).
        
        /* ================================================================= */
        /* Find the Debtor record                                            */
        /* Fill in Debtor_ID as we need that to default the bank-data etc    */
        /* Assign the SoldToDebtor and ShipTo equal to the Debtor when empty */
        /* ================================================================= */
        Release Debtor no-error.
        if tApiDInvoice.Debtor_ID = ? or 
           tApiDInvoice.Debtor_ID = 0 
        then do:
            if tApiDInvoice.tcDebtorCode <> "":U and 
               tApiDInvoice.tcDebtorCode <> ?
            then do :
                find Debtor where 
                     Debtor.SharedSet_ID = viXDebtorSharedSetID  and 
                     Debtor.DebtorCode = tApiDInvoice.tcDebtorCode
                     no-lock no-error.
                if available Debtor 
                then assign tApiDInvoice.Debtor_ID = Debtor.Debtor_ID.
            end. /* if tApiDInvoice.tcDebtorCode <> "":U and  */
        end. /* if (tApiDInvoice.Debtor_ID = ? or  */
        else find Debtor where 
                  Debtor.Debtor_ID = tApiDInvoice.Debtor_ID
                  no-lock no-error.
        if not available Debtor
        then Return. /* If this missing then further defaulting makes no sense */
        if tApiDInvoice.tcSoldToDebtorCode = "":U or 
           tApiDInvoice.tcSoldToDebtorCode = ?
        then assign tApiDInvoice.tcSoldToDebtorCode = Debtor.DebtorCode.
        if tApiDInvoice.DInvoiceShipToCode = "":U or 
           tApiDInvoice.DInvoiceShipToCode = ?
        then assign tApiDInvoice.DInvoiceShipToCode = Debtor.DebtorCode.
        
        /* ============================================= */
        /* Fill in the ShipTo-fields when not specified  */
        /* ============================================= */
        if (tApiDInvoice.tcShipToAddressStreet1 = "":U or 
            tApiDInvoice.tcShipToAddressStreet1 = ?) and 
           (tApiDInvoice.tcShipToBusinessRelationCode = "":U or 
            tApiDInvoice.tcShipToBusinessRelationCode = ?)
        then do :
            /* If the Debtor has got only one DebtorShipTo then the data is taken from there */
            Find DebtorShipTo where 
                 DebtorShipTo.Debtor_ID    = Debtor.Debtor_ID and 
                 DebtorShipTo.SharedSet_ID = Debtor.SharedSet_ID
                 no-lock no-error. /* do not use the first option as we only want the DebtorShipTo in case there is only one */
            if available DebtorShipTo
            then do :
                /* Read the Address of the DebtorShipTo */
                For first Address of DebtorShipTo
                          no-lock,
                    first BusinessRelation where
                          BusinessRelation.BusinessRelation_ID = Address.BusinessRelation_ID 
                          no-lock,
                    first AddressType of Address
                          no-lock,
                    first Country of Address
                          no-lock
                          on error undo, throw :
                    /* Assign the ShipTo-related fields */
                    assign tApiDInvoice.tcShipToBusinessRelationCode = BusinessRelation.BusinessRelationCode
                           tApiDInvoice.tcShipToAddressTypeCode      = AddressType.AddressTypeCode
                           tApiDInvoice.tcShipToAddressStreet1       = Address.AddressStreet1
                           tApiDInvoice.tcShipToAddressStreet2       = Address.AddressStreet2
                           tApiDInvoice.tcShipToAddressStreet3       = Address.AddressStreet3
                           tApiDInvoice.tcShipToAddressZip           = Address.AddressZip
                           tApiDInvoice.tcShipToAddressCity          = Address.AddressCity
                           tApiDInvoice.tcShipToCountryCode          = Country.CountryCode
                           tApiDInvoice.ShipToAddress_ID             = Address.Address_ID.
                    /* Read some optional tables and assign the field */
                    Find State of Address no-lock no-error.
                    if available State 
                    then assign tApiDInvoice.tcShipToAddressState = State.StateCode.
                end. /* For first Address of DebtorShipTo */                                
            end. /* if available DebtorShipTo */
            else do :
                /* Read the Address of the DebtorShipTo */
                For first BusinessRelation where
                          BusinessRelation.BusinessRelation_ID = Debtor.BusinessRelation_ID 
                          no-lock,
                    each  Address of BusinessRelation 
                          no-lock,
                    first AddressType of Address where 
                          AddressType.AddressTypeCode = {&ADDRESSTYPECODESYSTEM-HEADOFFICE} /* HEADOFFICE */
                          no-lock,
                    first Country of Address
                          no-lock
                          on error undo, throw :
                    /* Assign the ShipTo-related fields */
                    assign tApiDInvoice.tcShipToBusinessRelationCode = BusinessRelation.BusinessRelationCode
                           tApiDInvoice.tcShipToAddressTypeCode      = AddressType.AddressTypeCode
                           tApiDInvoice.tcShipToAddressStreet1       = Address.AddressStreet1
                           tApiDInvoice.tcShipToAddressStreet2       = Address.AddressStreet2
                           tApiDInvoice.tcShipToAddressStreet3       = Address.AddressStreet3
                           tApiDInvoice.tcShipToAddressZip           = Address.AddressZip
                           tApiDInvoice.tcShipToAddressCity          = Address.AddressCity
                           tApiDInvoice.tcShipToCountryCode          = Country.CountryCode
                           tApiDInvoice.ShipToAddress_ID             = Address.Address_ID.
                    /* Read some optional tables and assign the field */
                    Find State of Address no-lock no-error.
                    if available State 
                    then assign tApiDInvoice.tcShipToAddressState = State.StateCode.
                end. /* For first Address of DebtorShipTo */
            end. /* if available DebtorShipTo */
        end. /* if (tApiDInvoice.tcShipToAddressStreet1 = "":U or */
        
        /* ============================================== */
        /* Fill in the ShipFrom-fields when not specified */
        /* ============================================== */
        if (tApiDInvoice.tcShipFromAddressStreet1 = "":U or 
            tApiDInvoice.tcShipFromAddressStreet1 = ?) and 
           (tApiDInvoice.tcShipFromBusinessRelationCode = "":U or 
            tApiDInvoice.tcShipFromBusinessRelationCode = ?)
        then do :
            /* Get the address-id that is in operationals linked to the site of the customer */
            vhXQueryCmMstr:Query-Prepare("for each cm_mstr where cm_mstr.cm_domain = '" + "21NL" + "' and " + " cm_mstr.cm_addr = '" + "21C1000" + "'," +  
                                         "    each si_mstr where si_mstr.si_domain = cm_mstr.cm_domain and si_mstr.si_site = cm_mstr.cm_site , " + 
                                         "    each ls_mstr where ls_mstr.ls_domain = si_mstr.si_domain and ls_mstr.ls_addr = si_mstr.si_site and ls_mstr.ls_type = 'COMPANY'  , " + 
                                         "    each ad_mstr where ad_mstr.ad_addr = ls_mstr.ls_addr and ad_mstr.ad_domain = ls_mstr.ls_domain ").
            vhXQueryCmMstr:Query-Open.
            vhXQueryCmMstr:Get-First(no-lock).
            if valid-handle(vhXBufferAdMstr)       and  
               vhXBufferAdMstr:available           and 
               vhXBufferAdMstr::ad_address_id <> 0 and 
               vhXBufferAdMstr::ad_address_id <> ?
            then do :             
                /* Get the address based upon the address-id of the customer its site */
                For first Address where 
                          Address.Address_ID = vhXBufferAdMstr::ad_address_id
                          no-lock,
                    first BusinessRelation of Address
                          no-lock,
                    first AddressType of Address 
                          no-lock,
                    first Country of Address
                          no-lock
                          on error undo, throw :
                    /* Assign the ShipFrom-related fields */
                    assign tApiDInvoice.tcShipFromBusinessRelationCode = BusinessRelation.BusinessRelationCode
                           tApiDInvoice.tcShipFromAddressTypeCode      = AddressType.AddressTypeCode
                           tApiDInvoice.tcShipFromAddressStreet1       = Address.AddressStreet1
                           tApiDInvoice.tcShipFromAddressStreet2       = Address.AddressStreet2
                           tApiDInvoice.tcShipFromAddressStreet3       = Address.AddressStreet3
                           tApiDInvoice.tcShipFromAddressZip           = Address.AddressZip
                           tApiDInvoice.tcShipFromAddressCity          = Address.AddressCity
                           tApiDInvoice.tcShipFromCountryCode          = Country.CountryCode
                           tApiDInvoice.tlShipFromCountryIsEUCountry   = Country.CountryIsEUCountry
                           tApiDInvoice.tcShipFromTaxZone              = Address.TxzTaxZone
                           tApiDInvoice.ShipFromAddress_ID             = Address.Address_ID.
                    /* Read some optional tables and assign the field */
                    Find State of Address no-lock no-error.
                    if available State 
                    then assign tApiDInvoice.tcShipFromAddressState = State.StateCode.
                end. /* For first Address of DebtorShipTo */
            end. /* if valid-handle(vhXBufferAdMstr)    and */
        end. /* if (tApiDInvoice.tcShipFromAddressStreet1 = "":U or */
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Ship-From-To":U,"":U).
        publish "Logging.BusinessCode":U  ("START-SUB,Accounting-details":U,"":U).
        
        /* =============================================================== */
        /* Fill in the Reason when not speified                            */ 
        /* =============================================================== */
        Release Reason no-error.
        if tApiDInvoice.tcReasonCode = "":U or 
           tApiDInvoice.tcReasonCode = ?
        then do :
            Find Reason where 
                 Reason.Reason_ID = Debtor.Reason_ID
                 no-lock no-error.
            if available Reason 
            then assign tApiDInvoice.tcReasonCode = Reason.ReasonCode
                        tApiDInvoice.Reason_ID    = Reason.Reason_ID.
        end. /* if sApiDInvoice.tcReasonCode = "":U or */
        
        /* ====================================================================================================================== */
        /* Fill in the Control-GL, Div, CC and Prj-info on the Invoice when not filled                                            */
        /* If the Control-GL is enabled for Div/Prj/CC:                                                                           */
        /*   1st: Take the Div/Prj/CC from the input if it is provided                                                            */
        /*   2nd: If the Div is not yet filled then take the Div from the Debtor-definition (no debtor-default exists for Prj/CC) */
        /*   3rd: If the Div/Prj/CC is not yet filled then take the Div/Prj/CC from the Control-GL-definition                     */
        /* ====================================================================================================================== */
        assign viXProjectProfileID      = 0
               viXCostCentreProfileID   = 0
               viXDivisionProfileID     = 0
               viXGLIsDivisionAccount   = false 
               viXGLIsCostCentreAccount = false
               viXGLIsProjectAccount    = false.
        if tApiDInvoice.tcControlGLCode = "":U or 
           tApiDInvoice.tcControlGLCode = ?
        then do :
            assign viXGLProfileID = if tApiDInvoice.DInvoiceType= {&INVOICETYPE-PREPAYMENT} /* PREPAYMENT */
                                    then Debtor.PrePayControlGLProfile_ID
                                    else if tApiDInvoice.DInvoiceType= {&INVOICETYPE-DEDUCTION} /* DEDUCTION */
                                         then Debtor.DeductionCtrlGLProfile_ID
                                         else if tApiDInvoice.DInvoiceType= {&INVOICETYPE-INVOICE}           or /* INVOICE */
                                                 tApiDInvoice.DInvoiceType= {&INVOICETYPE-INVOICECORRECTION} or /* INVOICECORRECTION */
                                                 tApiDInvoice.DInvoiceType= {&INVOICETYPE-FINANCECHARGE}        /* FINANCECHARGE */
                                              then Debtor.InvControlGLProfile_ID
                                              else Debtor.CnControlGLProfile_ID. 
            for first ProfileLink  where 
                      ProfileLink.Profile_ID = viXGLProfileID and 
                      ProfileLink.SharedSet_ID = viXGLSharedSetID
                      no-lock,
                first GL where 
                      GL.GL_ID = ProfileLink.ProfileLinkObject_ID 
                      no-lock
                      on error undo, throw:
                assign tApiDInvoice.tcControlGLCode = GL.GLCode
                       tApiDInvoice.ControlGL_ID    = GL.GL_ID                      
                       viXGLIsDivisionAccount       = GL.GLIsDivisionAccount
                       viXGLIsCostCentreAccount     = GL.GLIsCostCentreAccount
                       viXGLIsProjectAccount        = GL.GLIsProjectAccount.
                if GL.GLIsDivisionAccount = true
                then assign viXDivisionProfileID = GL.DivisionProfile_ID.
                if GL.GLIsCostCentreAccount = true
                then assign viXCostCentreProfileID = GL.CostCentreProfile_ID.
                if GL.GLIsProjectAccount = true
                then assign viXProjectProfileID = GL.ProjectProfile_ID.
            end. /* for first ProfileLink  where */
        end. /* if tApiDInvoice.tcControlGLCode = "":U or */
        else do :
            Find GL where 
                 GL.SharedSet_ID = viXGLSharedSetID and 
                 GL.GLCode       = tApiDInvoice.tcControlGLCode
                 no-lock no-error.
            if available GL
            then do :     
                assign tApiDInvoice.ControlGL_ID = GL.GL_ID.
                if GL.GLIsDivisionAccount = true
                then assign viXDivisionProfileID = GL.DivisionProfile_ID.
                if GL.GLIsCostCentreAccount = true
                then assign viXCostCentreProfileID = GL.CostCentreProfile_ID.
                if GL.GLIsProjectAccount = true
                then assign viXProjectProfileID = GL.ProjectProfile_ID.
                assign viXGLIsDivisionAccount             = GL.GLIsDivisionAccount
                       viXGLIsCostCentreAccount           = GL.GLIsCostCentreAccount
                       viXGLIsProjectAccount              = GL.GLIsProjectAccount.
            end. /* if available GL */
        end. /* Not if tApiDInvoice.tcControlGLCode = "":U or */
        /* Default the division when the ControlGL supports divisions */                
        if viXGLIsDivisionAccount = true and 
           viXDivisionProfileID <> 0 and 
           viXDivisionProfileID <> ?
        then do :
            if (tApiDInvoice.tcDivisionCode = "":U or
                tApiDInvoice.tcDivisionCode = ?) and 
               Debtor.DivisionProfile_ID <> 0 and 
               Debtor.DivisionProfile_ID <> ?
            then for first ProfileLink  where 
                           ProfileLink.Profile_ID   = Debtor.DivisionProfile_ID and 
                           ProfileLink.SharedSet_ID = viXDivisionSharedSetID
                           no-lock,
                     first Division where 
                           Division.Division_ID = ProfileLink.ProfileLinkObject_ID 
                           no-lock
                           on error undo, throw:
                    assign tApiDInvoice.tcDivisionCode = Division.DivisionCode
                           tApiDInvoice.Division_ID    = Division.Division_ID.                    
                 end. /* or first Profile where */
            if tApiDInvoice.tcDivisionCode = "":U or
               tApiDInvoice.tcDivisionCode = ?
            then for first ProfileLink  where 
                           ProfileLink.Profile_ID   = viXDivisionProfileID and 
                           ProfileLink.SharedSet_ID = viXDivisionSharedSetID
                           no-lock,
                     first Division where 
                           Division.Division_ID = ProfileLink.ProfileLinkObject_ID 
                           no-lock
                           on error undo, throw:
                    assign tApiDInvoice.tcDivisionCode = Division.DivisionCode
                           tApiDInvoice.Division_ID    = Division.Division_ID.                    
                 end. /* or first Profile where */
        end. /* if viXDivisionProfileID <> 0 and */
        /* Default the cost-centre when the ControlGL supports cost-centress */
        if viXGLIsCostCentreAccount and 
           viXCostCentreProfileID <> 0 and 
           viXCostCentreProfileID <> ? and 
           (tApiDInvoice.tcCostCentreCode = "":U or 
            tApiDInvoice.tcCostCentreCode = ?)
        then do :
            for first ProfileLink  where 
                      ProfileLink.Profile_ID = viXCostCentreProfileID and 
                      ProfileLink.SharedSet_ID = viXCostCentreSharedSetID
                      no-lock,
                first CostCentre where 
                      CostCentre.CostCentre_ID = ProfileLink.ProfileLinkObject_ID 
                      no-lock
                      on error undo, throw:
                assign tApiDInvoice.tcCostCentreCode = CostCentre.CostCentreCode
                       tApiDInvoice.CostCentre_ID    = CostCentre.CostCentre_ID.                    
            end. /* or first Profile where */
        end. /* if viXCostCentreProfileID <> 0 and */
        /* Default the project when the ControlGL supports projects */
        if viXGLIsProjectAccount and 
           viXProjectProfileID <> 0 and 
           viXProjectProfileID <> ? and 
           (tApiDInvoice.tcProjectCode = "":U or 
            tApiDInvoice.tcProjectCode = ?)
        then do :
            for first ProfileLink  where 
                      ProfileLink.Profile_ID = viXProjectProfileID and 
                      ProfileLink.SharedSet_ID = viXProjectSharedSetID
                      no-lock,
                first qaddb.Project where 
                      qaddb.Project.Project_ID = ProfileLink.ProfileLinkObject_ID 
                      no-lock
                      on error undo, throw:
                assign tApiDInvoice.tcProjectCode = qaddb.Project.ProjectCode
                       tApiDInvoice.Project_ID    = qaddb.Project.Project_ID.                    
            end. /* or first Profile where */
        end. /* if viXProjectProfileID <> 0 and */

        /* =========================================================================================== */
        /* Fill in the Journal-related fields based on the InvoiceType/Debtor when not specified     */
        /* =========================================================================================== */
        if tApiDInvoice.tcJournalCode = ? 
        then assign tApiDInvoice.tcJournalCode = "":U.
        if tApiDInvoice.tcJournalCode = "":U
        then 
            for each  Journal where 
                      Journal.SharedSet_ID    = viXJournalSharedSetID       and 
                      Journal.JournalIsActive = true                        and 
                      Journal.JournalControl  = {&JOURNALCONTROL-FINANCIAL} and  /* FINANCIAL */ 
                      Journal.JournalTypeCode = (if tApiDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} /* CREDITNOTE */
                                                 then {&JOURNALTYPE-DEBTORCREDITNOTE}
                                                 else if tApiDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} /* INVOICECORRECTION */
                                                      then {&JOURNALTYPE-DEBTORINVOICECORRECT}
                                                      else if tApiDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} /* CREDITNOTECORRECTION */
                                                           then {&JOURNALTYPE-DEBTORCREDITNOTECORRECT}
                                                           else {&JOURNALTYPE-DEBTORINVOICE}) /* meaning {&INVOICETYPE-INVOICE} or {&INVOICETYPE-FINANCECHARGE} */                                                
                      no-lock,
                each  JournalType of Journal where 
                      JournalType.JournalTypeIsCorrection = (if tApiDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} or /* INVOICECORRECTION */
                                                                tApiDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} /* CREDITNOTECORRECTION */
                                                             then true
                                                             else false) 
                      no-lock,
                each  Layer of Journal where
                      Layer.LayerTypeCode = {&LAYERTYPECODE-OFFICIAL} /* OFFICIAL */
                      no-lock 
                      on error undo, throw:
                assign tApiDInvoice.tcJournalCode = Journal.JournalCode. 
                Leave.
            end. /* for first Profile where */
        
        /* ================================================= */
        /* Fill in the Payment Condition when not filled yet */
        /* ================================================= */
        Release PaymentCondition.
        if (tApiDInvoice.tcNormalPaymentConditionCode = "":U or
            tApiDInvoice.tcNormalPaymentConditionCode = ?) and 
           Debtor.NormalPaymentCondition_ID <> 0 and 
           Debtor.NormalPaymentCondition_ID <> ?
        then do :
            Find PaymentCondition where 
                 PaymentCondition.PaymentCondition_ID  = Debtor.NormalPaymentCondition_ID
                 no-lock no-error.
            if available PaymentCondition
            then assign tApiDInvoice.tcNormalPaymentConditionCode = PaymentCondition.PaymentConditionCode
                        tApiDInvoice.tcNormalPaymentConditionType = PaymentCondition.PaymentConditionPaymentTyp.
        end. /* if (tApiDInvoice.tcNormalPaymentConditionCode = "":U or */
                
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Accounting-details":U,"":U).
        publish "Logging.BusinessCode":U  ("START-SUB,Banking-details":U,"":U).
        
        /* ============================================================ */
        /* Fill in the Due-Date and Disc-Due-Date - only for non-staged */
        /* ============================================================ */
        if (tApiDInvoice.DInvoiceDueDate          = ? or 
            tApiDInvoice.DInvoiceDiscountDueDate = ?)        and 
           tApiDInvoice.DInvoiceDate                 <> ?    and 
           tApiDInvoice.tcNormalPaymentConditionCode <> "":U and 
           tApiDInvoice.tcNormalPaymentConditionCode <> ?    and 
           tApiDInvoice.tcNormalPaymentConditionType <> "":U and 
           tApiDInvoice.tcNormalPaymentConditionType <> ?    
        then PAYMENTDATESBLOCK: do :
            If not available PaymentCondition 
            then Find PaymentCondition where 
                      PaymentCondition.PaymentConditionCode = tApiDInvoice.tcNormalPaymentConditionCode
                      no-lock no-error.
            if available PaymentCondition and 
               PaymentCondition.PaymentConditionPaymentTyp = {&PAYMENTCONDITIONPAYMENTTYPE-NORMAL} /* NORMAL */
            then do :
                assign vcXPaymentConditionPeriodType = PaymentCondition.PaymentConditionPeriodType  
                       vtXPaymentConditionBaseDate   = PaymentCondition.PaymentConditionBaseDate
                       viXPaymentConditionDaysMonths = PaymentCondition.PaymentConditionDaysMonths
                       viXPaymentConditionSupplDays  = PaymentCondition.PaymentConditionSupplDays
                       viXPaymentConditionBaseDays   = PaymentCondition.PaymentConditionBaseDays
                       viXPaymentConditionDueDays    = PaymentCondition.PaymentConditionDueDays
                       viXPaymentConditionDayMthDisc = PaymentCondition.PaymentConditionDayMthDisc
                       viXPaymentConditionSupDayDisc = PaymentCondition.PaymentConditionSupDayDisc
                       vcXPaymentConditionpDiscType  = PaymentCondition.PaymentConditionPdDiscType.                   
               /* === Set Due Date ==== */
               assign vtXPaymentConditionStartDate = tApiDInvoice.DInvoiceDate.
               if vtXPaymentConditionBaseDate <> ?
               then do:
                   if tApiDInvoice.DInvoiceDate < vtXPaymentConditionBaseDate
                   then assign vtXPaymentConditionStartDate = vtXPaymentConditionBaseDate.
               end. /* if vtXPaymentConditionBaseDate <> ? */
               if vtXPaymentConditionStartDate = ? then Leave PAYMENTDATESBLOCK.                   
               if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-MONTHS}  /* MONTHS */
               then assign vtXPaymentConditionStartDate                  = date((viXPaymentConditionDaysMonths + month(vtXPaymentConditionStartDate)) modulo 12 + 1,
                                                                1,
                                                                int(year(vtXPaymentConditionStartDate) + (viXPaymentConditionDaysMonths + month(vtXPaymentConditionStartDate) - (viXPaymentConditionDaysMonths + month(vtXPaymentConditionStartDate)) modulo 12) / 12))
                           vtXPaymentConditionStartDate                  = vtXPaymentConditionStartDate - 1
                           tApiDInvoice.DInvoiceDueDate = vtXPaymentConditionStartDate + viXPaymentConditionSupplDays + viXPaymentConditionBaseDays.
               else if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT}  /* FORTNIGHT */
                    then do:
                       if day(vtXPaymentConditionStartDate) <= 15
                       then assign vtXPaymentConditionStartDate = date(month(vtXPaymentConditionStartDate), 15, year(vtXPaymentConditionStartDate)).
                       else assign vtXPaymentConditionStartDate = date((month(vtXPaymentConditionStartDate) modulo 12) + 1, 1, year(vtXPaymentConditionStartDate) + if month(vtXPaymentConditionStartDate) = 12 then 1 else 0)
                                   vtXPaymentConditionStartDate = vtXPaymentConditionStartDate - 1.
                       assign tApiDInvoice.DInvoiceDueDate = vtXPaymentConditionStartDate + (viXPaymentConditionDaysMonths * 14) + viXPaymentConditionBaseDays.
                    end. /* if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT}  /* FORTNIGHT */ */
                    else if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-WEEK}  /* WEEK */
                         then assign vtXPaymentConditionStartDate                  = vtXPaymentConditionStartDate + 7 - weekday(vtXPaymentConditionStartDate)
                                     tApiDInvoice.DInvoiceDueDate = vtXPaymentConditionStartDate + viXPaymentConditionDaysMonths * 7 + viXPaymentConditionBaseDays.
                           else assign tApiDInvoice.DInvoiceDueDate = vtXPaymentConditionStartDate + viXPaymentConditionDaysMonths + viXPaymentConditionBaseDays.
               if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-MONTHS}    or  /* MONTHS */
                  vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT} or  /* FORTNIGHT */
                  vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-WEEK}          /* WEEK */
               then do while (tApiDInvoice.DInvoiceDueDate - tApiDInvoice.DInvoiceDate) < viXPaymentConditionDueDays:
                   if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-MONTHS} /* MONTHS */
                   then assign tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate - viXPaymentConditionSupplDays - viXPaymentConditionBaseDays + 1
                               tApiDInvoice.DInvoiceDueDate = date(month(tApiDInvoice.DInvoiceDueDate) modulo 12 + 1,
                                                                    1,
                                                                    int(year(tApiDInvoice.DInvoiceDueDate) + (1 + month(tApiDInvoice.DInvoiceDueDate) - (1 + month(tApiDInvoice.DInvoiceDueDate)) modulo 12) / 12))
                               tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate  - 1
                               tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate + viXPaymentConditionSupplDays + viXPaymentConditionBaseDays.
                   else if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT} /* FORTNIGHT */
                        then do:
                           assign tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate - viXPaymentConditionDaysMonths - viXPaymentConditionBaseDays.
                           if day(tApiDInvoice.DInvoiceDueDate) = 15
                           then assign tApiDInvoice.DInvoiceDueDate = date(month(tApiDInvoice.DInvoiceDueDate) modulo 12 + 1,
                                                                            1, 
                                                                            year(tApiDInvoice.DInvoiceDueDate) + if month(tApiDInvoice.DInvoiceDueDate) = 12 then 1 else 0)
                                       tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate - 1.
                           else assign tApiDInvoice.DInvoiceDueDate = date(month(tApiDInvoice.DInvoiceDueDate) modulo 12 + 1,
                                                                            15,
                                                                            year(tApiDInvoice.DInvoiceDueDate) + if month(tApiDInvoice.DInvoiceDueDate) = 12 then 1 else 0).
                           assign tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate + viXPaymentConditionDaysMonths + viXPaymentConditionBaseDays.
                        end. /* if vcXPaymentConditionPeriodType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT} */
                        else assign tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDueDate + 7.
               end. /* then do while (tApiDInvoice.DInvoiceDueDate - tApiDInvoice.DInvoiceDate) < viXPaymentConditionDueDays */
               else if tApiDInvoice.DInvoiceDueDate - tApiDInvoice.DInvoiceDate < viXPaymentConditionDueDays
                    then assign tApiDInvoice.DInvoiceDueDate = tApiDInvoice.DInvoiceDate + viXPaymentConditionDueDays.
               /* === Set Discount Due Date === */
               assign vtXPaymentConditionStartDate = if vtXPaymentConditionBaseDate = ?
                                    then tApiDInvoice.DInvoiceDate
                                    else vtXPaymentConditionBaseDate.
               if vtXPaymentConditionStartDate = ? then Leave PAYMENTDATESBLOCK.
               if vcXPaymentConditionpDiscType = {&PAYMENTCONDITIONPERIODTYPE-MONTHS} /* MONTHS */
               then assign vtXPaymentConditionStartDate    = date((viXPaymentConditionDayMthDisc + month(vtXPaymentConditionStartDate)) modulo 12 + 1,  
                                                   1,
                                                   int(year(vtXPaymentConditionStartDate) + (viXPaymentConditionDayMthDisc + month(vtXPaymentConditionStartDate) - (viXPaymentConditionDayMthDisc + month(vtXPaymentConditionStartDate)) modulo 12) / 12))
                           vtXPaymentConditionStartDate    = vtXPaymentConditionStartDate - 1
                           tApiDInvoice.DInvoiceDiscountDueDate = vtXPaymentConditionStartDate + viXPaymentConditionSupDayDisc + viXPaymentConditionBaseDays.
               else if vcXPaymentConditionpDiscType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT} /* FORTNIGHT */
                    then do:
                       if day(vtXPaymentConditionStartDate) <= 15
                       then assign vtXPaymentConditionStartDate = date(month(vtXPaymentConditionStartDate), 15, year(vtXPaymentConditionStartDate)).
                       else assign vtXPaymentConditionStartDate = date((month(vtXPaymentConditionStartDate) modulo 12) + 1,
                                                      1,
                                                      year(vtXPaymentConditionStartDate) + if month(vtXPaymentConditionStartDate) = 12 then 1 else 0)
                                   vtXPaymentConditionStartDate = vtXPaymentConditionStartDate - 1.
                       assign tApiDInvoice.DInvoiceDiscountDueDate = vtXPaymentConditionStartDate + (viXPaymentConditionDayMthDisc  * 14) + viXPaymentConditionBaseDays.
                    end. /* if vcXPaymentConditionpDiscType = {&PAYMENTCONDITIONPERIODTYPE-FORTNIGHT} */
                    else if vcXPaymentConditionpDiscType = {&PAYMENTCONDITIONPERIODTYPE-WEEK} /* WEEK */
                         then assign vtXPaymentConditionStartDate    = vtXPaymentConditionStartDate + 7 - weekday(vtXPaymentConditionStartDate)
                                     tApiDInvoice.DInvoiceDiscountDueDate = vtXPaymentConditionStartDate + (viXPaymentConditionDayMthDisc  * 7) + viXPaymentConditionBaseDays.
                         else assign tApiDInvoice.DInvoiceDiscountDueDate = vtXPaymentConditionStartDate + viXPaymentConditionDayMthDisc + viXPaymentConditionBaseDays.               
            end. /* if available PaymentCondition */
        end. /* if (tApiDInvoice.DInvoiceDueDate  = ? or   + PAYMENTDATESBLOCK  */
        
        /* ===================================================== */
        /* Fill in the default bank information if not specified */
        /* ===================================================== */
        if tApiDInvoice.Debtor_ID <> 0 and 
           tApiDInvoice.Debtor_ID <> ? and 
           not can-find (first tApiDInvoiceBank where 
                               tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid)
        then do :
            /* Read the best applicable banknumber that is related to this Debtor: including Default and CompanyID */
            if not can-find (first tApiDInvoiceBank where 
                                   tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid)
            then do :
                for each  BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and
                          BankNumber.BankNumberIsDefault = true                     and
                          BankNumber.BankNumberIsActive  = true
                          no-lock,        
                    each BankPayFormat where 
                         BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                         no-lock,
                    each bXBankNumber where 
                         bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID 
                         no-lock,
                    each CompanySharedSet where
                         CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                         CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                         no-lock 
                         on error undo, throw :
                    create tApiDInvoiceBank.
                    assign tApiDInvoiceBank.tc_ParentRowid         = tApiDInvoice.tc_Rowid
                           tApiDInvoiceBank.tiParentObject_ID      = tApiDInvoice.Debtor_ID
                           tApiDInvoiceBank.BankNumber_ID          = BankNumber.BankNumber_ID
                           tApiDInvoiceBank.tcBankNumber           = BankNumber.BankNumberFormatted
                           tApiDInvoiceBank.tcBankNumberExtension  = BankNumber.BankNumberExtension
                           tApiDInvoiceBank.tcBankNumberValidation = BankNumber.BankNumberValidation
                           tApiDInvoiceBank.tcBankNumberSwiftCode  = BankNumber.BankNumberSwiftCode
                           tApiDInvoiceBank.tiBankPayFormat_ID     = BankNumber.BankPayFormat_ID
                           tApiDInvoiceBank.DInvoiceBankToPayTC    = /* Assign the value to pay equal to the amount of the invoice */
                                                                     if tApiDInvoice.DInvoiceOriginalCreditTC <> 0 and
                                                                        tApiDInvoice.DInvoiceOriginalCreditTC <> ?
                                                                     then tApiDInvoice.DInvoiceOriginalCreditTC
                                                                     else tApiDInvoice.DInvoiceOriginalDebitTC
                           tApiDInvoiceBank.tc_Rowid               =  string(rowid(BankNumber)).
                    Leave.
                end. /* for first BankNumber where */
            end. /* if not can-find (first tApiDInvoiceBank where  */
            /* Read the second best applicable banknumber that is related to this Debtor: including CompanyID without Default */
            if not can-find (first tApiDInvoiceBank where 
                                   tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid)
            then do :
                for each  BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and
                          BankNumber.BankNumberIsActive  = true
                          no-lock,        
                    each BankPayFormat where 
                         BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                         no-lock,
                    each bXBankNumber where 
                         bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID 
                         no-lock,
                    each CompanySharedSet where
                         CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                         CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                         no-lock
                         on error undo, throw :
                    create tApiDInvoiceBank.
                    assign tApiDInvoiceBank.tc_ParentRowid         = tApiDInvoice.tc_Rowid
                           tApiDInvoiceBank.tiParentObject_ID      = tApiDInvoice.Debtor_ID
                           tApiDInvoiceBank.BankNumber_ID          = BankNumber.BankNumber_ID
                           tApiDInvoiceBank.tcBankNumber           = BankNumber.BankNumberFormatted
                           tApiDInvoiceBank.tcBankNumberExtension  = BankNumber.BankNumberExtension
                           tApiDInvoiceBank.tcBankNumberValidation = BankNumber.BankNumberValidation
                           tApiDInvoiceBank.tcBankNumberSwiftCode  = BankNumber.BankNumberSwiftCode
                           tApiDInvoiceBank.tiBankPayFormat_ID     = BankNumber.BankPayFormat_ID
                           tApiDInvoiceBank.DInvoiceBankToPayTC    = /* Assign the value to pay equal to the amount of the invoice */
                                                                     if tApiDInvoice.DInvoiceOriginalCreditTC <> 0 and
                                                                        tApiDInvoice.DInvoiceOriginalCreditTC <> ?
                                                                     then tApiDInvoice.DInvoiceOriginalCreditTC
                                                                     else tApiDInvoice.DInvoiceOriginalDebitTC
                           tApiDInvoiceBank.tc_Rowid               = string(rowid(BankNumber)).  
                    Leave.
                end. /* for first BankNumber where */
            end. /* if not can-find (first tApiDInvoiceBank where  */
            /* Read the third best applicable banknumber that is related to this Debtor: including Default without CompanyID */
            if not can-find (first tApiDInvoiceBank where 
                                   tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid)
            then do :
                for first BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and
                          BankNumber.BankNumberIsActive  = true                   and 
                          BankNumber.BankNumberIsDefault = true
                          no-lock
                          on error undo, throw :
                    create tApiDInvoiceBank.
                    assign tApiDInvoiceBank.tc_ParentRowid         = tApiDInvoice.tc_Rowid
                           tApiDInvoiceBank.tiParentObject_ID      = tApiDInvoice.Debtor_ID
                           tApiDInvoiceBank.BankNumber_ID          = BankNumber.BankNumber_ID
                           tApiDInvoiceBank.tcBankNumber           = BankNumber.BankNumberFormatted
                           tApiDInvoiceBank.tcBankNumberExtension  = BankNumber.BankNumberExtension
                           tApiDInvoiceBank.tcBankNumberValidation = BankNumber.BankNumberValidation
                           tApiDInvoiceBank.tcBankNumberSwiftCode  = BankNumber.BankNumberSwiftCode
                           tApiDInvoiceBank.tiBankPayFormat_ID     = BankNumber.BankPayFormat_ID
                           tApiDInvoiceBank.DInvoiceBankToPayTC    = /* Assign the value to pay equal to the amount of the invoice */
                                                                     if tApiDInvoice.DInvoiceOriginalCreditTC <> 0 and
                                                                        tApiDInvoice.DInvoiceOriginalCreditTC <> ?
                                                                     then tApiDInvoice.DInvoiceOriginalCreditTC
                                                                     else tApiDInvoice.DInvoiceOriginalDebitTC
                           tApiDInvoiceBank.tc_Rowid               = string(rowid(BankNumber)).  
                end. /* for first BankNumber where */
            end. /* if not can-find (first tApiDInvoiceBank where  */
            /* ================================================================================================================ */
            /* In case we have created a BankNumber by now, we will also create the underlying BankNumberPayCode-records for it */
            /* ================================================================================================================ */
            Find first tApiDInvoiceBank where 
                       tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid and 
                       tApiDInvoiceBank.BankNumber_ID <> 0                     and 
                       tApiDInvoiceBank.BankNumber_ID <> ?
                       no-lock no-error.
            if available tApiDInvoiceBank
            then do :
                for each BankNumberPayCode where 
                         BankNumberPayCode.BankNumber_ID = tApiDInvoiceBank.BankNumber_ID
                         no-lock
                         on error undo, throw :
                    create tApiDInvoiceBankPayCode.
                    assign tApiDInvoiceBankPayCode.tc_ParentRowid           = tApiDInvoiceBank.tc_Rowid
                           tApiDInvoiceBankPayCode.tc_Rowid                 = string(rowid(BankNumberPayCode))
                           tApiDInvoiceBankPayCode.PayFormatGroup_ID        = BankNumberPayCode.PayFormatGroup_ID
                           tApiDInvoiceBankPayCode.PayFormatCode_ID         = BankNumberPayCode.PayFormatCode_ID
                           tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = BankNumberPayCode.BankNumberPayCodeValue.
                    if BankNumberPayCode.PayFormatGroup_ID <> 0 and 
                       BankNumberPayCode.PayFormatGroup_ID <> ? 
                    then do :
                        find PayFormatGroup where 
                             PayFormatGroup.PayFormatGroup_ID = BankNumberPayCode.PayFormatGroup_ID
                             no-lock no-error.
                        if available PayFormatGroup 
                        then assign tApiDInvoiceBankPayCode.tcPayFormatGroupCode = PayFormatGroup.PayFormatGroupCode.
                    end. /* if BankNumberPayCode.PayFormatGroup_ID <> 0 and */
                    if tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = "":U or 
                       tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = ? 
                    then do :
                        find PayFormatCode of BankNumberPayCode
                             no-lock no-error.
                        if available PayFormatCode
                        then do:
                            assign tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = PayFormatCode.PayFormatCode.
                            if tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = ? or
                               tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = "":U
                            then do :  
                                find PayFormatGroup of BankNumberPayCode where
                                     PayFormatGroup.PayFormatGroupDataType = 'LOGICAL':U
                                     no-lock no-error.
                                if available PayFormatGroup
                                then assign tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = "false":U.
                            end. /* if tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = ? or */
                        end. /* if available PayFormatCode */
                    end. /* if tApiDInvoiceBankPayCode.DInvoiceBankPayCodeValue = "":U or */
                end. /* for each BankNumberPayCode where  */
            end. /* if available tApiDInvoiceBank */
        end. /* if tApiDInvoice.Debtor_ID <> 0 and */
        
        /* ======================================================================================================== */
        /* Fill tApiDInvoiceBank.BankNumber_ID: For those tApiDInvoiceBank record where BankNumber_ID is not filled */ 
        /* then we will try to assign it with the banknumber that best matches the filled properties                */
        /* ======================================================================================================== */
        /* This is the logical sequence for finding the correct BankNumber-record in the db:                        */
        /*  Case  Act  OwnBnkNbr  BnkNbr  Cy	Def                                                                 */
        /*    1   Y	    Y/N	  Y	  Y     Y                                                                  */
        /*    2   Y	    Y/N	  Y	  Y	 N                                                                  */
        /*    3   Y	    Y/N	  Y	  N	 Y                                                                  */
        /*    4   Y	    Y/N	  Y	  N	 N                                                                  */
        /*    5   Y	    Y/N	  N	  Y	 Y                                                                  */
        /*    6   Y	    Y/N	  N	  Y	 N                                                                  */
        /*    7   Y	    Y/N	  N	  N	 Y                                                                  */
        /*    8   Y	    Y/N	  N	  N	 N                                                                  */
        /*    9   Y	     N		  N	  N	 Y                                                                  */
        /*    10  Y	     N		  N	  N	 N                                                                  */
        /* ======================================================================================================== */
        /* While we assign tApiDInvoiceBank.BankNumber_ID here and we thus have a BankNumber-record available, we   */
        /* will also assign tApiDInvoiceBank.tiBankPayFormat_ID and optionally tApiDInvoiceBank.tcPayFormatTypeCode */
        /* as well in case we have a BankPayFormat record available next to the BankNumber reocrd.                  */
        /* ======================================================================================================== */
        if tApiDInvoice.Debtor_ID <> 0 and 
           tApiDInvoice.Debtor_ID <> ? 
        then for each tApiDInvoiceBank where 
                      tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid : 
            
            /* Strip-off some formatting characters that are not stored in the db */
            assign tApiDInvoiceBank.tcBankNumber = replace(tApiDInvoiceBank.tcBankNumber, " ":U, "":U)
                   tApiDInvoiceBank.tcBankNumber = replace(tApiDInvoiceBank.tcBankNumber, ".":U, "":U)
                   tApiDInvoiceBank.tcBankNumber = replace(tApiDInvoiceBank.tcBankNumber, "/":U, "":U)
                   tApiDInvoiceBank.tcBankNumber = replace(tApiDInvoiceBank.tcBankNumber, "-":U, "":U).
            
            /* Skip record in case the BankNumber_ID is already filled */
            if tApiDInvoiceBank.BankNumber_ID <> 0 and 
               tApiDInvoiceBank.BankNumber_ID <> ? 
            then next.
            assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + chr(10) + "Out: Conversion-option used for bank-number ":U + trim(tApiDInvoiceBank.tcBankNumber) + " is: ":U.
            
            /* Try to find the correct BankNumber - first reset the IDs of the found records */
            Assign viXBankNumberID    = 0
                   viXBankPayFormatID = 0
                   viXbXBankNumberID  = 0.
            /*    1  First try finding with Active, tcOwnBankNumber, BankNbr, Company, Default */
            for each BankNumber where
                     BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID   and 
                     BankNumber.BankNumberIsActive  = true                     and 
                     BankNumber.BankNumberIsDefault = true                     and
                     BankNumber.BankNumber          = tApiDInvoiceBank.tcBankNumber 
                     no-lock,        
                each BankPayFormat where 
                     BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                     no-lock,
                each bXBankNumber where 
                     bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                     bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                      tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                   then tApiDInvoiceBank.tcOwnBankNumber
                                                   else bXBankNumber.BankNumber) 
                     no-lock,
                each CompanySharedSet where
                     CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                     CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                     no-lock 
                     on error undo, throw :
                assign viXBankNumberID    = BankNumber.BankNumber_ID
                       viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                       viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "1":U.
                Leave.
            end. /* for each BankNumber */
            /*    2  Second try finding with Active, tcOwnBankNumber, BankNbr, Company */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID   and 
                          BankNumber.BankNumberIsActive  = true                     and 
                          BankNumber.BankNumber          = tApiDInvoiceBank.tcBankNumber 
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock,
                     each CompanySharedSet where
                          CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                          CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "2":U.
                    Leave.                          
                 end. /* for each BankNumber */
            /*    3  Third try finding with Active, tcOwnBankNumber, BankNbr, Default */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID   and 
                          BankNumber.BankNumberIsActive  = true                     and 
                          BankNumber.BankNumberIsDefault = true                     and
                          BankNumber.BankNumber          = tApiDInvoiceBank.tcBankNumber 
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "3":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    4  Fourth try finding with Active, tcOwnBankNumber, BankNbr */ 
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID   and 
                          BankNumber.BankNumberIsActive  = true                     and 
                          BankNumber.BankNumber          = tApiDInvoiceBank.tcBankNumber 
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "4":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    5  Fifth try finding with Active, tcOwnBankNumber, Company, Default  */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true                   and 
                          BankNumber.BankNumberIsDefault = true  
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock,
                     each CompanySharedSet where
                          CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                          CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "5":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    6  Sixth try finding with Active, tcOwnBankNumber, Company  */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true   
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock,
                     each CompanySharedSet where
                          CompanySharedSet.CompanySharedSet_ID = bXBankNumber.CompanySharedSet_ID and 
                          CompanySharedSet.Company_ID          = tApiDInvoice.Company_ID
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "6":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    7  Seventh try finding with Active, tcOwnBankNumber, Default  */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true                   and 
                          BankNumber.BankNumberIsDefault = true  
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "7":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    8  Eighth try finding with Active, tcOwnBankNumber  */ 
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true  
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID and 
                          bXBankNumber.BankNumber    = (if tApiDInvoiceBank.tcOwnBankNumber <> "":U and 
                                                           tApiDInvoiceBank.tcOwnBankNumber <> ?
                                                        then tApiDInvoiceBank.tcOwnBankNumber
                                                        else bXBankNumber.BankNumber) 
                          no-lock 
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "8":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    9  Nineth try finding with Active, Default  */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true                   and 
                          BankNumber.BankNumberIsDefault = true  
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID
                          no-lock
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "10":U.
                    Leave.
                 end. /* for each BankNumber */
            /*    10 Tenth try finding with Active */
            if viXBankNumberID = 0
            then for each BankNumber where
                          BankNumber.ParentObject_ID     = tApiDInvoice.Debtor_ID and 
                          BankNumber.BankNumberIsActive  = true  
                          no-lock,        
                     each BankPayFormat where 
                          BankPayFormat.BankPayFormat_ID = BankNumber.BankPayFormat_ID 
                          no-lock,
                     each bXBankNumber where 
                          bXBankNumber.BankNumber_ID = BankPayFormat.BankNumber_ID
                          no-lock
                          on error undo, throw :
                    assign viXBankNumberID    = BankNumber.BankNumber_ID
                           viXBankPayFormatID = BankPayFormat.BankPayFormat_ID
                           viXbXBankNumberID  = bXBankNumber.BankNumber_ID.
                    assign vcAdditionalCTLogDetails = vcAdditionalCTLogDetails + "11":U.
                    Leave.
                 end. /* for each BankNumber */
            
            /* Fill tApiDInvoiceBank.BankNumber_ID and its 'updatable-related key-business-fields' */
            if viXBankNumberID <> 0 and 
               viXBankNumberID <> ?
            then do :
                Find BankNumber where 
                     BankNumber.BankNumber_ID = viXBankNumberID 
                     no-lock no-error.
                if available BankNumber 
                then assign tApiDInvoiceBank.BankNumber_ID         = BankNumber.BankNumber_ID
                            tApiDInvoiceBank.tiBankPayFormat_ID    = BankNumber.BankPayFormat_ID
                            tApiDInvoiceBank.tiParentObject_ID     = BankNumber.ParentObject_ID
                            tApiDInvoiceBank.tcBankNumber          = BankNumber.BankNumber
                            tApiDInvoiceBank.tcBankNumberExtension = BankNumber.BankNumberExtension.
                Find BankPayFormat where 
                     BankPayFormat.BankPayFormat_ID = viXBankPayFormatID 
                     no-lock no-error.
                if available BankPayFormat
                then assign tApiDInvoiceBank.tcPayFormatTypeCode = BankPayFormat.PayFormatTypeCode.                
                Find BankNumber where 
                     BankNumber.BankNumber_ID = viXbXBankNumberID
                     no-lock no-error.
                if available BankNumber 
                then assign tApiDInvoiceBank.tcOwnBankNumber = BankNumber.BankNumber.                
            end. /* if viXBankNumberID <> 0 and  */
            
        end. /* if tApiDInvoice.Debtor_ID <> 0 and tApiDInvoice.Debtor_ID <> ? then for each tApiDInvoiceBank where */ 
        
        /* ==================================================================================================================== */
        /* If there is only a single tApiDInvoiceBank and its amount is empty then default the amount on it from the invoice    */
        /* ==================================================================================================================== */
        Find tApiDInvoiceBank where 
             tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid 
             no-lock no-error. /* do not use the last or first option as we only want the record to be available in case there is only one for the invoice */
        if available tApiDInvoiceBank and 
           (tApiDInvoiceBank.DInvoiceBankToPayTC = 0 or
            tApiDInvoiceBank.DInvoiceBankToPayTC = ?)
        then if tApiDInvoice.DInvoiceOriginalCreditTC <> 0 and 
                tApiDInvoice.DInvoiceOriginalCreditTC <> ?
             then assign tApiDInvoiceBank.DInvoiceBankToPayTC = tApiDInvoice.DInvoiceOriginalCreditTC.
             else if tApiDInvoice.DInvoiceOriginalDebitTC <> 0 and 
                     tApiDInvoice.DInvoiceOriginalDebitTC <> ?
                  then assign tApiDInvoiceBank.DInvoiceBankToPayTC = tApiDInvoice.DInvoiceOriginalDebitTC.
        
        /* ================================================================================================ */
        /* Apply some additional defaulting on the tApiDInvoiceBank and the tApiDInvoiceBankPayCode records */
        /* ================================================================================================ */
        for each tApiDInvoiceBank where 
                 tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid :                         
            /* Fill tApiDInvoiceBank.tiBankPayFormat_ID */
            if tApiDInvoiceBank.BankNumber_ID <> 0 and 
               tApiDInvoiceBank.BankNumber_ID <> ? and 
               (tApiDInvoiceBank.tiBankPayFormat_ID = 0 or 
                tApiDInvoiceBank.tiBankPayFormat_ID = ?)
            then do :
                find BankNumber where 
                     BankNumber.BankNumber_ID = tApiDInvoiceBank.BankNumber_ID
                     no-lock no-error.
                if available BankNumber
                then assign tApiDInvoiceBank.tiBankPayFormat_ID = BankNumber.BankPayFormat_ID.
            end. /* if tApiDInvoiceBank.BankNumber_ID <> 0 and  */
            /* Fill tApiDInvoiceBank.tcPayFormatTypeCode */
            if tApiDInvoiceBank.tiBankPayFormat_ID <> 0 and 
               tApiDInvoiceBank.tiBankPayFormat_ID <> ? and 
               (tApiDInvoiceBank.tcPayFormatTypeCode = "":U or 
                tApiDInvoiceBank.tcPayFormatTypeCode = ?)
            then do :
                find BankPayFormat where 
                     BankPayFormat.BankPayFormat_ID = tApiDInvoiceBank.tiBankPayFormat_ID
                     no-lock no-error.
                if available BankPayFormat
                then assign tApiDInvoiceBank.tcPayFormatTypeCode = BankPayFormat.PayFormatTypeCode.
            end. /* if tApiDInvoiceBank.tiBankPayFormat_ID <> 0 and  */
            /* Go through the underlying tApiDInvoiceBankPayCode */
            for each tApiDInvoiceBankPayCode where 
                     tApiDInvoiceBankPayCode.tc_ParentRowid = tApiDInvoiceBank.tc_Rowid :
                /* Fill tApiDInvoiceBankPayCode.tcPayFormatGroupCode */
                if tApiDInvoiceBankPayCode.PayFormatGroup_ID <> 0 and 
                   tApiDInvoiceBankPayCode.PayFormatGroup_ID <> ? and 
                   (tApiDInvoiceBankPayCode.tcPayFormatGroupCode = "":U or 
                    tApiDInvoiceBankPayCode.tcPayFormatGroupCode = ?)
                then do :
                    find PayFormatGroup where 
                         PayFormatGroup.PayFormatGroup_ID = tApiDInvoiceBankPayCode.PayFormatGroup_ID
                         no-lock no-error.
                    if available PayFormatGroup 
                    then assign tApiDInvoiceBankPayCode.tcPayFormatGroupCode = PayFormatGroup.PayFormatGroupCode.
                end. /* if BankNumberPayCode.PayFormatGroup_ID <> 0 and */
            end. /* for each tApiDInvoiceBankPayCode where */
        end. /* for each tApiDInvoiceBank where */
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Banking-details":U,(if vcAdditionalCTLogDetails = ?    or 
                                                                           vcAdditionalCTLogDetails = "":U or
                                                                           length(vcAdditionalCTLogDetails,"character":U) < 2 
                                                                        then "":U 
                                                                        else substring(vcAdditionalCTLogDetails,2,-1,"character":U))).
        publish "Logging.BusinessCode":U  ("START-SUB,Tax-details":U,"":U).
        
        /* ================================================ */
        /* Default the VatCurrency with the InvoiceCurrency */
        /* ================================================ */
        if tApiDInvoice.tcVatCurrencyCode = "":U or 
           tApiDInvoice.tcVatCurrencyCode = ?
        then assign tApiDInvoice.tcVatCurrencyCode = tApiDInvoice.tcCurrencyCode. 
        if tApiDInvoice.tcVatCurrencyCode <> "":U     and 
           tApiDInvoice.tcVatCurrencyCode <> ?        and
           tApiDInvoice.tcCurrencyCode    <> "":U     and 
           tApiDInvoice.tcCurrencyCode    <> ?        and
           (tApiDInvoice.DInvoiceVatExchangeRate = 0 or 
            tApiDInvoice.DInvoiceVatExchangeRate = ? or 
            tApiDInvoice.DInvoiceVatRateScale    = 0 or
            tApiDInvoice.DInvoiceVatRateScale    = ?) 
        then if tApiDInvoice.tcVatCurrencyCode = vcCompanyLC
             then /* if VatCurrency=LocalCurrency then the Vat-rate equals the Invoice-rate */
                  assign tApiDInvoice.DInvoiceVatExchangeRate = tApiDInvoice.DInvoiceExchangeRate
                         tApiDInvoice.DInvoiceVatRateScale    = tApiDInvoice.DInvoiceRateScale.
             else if tApiDInvoice.tcVatCurrencyCode = tApiDInvoice.tcCurrencyCode
                  then /* if VatCurrency=Invoice-Currency then Vat-rate should be 1 */
                       assign tApiDInvoice.DInvoiceVatExchangeRate = 1
                              tApiDInvoice.DInvoiceVatRateScale    = 1.
        
        /* ====================================================================== */
        /* Fill in defaults in tApiDInvoiceVat records that are in the input      */
        /* Set the Taxable flag on the invoice-level based on the Vat-records     */
        /* ====================================================================== */
        for each tApiDInvoiceVat where 
                 tApiDInvoiceVat.tc_ParentRowid = tApiDInvoice.tc_rowid
                 on error undo, throw :
            /* Replace empty fields with default fixed values */
            if tApiDInvoiceVat.tcDomainCode = "":U or 
               tApiDInvoiceVat.tcDomainCode = ?
            then assign tApiDInvoiceVat.tcDomainCode = vcXDomainCode.
            if tApiDInvoiceVat.tcVatInOut = "":U or 
               tApiDInvoiceVat.tcVatInOut = ?
            then assign tApiDInvoiceVat.tcVatInOut =  {&VATINOUT-OUTPUT}. /* OUTPUT */               
            if tApiDInvoiceVat.DInvoiceVatSequence = 0 or 
               tApiDInvoiceVat.DInvoiceVatSequence = ?
            then assign tApiDInvoiceVat.DInvoiceVatSequence = 1.
            /* Replace unknown values with data from the tax-definitions */
            if tApiDInvoiceVat.tcVatCode <> "":U and 
               tApiDInvoiceVat.tcVatCode <> ?
            then do :
                vhXQueryTx2Mstr:Query-Prepare("for each tx2_mstr where tx2_mstr.tx2_domain = '" + vcXDomainCode + "' and " + 
                                              "tx2_mstr.tx2_tax_code = '" + tApiDInvoiceVat.tcVatCode + "'").
                vhXQueryTx2Mstr:Query-Open.
                vhXQueryTx2Mstr:Get-First(no-lock).                
                /* Additional logging in the CTLog */
                publish "Logging.DatabaseAccess":U
                   ("query Manual query on table tx2_mstr":U + chr(10) + 
                    "Query-prepare: ":U + vhXQueryTx2Mstr:prepare-string  + chr(10) +
                    "Indexes: " + vhXQueryTx2Mstr:index-information(1)  + chr(10) +
                    "record count: " + string(vhXQueryTx2Mstr:num-results) , ?).
                if valid-handle(vhXBufferTx2Mstr) and 
                   vhXBufferTx2Mstr:available 
                then do :
                    if tApiDInvoiceVat.DInvoiceVatIsUpdAllow = ?
                    then assign tApiDInvoiceVat.DInvoiceVatIsUpdAllow = vhXBufferTx2Mstr::tx2_update_tax. .
                    if tApiDInvoiceVat.DInvoiceVatIsAbsRet = ?
                    then assign tApiDInvoiceVat.DInvoiceVatIsAbsRet = vhXBufferTx2Mstr::tx2_apr_use.
                    if tApiDInvoiceVat.DInvoiceVatIsAccrRcpUs = ?  
                    then assign tApiDInvoiceVat.DInvoiceVatIsAccrRcpUs = vhXBufferTx2Mstr::tx2_rcpt_tax_point or vhXBufferTx2Mstr::tx2_usage_tax_point.
                    if tApiDInvoiceVat.DInvoiceVatIsRevCharge = ?
                    then assign tApiDInvoiceVat.DInvoiceVatIsRevCharge = vhXBufferTx2Mstr::tx2_reverse_charge.
                    if tApiDInvoiceVat.DInvoiceVatIsSuspDel = ?
                    then assign tApiDInvoiceVat.DInvoiceVatIsSuspDel = vhXBufferTx2Mstr::tx2_stx_dltx_use.
                    /* set if this tax method is Avatax or not */                   
                    if vhXBufferTx2Mstr::tx2_method = "40":U
                    then assign tApiDInvoiceVat.tlIsAvataxTaxLine = true. 
                    else assign tApiDInvoiceVat.tlIsAvataxTaxLine = false.  
                end. /* if valid-handle(vhXBufferTx2Mstr) */
            end. /* if tApiDInvoiceVat.tcVatCode <> "":U and  */
            /* Avoid unknown values */
            if tApiDInvoiceVat.TxuTaxUsage = ?
            then assign tApiDInvoiceVat.TxuTaxUsage = "":U.
            if tApiDInvoiceVat.TxenvTaxEnv = ?
            then assign tApiDInvoiceVat.TxenvTaxEnv = "":U.
            if tApiDInvoiceVat.TxclTaxCls = ?
            then assign tApiDInvoiceVat.TxclTaxCls = "":U.
            /* Set the Taxable flag on the invoice-level based on the Vat-records     */
            if ((tApiDInvoiceVat.DInvoiceVatVatDebitTC  <> 0 and 
                 tApiDInvoiceVat.DInvoiceVatVatDebitTC  <> ?) or  
                (tApiDInvoiceVat.DInvoiceVatVatCreditTC <> 0 and 
                 tApiDInvoiceVat.DInvoiceVatVatCreditTC <> ?)) and 
               (tApiDInvoice.DInvoiceIsTaxable = ? or 
                tApiDInvoice.DInvoiceIsTaxable = false)
            then assign tApiDInvoice.DInvoiceIsTaxable = true.
        end. /* for each tApiDInvoiceVat where */
        
        /* Additional logging in the CTLog */
        publish "Logging.BusinessCode":U  ("END-SUB,Tax-details":U,"":U).
        
    end. /* for each tApiDInvoice where */  
    
    
    /* ============================================== */        
    /* Actions that should be done in ALL cases       */
    /* ============================================== */         
    FINALLY:
        
        if valid-handle(vhXQueryCmMstr)
        then do:
            vhXQueryCmMstr:QUERY-CLOSE().
            delete object vhXQueryCmMstr.
        end. /* if valid-handle(vhXQueryCmMstr) */
        if valid-handle(vhXBufferCmMstr) 
        then delete object vhXBufferCmMstr.
        if valid-handle(vhXBufferLsMstr) 
        then delete object vhXBufferLsMstr.
        if valid-handle(vhXBufferSiMstr) 
        then delete object vhXBufferSiMstr.
        if valid-handle(vhXBufferAdMstr) 
        then delete object vhXBufferAdMstr.
        
        if valid-handle(vhXQueryTx2Mstr)
        then do:
            vhXQueryTx2Mstr:QUERY-CLOSE().
            delete object vhXQueryTx2Mstr.
        end. /* if valid-handle */
        if valid-handle(vhXBufferTx2Mstr) 
        then delete object vhXBufferTx2Mstr.
                
    END FINALLY.