project QadFinancials > class BRecurringEntry > method GenerateCalendar

Description

Procedure to generate the calendar (Recurring Entry Lines) based on the settings on the header (Recurring Entry)


Parameters


icRecEntryRowidinputcharacterRecurring Entry Rowid
icRecEntryFreqinputcharacterRecurring Entry Frequency - Possible values:
- PER (Period)
- MONTH (Monthly)
- WEEK (Weekly)
- QUARTER (Quarterly)
- MAN (Manually)
itRecEntryStartDateinputdateRecurring Entry Starting Date
ilRecEntryIsOpenEndedinputlogicalRecurring Entry Is Open Ended (only one detail-record will be generated - the next one is generated after the posting)
itRecEntryEndDateinputdateRecurring Entry End Date
ilRecEntryIsAmountApplyinputlogicalRecurring Entry Is Amount Apply (The amount in the recurring entry will be used in the posting instead of the template amount)
idRecEntryAmountLCinputdecimalRecurring Entry AmountLC
ilRecEntryIsReversinginputlogicalRecurring Entry Is Reversing (A reversing posting will be created , together with the normal posting)
icRecEntryCodeinputcharacterRecurring Entry Code
ilToBeDeletedinputlogicalRecords needs to be deleted only if calender is revised. So only when called from GenerateCalenderUI it should be True
ilToPostinputlogicalOnly if the To Post flag is yes then create a new record in next period.
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


QadFinancials
method BRecurringEntry.ApiPostRecEntryCommit
method BRecurringEntry.GenerateCalendarUI


program code (program6/brecurringentry.p)

/* ================================ */
/* Test if the parameters are valid */
/* ================================ */

/* ==================================================================================== */
/* Parameter 010: icRecEntryRowId - must be a valid RowId                               */
/* ==================================================================================== */
find tRecEntry where
     tRecEntry.tc_Rowid = icRecEntryRowid
     no-lock no-error.
if not available tRecEntry
then do:
    assign vcMessageRE = trim(#T-18'The recurring entry record is not available.':150(3512)t-18#)
           oiReturnStatus = -1.
    <M-8 run SetMessage (input  vcMessageRE (icMessage),
                     input  '':U (icArguments),
                     input  '':U (icFieldName),
                     input  icRecEntryCode (icFieldValue),
                     input  'D':U (icType),
                     input  3 (iiSeverity),
                     input  icRecEntryRowid (icRowid),
                     input  'QADFIN-990':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>    
end.

/* ==================================================================================== */
/* Parameter 020: Frequency - must contain a valid value                                */
/* ==================================================================================== */
if not (lookup(icRecEntryFreq, {&RECENTRYFREQS}, chr(2))         <> 0 and
        lookup(icRecEntryFreq, {&RECENTRYFREQS}, chr(2)) modulo 2 = 0)
then do:
    assign vcMessageRE = trim(substitute(#T-19'The specified frequency (&1) is invalid.':150(3497)t-19#, trim(icRecEntryFreq) ))
           oiReturnStatus = -1.    
    <M-9 run SetMessage (input  vcMessageRE (icMessage),
                     input  '':U (icArguments),
                     input  'tRecEntry.RecEntryFreq':U (icFieldName),
                     input  icRecEntryFreq (icFieldValue),
                     input  'E':U (icType),
                     input  3 (iiSeverity),
                     input  icRecEntryRowid (icRowid),
                     input  'QADFIN-991':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>    
end.
         
/* ==================================================================================== */                                                                                          
/* Parameter 030: Start Date - Must be entered if freq <> Manually                      */
/*                           - Must be last date of period if freq = Period / Quarterly */
/* ==================================================================================== */
<M-1 run ValRecEntryStartDate
   (input  itRecEntryStartDate (itTargetField), 
    input  'itRecEntryStartDate':U (icTargetFieldName), 
    input  icRecEntryRowid (icRowid), 
    input  icRecEntryFreq (icRecEntryFreq), 
    input  icRecEntryCode (icRecEntryCode), 
    output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.

/* ==================================================================================== */                                                                                          
/* Parameter 040: Open Ended - Tests included in tests for End Date                     */
/* ==================================================================================== */
/* Parameter 050: End Date - Start Date should be situated before End Date              */
/*                         - If flag Open End is true --> End Date must be blank        */
/*                         - If flag Open End is false --> End Date can not be blank    */
/* ==================================================================================== */
<M-2 run ValRecEntryEndDate
   (input  itRecEntryEndDate (itTargetField), 
    input  'itRecEntryEndDate':U (icTargetFieldName), 
    input  icRecEntryRowid (icRowid), 
    input  itRecEntryStartDate (itRecEntryStartDate), 
    input  ilRecEntryIsOpenEnded (ilRecEntryIsOpenEnded), 
    input  icRecEntryCode (icRecEntryCode), 
    input  icRecEntryFreq (icRecEntryFreq), 
    output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.

/* ==================================================================================== */
/* Parameter 060: Apply Amount - Tests included in the tests for Amount TC              */
/* ==================================================================================== */
/* Parameter 070: Amount TC - The amount must be filled in when apply amount is true    */
/*                          - The amount must be blank when apply amount is false       */
/* ==================================================================================== */
<M-3 run ValRecEntryLineAmountLC (input  idRecEntryAmountLC (idTargetField), 
                                  input  'idRecEntryAmountLC':U (icTargetFieldName), 
                                  input  icRecEntryRowId (icRowid), 
                                  input  ilRecEntryIsAmountApply (ilRecEntryIsAmountApply), 
                                  input  icRecEntryCode (icRecEntryCode), 
                                  output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
then assign oiReturnStatus = viFcReturnSuper.

/* ==================================================================================== */
/* Parameter 080: Reversing - Tests op unknown value                                    */
/* ==================================================================================== */
if ilRecEntryIsReversing = ?
then do:
    assign vcMessageRE = trim(#T-20'The Reversing field must be selected or cleared.':150(3513)t-20#)
           oiReturnStatus = -1.
    <M-10 run SetMessage (input  vcMessageRE (icMessage),
                     input  '':U (icArguments),
                     input  'tRecEntry.RecEntryIsReversing':U (icFieldName),
                     input  string(ilRecEntryIsReversing) (icFieldValue),
                     input  'E':U (icType),
                     input  3 (iiSeverity),
                     input  icRecEntryRowid (icRowid),
                     input  'QADFIN-988':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>    
    if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
    then assign oiReturnStatus = viFcReturnSuper.        
end.

/* ==================================================================================== */
/* Parameter 090: RecEntry Code - No Tests                                              */
/* ==================================================================================== */

/* =============================================== */
/* Leave Calendar generation when an error occured */
/* =============================================== */
if oiReturnStatus < 0
then return.

/* =========================================== */
/* Delete existing lines with status 'waiting' */
/* =========================================== */
if ilToBeDeleted 
then Do:
    for each tRecEntryLine where
             tRecEntryLine.tc_ParentRowid     = icRecEntryRowid and
             tRecEntryLine.RecEntryLineStatus = {&RECENTRYLINESTATUS-WAITING}:
        if tRecEntryLine.tc_status = 'N':U
        then delete tRecEntryLine.
        else assign tRecEntryLine.tc_Status = 'D':U.
   end.
end.  

/* ========================================================== */
/* No Calendar Generation if the frequency is set to manaully */
/* ========================================================== */
if icRecEntryFreq = {&RECENTRYFREQ-MANUALLY}
then return.

/* ================================================================== */
/* Define the date of the last posted or deleted recurring entry line */
/* No new recurring entry lines should be created before this date.   */
/* ================================================================== */
assign vtLastPostedDeletedDate = ?.
<Q-17 run RecEntryLineByIDStatus (last) (Read) (NoCache)
          (input tRecEntry.RecEntry_ID, (RecEntryID)
           input {&RECENTRYLINESTATUS-WAITING}, (RecEntryLineStatus)
           output dataset tqRecEntryLineByIDStatus) in BRecurringEntry >
find last tqRecEntryLineByIDStatus where
          tqRecEntryLineByIDStatus.tiRecEntry_ID = tRecEntry.RecEntry_ID and
          tqRecEntryLineByIDStatus.tcRecEntryLineStatus <> {&RECENTRYLINESTATUS-WAITING}
          no-lock no-error.
if available tqRecEntryLineByIDStatus
then assign vtLastPostedDeletedDate = tqRecEntryLineByIDStatus.ttRecEntryLinePostingDate.

/* ================================================= */
/* Generate Calendar (except for Frequency Manually) */
/* ================================================= */
/* Get Initial Posting Date And Period */
<Q-4 run PeriodByStartEndDate (all) (Read) (Cache)
          (input viCompanyId, (CompanyId)
           input itRecEntryStartDate, (Date)
           output dataset tqPeriodByStartEndDate) in BPeriod >
find tqPeriodByStartEndDate where
     tqPeriodByStartEndDate.tcPeriodTypeCode = {&PERIODTYPECODE-NORMAL}
     no-lock no-error.
if not available tqPeriodByStartEndDate
then do:
    assign vcDatetemp  = <M-69 DisplayDate  (input  itRecEntryStartDate (itDate)) in BRecurringEntry>
           vcDatetemp1 = <M-90 DisplayDate  (input  tRecEntry.RecEntryStartDate (itDate)) in BRecurringEntry>.
    assign vcMessageRE = trim(substitute(#T-21'There is no GL period available yet for the recurring entry posting date (&1).':150(3514)T-21#, vcDatetemp1))
           oiReturnStatus = -1.
    <M-5 run SetMessage
       (input  vcMessageRE (icMessage), 
        input  '':U (icArguments), 
        input  'tRecEntry.RecEntryStartDate':U (icFieldName), 
        input  vcDatetemp (icFieldValue), 
        input  'E':U (icType), 
        input  3 (iiSeverity), 
        input  icRecEntryRowid (icRowid), 
        input  'QADFIN-983':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>    
    return.
end.

assign vtPostingDate     = itRecEntryStartDate
       vtOrigPostingDate = vtPostingDate
       viPeriodID        = tqPeriodByStartEndDate.tiPeriod_ID
       viPeriodPeriod    = tqPeriodByStartEndDate.tiPeriodPeriod
       viPeriodYear      = tqPeriodByStartEndDate.tiPeriodYear.

<Q-14 run PeriodByStartEndDate (Start) in BPeriod >
repeat:
    /* Get Reversing Date */
    if ilRecEntryIsReversing = true
    then do:
        <M-7 run GetNextPeriod (input  viPeriodID (iiPeriodID), 
                        input  ? (iiPeriodYear), 
                        input  ? (iiPeriodPeriod), 
                        output viNextPeriodPeriodID (oiPeriodID), 
                        output viNextPeriodYear (oiPeriodYear), 
                        output viNextPeriodPeriod (oiPeriodPeriod), 
                        output vtReversingDate (otPeriodStartDate), 
                        output vtNextPeriodEndDate (otPeriodEndDate), 
                        output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
        if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
        then assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then leave.        
    end.
    else assign vtReversingDate = ?.

    if ( vtLastPostedDeletedDate = ? or
         vtLastPostedDeletedDate < vtPostingDate ) and
         ilToPost
    then do:
        /* Create Recurring Entry Line */
        <M-16 run AddDetailLine (input  'RecEntryLine':U (icTable), 
                            input  icRecEntryRowid (icParentRowid), 
                            output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
        if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
        then assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then leave.
    
        /* Assign Period, Postingdate, Status, Code */
        assign tRecEntryLine.RecEntryLineCode          = icRecEntryCode
               tRecEntryLine.Period_ID                 = viPeriodID
               tRecEntryLine.RecEntryLinePostingDate   = vtPostingDate
               tRecEntryLine.RecEntryLineStatus        = {&RECENTRYLINESTATUS-WAITING}
               tRecEntryLine.RecEntryLineAmountLC      = idRecEntryAmountLC
               tRecEntryLine.RecEntryLineReversingDate = vtReversingDate
               tRecEntryLine.tiPeriodPeriod            = viPeriodPeriod
               tRecEntryLine.tiPeriodYear              = viPeriodYear.
    end.

    /* Leave if open-ended and there is already a waiting line */
    /* Leave if Periodicaly, Non-Reversing, Non-open-ended and the next-period-end-date is behind the end-date */
    if (ilRecEntryIsOpenEnded = true and
        can-find(first tRecEntryLine where
                       tRecEntryLine.RecEntry_ID        = tRecEntry.RecEntry_ID         and
                       tRecEntryLine.RecEntryLineStatus = {&RECENTRYLINESTATUS-WAITING} and
                       tRecEntryLine.tc_Status         <> 'D':U)) or 
       (icRecEntryFreq         = {&RECENTRYFREQ-PERIOD} and 
        ilRecEntryIsReversing  = false and 
        ilRecEntryIsOpenEnded  = false and 
        vtNextPeriodEndDate   <> ? and 
        itRecEntryEndDate     <> ?  and 
        vtNextPeriodEndDate   >= itRecEntryEndDate)
    then leave.

    /* Get next posting-date                    */
    /* Period -> End date of next period      */
    /* Quarterly -> Add three months, first day */
    /* Weekly -> Add 7 days                     */
    /* Monthly -> Add one month, same day       */
    if icRecEntryFreq = {&RECENTRYFREQ-PERIOD}
    then do:
        <M-11 run GetNextPeriod
           (input  viPeriodID (iiPeriodID), 
            input  ? (iiPeriodYear), 
            input  ? (iiPeriodPeriod), 
            output viPeriodID (oiPeriodID), 
            output viPeriodYear (oiPeriodYear), 
            output viPeriodPeriod (oiPeriodPeriod), 
            output vtDummy (otPeriodStartDate), 
            output vtNextPeriodEndDate (otPeriodEndDate), 
            output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>
        if viFcReturnSuper < 0 or (viFcReturnSuper > 0 and oiReturnStatus = 0)
        then assign oiReturnStatus = viFcReturnSuper.
        if oiReturnStatus < 0
        then leave.     
        
        assign vtPostingDate = vtNextPeriodEndDate.
        
        if vtPostingDate         > itRecEntryEndDate and
           ilRecEntryIsOpenEnded = false
        then leave.
        next.
    end. /* if icRecEntryFreq = {&RECENTRYFREQ-PERIOD} */

    if icRecEntryFreq = {&RECENTRYFREQ-QUARTERLY} or
       icRecEntryFreq = {&RECENTRYFREQ-MONTHLY}
    then do:
        assign viNextDay   = day(vtOrigPostingDate)
               viNextMonth = month(vtPostingDate) + (if icRecEntryFreq = {&RECENTRYFREQ-QUARTERLY} then 3 else 1) 
               viNextYear  = year(vtPostingDate).
        if viNextMonth > 12
        then assign viNextMonth = viNextMonth - 12
                    viNextYear  = viNextYear + 1.
        repeat:
            assign vtPostingDate = date(viNextMonth, viNextDay, viNextYear) no-error. 
            if error-status:error
            then assign viNextDay = viNextDay - 1.
            else leave.
        end.
    end.
    
    if icRecEntryFreq = {&RECENTRYFREQ-WEEKLY}
    then assign vtPostingDate = vtPostingDate + 7.
    
    if vtPostingDate         > itRecEntryEndDate and
       ilRecEntryIsOpenEnded = false
    then leave.

    /* Get the period for this new posting date */
    <Q-12 run PeriodByStartEndDate (all) (Read) (Cache)
          (input viCompanyId, (CompanyId)
           input vtPostingDate, (Date)
           output dataset tqPeriodByStartEndDate) in BPeriod >
    find tqPeriodByStartEndDate where
         tqPeriodByStartEndDate.tcPeriodTypeCode = {&PERIODTYPECODE-NORMAL}
         no-lock no-error.
    if not available tqPeriodByStartEndDate
    then do:
        assign vcMessageRE = trim(substitute(#T-22'There is no GL period available yet for the recurring entry posting date (&1).':150(3514)T-22#, string(vtPostingDate)))
               oiReturnStatus = -1.
        <M-13 run SetMessage (input  vcMessageRE (icMessage),
                     input  '':U (icArguments),
                     input  '':U (icFieldName),
                     input  string(vtPostingDate) (icFieldValue),
                     input  'E':U (icType),
                     input  3 (iiSeverity),
                     input  icRecEntryRowid (icRowid),
                     input  'QADFIN-989':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BRecurringEntry>    
        leave.
    end.
    assign viPeriodID     = tqPeriodByStartEndDate.tiPeriod_ID
           viPeriodPeriod = tqPeriodByStartEndDate.tiPeriodPeriod
           viPeriodYear   = tqPeriodByStartEndDate.tiPeriodYear.
end. /* repeat */
<Q-15 run PeriodByStartEndDate (Stop) in BPeriod >

if oiReturnStatus < 0
then do:
    for each tRecEntryLine where
             tRecEntryLine.tc_ParentRowid     = icRecEntryRowid and
             tRecEntryLine.RecEntryLineStatus = {&RECENTRYLINESTATUS-WAITING}:
        if tRecEntryLine.tc_status = 'N':U
        then delete tRecEntryLine.
        else assign tRecEntryLine.tc_Status = 'D':U.        
    end.
    return.
end.