project BLF > class BSODPolicyException > method AdditionalUpdates

Description

This method is part of the SetPublicTables flow.
When executed, data in the input class tables (prefix t_s) is validated and found correct, and copied into the class tables (prefix t_o).
This method can be extended to do updates that do not require a validation or that involve running business methods of other business classes. These classes should be started with ADD-TO-TRANSACTION = 'true'. Also make sure to add these classes in method StopExternalInstances.


Parameters


oiReturnStatusoutputinteger


Internal usage


unused


program code (program/bsodpolicyexception.p)

<ANCESTOR-CODE>

/* ========================================================== */
/* When the user changed, convert this do a delete and create */
/* ========================================================== */
for each bSODException where
         bSODException.tc_Status = "C",
    each t_iSODException where
         t_iSODException.tc_Rowid = bSODException.tc_Rowid and
         t_iSODException.Usr_ID  <> bSODException.Usr_ID:
    <M-31 run AddDetailLine
       (input  'SODException' (icTable), 
        input  '' (icParentRowid), 
        output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
        
    if viFcReturnSuper <> 0
    then assign oiReturnStatus = viFcReturnSuper.

    if viFcReturnSuper < 0
    then return.

    assign tSODException.SODExceptionCode        = bSODException.SODExceptionCode
           tSODException.SODExceptionDescription = bSODException.SODExceptionDescription
           tSODException.Usr_ID                  = bSODException.Usr_ID
           tSODException.tcUsrLogin              = bSODException.tcUsrLogin.

    for each bSODExceptionLine where
             bSODExceptionLine.tc_ParentRowid = bSODException.tc_Rowid:
        if bSODExceptionLine.tc_Status <> "N"
        then do:
            find t_iSODExceptionLn where
                 t_iSODExceptionLn.tc_Rowid = bSODExceptionLine.tc_Rowid
                 no-error.

            if not available t_iSODExceptionLn
            then do:
                <M-88 run SetMessage
                   (input  trim(#T-73'Internal error: no initial record found for modified SODExceptionLn record.':255(63585387)T-73#) (icMessage), 
                    input  '' (icArguments), 
                    input  '' (icFieldName), 
                    input  '' (icFieldValue), 
                    input  'E' (icType), 
                    input  3 (iiSeverity), 
                    input  bSODException.tc_Rowid (icRowid), 
                    input  'blf-762514':U (icFcMsgNumber), 
                    input  '' (icFcExplanation), 
                    input  '' (icFcIdentification), 
                    input  '' (icFcContext), 
                    output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
                    
                assign oiReturnStatus = -3.
                return.
            end.
        end.

        if bSODExceptionLine.tc_Status <> "D"
        then do:
            <M-41 run AddDetailLine
               (input  'SODExceptionLn' (icTable), 
                input  tSODException.tc_Rowid (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
                
            assign tSODExceptionLn.Company_ID                = bSODExceptionLine.Company_ID
                   tSODExceptionLn.Domain_ID                 = bSODExceptionLine.Domain_ID
                   tSODExceptionLn.SODCategory1_ID           = bSODExceptionLine.SODCategory1_ID
                   tSODExceptionLn.SODCategory2_ID           = bSODExceptionLine.SODCategory2_ID
                   tSODExceptionLn.SODExceptionLnDescription = bSODExceptionLine.SODExceptionLnDescription
                   tSODExceptionLn.tcCompanyCode             = bSODExceptionLine.tcCompanyCode
                   tSODExceptionLn.tcDomainCode              = bSODExceptionLine.tcDomainCode
                   tSODExceptionLn.tcSODCategory1Code        = bSODExceptionLine.tcSODCategory1Code
                   tSODExceptionLn.tcSODCategory2Code        = bSODExceptionLine.tcSODCategory2Code.
        end.

        if bSODExceptionLine.tc_Status = "N"
        then delete bSODExceptionLine.
        else assign bSODExceptionLine.Company_ID                = t_iSODExceptionLn.Company_ID
                    bSODExceptionLine.Domain_ID                 = t_iSODExceptionLn.Domain_ID
                    bSODExceptionLine.SODCategory1_ID           = t_iSODExceptionLn.SODCategory1_ID
                    bSODExceptionLine.SODCategory2_ID           = t_iSODExceptionLn.SODCategory2_ID
                    bSODExceptionLine.SODExceptionLnDescription = t_iSODExceptionLn.SODExceptionLnDescription
                    bSODExceptionLine.tcCompanyCode             = t_iSODExceptionLn.tcCompanyCode
                    bSODExceptionLine.tcDomainCode              = t_iSODExceptionLn.tcDomainCode
                    bSODExceptionLine.tcSODCategory1Code        = t_iSODExceptionLn.tcSODCategory1Code
                    bSODExceptionLine.tcSODCategory2Code        = t_iSODExceptionLn.tcSODCategory2Code
                    bSODExceptionLine.tc_Status                 = "".
    end.

    assign bSODException.SODExceptionCode        = t_iSODException.SODExceptionCode
           bSODException.SODExceptionDescription = t_iSODException.SODExceptionDescription
           bSODException.Usr_ID                  = t_iSODException.Usr_ID
           bSODException.tcUsrLogin              = t_iSODException.tcUsrLogin
           bSODException.tc_Status               = "D".
end.

/* ================================================================= */
/* When anything except description is changed on a detail line,     */
/* convert this to a delete and a create.                            */
/* ================================================================= */
for each tSODException where
         tSODException.tc_Status <> "D",
    each bSODExceptionLine where
         bSODExceptionLine.tc_ParentRowid = tSODException.tc_Rowid and
         bSODExceptionLine.tc_Status = "C",
    each t_iSODExceptionln where
         t_iSODExceptionLn.tc_Rowid = bSODExceptionLine.tc_Rowid and
        (t_iSODExceptionLn.Domain_ID <> bSODExceptionLine.Domain_ID or
         t_iSODExceptionLn.Company_ID <> bSODExceptionLine.Company_ID or
         t_iSODExceptionLn.SODCategory1_ID <> bSODExceptionLine.SODCategory1_ID or
         t_iSODExceptionLn.SODCategory2_ID <> bSODExceptionLine.SODCategory2_ID):

    <M-72 run AddDetailLine
       (input  'SODExceptionLn' (icTable), 
        input  tSODException.tc_Rowid (icParentRowid), 
        output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
    if viFcReturnSuper <> 0
    then oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper < 0
    then return.

    assign tSODExceptionLn.SODException_ID = tSODException.SODException_ID
           tSODExceptionLn.Domain_ID       = bSODExceptionLine.Domain_ID
           tSODExceptionLn.Company_ID      = bSODExceptionLine.Company_ID
           tSODExceptionLn.SODCategory1_ID = bSODExceptionLine.SODCategory1_ID
           tSODExceptionLn.SODCategory2_ID = bSODExceptionLine.SODCategory2_ID
           tSODExceptionLn.SODExceptionLnDescription = bSODExceptionLine.SODExceptionLnDescription
           
           bSODExceptionLine.Domain_ID       = t_iSODExceptionln.Domain_ID
           bSODExceptionLine.Company_ID      = t_iSODExceptionln.Company_ID
           bSODExceptionLine.SODCategory1_ID = t_iSODExceptionln.SODCategory1_ID
           bSODExceptionLine.SODCategory2_ID = t_iSODExceptionln.SODCategory2_ID
           bSODExceptionLine.SODExceptionLnDescription = t_iSODExceptionln.SODExceptionLnDescription
           bSODExceptionLine.tc_Status = "D".
end.

<Q-14 assign vlFcQueryRecordsAvailable = SystSODBlockViolations (NoCache)  () in BSystem >

if vlFcQueryRecordsAvailable
then do:
    vlSystBlockViolations = yes.
    
    /* ================================================================= */
    /* Block deletes that would create a violation.                      */
    /* ================================================================= */
    for each tSODException where
             tSODException.Usr_ID <> 0 and
             tSODException.Usr_ID <> ?,
        each tSODExceptionLn where
             tSODExceptionLn.tc_ParentRowid = tSODException.tc_Rowid and
             tSODExceptionLn.SODCategory1_ID <> 0 and
             tSODExceptionLn.SODCategory1_ID <> ? and
             tSODExceptionLn.SODCategory2_ID <> 0 and
             tSODExceptionLn.SODCategory2_ID <> ? and
            (tSODExceptionLn.tc_Status = "D" or tSODException.tc_Status = "D") on error undo, throw:

        <Q-98 assign vlFcQueryRecordsAvailable = CategoriesAreInConflict (NoCache)
           (input tSODExceptionLn.SODCategory1_ID, (Category1ID)
            input tSODExceptionLn.SODCategory2_ID, (Category2ID)) in BSODCategoryExclusion >
        if vlFcQueryRecordsAvailable
        then if tSODExceptionLn.Company_ID = 0
             or tSODExceptionLn.Company_ID = ?
        then do:
            <Q-16 run ResourceMatrixByUser (all) (Read) (NoCache)
               (input 0, (CompanyId)
                input tSODException.Usr_ID, (UsrID)
                input tSODExceptionLn.Domain_ID, (DomainID)
                input tSODExceptionLn.SODCategory1_ID, (SODCategoryID)
                output dataset tqResourceMatrixByUser) in BUserRole >
            for each tqResourceMatrixByUser break by tqResourceMatrixByUser.tiCompany_ID on error undo, throw:
                if first-of (tqResourceMatrixByUser.tiCompany_ID)
                then do:
                    <Q-70 assign vlFcQueryRecordsAvailable = ResourceMatrixByUser (NoCache)
                       (input tqResourceMatrixByUser.tiCompany_ID, (CompanyId)
                        input tSODException.Usr_ID, (UsrID)
                        input 0, (DomainID)
                        input tSODExceptionLn.SODCategory2_ID, (SODCategoryID)) in BUserRole >
                    if vlFcQueryRecordsAvailable <> no
                    then do:
                        oiReturnStatus = -1.
                        <M-28 run SetMessage
                           (input  #T-95'Cannot delete the SOD policy exception, because it would violate SOD rules.':255(940169720)T-95# (icMessage), 
                            input  '' (icArguments), 
                            input  '' (icFieldName), 
                            input  '' (icFieldValue), 
                            input  'E' (icType), 
                            input  3 (iiSeverity), 
                            input  tSODExceptionLn.tc_Rowid (icRowid), 
                            input  'blf-715584':U (icFcMsgNumber), 
                            input  '' (icFcExplanation), 
                            input  '' (icFcIdentification), 
                            input  '' (icFcContext), 
                            output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
                        return.
                    end.
                end.
            end.
        end.
        else do:
            <Q-19 assign vlFcQueryRecordsAvailable = ResourceMatrixByUser (NoCache)
               (input tSODExceptionLn.Company_ID, (CompanyId)
                input tSODException.Usr_ID, (UsrID)
                input 0, (DomainID)
                input tSODExceptionLn.SODCategory1_ID, (SODCategoryID)) in BUserRole >
            if vlFcQueryRecordsAvailable <> no
            then do:
                <Q-76 assign vlFcQueryRecordsAvailable = ResourceMatrixByUser (NoCache)
                   (input tSODExceptionLn.Company_ID, (CompanyId)
                    input tSODException.Usr_ID, (UsrID)
                    input 0, (DomainID)
                    input tSODExceptionLn.SODCategory2_ID, (SODCategoryID)) in BUserRole >
                if vlFcQueryRecordsAvailable <> no
                then do:
                    oiReturnStatus = -1.
                    <M-71 run SetMessage
                       (input  #T-54'Cannot delete the SOD policy exception, because it would violate SOD rules.':255(940169720)T-54# (icMessage), 
                        input  '' (icArguments), 
                        input  '' (icFieldName), 
                        input  '' (icFieldValue), 
                        input  'E' (icType), 
                        input  3 (iiSeverity), 
                        input  tSODExceptionLn.tc_Rowid (icRowid), 
                        input  'blf-647275':U (icFcMsgNumber), 
                        input  '' (icFcExplanation), 
                        input  '' (icFcIdentification), 
                        input  '' (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
                    return.
                end.
            end.
        end.
    end.
end.

vcEUsersForSODViolationCheck = "".

<Q-25 assign vlFcQueryRecordsAvailable = SystSODActive (NoCache)  () in BSystem >
if vlFcQueryRecordsAvailable
then do:

/* ================================================================= */
/* Creating new exceptions may solve existing violations.            */
/* ================================================================= */
if can-find (first tSODExceptionLn where tSODExceptionLn.tc_Status = "N")
then do:
    <I-1 {bFcAddToTransaction
         &CLASS           = "BSODViolationRule2"}>

    for each tSODException where tSODException.tc_Status <> "D",
        each tSODExceptionLn where
             tSODExceptionLn.tc_ParentRowid = tSODException.tc_Rowid and
             tSODExceptionLn.tc_Status = "N" on error undo, throw:
        <M-2 run DeleteByUserRoleCompanyCategory
           (input  tSODException.Usr_ID (iiUsrID), 
            input  0 (iiRoleID), 
            input  tSODExceptionLn.Domain_ID (iiDomainID), 
            input  tSODExceptionLn.Company_ID (iiCompanyID), 
            input  tSODExceptionLn.SODCategory1_ID (iiSODCategory1ID), 
            input  tSODExceptionLn.SODCategory2_ID (iiSODCategory2ID), 
            output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
        if viFcReturnSuper = -4
        then viFcReturnSuper = 0.
        else vlDeletesDone = yes.
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
    end.

    if vlDeletesDone
    then do:
        <M-4 run DeleteFinish  (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
        <I-6 {bFcCloseInstance
             &CLASS           = "BSODViolationRule2"}>
    end.
    else do:
        <I-7 {bFcCloseAndStopInstance
             &CLASS           = "BSODViolationRule2"}>
    end.
end.

if not vlSystBlockViolations
then do:
    /* ================================================================= */
    /* Check if delete of exceptions creates new violations.             */
    /* These violations are created outside current transaction and will */
    /* not block the delete.                                             */
    /* ================================================================= */
    for each tSODException where tSODException.tc_Status = "D" on error undo, throw:
        if not can-do(vcEUsersForSODViolationCheck,string(tSODException.Usr_ID))
        then vcEUsersForSODViolationCheck = (if vcEUsersForSODViolationCheck = ""
                                             then ""
                                             else vcEUsersForSODViolationCheck + ",")
                                          + string(tSODException.Usr_ID).
    end.
    
    for each tSODException where tSODException.tc_Status <> "D" on error undo, throw:
        if can-find (first tSODExceptionLn where
                           tSODExceptionLn.tc_ParentRowid = tSODException.tc_Rowid and
                           tSODExceptionLn.tc_Status      = "D")
        then
        if not can-do(vcEUsersForSODViolationCheck,string(tSODException.Usr_ID))
        then vcEUsersForSODViolationCheck = (if vcEUsersForSODViolationCheck = ""
                                             then ""
                                             else vcEUsersForSODViolationCheck + ",")
                                          + string(tSODException.Usr_ID).
    end.
end.

end.

finally:
    if oiReturnStatus < 0
    then do:
        <M-93 run StopExternalInstances  (output viFcReturnSuper (oiReturnStatus)) in BSODPolicyException>
    end.
end finally.