project QadFinancials > class BBudget > method ValidateComponentValidateStruct

Description

This method will validate the Budget-Structure
Note that this method updates the tBudget and tBudgetPeriod tables and passes these updates towrds the caller using the input-output table parameters.


Parameters


tNewBudgetinput-outputtemp-tableTemp table containing a single Budget;
tNewBudgetPeriodinput-outputtemp-tableNewBugetPeriod
tNewBudgetCompanyinputtemp-tableNewBudgetCompany
tNewBudgetFDSinputtemp-tableNewBudgetFDS
ilCopyContentToInstanceTablesinputlogicalCopyContentToInstanceTables
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BBudget.ValidateComponent


program code (program5/bbudget.p)

/* ========================= */
/* Set default Return Status */
/* ========================= */
assign oiReturnStatus = -9999999. /* this fixed value is also used at the end of this method */

/* ====================================================================================== */
/* General Budget Checks:                                                                 */
/*   Check for a single Budget record                                                     */
/*   Company-dependant budgets should only have a single BudgetCompany record             */
/* After going through all tNewBudget-records; find tNewBudget so it can be used later on */
/* ====================================================================================== */
assign vcMessage = "":U.
NEWBUDGETBLOCK : DO :
for each tNewBudget where 
         tNewBudget.tc_Status <> "D":U no-lock : 
    assign viNewRecordCounter = viNewRecordCounter + 1.
end. /* for each tNewBudget no-lock */
if viNewRecordCounter <> 1
then do :
    assign vcMessage      = trim(#T-22'You must enter one single budget record for the structure validation.':255(515)T-22#).
    Leave NEWBUDGETBLOCK.
end. /* viNewRecordCounter <> 1 */
find first tNewBudget no-error.
assign viNewRecordCounter = 0.
for each tNewBudgetCompany where 
         tNewBudgetCompany.tc_ParentRowid  = tNewBudget.tc_Rowid and 
         tNewBudgetCompany.tc_Status      <> "D":U
         no-lock : 
    assign viNewRecordCounter = viNewRecordCounter + 1.
end. /* for each tNewBudgetCompany no-lock */
if viNewRecordCounter = 0 
then do :
    assign vcMessage      = trim(#T-23'A budget should be linked to at least one entity.':255(516)T-23#).
    Leave NEWBUDGETBLOCK.
end. /* if viNewRecordCounter = 0 */
END. /* NEWBUDGETBLOCK */
find first tNewBudget no-error.
if vcMessage <> "":U
then do :
    assign oiReturnStatus = -1.
    <M-8 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-500':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BBudget>
end. /* if vcMessage <> "":U */

/* ================================================================================ */
/* FDS Validations:                                                                 */
/*   Some FDS-types should only appear once: GL/Div/Prj/CC                          */
/*   Safs should be defined on the lowest level (except towards totals)             */
/*   Project-budgets should not contain FDS-types 'Project'                         */
/*   CostCentre-budgets should not contain FDS-types 'CostCentre'                   */
/*   Sequence should start by 1 and be consequetive                                 */            
/* ================================================================================ */
assign vcMessage = "":U.
NEWBUDGETFDSBLOCK : do : 
    /* === Sequence should start by 1 and be consequetive === */
    assign viNewRecordCounter = 0.
    for each tNewBudgetFDS where
             tNewBudgetFDS.tc_Status <> "D":U and 
             tNewBudgetFDS.tc_ParentRowid = tNewBudget.tc_Rowid
             no-lock by tNewBudgetFDS.BudgetFDSSeq :
        assign viNewRecordCounter = viNewRecordCounter + 1.
        if viNewRecordCounter <> tNewBudgetFDS.BudgetFDSSeq
        then do :
            assign vcMessage      = trim(#T-25'The sequence of the budget structure levels (COA) should be consecutive and start with 1.':255(518)T-25#).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if viNewRecordCounter <> tNewBudgetFDS.BudgetFDSSeq */
    end. /* for each tNewBudgetFDS no-lock */
    
    assign viBudgetUpperLimitLevels = <M-87 GetBudgetUpperLimitLevels  () in BBudget>.
    
    if viNewRecordCounter > viBudgetUpperLimitLevels
    then do :
        assign vcMessage  = trim(substitute(#T-26'A budget cannot have more than &1 budget structure levels (COA).':255(338821507)T-26#,string(viBudgetUpperLimitLevels))) + chr(10) +
                            trim(substitute(#T-27'Budget: &1.':255(470)T-27#,tNewBudget.BudgetCode)).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if viNewRecordCounter = 0 */
    if tNewBudget.BudgetInputLevelBudget <> viNewRecordCounter
    then do :
        assign vcMessage  = trim(substitute(#T-28'The input level for budget figures (&1) should match the highest COA sequence (&2).':255(520)T-28#,string(tNewBudget.BudgetInputLevelBudget),string(viNewRecordCounter))) + chr(10) +
                            trim(substitute(#T-29'Budget: &1.':255(470)T-29#,tNewBudget.BudgetCode)).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if */
    if tNewBudget.BudgetInputLevelEAC > viNewRecordCounter
    then do :
        assign vcMessage  = trim(substitute(#T-30'The input level for EAC figures (&1) cannot exceed the highest COA sequence (&2).':255(521)T-30#,string(tNewBudget.BudgetInputLevelEAC),string(viNewRecordCounter))) + chr(10) +
                            trim(substitute(#T-31'Budget: &1.':255(470)T-31#,tNewBudget.BudgetCode)).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if */
    if tNewBudget.BudgetInputLevelFin > viNewRecordCounter
    then do :
        assign vcMessage  = trim(substitute(#T-32'The input level for financial figures (&1) cannot exceed the highest COA sequence (&2).':255(522)T-32#,string(tNewBudget.BudgetInputLevelFin),string(viNewRecordCounter))) + chr(10) +
                            trim(substitute(#T-33'Budget: &1.':255(470)T-33#,tNewBudget.BudgetCode)).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if */
    if viNewRecordCounter = 0
    then do :
        assign vcMessage  = trim(#T-34'A budget should have at least 1 budget structure level (COA).':255(523)T-34#) + chr(10) +
                            trim(substitute(#T-35'Budget: &1.':255(470)T-35#,tNewBudget.BudgetCode)).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if viNewRecordCounter = 0 */
    /* Totals not allowed on the lowest level */
    find last tNewBudgetFDS where
              tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid    and
              tNewBudgetFDS.tc_Status      <> "D":U                  and
              tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-TOTAL} and 
              tNewBudgetFDS.BudgetFDSSeq    = viNewRecordCounter
              no-lock no-error.
    if available tNewBudgetFDS
    then do :
        assign vcMessage = trim(substitute(#T-36'The budget structure type &1 cannot be on the lowest levels of the tree.':255(524)t-36#,trim({&BUDGETFDSTYPE-TOTAL-TR}))).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if available tNewBudgetFDS */
    /* === Project/CC-budgets should only contain FDS-types TOTAL and SAF === */
    if ((tNewBudget.tcProjectCode <> "":U and 
         tNewBudget.tcProjectCode <> ?)  or
        (tNewBudget.tcCostCentreCode <> "":U and 
         tNewBudget.tcCostCentreCode <> ?)) and 
       can-find (first tNewBudgetFDS where
                       tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid  and
                       tNewBudgetFDS.tc_Status      <> "D":U                and
                       tNewBudgetFDS.BudgetFDSType  <> {&BUDGETFDSTYPE-SAF} and
                       tNewBudgetFDS.BudgetFDSType  <> {&BUDGETFDSTYPE-TOTAL})
    then do :
        assign vcMessage      = trim(substitute(#T-37'Project and cost center budgets can only have budget structure levels (COA) of type &1 or &2.':255(525)T-37#,trim({&BUDGETFDSTYPE-SAF-TR}),trim({&BUDGETFDSTYPE-TOTAL-TR}))).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if tNewBudget.tcProjectCode <> "":U */
    /* === GL: Existance only once === */
    assign viFDSSequence = 0.
    find first tNewBudgetFDS where
               tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
               tNewBudgetFDS.tc_Status      <> "D":U               and
               tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-GL}
               no-lock no-error.
    if available tNewBudgetFDS 
    then do :
        assign viFDSSequence = tNewBudgetFDS.BudgetFDSSeq.
        find first tNewBudgetFDS where
                   tNewBudgetFDS.tc_ParentRowid = tNewBudget.tc_Rowid and
                   tNewBudgetFDS.tc_Status      <> "D":U              and
                   tNewBudgetFDS.BudgetFDSType  = {&BUDGETFDSTYPE-GL} and 
                   tNewBudgetFDS.BudgetFDSSeq  <> viFDSSequence
                   no-lock no-error.
        if available tNewBudgetFDS
        then do :
            assign vcMessage      = trim(substitute(#T-38'Budget structure level &1 can only occur once.':255(526)T-38#,trim({&BUDGETFDSTYPE-GL-TR}))).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if available tNewBudgetFDS */
    end. /* if available tNewBudgetFDS */
    /* === DIV: Existance only once === */
    assign viFDSSequence = 0.
    find first tNewBudgetFDS where
               tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
               tNewBudgetFDS.tc_Status      <> "D":U               and
               tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-DIVISION}
               NO-LOCK no-error.
    if available tNewBudgetFDS 
    then do :
        assign viFDSSequence = tNewBudgetFDS.BudgetFDSSeq.
        find first tNewBudgetFDS where
                   tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
                   tNewBudgetFDS.tc_Status      <> "D":U               and
                   tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-DIVISION} and 
                   tNewBudgetFDS.BudgetFDSSeq   <> viFDSSequence
                   no-lock no-error.
        if available tNewBudgetFDS
        then do :
            assign vcMessage      = trim(substitute(#T-39'Budget structure level &1 can only occur once.':255(526)T-39#,trim({&BUDGETFDSTYPE-DIVISION-TR}))).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if available tNewBudgetFDS */
    end. /* if available tNewBudgetFDS */
    /* === Project: Existance only once // not with CC === */
    assign viFDSSequence = 0.
    find first tNewBudgetFDS where
               tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
               tNewBudgetFDS.tc_Status      <> "D":U               and
               tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-PROJECT}
               no-lock no-error.
    if available tNewBudgetFDS 
    then do :
        assign viFDSSequence = tNewBudgetFDS.BudgetFDSSeq.
        find first tNewBudgetFDS where
                   tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
                   tNewBudgetFDS.tc_Status      <> "D":U               and
                   tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-PROJECT} and 
                   tNewBudgetFDS.BudgetFDSSeq   <> viFDSSequence
                   no-lock no-error.
        if available tNewBudgetFDS
        then do :
            assign vcMessage      = trim(substitute(#T-40'Budget structure level &1 can only occur once.':255(526)T-40#,trim({&BUDGETFDSTYPE-PROJECT-TR}))).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if available tNewBudgetFDS */
    end. /* if available tNewBudgetFDS */
    /* === CostCentre: Existance only once === */
    assign viFDSSequence = 0.
    find first tNewBudgetFDS where
               tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
               tNewBudgetFDS.tc_Status      <> "D":U               and
               tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-COSTCENTRE}
               no-lock no-error.
    if available tNewBudgetFDS 
    then do :
        assign viFDSSequence = tNewBudgetFDS.BudgetFDSSeq.
        find first tNewBudgetFDS where
                   tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
                   tNewBudgetFDS.tc_Status      <> "D":U               and
                   tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-COSTCENTRE} and 
                   tNewBudgetFDS.BudgetFDSSeq   <> viFDSSequence
                   no-lock no-error.
        if available tNewBudgetFDS
        then do :
            assign vcMessage      = trim(substitute(#T-42'Budget structure level &1 can only occur once.':255(526)T-42#,trim({&BUDGETFDSTYPE-COSTCENTRE-TR}))).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if available tNewBudgetFDS */
    end. /* if available tNewBudgetFDS */
    /* === Safs need to be on the lowest level === */
    assign viFDSSequence = 0.
    for each tNewBudgetFDS where 
             tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid and
             tNewBudgetFDS.tc_Status      <> "D":U               and
             tNewBudgetFDS.BudgetFDSType   = {&BUDGETFDSTYPE-SAF}
             no-lock :
        assign viSAFCounter = viSAFCounter + 1.
        if tNewBudgetFDS.BudgetFDSSeq < viFDSSequence or
           viFDSSequence = 0
        then assign viFDSSequence = tNewBudgetFDS.BudgetFDSSeq.
    end. /* for each tNewBudgetFDS no-lock */
    if viFDSSequence > 0
    then do :
        find first tNewBudgetFDS where
                   tNewBudgetFDS.tc_ParentRowid  = tNewBudget.tc_Rowid    and
                   tNewBudgetFDS.tc_Status      <> "D":U                  and
                   tNewBudgetFDS.BudgetFDSType  <> {&BUDGETFDSTYPE-SAF}   and 
                   tNewBudgetFDS.BudgetFDSType  <> {&BUDGETFDSTYPE-TOTAL} and 
                   tNewBudgetFDS.BudgetFDSSeq    > viFDSSequence
                   no-lock no-error.
        if available tNewBudgetFDS
        then do :
            assign vcMessage = trim(substitute(#T-43'Budget structure types &1 and &2 should always be on the lowest levels of the tree.':255(528)T-43#,trim({&BUDGETFDSTYPE-SAF-TR}),trim({&BUDGETFDSTYPE-TOTAL-TR}))).
            Leave NEWBUDGETFDSBLOCK.
        end. /* if available tNewBudgetFDS */
    end. /* if viFDSSequence > 0 */
    /* Max 5 saf levels */
    if viSAFCounter > 5
    then do :
        assign vcMessage = trim(substitute(#T-44'The COA tree can contain a maximum of 5 entries of COA type &2. Budget: &1.':255(529)t-44#,tNewBudget.BudgetCode,{&BUDGETFDSTYPE-SAF-TR})).
        Leave NEWBUDGETFDSBLOCK.
    end. /* if viSAFCounter > 5 */
END. /* NEWBUDGETFDSBLOCK */
if vcMessage <> "":U
then do :
    ASSIGN oiReturnStatus = -1.
    <M-10 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-499':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BBudget>
end. /* if vcMessage <> "":U */

/* Check for Structurereports */

if avail tnewbudget and tNewBudget.BudgetIsReportStruct
Then do:
    <M-54 run ValidateComponentValidateStructIsReportStruct
       (input  recid(tnewbudget) (ietnewbudget), 
        output viFcReturnSuper (oiReturnStatus)) in BBudget>
    if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.   
end.


/* ======================= */
/* Start additional checks */
/* ======================= */
<M-21 run ValidateComponentValidateStructDet (output viFcReturnSuper (oiReturnStatus)) in BBudget>
if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.


/* ============================================ */
/* Return if errors occured                     */
/* State that the budget is properly structured */
/* ============================================ */
if oiReturnStatus  < 0 and
   oiReturnStatus <> -9999999
then return.   
find first tNewBudget no-error.
if tNewBudget.BudgetStatus = {&BUDGETSTATUS-INITIAL}
then assign tNewBudget.BudgetStatus = {&BUDGETSTATUS-VALID}
            tNewBudget.tc_Status    = (if tNewBudget.tc_Status = "":U then "C":U else tNewBudget.tc_Status).

/* ==================================================== */
/* Copy the tNew-tables into the t-tables (Conditional) */
/* ==================================================== */
if ilCopyContentToInstanceTables = true
then do :
    
    assign vcMessage = "":U.
    ALLBUDGETINFOCOPYBLOCK : DO :
        find tBudget where 
             tBudget.tc_Rowid = tNewBudget.tc_Rowid
             no-error.
        if not available tBudget
        then do :
            assign vcMessage = trim(substitute(#T-45'Internal error: cannot find the original &1 based on its row ID (&2).':255(530)t-45#,trim(#T-46'Budget':30(531)t-46#),(if tNewBudget.tc_Rowid = ? then "?":U else tNewBudget.tc_Rowid))).
            leave ALLBUDGETINFOCOPYBLOCK.
        end. /* if not avail */
        buffer-copy tNewBudget except tc_status to tBudget.
        if tBudget.tc_Status = "":U then assign tBudget.tc_Status = "C":U.
        for each tNewBudgetPeriod where 
                 tNewBudgetPeriod.tc_ParentRowid = tNewBudget.tc_Rowid
                 no-lock :
            find tBudgetPeriod where 
                 tBudgetPeriod.tc_Rowid = tNewBudgetPeriod.tc_Rowid
                 no-lock no-error.
            if not available tBudgetPeriod
            then do :
                assign vcMessage = trim(substitute(#T-47'Internal error: cannot find the original &1 based on its row ID (&2).':255(530)t-47#,trim(#T-48'Budget Period':30(532)T-48#),(if tNewBudgetPeriod.tc_Rowid = ? then "?":U else tNewBudgetPeriod.tc_Rowid))).
                leave ALLBUDGETINFOCOPYBLOCK.
            end. /* if not avail */
            buffer-copy tNewBudgetPeriod except tc_status to tBudgetPeriod.
            if tBudgetPeriod.tc_Status = "":U then assign tBudgetPeriod.tc_Status = "C":U.
        end. /* for each tNewBudgetPeriod where */
        for each tNewBudgetFDS where 
                 tNewBudgetFDS.tc_ParentRowid = tNewBudget.tc_Rowid
                 no-lock :
            find tBudgetFDS where 
                 tBudgetFDS.tc_Rowid = tNewBudgetFDS.tc_Rowid
                 no-lock no-error.
            if not available tBudgetFDS
            then do :
                assign vcMessage = trim(substitute(#T-49'Internal error: cannot find the original &1 based on its row ID (&2).':255(530)t-49#,trim(#T-50'Budget COA':30(533)T-50#),(if tNewBudgetFDS.tc_Rowid = ? then "?":U else tNewBudgetFDS.tc_Rowid))).
                leave ALLBUDGETINFOCOPYBLOCK.
            end. /* if not avail */
            buffer-copy tNewBudgetFDS except tc_status to tBudgetFDS.
            if tBudgetFDS.tc_Status = "":U then assign tBudgetFDS.tc_Status = "C":U.
        end. /* for each tNewBudgetFDS where */
        for each tNewBudgetCompany where 
                 tNewBudgetCompany.tc_ParentRowid = tNewBudget.tc_Rowid
                 no-lock :
            find tBudgetCompany where 
                 tBudgetCompany.tc_Rowid = tNewBudgetCompany.tc_Rowid
                 no-lock no-error.
            if not available tBudgetCompany
            then do :
                assign vcMessage = trim(substitute(#T-51'Internal error: cannot find the original &1 based on its row ID (&2).':255(530)t-51#,trim(#T-52'Budget Entity':30(534)T-52#),(if tNewBudgetCompany.tc_Rowid = ? then "?":U else tNewBudgetCompany.tc_Rowid))).
                leave ALLBUDGETINFOCOPYBLOCK.
            end. /* if not avail */
            buffer-copy tNewBudgetCompany except tc_status to tBudgetCompany.
            if tBudgetCompany.tc_Status = "":U then assign tBudgetCompany.tc_Status = "C":U.
        end. /* for each tNewBudgetCompany where */
    end. /* ALLBUDGETINFOCOPYBLOCK */
    if vcMessage <> "":U
    then do :
        assign oiReturnStatus = -1.
        <M-12 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-501':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BBudget>
    end. /* if vcMessage <> "":U */
    
end. /* if CopyContentToInstanceTables = true */

/* ========================= */
/* Set Return Status = OK    */
/* ========================= */
if oiReturnStatus = -9999999 /* this fixed value is also used at the start of this method */ 
then assign oiReturnStatus = 0.