project QadFinancials > class BDInvoice > method PreSave

Description

Actions to take before writing current instance to the database (inside the db transaction!).
Use the field tc_status to test the status of the updated records:
'' = unchanged
'N' = new
'C' = changed
'D' = deleted

If the consecutive numbering is active, the temporary voucher of the invoices will be changed to a permanent voucher in this method.

Creation Date/Time:
Three fields concerning creation date/time will be filled in this method with the current date/time.
DInvoiceCreationDate, DInvoiceCreationMTime, DInvoiceCreationTimeString

Invoice Certification:
When invoice certification is enabled on domain, the invoice certification fields will be filled in this method.
Note that invoice numbering will only be allowed when either the base currency or the statutory currency is EUR.
DInvoiceInvCertCertificate will be filled with data stored in the systemproperty table.
DInvoiceInvCertKey will be filled with a unique key for the new invoice + the signature of the previous invoice.
DInvoiceInvCertSignaturePrev will be filled with the signature of the previous invoice.
DInvoiceInvCertSignatureCurr will be filled with the signature of the current invoice.
This signature is retrieved in method SignStringUsingOpenSSL.


Parameters


oiReturnStatusoutputintegerReturn status of the method.


Internal usage


unused


program code (program/bdinvoice.p)

<ANCESTOR-CODE>
    
    /* ====================================================================================================== */
    /* The instance-dep data-item vcListDInvoiceIDsForQCrossCy contains a comma-separated list of             */
    /* DInvoiceIDs for the DInvoices wherefor a tNewCrossCyPostingTable-record is created in method           */
    /* CreateDInvoiceMovement (and the submethods of it).                                                     */  
    /* Based on this list, PreSave-method will update the DInvoiceIsSelected-flag for these DInvoices (that   */
    /* are not loaded into the business-instance).                                                            */
    /* Once everything is done then empty the class data-item to avoid problems the next time save is done    */
    /* ====================================================================================================== */
    if vcListDInvoiceIDsForQCrossCy <> "":U and 
       vcListDInvoiceIDsForQCrossCy <> ?
    then do:
        
        <M-1 run StartPersistence (output vhFcComponent (ohPersistence), 
                           output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        if viFcReturnSuper <> 0
        then do :
            assign oiReturnStatus                = viFcReturnSuper
                   vcListDInvoiceIDsForQCrossCy  = "":U.
            if oiReturnStatus < 0
            then return.
        end. /* if viFcReturnSuper <> 0 */
        assign viTotalCount  = num-entries(vcListDInvoiceIDsForQCrossCy,",":U)
           vcWhereClause = ''
           viCounterSub  = 0.
    
        do viCounter = viTotalCount to 1 by -1 :
             assign vcWhereClause = vcWhereClause + " ":U + 
                                      (if vcWhereClause = '':U
                                          then "for each DInvoice where ":U 
                                           else " or ":U ) + 
                                        "DInvoice.DInvoice_ID = ":U + entry(viCounter,vcListDInvoiceIDsForQCrossCy,",":U)
                    viCounterSub = viCounterSub + 1.
        /* process in bunch of 100 */             
             if viCounterSub = 100 or viCounter = 1 
             then do :

                 <M-2 run WriteDirect
                    (input  'DInvoice':U (icTableName), 
                     input  vcWhereClause (icPrepare), 
                     input  'DInvoiceIsSelected':U (icFieldList), 
                     input  'L':U (icFieldListDataTypes), 
                     input  'true':U (icAbsolute), 
                     input  '':U (icIncremental), 
                     input  {&TARGETPROCEDURE} (ihClass), 
                     input  vcUserLogin (icUserLogin), 
                     output viFcReturnSuper (oiReturnStatus)) in Progress>                               
                 if viFcReturnSuper <> 0
                 then do :
                 assign oiReturnStatus                = viFcReturnSuper
                        vcListDInvoiceIDsForQCrossCy  = "":U.
                 if oiReturnStatus < 0
                 then return.
                 end. /* if viFcReturnSuper <> 0 */
                 assign vcWhereClause = '':U
                        viCounterSub  = 0. 
             end.  /* vicountersub = 100 or vicounter = 1 */
        end.  /* do vicounter */

        assign vcListDInvoiceIDsForQCrossCy  = "":U.
    end. /* if vcListDInvoiceIDsForQCrossCy <> "":U and */
    
    
    /* ===================================================================================== */
    /* Execute some extra validations to ensure sub-ledger and general ledger are in line    */
    /* ===================================================================================== */
    <M-49 run PreSaveValidate  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper <  0 then return.
        
    /* ======================================================================================================= */
    /* In case of Consecutive-invoice-numbering: Obtain a new voucher number and update the necessary records. */
    /* ======================================================================================================= */
    NUMBERBLOCK: DO:
       
        /* ======================================================================================== */
        /* Replace all occurrences of the invoice voucher number when concecutive numbering is used */
        /* ======================================================================================== */
        if vlCCNIsConsecutNr = TRUE 
        then do: 
            empty temp-table tUpdateInvoicesNumbersDI.
            for each tDInvoice where 
                     tDInvoice.tc_Status = 'N':U or
                     tDInvoice.tc_Status = 'C':U and
                     tDInvoice.DInvoiceVoucher >= 999000000
                     exclusive-lock:
                /* Skip the consecutive numbering for Prepayments and for deductions */
                if tDInvoice.DInvoiceType = {&INVOICETYPE-PREPAYMENT} or
                   tDInvoice.DInvoiceType = {&INVOICETYPE-DEDUCTION}
                then next.
                /* Although the consequtive numbering is on, invoices that come via integtration and therefore 
                   the a posting weas already created by the integration-methods ccalling BPosting/BJournalEntry, 
                   will have a proper number and not a temporarely one. For these invoices we do not need to retrieve 
                   another new number as we will otherwise have gaps in our numbering. */ 
                if tDInvoice.DInvoiceVoucher <> 0                and 
                   tDInvoice.DInvoiceVoucher <> ?                and 
                   tDInvoice.DInvoiceVoucher  < viCCNTempDInvNbr and 
                   tDInvoice.DInvoiceVoucher  < 999000000 
                then next.
                /* If in modify and the year and the journal haven't changed, then go to next record */
                if tDInvoice.tc_Status = 'C':U
                then do:
                    find t_iDInvoice where
                         t_iDInvoice.tc_Rowid = tDInvoice.tc_Rowid
                         no-lock no-error.
                    if not available t_iDInvoice
                    then next.
                    if t_iDInvoice.DInvoicePostingYear = tDInvoice.DInvoicePostingYear and
                       t_iDInvoice.Journal_ID          = tDInvoice.Journal_ID
                    then next.
                end. /* if tDInvoice.tc_Status = 'C':U */
                /* Skip invoices that come from the operationals = JournalControl is Logistics */
                <Q-41 run JournalBeginsForJEDefault (all) (Read) (Cache)
                   (input viCompanyId, (CompanyId)
                    input tDInvoice.tcJournalCode, (JournalCode)
                    input {&JOURNALCONTROL-LOGISTIC}, (JournalControl)
                    input '':U, (JournalTypeCode)
                    output dataset tqJournalBeginsForJEDefault) in BJournal>
                find first tqJournalBeginsForJEDefault where
                           tqJournalBeginsForJEDefault.tcJournalCode     = tDInvoice.tcJournalCode and
                           tqJournalBeginsForJEDefault.tcJournalControl  = {&JOURNALCONTROL-LOGISTIC}
                           no-lock no-error.
                if available tqJournalBeginsForJEDefault
                then next.
                /* Obtain the new voucher number. */
                assign vhFcComponent = ?.
                <M-94 run GetNumber
                   (input  viCompanyId (iiCompanyId), 
                    input  tDInvoice.DInvoicePostingYear (iiNumbrYear), 
                    input  tDInvoice.tcJournalCode (icNumbrType), 
                    output viNewVoucher (oiNumber), 
                    input  viFcCurrentInstanceId (iiInstanceId), 
                    input  vcFcComponentName (icClassName), 
                    output viFcReturnSuper (oiReturnStatus)) in BNumber>
                if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
                then assign oiReturnStatus = viFcReturnSuper.
                if viFcReturnSuper < 0
                then return.
                create tUpdateInvoicesNumbersDI.
                assign tUpdateInvoicesNumbersDI.tiCompany_ID   = tDInvoice.Company_ID
                       tUpdateInvoicesNumbersDI.tiDInvoice_ID  = tDInvoice.DInvoice_ID
                       tUpdateInvoicesNumbersDI.tiPeriodYear   = tDInvoice.DInvoicePostingYear
                       tUpdateInvoicesNumbersDI.tiPeriodPeriod = tDInvoice.DInvoicePostingPeriod
                       tUpdateInvoicesNumbersDI.tcJournalCode  = tDInvoice.tcJournalCode
                       tUpdateInvoicesNumbersDI.tiTempVoucher  = tDInvoice.DInvoiceVoucher
                       tUpdateInvoicesNumbersDI.tiNewVoucher   = viNewVoucher
                       tDInvoice.DInvoiceVoucher               = viNewVoucher.
            end. /* for each tDInvoice where */ 
            /* ========================= */
            /* Update fields in BPosting */
            /* ========================= */
            if viBJournalEntryDIID <> 0 and viBJournalEntryDIID <> ?
            then do:
                <I-18 {bFcOpenInstance
                     &CLASS           = "Transaction"}>
                <M-60 run GetInstanceDetails
                   (input  'BJournalEntry':U (icComponentShortName), 
                    input  viCompanyId (iiCompanyIdOfInstance), 
                    output viDummy (oiInstanceId), 
                    output vhBJournalEntryDIInst (ohInstanceHandle), 
                    output viFcReturnSuper (oiReturnStatus)) in Transaction>
                <I-76 {bFcCloseInstance
                     &CLASS           = "Transaction"}>           
                if viFcReturnSuper<> 0 and oiReturnStatus >= 0
                then assign oiReturnStatus = viFcReturnSuper.
                if viFcReturnSuper < 0
                then leave NUMBERBLOCK.
                if valid-handle(vhBJournalEntryDIInst)
                then do:
                    <M-55 run UpdateInvoiceNumbers
                       (input  tUpdateInvoicesNumbersDI (tUpdateInvoiceNumbersPosting), 
                        output viFcReturnSuper (oiReturnStatus)) in BJournalEntry>
                    if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
                    then assign oiReturnStatus = viFcReturnSuper.
                    if viFcReturnSuper < 0
                    then leave NUMBERBLOCK.
                end.   /* if valid-handle(vhBJournalEntryCIInst) */     
            end. /* if viBJournalEntryDIID <> 0 and viBJournalEntryDIID <> ? */ 
            /* =================================== */
            /* Update fields in BQDInvoiceMovement */
            /* =================================== */
            if viBQDInvoiceMovementID <> 0 and viBQDInvoiceMovementID <> ?
            then do:
                <I-56 {bFcOpenInstance
                     &CLASS           = "Transaction"}>
                <M-32 run GetInstanceDetails
                   (input  'BQDInvoiceMovement':U (icComponentShortName), 
                    input  viCompanyId (iiCompanyIdOfInstance), 
                    output viDummy (oiInstanceId), 
                    output vhBQDInvoiceMovementInst (ohInstanceHandle), 
                    output viFcReturnSuper (oiReturnStatus)) in Transaction>
                <I-70 {bFcCloseInstance
                     &CLASS           = "Transaction"}>
                if viFcReturnSuper <> 0 and oiReturnStatus >= 0
                then assign oiReturnStatus = viFcReturnSuper.
                if viFcReturnSuper < 0
                then leave NUMBERBLOCK.
                if valid-handle(vhBQDInvoiceMovementInst)
                then do:
                    <M-59 run UpdateInvoiceNumbers
                       (input  tUpdateInvoicesNumbersDI (tQDINvMoveInvoices), 
                        output viFcReturnSuper (oiReturnStatus)) in BQDInvoiceMovement>
                    if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
                    then assign oiReturnStatus = viFcReturnSuper.
                    if viFcReturnSuper < 0
                    then leave NUMBERBLOCK.
                end. /* if valid-handle(vhBQDInvoiceMovementInst) */
            end. /* if viBQDInvoiceMovementID <> 0 and viBQDInvoiceMovementID <> ? */
            /* ========================================== */
            /* Update fields in customer document records */
            /* ========================================== */
            if viBDDocumentID <> 0 and viBDDocumentID <> ?
            then do:
                <I-95 {bFcOpenInstance
                     &CLASS           = "Transaction"}>
                <M-27 run GetInstanceDetails
                   (input  'BDDocument':U (icComponentShortName), 
                    input  viCompanyId (iiCompanyIdOfInstance), 
                    output viDummy (oiInstanceId), 
                    output vhBDDocumentInst (ohInstanceHandle), 
                    output viFcReturnSuper (oiReturnStatus)) in Transaction>
                <I-5 {bFcCloseInstance
                     &CLASS           = "Transaction"}>
                if viFcReturnSuper <> 0 and oiReturnStatus >= 0
                then assign oiReturnStatus = viFcReturnSuper.
                if viFcReturnSuper < 0
                then leave NUMBERBLOCK.
                if valid-handle(vhBDDocumentInst)
                then do:
                    <M-53 run UpdateInvoiceNumbers
                       (input  tUpdateInvoicesNumbersDI (tDDocumentInvoices), 
                        output viFcReturnSuper (oiReturnStatus)) in BDDocument>
                    if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
                    then assign oiReturnStatus = viFcReturnSuper.
                    if viFcReturnSuper < 0
                    then return.
                end. /* if valid-handle(vhBDDocumentInst) */
            end. /* if viBDDocumentID <> 0 and viBDDocumentID <> ? */
        end. /* if vlCCNIsConsecutNr = TRUE */    
    END. /* NUMBERBLOCK */
    /* Releae number on errors */
    if oiReturnStatus < 0
    then do:
        for each tUpdateInvoicesNumbersDI:
            assign vhFcComponent = ?.
            <M-48 run ReleaseNumber
               (input  tUpdateInvoicesNumbersDI.tiCompany_ID (iiCompanyId), 
                input  tUpdateInvoicesNumbersDI.tiPeriodYear (iiNumbrYear), 
                input  tUpdateInvoicesNumbersDI.tcJournalCode (icNumbrType), 
                input  tUpdateInvoicesNumbersDI.tiNewVoucher (iiNumbr), 
                input  viFcCurrentInstanceId (iiInstanceId), 
                input  vcFcComponentName (icClassName), 
                output viFcReturnSuper (oiReturnStatus)) in BNumber>
            if viFcReturnSuper <> 0 and oiReturnStatus >= 0
            then assign oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0
            then return.
        end. /* for each tUpdateInvoiceNumbers: */
    end. /* if oiReturnStatus < 0 */
    
    
    /* ================================== */
    /* Assign Creation Date / Time fields */
    /* ================================== */
    for each tDInvoice where
             tDInvoice.tc_Status = "N":
        assign tDInvoice.DInvoiceCreationDate         = today
               tDInvoice.DInvoiceCreationTimeString   = string(time,"HH:MM:SS":U).
    end. /* for each tDInvoice where */
    
    
    /* ================================================================================================= */
    /* Invoice Certification: Fill the necessary fields for invoice certification and create a signature */
    /* ================================================================================================= */
    /* ========================================================= */
    /* Check if invoice certification is enabled for this domain */
    /* ========================================================= */
    <Q-50 run DomainPropertyByDomainCodeID (all) (Read) (Cache)
       (input vcDomainCode, (DomainCode)
        input viDomainID, (DomainID)
        output dataset tqDomainPropertyByDomainCodeID) in BDomainProperty>
    find first tqDomainPropertyByDomainCodeID where 
               tqDomainPropertyByDomainCodeID.tiDomain_ID = viDomainID
               no-lock no-error.
    if not available tqDomainPropertyByDomainCodeID
    then do:
        assign vcMessage      = #T-61'Unable to retrieve the domain settings.':255(576266750)T-61#
               oiReturnStatus = -3.
        <M-71 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  '':U (icFieldName), 
            input  '':U (icFieldValue), 
            input  'E':U (icType), 
            input  1 (iiSeverity), 
            input  '':U (icRowid), 
            input  'qadfin-173738':U (icFcMsgNumber), 
            input  '':U (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
        return.
    end. /* if not available tqDomainPropertyByDomainCodeID */
    if tqDomainPropertyByDomainCodeID.tlDomainPropertyIsInvCertific = true
    then do:
        /* ====================================================== */
        /* Retrieve the system settings for invoice certification */
        /* ====================================================== */
        <Q-83 run SystemPropertyByAll (all) (Read) (Cache)  (output dataset tqSystemPropertyByAll) in BSystemProperty>
        find first tqSystemPropertyByAll no-lock no-error.
        if not available tqSystemPropertyByAll
        then do:
            assign vcMessage      = #T-72'Unable to retrieve the system settings.':255(803317630)T-72#
                   oiReturnStatus = -3.
            <M-22 run SetMessage
               (input  vcMessage (icMessage), 
                input  '':U (icArguments), 
                input  '':U (icFieldName), 
                input  '':U (icFieldValue), 
                input  'E':U (icType), 
                input  1 (iiSeverity), 
                input  '':U (icRowid), 
                input  'qadfin-564246':U (icFcMsgNumber), 
                input  '':U (icFcExplanation), 
                input  '':U (icFcIdentification), 
                input  '':U (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
            return.
        end. /* if not available tqSystemPropertyByAll */
        /* ================================================================ */
        /* Fill the class data item to use in method SignStringUsingOpenSSL */
        /* ================================================================ */
        assign vcOpenSSLDir = tqSystemPropertyByAll.tcSysPropertyInvCertOpenSSLDir.
        if vcOpenSSLDir <> "" and
           vcOpenSSLDIR <> ?  and
           substring(vcOpenSSLDir, length(vcOpenSSLDir, "CHARACTER"), 1, "CHARACTER") <> "~\"
        then assign vcOpenSSLDir = vcOpenSSLDir + "~\".
        /* ========================================= */
        /* Either the LC or the SC needs to be "EUR" */
        /* ========================================= */
        if tqDomainPropertyByDomainCodeID.tcCurrencyCode          <> "EUR" and
           tqDomainPropertyByDomainCodeID.tcStatutoryCurrencyCode <> "EUR" 
        then do:
            assign vcMessage      = substitute(#T-93'Either the base currency or the statutory currency of domain &1 need to be EUR when Invoice Certification is enabled.':255(11607730)T-93#, tqDomainPropertyByDomainCodeID.tcDomainCode)
                   oiReturnStatus = -3.
            <M-67 run SetMessage
               (input  vcMessage (icMessage), 
                input  '':U (icArguments), 
                input  '':U (icFieldName), 
                input  '':U (icFieldValue), 
                input  'E':U (icType), 
                input  1 (iiSeverity), 
                input  '':U (icRowid), 
                input  'qadfin-77681':U (icFcMsgNumber), 
                input  '':U (icFcExplanation), 
                input  '':U (icFcIdentification), 
                input  '':U (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
            return.
        end. /* if tqDomainPropertyByDomainCodeID.tcCurrencyCode <> "EUR" and */
        /* ============================= */
        /* Loop through all new invoices */
        /* ============================= */
        for each tDInvoice where
                 tDInvoice.tc_Status = "N":
            /* ============================================================== */
            /* get the signature of the previous invoice                      */
            /* First check the instance, if nothing there, check the database */
            /* ============================================================== */
            find last btDInvoice where 
                      btDInvoice.Company_ID          = tDInvoice.Company_ID          and
                      btDInvoice.Journal_ID          = tDInvoice.Journal_ID          and
                      btDInvoice.DInvoicePostingYear = tDInvoice.DInvoicePostingYear and
                      btDInvoice.tc_Rowid           <> tDInvoice.tc_Rowid
                      use-index UniqueIdx
                      no-error.
            if not available btDInvoice
            then do:
                find last btDInvoice where 
                          btDInvoice.Company_ID          = tDInvoice.Company_ID                and
                          btDInvoice.Journal_ID          = tDInvoice.Journal_ID                and
                          btDInvoice.DInvoicePostingYear = (tDInvoice.DInvoicePostingYear - 1) and
                          btDInvoice.tc_Rowid           <> tDInvoice.tc_Rowid
                          use-index UniqueIdx
                          no-error.
                if not available btDInvoice
                then do:
                    <Q-12 run DInvoiceForInvCertification (last) (Read) (NoCache)
                       (input tDInvoice.Company_ID, (CompanyId)
                        input tDInvoice.Journal_ID, (JournalID)
                        output dataset tqDInvoiceForInvCertification) in BDInvoice >
                    find last tqDInvoiceForInvCertification where
                              tqDInvoiceForInvCertification.tiCompany_ID = tDInvoice.Company_ID and
                              tqDInvoiceForInvCertification.tiJournal_ID = tDInvoice.Journal_ID
                              no-error.
                    if available tqDInvoiceForInvCertification
                    then assign vcPreviousSignature = tqDInvoiceForInvCertification.tcDInvoiceInvCertSignatureCurr.
                    else assign vcPreviousSignature = "".
                end. /* if not available bDInvoice */
                else assign vcPreviousSignature = btDInvoice.DInvoiceInvCertSignatureCurr.
            end. /* if not available bDInvoice */
            else assign vcPreviousSignature = btDInvoice.DInvoiceInvCertSignatureCurr.
            /* ============================================= */
            /* Fill in necessary fields to get our signature */
            /* ============================================= */
            assign tDInvoice.DInvoiceInvCertCertificate   = tqSystemPropertyByAll.tcSysPropertyInvCertCertificate
                   tDInvoice.DInvoiceInvCertSignaturePrev = vcPreviousSignature.
            if tqDomainPropertyByDomainCodeID.tcCurrencyCode = "EUR"
            then assign vdInvoiceAmountInEUR = abs(tDInvoice.DInvoiceOriginalDebitLC - tDInvoice.DInvoiceOriginalCreditLC).
            else assign vdInvoiceAmountInEUR = abs(tDInvoice.DInvoiceOriginalDebitCC - tDInvoice.DInvoiceOriginalCreditCC).        
            /* ============================================================== */
            /* Create the Key for our invoice, so we can create the signature */
            /* This fields in this key need to semicolon separated.           */
            /* ============================================================== */
            if tDInvoice.DInvoiceType = {&INVOICETYPE-CREDITNOTE} or
               tDInvoice.DInvoiceType = {&INVOICETYPE-INVOICECORRECTION}
            then assign vcInvoiceType = "NC".
            else assign vcInvoiceType = "FT".
            assign tDInvoice.DInvoiceInvCertKey = 
                        string(year(tDInvoice.DInvoiceDate), "9999")         + "-" + string(month(tDInvoice.DInvoiceDate), "99")         + "-" + string(day(tDInvoice.DInvoiceDate), "99") + ";" +
                        string(year(tDInvoice.DInvoiceCreationDate), "9999") + "-" + string(month(tDInvoice.DInvoiceCreationDate), "99") + "-" + string(day(tDInvoice.DInvoiceCreationDate), "99") + "T" + trim(tDInvoice.DInvoiceCreationTimeString) + ";" +
                        trim(vcInvoiceType) + " " + string(tDInvoice.DInvoicePostingYear, "9999") + trim(caps(tDInvoice.tcJournalCode)) + "/" + string(tDInvoice.DInvoiceVoucher, "999999999") + ";" +
                        trim(string(vdInvoiceAmountInEUR, ">>>>>>>>>>>>>>>9.99")) + ";".
            /* ================================== */
            /* Get the signature for this invoice */
            /* ================================== */
            assign vhFcComponent = ?.
            <M-38 run SignStringUsingOpenSSL
               (input  tDInvoice.DInvoiceInvCertKey + vcPreviousSignature (icStringToSign), 
                input  vcOpenSSLDir (icOpenSSLDir), 
                input  viSessionId (iiSessionId), 
                output tDInvoice.DInvoiceInvCertSignatureCurr (ocSignatureForInputString), 
                output vcMessage (ocMessage), 
                output viFcReturnSuper (oiReturnStatus)) in TOpenSSL>
            if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
            then assign oiReturnStatus = viFcReturnSuper.
                        
            if viFcReturnSuper <> 0 and 
               vcMessage <> ''      and 
               vcMessage <> ?
            then do:
                <M-52 run SetMessage
                   (input  vcMessage (icMessage), 
                    input  '':U (icArguments), 
                    input  '':U (icFieldName), 
                    input  '':U (icFieldValue), 
                    input  'E':U (icType), 
                    input  1 (iiSeverity), 
                    input  '':U (icRowid), 
                    input  'qadfin-365024':U (icFcMsgNumber), 
                    input  '':U (icFcExplanation), 
                    input  '':U (icFcIdentification), 
                    input  '':U (icFcContext), 
                    output viFcReturnSuper (oiReturnStatus)) in BDInvoice>                
            end. /* if viFcReturnSuper <> 0 and vcMessage <> '' */

            run gipr_DeleteProcedure in vhFcComponent.
            delete procedure vhFcComponent.
            if oiReturnStatus < 0
            then return.            
            
            /* Set the 4-character signature of the invoice based upon the full signature and redundantly store the invoice-certificate - that is stored on system-level - on the invoice itself */
            assign tDInvoice.DInvoiceInvCertSignatureShort = substring(tDInvoice.DInvoiceInvCertSignatureCurr,1,1,'Character':U) + 
                                                             substring(tDInvoice.DInvoiceInvCertSignatureCurr,11,1,'Character':U) + 
                                                             substring(tDInvoice.DInvoiceInvCertSignatureCurr,21,1,'Character':U) + 
                                                             substring(tDInvoice.DInvoiceInvCertSignatureCurr,31,1,'Character':U)  
                   tDInvoice.DInvoiceInvCertVersion        = tqSystemPropertyByAll.tcSysPropertyInvCertVersion.
                   
             end. /* for each tDInvoice where */         
    end. /* if tqDomainPropertyByDomainCodeID.tlDomainPropertyIsInvCertific = true */
    /* make sure that avatax is active, and there are avatax tax records */     
    find first tDInvoiceVat where tDInvoiceVat.tlIsAvataxTaxLine = true no-error.
    if vlAvataxIsActive and available tDInvoiceVat
    then do:
        for each tDInvoice where tDInvoice.tc_Status = "N" and tDInvoice.DInvoiceIsExternal = false:           
            /* Post the amounts to Avatax Database */
            <M-66 run PreSaveCommitTax  (output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
             if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
                then assign oiReturnStatus = viFcReturnSuper.           
        end. /* for each tDInvoice where tDInvoice.tc_Status = "N" */
    end. /* if vlAvataxIsActive */
    
    find first tUpdateInvoicesNumbersDI where
           tUpdateInvoicesNumbersDI.tiNewVoucher >= 999000000 no-error.
           
    if available tUpdateInvoicesNumbersDI
    then do:
    
        <M-69 run SetMessage
           (input  #T-37'Internal error: an invoice can not be saved with a temporary voucher':255(636431397)T-37# (icMessage), 
            input  '':U (icArguments), 
            input  'tDInvoice.DInvoiceVoucher' (icFieldName), 
            input  string(tUpdateInvoicesNumbersDI.tiNewVoucher) (icFieldValue), 
            input  'S' (icType), 
            input  3 (iiSeverity), 
            input  '':U (icRowid), 
            input  'qadfin-844896':U (icFcMsgNumber), 
            input  '':U (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BDInvoice>
 
        assign oiReturnStatus = -1.
        if viFcReturnSuper < 0
        then return.
    end.