project QadFinancials > class BPosting > method AdditionalUpdatesPostFallBack

Description

Create Cross Company Posting Daemon request


Parameters


oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BPosting.AdditionalUpdates


program code (program5/bposting.p)

/* ============================================================================================ *
 * Method:          AdditionalUpdatesPostFallBack                                               *
 * DeCCription:     This method checks whether the posting is balanced in CC and BC. If the     *
 *                  posting is not balanced, then routine tries to generate Auto-Balancing      *
 *                  posting line.                                                               *
 * ============================================================================================ */
assign oiReturnStatus      = -98
       viLocalReturnStatus = 0.

/* Empty collection of the mails to be send out by Auto-Balancing posting */
empty temp-table tAutoBalanceMailNotif.

MAIN_BLOCK:
do on error undo, throw:
    for each tPosting where
             tPosting.tc_Status = "N":U or
             tPosting.tc_Status = "C":U:
        
        assign vdBalanceTC         = 0
               vdBalanceCC         = 0
               vdBalanceLC         = 0
               viCurrencyId        = 0
               viPostingLinesCount = 0.
    
        /* Calculate balance of the posting */
        for each tPostingLine where
                 tPostingLine.tc_ParentRowid = tPosting.tc_Rowid and
                 tPostingLine.tc_Status     <> "D":U:
    
            /* Balance of the posting */
            assign vdBalanceTC         = vdBalanceTC + tPostingLine.PostingLineDebitTC - tPostingLine.PostingLineCreditTC
                   vdBalanceCC         = vdBalanceCC + tPostingLine.PostingLineDebitCC - tPostingLine.PostingLineCreditCC
                   vdBalanceLC         = vdBalanceLC + tPostingLine.PostingLineDebitLC - tPostingLine.PostingLineCreditLC
                   viPostingLinesCount = viPostingLinesCount + 1.                              
    
            /* Currency of the transaction */
            if viCurrencyId <> ?
            then if viCurrencyId <> 0 and viCurrencyId <> tPostingLine.Currency_ID
                 then assign viCurrencyId = ?.
                 else assign viCurrencyId = tPostingLine.Currency_ID.
        end. /* for each tPostingLine where */               
    
        /* If the balance of the posting is zero, no action required */
        if vdBalanceCC = 0 and
           vdBalanceLC = 0
        then next.
                   
        /* Check, if the balance of the posting can be cleared by the Auto-balance posting line */
        assign vlIsCreateAutoBalance = false.
    
        /* 1. Check, if there is defined GL account of sytem type auto-balance. If there is not *
         *    defined this GL account, no auto-balance posting line is created                  */
        <Q-93 run GLBySystemTypeAndType (all) (Read) (NoCache)
           (input ?, (GLCode)
            input {&GLSYSTEMTYPE-AUTOBALANCE}, (GLSystemTypeCode)
            input ?, (GLId)
            input {&GLTYPECODE-SYST}, (GLTypeCode)
            input tPosting.Company_ID, (CompanyId)
            input true, (GlIsActive)
            output dataset tqGLBySystemTypeAndType) in BGL>
        
        find tqGLBySystemTypeAndType where
             tqGLBySystemTypeAndType.tcGLSystemTypeCode = {&GLSYSTEMTYPE-AUTOBALANCE} and
             tqGLBySystemTypeAndType.tcGLTypeCode       = {&GLTYPECODE-SYST}          and
             tqGLBySystemTypeAndType.tlGLIsActive       = true
             no-error.
    
        if not available tqGLBySystemTypeAndType
        then leave MAIN_BLOCK.
        /* 1. For Automatic posting - When there is only 1 currency and TC amount is balanced,  *
         *    post remaining unbalanced amount to Auto-balance account                          */
        if not vlIsCreateAutoBalance       and
           viCurrencyId               <> ? and
           vdBalanceTC                 = 0 and
           ((tPosting.tcJournalTypeCode <> {&JOURNALTYPE-JOURNALENTRY} and
             tPosting.tcJournalTypeCode <> {&JOURNALTYPE-YEARLYCLOSING}) or
            tPosting.PostingOriginIsExternal = TRUE)
        then vlIsCreateAutoBalance = true.
        /* 2. For Automatic posting - Whent the posting is balanced in LC but not in CC */
        if not vlIsCreateAutoBalance       and
           vdBalanceLC                 = 0 and
           vdBalanceCC                <> 0 and
           ((tPosting.tcJournalTypeCode <> {&JOURNALTYPE-JOURNALENTRY} and
             tPosting.tcJournalTypeCode <> {&JOURNALTYPE-YEARLYCLOSING}) or
            tPosting.PostingOriginIsExternal = TRUE)
        then vlIsCreateAutoBalance = true.
        /* 3. For Automatic posting - Whent the posting is balanced in CC but not in LC */
        if not vlIsCreateAutoBalance       and
           vdBalanceCC                 = 0 and
           vdBalanceLC                <> 0 and
           ((tPosting.tcJournalTypeCode <> {&JOURNALTYPE-JOURNALENTRY} and
             tPosting.tcJournalTypeCode <> {&JOURNALTYPE-YEARLYCLOSING}) or
            tPosting.PostingOriginIsExternal = TRUE)
        then vlIsCreateAutoBalance = true.               
        
        /* 4. For all types - when the balance amount is small enough, then create roudning posting also */
        if not vlIsCreateAutoBalance and
           tPosting.tcJournalTypeCode <> {&JOURNALTYPE-YEARLYCLOSING}
        then do:                   
            assign vlIsCreateAutoBalanceLCSmallAm = ?
                   vlIsCreateAutoBalanceCCSmallAm = ?.
             
            if vdBalanceLC <> 0
            then do:
                <Q-49 run CurrencyByCurrRoundingMethod (all) (Read) (NoCache)
                    (input viCompanyLCId, (CurrencyID)
                     input ?, (CurrencyCode)
                     input ?, (RoundingMethodCode)
                     output dataset tqCurrencyByCurrRoundingMethod) in BCurrency>
                 
                find tqCurrencyByCurrRoundingMethod where 
                     tqCurrencyByCurrRoundingMethod.tiCurrency_ID = viCompanyLCId
                     no-error.
                if not available tqCurrencyByCurrRoundingMethod
                then do:
                    assign vcMsgExplanation = <M-47 GetErrorExplanation
                                                 (input  tPosting.tc_Rowid (icPostingRowId), 
                                                  input  ? (icPostingLineRowId), 
                                                  output viFcReturnSuper (oiReturnStatus)) in BPosting>.
                              
                    assign vcMessage = trim(substitute(#T-94'Setup-error: unable to find the rounding-method for the base-currency (&1 / &2)':255(73476216)T-94#,vcCompanyLC,viCompanyLCId)).
                    <M-35 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-560668':U (icFcMsgNumber), 
                        input  vcMsgExplanation (icFcExplanation), 
                        input  '':U (icFcIdentification), 
                        input  '':U (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BPosting>
                    assign viLocalReturnStatus = -1.
                    leave MAIN_BLOCK.
                end. /* if not available tqCurrencyByCurrRoundingMethod */
                        
                if abs(vdBalanceLC) <= abs(tqCurrencyByCurrRoundingMethod.tdRoundingMethodUnit * (viPostingLinesCount - 1))
                then assign vlIsCreateAutoBalanceLCSmallAm = true.
                else assign vlIsCreateAutoBalanceLCSmallAm = false.
            end. /* if vdBalanceLC <> 0 */
            
            if vdBalanceCC <> 0
            then do:                           
            
                <Q-28 run CurrencyByCurrRoundingMethod (all) (Read) (NoCache)
                    (input viCompanyCCId, (CurrencyID)
                     input ?, (CurrencyCode)
                     input ?, (RoundingMethodCode)
                     output dataset tqCurrencyByCurrRoundingMethod) in BCurrency>
                 
                find tqCurrencyByCurrRoundingMethod where 
                     tqCurrencyByCurrRoundingMethod.tiCurrency_ID = viCompanyCCId
                     no-error.
                if not available tqCurrencyByCurrRoundingMethod
                then do:
                    assign vcMsgExplanation = <M-16 GetErrorExplanation
                                                 (input  tPosting.tc_Rowid (icPostingRowId), 
                                                  input  ? (icPostingLineRowId), 
                                                  output viFcReturnSuper (oiReturnStatus)) in BPosting>.
                              
                    assign vcMessage = trim(substitute(#T-63'Setup-error: unable to find the rounding-method for the statutory-currency (&1 / &2)':255(413968626)T-63#,vcCompanyLC,viCompanyLCId)).
                    <M-22 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-66823':U (icFcMsgNumber), 
                        input  vcMsgExplanation (icFcExplanation), 
                        input  '':U (icFcIdentification), 
                        input  '':U (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BPosting>
                    assign viLocalReturnStatus = -1.
                    leave MAIN_BLOCK.
                end. /* if not available tqCurrencyByCurrRoundingMethod */
                        
                if abs(vdBalanceCC) <= abs(tqCurrencyByCurrRoundingMethod.tdRoundingMethodUnit * (viPostingLinesCount - 1))
                then assign vlIsCreateAutoBalanceCCSmallAm = true.
                else assign vlIsCreateAutoBalanceCCSmallAm = false.
            end. /* if vdBalanceLC <> 0 */

            assign vlIsCreateAutoBalance = (vlIsCreateAutoBalanceCCSmallAm = ? and
                                            vlIsCreateAutoBalanceLCSmallAm = true)    or
                                           (vlIsCreateAutoBalanceCCSmallAm = true and
                                            vlIsCreateAutoBalanceLCSmallAm = ?)       or
                                           (vlIsCreateAutoBalanceCCSmallAm = true and
                                            vlIsCreateAutoBalanceLCSmallAm = true).
        end. /* if not vlIsCreateAutoBalance */
   
        /* Create a message containing content of the posting */
        assign vcPostingMessage = #T-1'Posting details:  &1/&2/&3/&4':255(43446359)T-1#
               vcPostingMessage = substitute(vcPostingMessage, tPosting.PostingYear, tPosting.PostingYearPeriod, tPosting.tcJournalCode, tPosting.PostingVoucher)
               vcPostingMessage = vcPostingMessage + chr(10)
               vcPostingMessage = vcPostingMessage + substitute(#T-82'Balance in transaction currency: &1':255(3215)T-82#, vdBalanceTC) + chr(10)
               vcPostingMessage = vcPostingMessage + substitute(#T-55'Balance in statutory currency: &1':255(298364963)T-55#, vdBalanceCC) + chr(10)
               vcPostingMessage = vcPostingMessage + substitute(#T-2'Balance in base currency: &1':255(3216)T-2#, vdBalanceLC) + chr(10)
               vcPostingMessage = vcPostingMessage + chr(10)
               vcPostingMessage = vcPostingMessage + #T-79'Posting line details:':255(39827807)T-79#
               vcPostingMessage = vcPostingMessage + chr(10).

        for each tPostingLine where
                 tPostingLine.tc_ParentRowid = tPosting.tc_Rowid and 
                 tPostingLine.tc_Status <> "D":U :
           
            if length(vcPostingMessage, "CHARACTER") < 30000
            then assign vcPostingMessage = vcPostingMessage + chr(10) + 
                                           trim(substitute(#T-26'Amount for account &1 (&2):  transaction currency: &3 &4, base currency: &5 &6, Statutory Currency: &7 &8':255(595660160)T-26#,
                                                           tPostingLine.tcGLCode,
                                                           tPostingLine.tcGLDescription,
                                                           tPostingLine.PostingLineDebitTC - tPostingLine.PostingLineCreditTC,
                                                           tPostingLine.tcCurrencyCode,
                                                           tPostingLine.PostingLineDebitLC - tPostingLine.PostingLineCreditLC,
                                                           vcCompanyLC,
                                                           tPostingLine.PostingLineDebitCC - tPostingLine.PostingLineCreditCC,
                                                           vcCompanyCC)).  
            else do:
                assign vcPostingMessage = vcPostingMessage + chr(10) +
                                          trim(#T-78'Note: Not all postinglines are included in the message.':255(999890618)T-78#).
                leave.
            end. /* else do */
        end. /* for each tPostingLine where */
        
        assign vcMsgExplanation = <M-34 GetErrorExplanation
                                     (input  tPosting.tc_Rowid (icPostingRowId), 
                                      input  ? (icPostingLineRowId), 
                                      output viFcReturnSuper (oiReturnStatus)) in BPosting>.
                              
        /* Now, create a message to alert/block user about the situation */
        assign vcMessage = substitute(#T-80'The journal entry balance must be zero for posting &1\&2\&3.':255(63303)T-80#, tPosting.PostingYear, tPosting.tcJournalCode, tPosting.PostingVoucher) + chr(10) +
                           (if vlIsCreateAutoBalance then #T-3'Therefore system automatically created Auto-balance posting line, which does full balancing of the posting. This posting has to be carefully reviewed and the posted balance needs to be posted to correct GL account manually.':255(674407668)T-3# else "":U) + chr(10) + chr(10) +
                           vcPostingMessage.
        
        <M-62 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  '':U (icFieldName), 
            input  '':U (icFieldValue), 
            input  if vlIsCreateAutoBalance then 'W':U else 'E':U (icType), 
            input  3 (iiSeverity), 
            input  tPosting.tc_Rowid (icRowid), 
            input  'qadfin-429645':U (icFcMsgNumber), 
            input  vcMsgExplanation (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BPosting>

        assign viLocalReturnStatus = if vlIsCreateAutoBalance then 1 else -1.
        if not vlIsCreateAutoBalance
        then next.
        
        /* Create the Auto-balancing posting line */
        <M-19 run AddDetailLine
           (input  'PostingLine':U (icTable), 
            input  tPosting.tc_Rowid (icParentRowid), 
            output viFcReturnSuper (oiReturnStatus)) in BPosting>
        if viFcReturnSuper < 0 or viFcReturnSuper > 0 and viLocalReturnStatus = 0 then assign viLocalReturnStatus = viFcReturnSuper.
        if viLocalReturnStatus  < 0 then leave MAIN_BLOCK.
                                          
        assign tPostingLine.PostingLine_ID               = tPostingLine.PostingLine_ID
               tPostingLine.PostingLineDebitTC           = 0
               tPostingLine.PostingLineCreditTC          = 0
               tPostingLine.PostingLineDebitLC           = if vdBalanceLC > 0 then 0 else - vdBalanceLC
               tPostingLine.PostingLineCreditLC          = if vdBalanceLC > 0 then vdBalanceLC else 0
               tPostingLine.PostingLineDebitCC           = if vdBalanceCC > 0 then 0 else - vdBalanceCC
               tPostingLine.PostingLineCreditCC          = if vdBalanceCC > 0 then vdBalanceCC else 0
               tPostingLine.PostingLineExchangeRate      = 1
               tPostingLine.PostingLineRateScale         = 1
               tPostingLine.PostingLineCCRate            = 1
               tPostingLine.PostingLineCCScale           = 1
               tPostingLine.Period_ID                    = tPosting.Period_ID            
               tPostingLine.Company_ID                   = tPosting.Company_ID
               tPostingLine.PostingYearPeriod            = tPosting.PostingYearPeriod    
               tPostingLine.PostingDate                  = tPosting.PostingDate
               tPostingLine.Currency_ID                  = viCompanyLCId
               tPostingLine.tcCurrencyCode               = vcCompanyLC
               tPostingLine.GL_ID                        = tqGLBySystemTypeAndType.tiGL_ID
               tPostingLine.tcGLCode                     = tqGLBySystemTypeAndType.tcGLCode
               tPostingLine.tcGLTypeCode                 = tqGLBySystemTypeAndType.tcGLSystemTypeCode
               tPostingLine.tlLinkedCrCyDaemonReqExists  = false
               vcAutoBalancePostingRowIds                = (if vcAutoBalancePostingRowIds = ? or vcAutoBalancePostingRowIds = "":U
                                                            then tPostingLine.tc_Rowid
                                                            else vcAutoBalancePostingRowIds + ',':U + tPostingLine.tc_Rowid).
                                                                      
        /* ================================================================================*/
        /* Create Q posting hist record for Posing hist daemon update                      */
        /* ================================================================================*/
        <M-92 run AdditionalUpdatesCreateQPostingLineN  (output viFcReturnSuper (oiReturnStatus)) in BPosting>
        if viFcReturnSuper < 0 or viFcReturnSuper > 0 and viLocalReturnStatus = 0 then assign viLocalReturnStatus = viFcReturnSuper.
        if viLocalReturnStatus  < 0 then leave MAIN_BLOCK.

        /* ================================================================================*/
        /* Create mail for all people in the  Auto-balancing notification role             */
        /* ================================================================================*/
        find tAutoBalanceMailNotif where
             tAutoBalanceMailNotif.tiCompanyId = tPosting.Company_ID no-error.

        if not available tAutoBalanceMailNotif
        then do:
            create tAutoBalanceMailNotif.
            assign tAutoBalanceMailNotif.tiCompanyId = tPosting.Company_ID
                   tAutoBalanceMailNotif.tcSubject   = #T-29'QAD Finance EE - Unexpected Auto-balancing posting was created.':255(869369984)T-29#
                   tAutoBalanceMailNotif.tcMailBody  = #T-60'Unexpected issue during creation of the Journal Entry':255(152597130)T-60# + chr(10) + chr(10) +
                                                       #T-77'During creation of the Journal Entry transaction, the transaction was not created completely correct.':255(814663754)T-77# + " ":U +
                                                       #T-42'Created transaction was not balanced either in Base or Statutory currency.':255(401730655)T-42# + " ":U +
                                                       #T-96'Therefore system automatically balanced the posting by creation of one extra posting line to Auto-Balance GL account.':255(257812680)T-96# + " ":U + 
                                                       #T-44'This Auto-balancing posting prevents users to be blocked by execution of the required activity.':255(20194736)T-44# + " ":U +
                                                       #T-32'Nevertheless the Journal entry is not correct and thus has to be reviewed and corrected by manual Journal Entry.':255(646551606)T-32# + " ":U +
                                                       #T-10'In other case system can produce incorrect financial result.':255(639179058)T-10# + chr(10) + chr(10) +
                                                       substitute(#T-7'Entity: &1':255(117782143)T-7#, vcCompanyCode) + chr(10).

            /* If there is role "Auto Balance Notification" created, send a mail to all people */
            /* if there is not such role, no mail is send                                      */
            <Q-75 run RolePrim (all) (Read) (NoCache)
               (input ?, (RoleID)
                input {&NOTIFICATION-AUTOBALANCE}, (RoleName)
                output dataset tqRolePrim) in BRole>
            find tqRolePrim where 
                 tqRolePrim.tcRoleName = {&NOTIFICATION-AUTOBALANCE}
                 no-error.
            if available tqRolePrim
            then do:
                /* Get all users linked to the role */
                <Q-97 run UsrRoleCompanyForMail (all) (Read) (NoCache)
                   (input tPosting.Company_ID, (CompanyId)
                    input tqRolePrim.tiRole_ID, (RoleId)
                    output dataset tqUsrRoleCompanyForMail) in BUserRole>
        
                /* Make list of email addresses where the mail is send to */
                assign vcEmailAddressList = "":U.
                for each tqUsrRoleCompanyForMail where
                         tqUsrRoleCompanyForMail.tlUsrIsactive     = true and
                         tqUsrRoleCompanyForMail.tcUsrMailAddress <> "":U and
                         tqUsrRoleCompanyForMail.tcUsrMailAddress <> ?:
                    assign tAutoBalanceMailNotif.tcSendTo = if tAutoBalanceMailNotif.tcSendTo = "":U
                                                            then tqUsrRoleCompanyForMail.tcUsrMailAddress
                                                            else tAutoBalanceMailNotif.tcSendTo + "|":U + tqUsrRoleCompanyForMail.tcUsrMailAddress.
                end.
            end. /* if available tqRolePrim */
        end. /* if not availalbe tAutoBalanceMailNotif */

        /* put posting details to the mail body */
        assign tAutoBalanceMailNotif.tcMailBody = tAutoBalanceMailNotif.tcMailBody + chr(10) + chr(10) + vcPostingMessage.
    end. /* for each tPosting where */
end. /* MAIN_BLOCK */

/* Error handling */
assign oiReturnStatus = viLocalReturnStatus.