project QadFinancials > class BDInvoice > method ApiStdMaintainTTWithIntPost

Description

This method is a submethod of ApiStdMaintainTT.

This method just creates the invoice itself, the DI Posting (can be taxable) and the movement record, based on the input temp-table.
Following tables will be updated : DInvoice, DInvoicePosting, DInvoiceVat, DInvoiceMovement
(The balance and the status will also be updated.)


Parameters


icActioninputcharacterThis parameter defines what should happen with the input data : -SAVE: Save the data if there were no errors, -SAVESTORE : Save the data if there were no errors. If there were errors, save as draft. -STORE : Save the data as draft -VALIDATE : Validate the input data, but do no save the data.
bcLstPrimKeyinput-outputcharacterCharacter 4 separated list with the primary keys of the newly created main-table records. The fields of the primary key are separated with Character 2.
bcLstRowIdinput-outputcharacterChar 4 separated list with the temporarely rowids (negative for new ones) of the newly created main-table records.
bcLstReturninput-outputcharacterChar 4 separated list with the return status of the newly created main-table records. Zero means not errors occurred.
olSaveAsDraftoutputlogicalOutput parameter that keeps if the data is saved as draft or not
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BDInvoice.ApiStdMaintainTT


program code (program9/bdinvoice.p)

assign oiReturnStatus = -98.
empty temp-table tDIOpenBalance.

/* Copy the content of tApiDInvoiceVat to tApiStdDInvoiceVat as tApiDInvoiceVat will be overwritten later on by the methods called from this method while method ApiStdMaintainTTWithIntPostCreateVat uses tApiStdDInvoiceVat to create the correct taxes when they were provided by the caller of this api */
empty temp-table tApiStdDInvoiceVat.
for each tApiDInvoiceVat no-lock:
    create tApiStdDInvoiceVat.
    buffer-copy tApiDInvoiceVat to tApiStdDInvoiceVat.
end. /* for each tApiDInvoiceVat no-lock: */

/* Initialise: Validate the value for the Company */
/* Replace unknown values             */
assign vlWarningsFound = false.
if tApiDInvoice.Company_ID <> 0 and tApiDInvoice.Company_ID <> ? and tApiDInvoice.Company_ID <> viCompanyId
then do:
    assign vcMessage      = trim(substitute(#T-28'The entity of the customer invoice (&1) must match the current entity (&2).':255(14472)T-28#, string(tApiDInvoice.Company_ID),string(viCompanyId)))
           oiReturnStatus = -1
           bcLstReturn    = bcLstReturn  + chr(4) + string(-1)
           bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
           bcLstRowid     = bcLstRowid   + chr(4) + "*":U
           vlSaveAsDraft  = false.
    <M-29 run SetMessage
       (input  vcMessage (icMessage), 
        input  '':U (icArguments), 
        input  '':U (icFieldName), 
        input  '':U (icFieldValue), 
        input  'E':U (icType), 
        input  3 (iiSeverity), 
        input  '':U (icRowid), 
        input  'QADFIN-3366':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
    Return.
end.
assign tApiDInvoice.Company_ID = viCompanyId.    
if tApiDInvoice.Debtor_ID = ? then assign tApiDInvoice.Debtor_ID = 0.
if tApiDInvoice.tcDebtorCode = ? then assign tApiDInvoice.tcDebtorCode = "":U.
if tApiDInvoice.DInvoiceType = ? then assign tApiDInvoice.DInvoiceType = "":U.
 
/* Create tOpenBalance record that will be used for a call to a submethod */
create tDIOpenBalance.
assign tDIOpenBalance.tiCompanyId                  = tApiDInvoice.Company_ID
       tDIOpenBalance.tcAction                     = icAction 
       tDIOpenBalance.tcDebtorCode                 = tApiDInvoice.tcDebtorCode
       tDIOpenBalance.tcInvoiceType                = tApiDInvoice.DInvoiceType
       tDIOpenBalance.tiPeriodYear                 = tApiDInvoice.DInvoicePostingYear
       tDIOpenBalance.tiPeriodPeriod               = tApiDInvoice.DInvoicePostingPeriod
       tDIOpenBalance.tcJournalCode                = tApiDInvoice.tcJournalCode
       tDIOpenBalance.tiInvoiceVoucher             = tApiDInvoice.DInvoiceVoucher
       tDIOpenBalance.ttInvoiceDate                = tApiDInvoice.DInvoiceDate
       tDIOpenBalance.ttPostingDate                = tApiDInvoice.DInvoicePostingDate
       tDIOpenBalance.tcPostingType                = if tApiDInvoice.DInvoiceOriginalDebitTC <> 0 and tApiDInvoice.DInvoiceOriginalDebitTC <> ? then {&POSTINGTYPE-DEBIT} else {&POSTINGTYPE-CREDIT}
       tDIOpenBalance.tcPostingText                = if tApiDInvoice.DInvoiceDescription = "":U or tApiDInvoice.DInvoiceDescription = ?
                                                     then trim(#T-23'Customer Invoice Import':40(999890045)T-23#)
                                                     else substring(tApiDInvoice.DInvoiceDescription,1,40,"Character":U)
       tDIOpenBalance.tdInvoiceAmountTC            = if tApiDInvoice.DInvoiceOriginalDebitTC <> 0 and tApiDInvoice.DInvoiceOriginalDebitTC <> ? then tApiDInvoice.DInvoiceOriginalDebitTC else tApiDInvoice.DInvoiceOriginalCreditTC
       tDIOpenBalance.tdInvoiceAmountLC            = if tApiDInvoice.DInvoiceOriginalDebitLC <> 0 and tApiDInvoice.DInvoiceOriginalDebitLC <> ? then tApiDInvoice.DInvoiceOriginalDebitLC else tApiDInvoice.DInvoiceOriginalCreditLC
       tDIOpenBalance.tdExchangeRateTCLC           = tApiDInvoice.DInvoiceExchangeRate
       tDIOpenBalance.tdExchangeRateScale          = tApiDInvoice.DInvoiceRateScale
       tDIOpenBalance.tdExchangeRateTCCC           = tApiDInvoice.DInvoiceCCRate
       tDIOpenBalance.tdCCExchangeRateScale        = tApiDInvoice.DInvoiceCCScale
       tDIOpenBalance.tcTCCurrencyCode             = tApiDInvoice.tcCurrencyCode
       tDIOpenBalance.ttInvoiceTaxPointDate        = tApiDInvoice.DInvoicePostingDate
       tDIOpenBalance.tcProjectCode                = tApiDInvoice.tcProjectCode
       tDIOpenBalance.tcReasonCode                 = tApiDInvoice.tcReasonCode
       tDIOpenBalance.tcCostCentreCode             = tApiDInvoice.tcCostCentreCode
       tDIOpenBalance.tcInvoiceReference           = trim(tDIOpenBalance.tcPostingText) + " (":U + trim(string(today)) + " - ":U + trim(string(tDIOpenBalance.tdInvoiceAmountTC)) + ")":U
       tDIOpenBalance.tcInvoiceDescription         = if tApiDInvoice.DInvoiceDescription = "":U or tApiDInvoice.DInvoiceDescription = ?
                                                     then substring(tDIOpenBalance.tcInvoiceReference,1,40,"Character":U)
                                                     else substring(tApiDInvoice.DInvoiceDescription,1,40,"Character":U)
       tDIOpenBalance.tcNormalPaymentConditionCode = tApiDInvoice.tcNormalPaymentConditionCode
       tDIOpenBalance.tcKey                        = "KEY":U
       tDIOpenBalance.tcDivisionCode               = tApiDInvoice.tcDivisionCode.
  
/* Get the AVRCode of the current company (used te retrieve the VAT-defaults */
assign 
    vcShipFromTaxZone     = tApiDInvoice.tcShipFromTaxZone
    vcShipFromCountryCode = tApiDInvoice.tcShipFromCountryCode
    vlShipFromIsEUCountry = tApiDInvoice.tlShipFromCountryIsEUCountry
    viShipFromAddressID   = tApiDInvoice.ShipFromAddress_ID.
    
<Q-1 run CompanyPropertyByBusinessRel (first) (Read) (NoCache)
   (input tDIOpenBalance.tiCompanyId, (CompanyId)
    input ?, (AddressType)
    output dataset tqCompanyPropertyByBusinessRel) in BCompanyProperty >
find first tqCompanyPropertyByBusinessRel no-error.
if available tqCompanyPropertyByBusinessRel
then do:
    <Q-2 run VatNumberByIdBusRelCntryVat (first) (Read) (NoCache)
       (input ?, (BusinessRelationId)
        input ?, (IdentityCountryId)
        input ?, (IdentityCountryCode)
        input tqCompanyPropertyByBusinessRel.tcVatNumberIdentity, (VatNumberIdentity)
        input tqCompanyPropertyByBusinessRel.tiVatNumber_ID, (VatNumberId)
        input ?, (VatNumberIsActive)
        output dataset tqVatNumberByIdBusRelCntryVat) in BBusinessRelation >
    find first tqVatNumberByIdBusRelCntryVat no-error.
    assign vcCompanyAVRCode      = if available tqVatNumberByIdBusRelCntryVat then tqVatNumberByIdBusRelCntryVat.tcBusinessRelationAVRCode else "":U
           vcShipFromTaxZone     = tqCompanyPropertyByBusinessRel.tcTxzTaxZone when vcShipFromTaxZone = "":U or vcShipFromTaxZone = ?
           viShipFromAddressID   = tqCompanyPropertyByBusinessRel.tiAddress_ID when viShipFromAddressID = 0 or viShipFromAddressID = ?
           vcShipFromCountryCode = tqCompanyPropertyByBusinessRel.tcAddressCountryCode when vcShipFromCountryCode = "":U or vcShipFromCountryCode = ?
           vlShipFromIsEUCountry = tqCompanyPropertyByBusinessRel.tlIdentityIsEUCountry when vlShipFromIsEUCountry = ?.
end.

/* Get some values from the debtor */
assign 
    vcShipToCountryCode  = tApiDInvoice.tcShipToCountryCode.
    
if tApiDInvoice.Company_ID   <> 0    and tApiDInvoice.Company_ID   <> ? and
   tApiDInvoice.tcDebtorCode <> "":U and tApiDInvoice.tcDebtorCode <> ?
then do:
    <Q-3 run DebtorByDebtor (first) (Read) (NoCache)
       (input tApiDInvoice.Company_ID, (CompanyId)
        input {&ADDRESSTYPECODESYSTEM-HEADOFFICE}, (AddressType)
        input tApiDInvoice.Debtor_ID, (DebtorId)
        input tApiDInvoice.tcDebtorCode, (DebtorCode)
        output dataset tqDebtorByDebtor) in BDebtor>
    find first tqDebtorByDebtor no-error.
    if available tqDebtorByDebtor
    then do:
        assign tDIOpenBalance.tcBusinessRelationCode = tqDebtorByDebtor.tcBusinessRelationCode
               vcVatDeliveryType                   = tqDebtorByDebtor.tcVatDeliveryType
               vcVatPercentageLevel                = tqDebtorByDebtor.tcVatPercentageLevel
               vcTxclTaxClass                      = tqDebtorByDebtor.tcTxclTaxCls
               vcTxuTaxUsage                       = tqDebtorByDebtor.tcTxuTaxUsage
               vcDebtorCode                        = tqDebtorByDebtor.tcDebtorCode
               vlAddressIsTaxInCity                = tqDebtorByDebtor.tlAddressIsTaxInCity
               vcShipToTaxZone                     = tqDebtorByDebtor.tcTxzTaxZone
               vcShipToCountryCode                 = tqDebtorByDebtor.tcCountryCode when vcShipToCountryCode = "":U or vcShipToCountryCode = ?
               vlShipToIsEUCountry                 = tqDebtorByDebtor.tlCountryIsEUCountry
               viShipToAddressID                   = tqDebtorByDebtor.tiAddress_ID
               vcDebtorTaxZone                     = tqDebtorByDebtor.tcTxzTaxZone.
               
        /* Get AVRCode */
        <Q-4 run AddressByAddressBusRelType (all) (Read) (NoCache)
           (input ?, (AddressTypeId)
            input {&ADDRESSTYPECODESYSTEM-HEADOFFICE}, (AddressTypeCode)
            input tqDebtorByDebtor.tiBusinessRelation_ID, (BusinessRelationId)
            input tqDebtorByDebtor.tcBusinessRelationCode, (BusinessRelationCode)
            input ?, (AddressId)
            output dataset tqAddressByAddressBusRelType) in BBusinessRelation >
        find first tqAddressByAddressBusRelType no-error.
        if available tqAddressByAddressBusRelType
        then assign vcDebtorAVRCode = tqAddressByAddressBusRelType.tcBusinessRelationAVRCode.
        /* Get division */
        if (tDIOpenBalance.tcDivisionCode = "":U or tDIOpenBalance.tcDivisionCode = ?) and 
           tqDebtorByDebtor.tiDivisionProfile_ID <> ? and tqDebtorByDebtor.tiDivisionProfile_ID <> 0
        then do:
            <Q-5 run GetDivisionFromProfile (all) (Read) (NoCache)
               (input tApiDInvoice.Company_ID, (CompanyId)
                input tqDebtorByDebtor.tiDivisionProfile_ID, (DivisionProfileId)
                output dataset tqDivisionFromProfile) in BProfile >
            find first tqDivisionFromProfile no-error.
            if available tqDivisionFromProfile
            then assign tDIOpenBalance.tcDivisionCode = tqDivisionFromProfile.tcDivisionCode.
        end.
        /* Get the Payment-conditions from the Debtor */
        if tApiDInvoice.tcNormalPaymentConditionCode   = "":U or tApiDInvoice.tcNormalPaymentConditionCode   = ? 
        then assign tDIOpenBalance.tcNormalPaymentConditionCode   = (if tDIOpenBalance.tcNormalPaymentConditionCode   = "":U or tDIOpenBalance.tcNormalPaymentConditionCode   = ? then tqDebtorByDebtor.tcNormalPaymentConditionCode else tDIOpenBalance.tcNormalPaymentConditionCode).
   
        /* Get the bank information if the debtor uses directdebit payment instruments */
        assign vhFcComponent = ?.
        <M-47 run GetParentBankData
           (input  viCompanyID (iiCompanyID), 
            input  ? (icCreditorCode), 
            input  tqDebtorByDebtor.tcDebtorCode (icDebtorCode), 
            input  {&PAYFORMATPAYINSTRUMENT-DIRECTDEBIT} (icPaymentInstrument), 
            output tDIOpenBalance.tiBankNumber_ID (oiBankNumberID), 
            output tDIOpenBalance.tcBankNumber (ocBankNumber), 
            output tDIOpenBalance.tcBankNumberExtension (ocBankNumberExtension), 
            input  ? (icOwnBankNumber), 
            input  ? (icGLCode), 
            output viFcReturnSuper (oiReturnStatus)) in BBankNumber>
        
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                       bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
                return.
            end.
            else assign vlWarningsFound = true.
        end.
    end.
end.

/* Calculate due dates */
<M-38 run ApiStdMaintainTTWithIntPostDates  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
if viFcReturnSuper <> 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    if oiReturnStatus < 0
    then do: 
        assign olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
               bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
               bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
               bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
        return.
    end.
    else assign vlWarningsFound = true.
end.

/* if the invoice is Taxable using an Avatax environment and the tax records have been
   submitted, then throw and error, as tax should always be calculated by the Avatax 
   tax engine in that situation.
   NOTE: current functionality disgards the incoming DInvoiceVat records and creates
   them from the defaults - however if this is fixed this check will ensure the correct action */
if tApiDInvoice.DInvoiceIsTaxable = true and vlAvataxIsActive = true
then do:
    /* passed in vat records specify avatax */
    find first tApiDInvoiceVat where tApiDInvoiceVat.tlIsAvataxTaxLine = true no-error.
    
    if available tApiDInvoiceVat 
    then do:        
        assign 
            vcMessage      = #T-60'This invoice uses an Avatax tax environment.  Therefore the tax records cannot be submitted in this API':255(285713906)T-60# 
            oiReturnStatus = -1
            bcLstReturn    = bcLstReturn  + chr(4) + string(-1)
            bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
            bcLstRowid     = bcLstRowid   + chr(4) + "*":U
            vlSaveAsDraft  = false.
        <M-54 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  '':U (icFieldName), 
            input  '':U (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  '':U (icRowid), 
            input  'qadfin-457871':U (icFcMsgNumber), 
            input  '' (icFcExplanation), 
            input  '' (icFcIdentification), 
            input  '' (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        return.
    end. /* if available tApiDInvoiceVat */
end. /* if tApiDInvoice.DInvoiceIsTaxable */

/* Call a submethod that will create the debtor invoices   */
/* Result: DInvoice, DInvoicePosting and DInvoiceMovement records created */
<M-11 run CreateDInvoices
   (input-output tDIOpenBalance (tDIOpenBalance), 
    input  0 (iiBJournalEntryId), 
    input  0 (iiPostingId), 
    output vcListNewInvoices (ocNewRecordInfo), 
    output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
if viFcReturnSuper <> 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    if oiReturnStatus < 0
    then do: 
        assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
               bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
               bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
               bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
        return.
    end.
    else assign vlWarningsFound = true.
end.

/* Search the debtor invoice that you have just created */
assign viListNewInvoices = integer(entry(2,vcListNewInvoices)) no-error.
if error-status:error = false
then find first tDInvoice where
                tDInvoice.DInvoice_ID = viListNewInvoices
                no-error.
if error-status:error = true or 
   not available tDInvoice
then do:
    assign vcMessage      = trim(substitute(#T-31'A customer invoice integration error ocurred. The call to method &1 (method that initiates the invoice) returned unexpected information.':255(264196006)T-31#, "CreateDInvoices":U)) + chr(10) + 
                            trim(substitute(#T-32'Data returned: &1.':255(14497)T-32#,viListNewInvoices)) 
           oiReturnStatus = -1
           bcLstReturn    = bcLstReturn  + chr(4) + string(-1)
           bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
           bcLstRowid     = bcLstRowid   + chr(4) + "*":U
           vlSaveAsDraft  = false.
    if error-status:error         = true and 
       error-status:num-messages >= 1
    then assign vcMessage = vcMessage + chr(10) + ERROR-STATUS:GET-MESSAGE(1).
    <M-30 run SetMessage
       (input  vcMessage (icMessage), 
        input  '':U (icArguments), 
        input  '':U (icFieldName), 
        input  '':U (icFieldValue), 
        input  'E':U (icType), 
        input  3 (iiSeverity), 
        input  '':U (icRowid), 
        input  'QADFIN-3379':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
    return.
end.

/* By calling CreateDInvoices, a single tDInvoiceBank-record has been created                                      */
/* But if there are tApiDInvoiceBank-records for the tApiDInvoice then we should use the data on                   */
/* the tApiDInvoiceBank-records and not the default ones that were created in CreateDInvoices                      */
/* Note: this is not just about the DInvoiceBank-records but also about the underlying DInvoiceBankPayCode-records */
if can-find (first tApiDInvoiceBank where 
                   tApiDInvoiceBank.tc_ParentRowid  = tApiDInvoice.tc_Rowid and 
                   tApiDInvoiceBank.tc_status      <> "D":U)
then do :
    /* Remove the default tDInvoiceBank-records that were created by CreateDInvoices */
    for each tDInvoiceBank where 
             tDInvoiceBank.tc_ParentRowid  = tDInvoice.tc_Rowid and 
             tDInvoiceBank.tc_Status       = "N":U : 
        for each tDInvoiceBankPayCode where 
                 tDInvoiceBankPayCode.tc_ParentRowid = tDInvoiceBank.tc_Rowid and 
                 tDInvoiceBankPayCode.tc_Status      = "N":U : 
            delete tDInvoiceBankPayCode .
        end. /* for each tDInvoiceBankPayCode where */
        delete tDInvoiceBank.
    end. /* for each tDInvoiceBank where */
    /* Create new tDInvoiceBank-records based upon the tApiDInvoiceBank-records */
    for each tApiDInvoiceBank where
             tApiDInvoiceBank.tc_ParentRowid = tApiDInvoice.tc_Rowid
             by tApiDInvoiceBank.tc_Rowid :
        <M-53 run AddDetailLine
           (input  'DInvoiceBank':U (icTable), 
            input  tDInvoice.tc_Rowid (icParentRowid), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                       bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
                return.
            end. /* if oiReturnStatus < 0 */
            else assign vlWarningsFound = true.
        end. /* if viFcReturnSuper <> 0 */
        buffer-copy tApiDInvoiceBank
             except tApiDInvoiceBank.DInvoiceBank_ID
                    tApiDInvoiceBank.DInvoice_ID
                    tApiDInvoiceBank.tc_ParentRowid
                    tApiDInvoiceBank.tc_Rowid
                    tApiDInvoiceBank.tc_Status
                 to tDInvoiceBank.
        for each tApiDInvoiceBankPayCode where
                 tApiDInvoiceBankPayCode.tc_ParentRowid = tApiDInvoiceBank.tc_Rowid
                 by tApiDInvoiceBankPayCode.tc_Rowid :
            <M-51 run AddDetailLine
               (input  'DInvoiceBankPayCode':U (icTable), 
                input  tDInvoiceBank.tc_Rowid (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
            if viFcReturnSuper <> 0
            then do:
                assign oiReturnStatus = viFcReturnSuper.
                if oiReturnStatus < 0
                then do: 
                    assign olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                           bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                           bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                           bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
                    return.
                end. /* if oiReturnStatus < 0 */
                else assign vlWarningsFound = true.
            end. /* if viFcReturnSuper <> 0 */
            buffer-copy tApiDInvoiceBankPayCode
                 except tApiDInvoiceBankPayCode.DInvoiceBankPayCode_ID
                        tApiDInvoiceBankPayCode.DInvoiceBank_ID
                        tApiDInvoiceBankPayCode.PayFormatCode_ID
                        tApiDInvoiceBankPayCode.PayFormatGroup_ID                    
                        tApiDInvoiceBankPayCode.tc_ParentRowid
                        tApiDInvoiceBankPayCode.tc_Rowid
                        tApiDInvoiceBankPayCode.tc_Status
                     to tDInvoiceBankPayCode.
        end. /* for each tApiDInvoiceBankPayCode where */
    end. /* for each tApiDInvoiceBank where */
end. /* if can-find (first tApiDInvoiceBank where  */

/* Copy all data into the new cinvoice                                                         */
/* Before continuing, we copy the primary-key-fields of the main table to the input parameters */
/* This is just to hold it there so it can be assigned to ocPrimKey if the save succeeds. This */
/* is done because tDInvoice is no longer available after the save. We use ocRowid in stead    */
assign vcDInvoiceRowId          = tDInvoice.tc_Rowid
       vcCommitNumber           = vcCommitNumber + ",":U + tDInvoice.tc_Rowid
       tDInvoice.tcReasonCode   = tApiDInvoice.tcReasonCode
       tApiDInvoice.DInvoice_ID = tDInvoice.DInvoice_ID.
<Q-43 run CurrencyByCode (all) (Read) (NoCache)
   (input tDInvoice.tcCurrencyCode, (CurrencyCode)
    output dataset tqCurrencyByCode) in BCurrency >
find first tqCurrencyByCode no-error.

/* Copy the is taxable-flag from the input into the newly created DI */
if tApiDInvoice.DInvoiceIsTaxable <> ? 
then assign tDInvoice.DInvoiceIsTaxable = tApiDInvoice.DInvoiceIsTaxable.

/* Copy the is tax excluded-flag from the input into the newly created DI */
if tApiDInvoice.DInvoiceIsTaxExcluded <> ? 
then assign tDInvoice.DInvoiceIsTaxExcluded = tApiDInvoice.DInvoiceIsTaxExcluded .

/* Handling the taxes */
if /* The taxes where passed as input */ 
   can-find(first tApiStdDInvoiceVat where
                  tApiStdDInvoiceVat.tc_ParentRowid = tApiDInvoice.tc_Rowid) or
   /* The caller marked the invoice as taxable but did not pass any taxes so the default ones should be used */ 
   (tDInvoice.DInvoiceIsTaxable = true and 
    not can-find (first tApiStdDInvoiceVat) )
then do:      
    /* Remove previously created default records */
    for each tDInvoiceVat where
             tDInvoiceVat.tc_ParentRowid = tDInvoice.tc_Rowid:
        if tDInvoiceVat.tc_Status = "N"
        then delete tDInvoiceVat.
        else assign tDInvoiceVat.tc_Status = "D".     
    end. /* for each tDInvoiceVat where */
    /* If the caller marked the invoice as taxable but did not pass any taxes meaning the default taxes should be used */ 
    /* Then we will first get the default taxes by calling DefaultValuesTax() that stores these taxes in tDInvoiceVat and then copy tDInvoiceVat into tApiStdDInvoiceVat */
    if tDInvoice.DInvoiceIsTaxable = true and 
        not can-find (first tApiStdDInvoiceVat) 
    then do :
        assign vdInvoiceAmountTC = if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} or 
                                      tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION}
                                   then tDInvoice.DInvoiceOriginalDebitTC 
                                   else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} or 
                                           tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} 
                                        then tDInvoice.DInvoiceOriginalCreditTC 
                                        else 0.
        <M-79 run DefaultValuesTax
           (input  tDInvoice.DInvoice_ID (iiDinvoiceId), 
            input  tDInvoice.tcCurrencyCode (icCurrencyCode), 
            input  tDInvoice.DInvoiceVoucher (icDocumentReference), 
            input  tDInvoice.DInvoiceTaxPointDate (itTaxPointDate), 
            input  vcShipFromTaxZone (icShipFromTaxZone), 
            input  vcShipToTaxZone (icShipToTaxZone), 
            input  tDInvoice.tcDebtorCode (icDebtorCode), 
            input  vcTxclTaxClass (icTxclTaxClass), 
            input  vcTxuTaxUsage (icTxuTaxUsage), 
            input  vdInvoiceAmountTC (idInvoiceAmountTC), 
            input  tDInvoice.DInvoiceExchangeRate (idExchangeRate), 
            input  tDInvoice.DInvoiceRateScale (idExchangeRateScale), 
            input  tDInvoice.tcNormalPaymentConditionCode (icPaymentConditionCode), 
            input  tDInvoice.DInvoicePostingDate (itPostingDate), 
            input  tDInvoice.DInvoiceIsTaxable (ilTaxable), 
            input  tDInvoice.DInvoiceIsTaxExcluded (ilDInvoiceIsTaxExcluded), 
            input  tDInvoice.DInvoiceType (icInvoiceType), 
            input  ? (ilShipToAddressIsTaxInCity), 
            input  tDInvoice.DInvoiceVatExchangeRate (idVatExchangeRate), 
            input  tDInvoice.DInvoiceVatRateScale (idVatRateScale), 
            input  tDInvoice.DInvoiceCCRate (idCCExchangeRate), 
            input  tDInvoice.DInvoiceCCScale (idCCExchangeRateScale), 
            input  viShipToAddressID (iiShipToAddressID), 
            input  viShipFromAddressID (iiShipFromAddressID), 
            output vcTaxEnv (ocTxenvTaxEnv), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>   
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign vcMessage     = trim(substitute(#T-615'An error (&1) occurred when saving the tax details of the new customer invoices. See other messages for further details.':255(1802)T-615#,string(viFcReturnSuper)))
                       olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                       bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
                <M-83 run SetMessage
                   (input  vcMessage (icMessage), 
                    input  '':U (icArguments), 
                    input  '':U (icFieldName), 
                    input  '':U (icFieldValue), 
                    input  'E':U (icType), 
                    input  3 (iiSeverity), 
                    input  '':U (icRowid), 
                    input  'qadfin-930664':U (icFcMsgNumber), 
                    input  '' (icFcExplanation), 
                    input  '' (icFcIdentification), 
                    input  '' (icFcContext), 
                    output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
                return.
            end. /*  if oiReturnStatus < 0 */
            else assign vlWarningsFound = true.
        end. /* if viFcReturnSuper <> 0 */
        /* Copy tDInvoiceVat into tApiStdDInvoiceVat as that will be used by the next call to ApiStdMaintainTTWithIntPostCreateVat */
        for each tDInvoiceVat :
            create tApiStdDInvoiceVat.
            buffer-copy tDInvoiceVat to tApiStdDInvoiceVat.
            /* Remove previously created records */
            if tDInvoiceVat.tc_Status = "N"
            then delete tDInvoiceVat.
            else assign tDInvoiceVat.tc_Status = "D":U.
        end. /* for each tDInvoiceVat  */
    end. /*     if tDInvoice.DInvoiceIsTaxable = true and  */
    /* Call the method that will Loop through the tApiStdDInvoiceVat records and create tDInvoiceVat for it and that will call CreateDIPosting so the posting gets corrected based upon the taxes */
    <M-96 run ApiStdMaintainTTWithIntPostCreateVat
       (input  tDInvoice.tc_Rowid (icDInvoiceRowid), 
        output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
    if viFcReturnSuper <> 0
    then do:
        assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then do: 
            assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                   bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                   bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
                   bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
            return.
        end. /* if oiReturnStatus < 0 */
        else assign vlWarningsFound = true.
    end. /* if viFcReturnSuper <> 0 */
end. /* if /* The taxes where passed as input */ */
else do :
    <M-42 run DefaultValuesTax
       (input  tDInvoice.DInvoice_ID (iiDinvoiceId), 
        input  tDInvoice.tcCurrencyCode (icCurrencyCode), 
        input  tDInvoice.DInvoiceVoucher (icDocumentReference), 
        input  tDInvoice.DInvoiceTaxPointDate (itTaxPointDate), 
        input  vcShipFromTaxZone (icShipFromTaxZone), 
        input  vcShipToTaxZone (icShipToTaxZone), 
        input  tDInvoice.tcDebtorCode (icDebtorCode), 
        input  vcTxclTaxClass (icTxclTaxClass), 
        input  vcTxuTaxUsage (icTxuTaxUsage), 
        input  if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} then tDInvoice.DInvoiceOriginalDebitTC else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} then tDInvoice.DInvoiceOriginalCreditTC else 0 (idInvoiceAmountTC), 
        input  tDInvoice.DInvoiceExchangeRate (idExchangeRate), 
        input  tDInvoice.DInvoiceRateScale (idExchangeRateScale), 
        input  tDInvoice.tcNormalPaymentConditionCode (icPaymentConditionCode), 
        input  tDInvoice.DInvoicePostingDate (itPostingDate), 
        input  tDInvoice.DInvoiceIsTaxable (ilTaxable), 
        input  tDInvoice.DInvoiceIsTaxExcluded (ilDInvoiceIsTaxExcluded), 
        input  tDInvoice.DInvoiceType (icInvoiceType), 
        input  ? (ilShipToAddressIsTaxInCity), 
        input  tDInvoice.DInvoiceVatExchangeRate (idVatExchangeRate), 
        input  tDInvoice.DInvoiceVatRateScale (idVatRateScale), 
        input  tDInvoice.DInvoiceCCRate (idCCExchangeRate), 
        input  tDInvoice.DInvoiceCCScale (idCCExchangeRateScale), 
        input  viShipToAddressID (iiShipToAddressID), 
        input  viShipFromAddressID (iiShipFromAddressID), 
        output vcTaxEnv (ocTxenvTaxEnv), 
        output viFcReturnSuper (oiReturnStatus)) in BDInvoice>   
    if viFcReturnSuper <> 0
    then do:
        assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then do: 
            assign vcMessage     = trim(substitute(#T-33'An error (&1) occurred when saving the tax details of the new customer invoices. See other messages for further details.':255(1802)T-33#,string(viFcReturnSuper)))
                   olSaveAsDraft = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                   bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                   bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                   bcLstRowid    = bcLstRowid   + chr(4) + "*":U.
            <M-34 run SetMessage
               (input  vcMessage (icMessage), 
                input  '':U (icArguments), 
                input  '':U (icFieldName), 
                input  '':U (icFieldValue), 
                input  'E':U (icType), 
                input  3 (iiSeverity), 
                input  '':U (icRowid), 
                input  'QADFIN-3380':U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
            return.
        end. /*  if oiReturnStatus < 0 */
        else assign vlWarningsFound = true.
    end. /* if viFcReturnSuper <> 0 */
    
    if vlAvataxIsActive = true and 
       tApiDInvoice.DInvoiceIsTaxable = true
    then do:
        /* Does this invoice uses Avatax environment? */
        find first tApiDInvoiceVat where 
                   tApiDInvoiceVat.tlIsAvataxTaxLine = true 
                   no-error.
        if available tApiDInvoiceVat 
        then assign tApiDInvoice.DInvoiceIsExternal = false.    
    end. /* if tApiDInvoice.DInvoiceIsTaxable */

    /* Call a submethod that will create the PostingVat records */
    find first tDInvoicePosting where
               tDInvoicePosting.DInvoice_ID = tDInvoice.DInvoice_ID
               no-error.
    if available tdinvoiceposting and 
       (tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} or 
        tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or 
        tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE}) and
       tDInvoice.DInvoiceIsTaxable = true
    then do:  
        empty temp-table tDIAccount. 
        assign vcPostingTcRowid = "":U
               vdAmountTC       = if tdinvoice.dinvoicetype = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then tDInvoice.DInvoiceOriginalDebitTC else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} or tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} then tDInvoice.DInvoiceOriginalCreditTC else 0
               vdAmountLC       = if tdinvoice.dinvoicetype = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then tDInvoice.DInvoiceOriginalDebitLC else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} or tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} then tDInvoice.DInvoiceOriginalCreditLC else 0
               vdAmountCC       = if tdinvoice.dinvoicetype = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then tDInvoice.DInvoiceOriginalDebitCC else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} or tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTECORRECTION} then tDInvoice.DInvoiceOriginalCreditCC else 0
               vdDebitAmountTC  = if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then 0 else vdAmountTC 
               vdCreditAmountTC = if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then vdAmountTC else 0.
        if viBJournalEntryDIID <> 0 
        then do:
            if valid-handle(vhBJournalEntryDIInst) = false
            then do:
                <I-41 {bFcOpenInstance
                     &CLASS           = "BJournalEntry"}>
            end.
            <M-40 run PassRowIdBasedOnPostingIdInInstance
               (input  tDInvoicePosting.Posting_ID (iiPostingId), 
                output vcPostingTcRowid (ocPostingRowId), 
                output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
        end.
        assign viControlGLProfileId = if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} or tDInvoice.DInvoiceType = {&INVOICETYPE-FINANCECHARGE} or tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION} then tqDebtorByDebtor.tiInvControlGLProfile_ID else tqDebtorByDebtor.tiCnControlGLProfile_ID .
        <Q-45 run ProfileLinkByGL (all) (Read) (NoCache)
           (input viControlGLProfileId, (GlProfileId)
            input viCompanyId, (CompanyId)
            output dataset tqProfileLinkByGL) in BProfile >
        find first tqProfileLinkByGL no-error.
        
        /* This method creates PostingLineVat records based upon the tApiDInvoiceVat records */
        <M-44 run CreateDIPostingTax
           (input  vcPostingTcRowid (icRowId), 
            input  tDInvoicePosting.Posting_ID (iiPostingId), 
            input  tDInvoice.DInvoiceTaxPointDate (itTaxPointDate), 
            input  tDInvoice.DInvoiceDIText (icDIText), 
            input  tDInvoice.tcCurrencyCode (icCurrencyCode), 
            input  tDInvoice.DInvoiceCurrency_ID (iiCurrencyId), 
            input  {&EXCHANGERATETYPE-ACCOUNTING} (icExchangeRateType), 
            input  tDInvoice.DInvoiceExchangeRate (idExchangeRate), 
            input  tDInvoice.DInvoiceRateScale (idExchangeRateScale), 
            input  vdDebitAmountTC (idVatFullDebitTC), 
            input  vdCreditAmountTC (idVatFullCreditTC), 
            input  (if tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICE} then {&POSTINGTYPE-DEBIT} else if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} then {&POSTINGTYPE-CREDIT} else '':U) (icDInvoiceType), 
            input  tDInvoice.tcDivisionCode (icDivisionCode), 
            input  tDInvoice.tcVatCurrencyCode (icVatCurrencyCode), 
            input  tDInvoice.VatCurrency_ID (iiVatCurrencyId), 
            input  tDInvoice.DInvoiceVatExchangeRate (idVatExchangeRate), 
            input  tDInvoice.DInvoiceVatRateScale (idVatExchangeRateScale), 
            input  vcShipFromCountryCode (icShipFromCountryCode), 
            input  vcShipToCountryCode (icShipToCountryCode), 
            input  vlShipFromIsEUCountry (ilShipFromCountryIsEUCountry), 
            input  vlShipToIsEUCountry (ilShipToCountryIsEUCountry), 
            input  vcTxclTaxClass (icTxclTaxCls), 
            input  vcTxuTaxUsage (icTxuTaxUsage), 
            input  vcShipFromTaxZone (icShipFromTaxZone), 
            input  vcShipToTaxZone (icShipToTxzTaxZone), 
            input  ? (icTxenvTaxEnv), 
            input  tDInvoice.DInvoiceVoucher (iiVoucher), 
            input  tDInvoice.tcNormalPaymentConditionCode (icPaymentCondition), 
            input  vlIsCompanyTaxInCity (ilIsTaxInCityFromShipTo), 
            input  if available tqProfileLinkByGL then tqprofileLinkByGL.tcGLCode else ? (icControlGLCode), 
            input  tDInvoice.Debtor_ID (iiMasterId), 
            input  tDInvoice.DInvoice_ID (iiTransactionId), 
            input  tDInvoice.DInvoiceIsTaxable (ilIsTaxable), 
            input  tDInvoice.tcCostCentreCode (icCostCentreCode), 
            input  tDInvoice.tcProjectCode (icProjectCode), 
            input  ? (iiShipFromAddressId), 
            input  ? (iiShipToAddressId), 
            input  '' (icSoldToDebtorCode), 
            input  0 (idInvoiceAmountTC), 
            input  ? (icShipFromTaxIDFeder), 
            input  ? (icShipFromTaxIDState), 
            input  ? (icShipFromTaxIDMisc1), 
            input  ? (icShipFromTaxIDMisc2), 
            input  ? (icShipFromTaxIDMisc3), 
            input  ? (iiShipFromTaxDeclaration), 
            input  ? (icShipToTaxIDFeder), 
            input  ? (icShipToTaxIDState), 
            input  ? (icShipToTaxIDMisc1), 
            input  ? (icShipToTaxIDMisc2), 
            input  ? (icShipToTaxIDMisc3), 
            input  ? (iiShipToTaxDeclaration), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign vcMessage     = trim(substitute(#T-26'An error (&1) occurred when saving the tax details of the new customer invoices. See other messages for further details.':255(1802)T-26#,string(viFcReturnSuper)))
                       bcLstReturn   = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey  = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid    = bcLstRowid   + chr(4) + "*":U 
                       vlSaveAsDraft = icAction <> {&DAEMONACTION-SAVE}.
                <M-16 run SetMessage
                   (input  vcMessage (icMessage), 
                    input  '':U (icArguments), 
                    input  '':U (icFieldName), 
                    input  '':U (icFieldValue), 
                    input  'E':U (icType), 
                    input  3 (iiSeverity), 
                    input  '':U (icRowid), 
                    input  'QADFIN-1852':U (icFcMsgNumber), 
                    input  '' (icFcExplanation), 
                    input  '' (icFcIdentification), 
                    input  '' (icFcContext), 
                    output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
                return.
            end.
            else assign vlWarningsFound = true.
        end. /* if viFcReturnSuper <> 0 */
    end. /* if available tdinvoiceposting and */
end. /* Not if /* The taxes where passed as input */ */

                                                              
/* This is where it ends if only SaveAsDraft is needed */
if vlSaveAsDraft
then do:
    assign oiReturnStatus = -1
           bcLstReturn    = bcLstReturn  + chr(4) + "-1":U
           bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
           bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
    Return.
end.

/* Add method which can be implemented to set some defaults */
<M-18 run ApiStdMaintainTTDefaulting  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
if viFcReturnSuper <> 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    if oiReturnStatus < 0
    then do: 
        assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
               bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
               bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
               bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
        return.
    end.
    else assign vlWarningsFound = true.
end.

/* Validate the data and performa AddUpd */
<M-19 run ValidateBC  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
if viFcReturnSuper <> 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    if oiReturnStatus < 0
    then do: 
        assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
               bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
               bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
               bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
        return.
    end.
    else assign vlWarningsFound = true.
end.
<M-20 run AdditionalUpdates  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
if viFcReturnSuper <> 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    if oiReturnStatus < 0
    then do: 
        assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
               bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
               bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
               bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
        return.
    end.
    else assign vlWarningsFound = true.
end.

/* Save the data */
if icAction <> {&DAEMONACTION-VALIDATE}
then do: 
    if vlReturnDatasetDI
    then do:
        <M-48 run GetXmlRepresentationDataset
           (input  '' (icObjectRowId), 
            input  false (ilHeaderOnly), 
            input  0 (iiPriority), 
            output vhTempDS by-reference (ozXMLDataset), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                       bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
                return.
            end.
            else assign vlWarningsFound = true.
        end.
        /* Make a deep-copy of the dataset to prevent any further updates in the class tables from being reflected into the published dataset of ApiMaintainByDataSetWithOutput. This construction is needed as when we would use "vhDatasetToReturnDI by-reference" as output of GetXmlRepresentationDataset then the output-dataset of ApiMaintainByDataSetWithOutput is empty */ 
        vhDatasetToReturnDI:copy-dataset (vhTempDS, true, false, false, "", false, "").
        delete object vhTempDS no-error.
        /* Get the key fields */
        assign vcTableName = "".
        <M-49 run GetKeyFields
           (input-output vcTableName (bcTableName), 
            output vcPrimKeyDI (ocPrimaryKey), 
            output vcDummy (ocAlternateKey), 
            output vcDummy (ocObjectID), 
            output vcDummy (ocObjectStatus), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        if viFcReturnSuper <> 0
        then do:
            assign oiReturnStatus = viFcReturnSuper.
            if oiReturnStatus < 0
            then do: 
                assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                       bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                       bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
                       bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
                return.
            end.
            else assign vlWarningsFound = true.
        end.
    end.
    <M-21 run DataSave  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
    if viFcReturnSuper <> 0
    then do:
        assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then do: 
            assign olSaveAsDraft  = (icAction <> {&DAEMONACTION-SAVE} and icAction <> {&DAEMONACTION-VALIDATE})
                   bcLstReturn    = bcLstReturn  + chr(4) + string(viFcReturnSuper)
                   bcLstPrimKey   = bcLstPrimKey + chr(4) + "*":U
                   bcLstRowid     = bcLstRowid   + chr(4) + "*":U.
            return.
        end.
        else assign vlWarningsFound = true.
    end.
end.

/* Indicate that everything was saved correctly */
/* Set return status = OK                       */
assign bcLstReturn    = bcLstReturn  + chr(4) + (if vlWarningsFound = true then "1":U else "0":U)
       bcLstPrimKey   = bcLstPrimKey + chr(4) + string(tApiDInvoice.DInvoice_ID)
       bcLstRowid     = bcLstRowid   + chr(4) + vcDInvoiceRowId
       oiReturnStatus = (if vlWarningsFound = true then 1 else 0).