SUBROUTINE MSD.TIME.ACCRUAL
*
* AUTHOR:   SCOTT REDMOND
* DATE:     03/20/95
* PURPOSE:  CALC HOURS WORKED AND ACCRUAL TOTALS FROM:
*           1 - CLOCK FILE USER RECORDS
*           2 - PROJECT FILE RECORDS 
*           3 - MANAGER'S RECORDS (MANUALLY ENTERED M-0-16-4)
*
*-------------------------------------------------------------------*
*
$INCLUDE GEN.COMMON
$INCLUDE USER
$INCLUDE SUPPORT.RECORD
*
*-------------------------------------------------------------------*
*
OPEN 'PC.CLIENT'      TO PC.CLIENT      ELSE ABORT 201, 'PC.CLIENT'
OPEN 'USER'           TO USER.FILE      ELSE ABORT 201, 'USER'
OPEN 'CUSTOMER.TRANS' TO CUSTOMER.TRANS ELSE ABORT 201, 'CUSTOMER.TRANS'
OPEN 'PROJECT'        TO PROJECT        ELSE ABORT 201, 'PROJECT'
OPEN 'INFO.ACCRUAL'   TO INFO.ACCRUAL   ELSE ABORT 201, 'INFO.ACCRUAL'
OPEN 'PT'             TO PT.FILE        ELSE ABORT 201, 'PT'
OPEN 'CLOCKFILE'      TO CLOCKFILE      ELSE ABORT 201, 'CLOCKFILE'
OPEN 'CLOCK.GEN.KEYS' TO CLOCK.GEN.KEYS ELSE ABORT 201, 'CLOCK.GEN.KEYS'
OPEN 'CM'             TO CM             ELSE ABORT 201, 'CM'
OPEN 'HP.CONTROL'     TO HP.CONTROL     ELSE ABORT 201, 'HP.CONTROL'
OPEN 'INFO.HIST'      TO INFO.HIST      ELSE ABORT 201, 'INFO.HIST'
*
*-------------------------------------------------------------------*
*
USER.ADD='' ; USER.REC='' ; TODAY=DATE()  
*
*-------------------------------------------------------------------*
10 *
CRT CS
HDG='MICAHTEK & IDM VACATION/SICK TIME ACCRUAL UTILITY'
HDL=(80 - LEN(HDG)) / 2
CRT @(0,0):CL:RV:STR(' ',80):ERV
CRT @(HDL,0):RV:HDG:ERV:
*
CRT @(20,5):CL:RV:" STEP 1 - PROCESS CLOCKFILE RECORDS  ":ERV
CRT @(20,7):CL:RV:" STEP 2 - PROCESS PROJECT RECORDS    ":ERV
CRT @(20,9):CL:RV:" STEP 3 - PROCESS MANAGER'S RECORDS  ":ERV
*
READ JEN.REC FROM CLOCK.GEN.KEYS,"NEXT.PAY.PERIOD" ELSE 
  *
  * NOTE:  IF CLOCK.GEN.KEYS ITEM "NEXT.PAY.PERIOD" IS MISSING:
  *        1.)   FIND THE LATEST <UR$LAST.PAY.DATE> IN THE USER FILE.
  *        2.)   ADD ONE DAY TO THAT.
  *        3.)   EDIT THE CLOCK.GEN.KEYS ITEM AND PUT THAT DATE
  *              IN ATTRIBUTE ONE OF THAT ITEM.
  *        4.)   START THIS PROCESS OVER AGAIN.
  *
  CRT @(0,22):CL:BEEP:RV:" SERIOUS ERROR - CLOCK.GEN.KEYS (NEXT.PAY.PERIOD) MISSING! ":ERV:
  INPUT ANY,3
  STOP  
END
*
READ TASK.REC FROM CLOCK.GEN.KEYS,"TASK.ASSIGNMENTS" ELSE 
  *
  * NOTE:  IF CLOCK.GEN.KEYS ITEM "TASK.ASSIGNMENTS" IS MISSING:
  *              fields are multi-valued.......
  *        <1>   VACATION TASK NUMBERS
  *        <2>   SICK TASK NUMBERS
  *        <3>   HOLIDAY TASK
  *        <4>   FUNERAL/BEREAVEMENT TASK 
  *        <5>   PERSONAL TIME TASK
  *        <6>   BONUS TASK (PERFECT ATTEND)
  *        <7>   WORKMANS COMP TIME TASK
  *        <8>   JURY DUTY TASK
  *
  CRT @(0,22):CL:BEEP:RV:" SERIOUS ERROR - CLOCK.GEN.KEYS (TASK.ASSIGNMENTS) MISSING! ":ERV:
  INPUT ANY,3
  STOP  
END
PAY.BEGIN=JEN.REC<1>
PASSWORD=CHAR(73):CHAR(88):CHAR(79):CHAR(89):CHAR(69)
2010 *
CRT @(20,12):CL:RV:" PAY PERIOD BEGIN DATE :":ERV:" ":OCONV(PAY.BEGIN,'D')
PAY.END=PAY.BEGIN+13
CRT @(20,14):CL:RV:" PAY PERIOD ENDING DATE:":ERV:" ":OCONV(PAY.END,'D')
*
CRT @(0,22):CL:RV:" ENTER 'B' TO BEGIN PROCESSING :":ERV:
INPUT BEGIN.ANS,5
IF BEGIN.ANS[1,1] # 'B' THEN RETURN
IF PAY.END >= TODAY THEN
  CRT @(0,22):CL:BEEP:RV:" ACTIVE PAY PERIOD! TRY AGAIN ON ":OCONV(PAY.END+1,'D'):" <return> :":ERV:
  INPUT ANY,3
  GO 10
END
CRT @(0,22):CL:RV:" SELECTING FILE...PLEASE WAIT! ":ERV:
*
GOSUB 35000 ;* verify manager records have been updated since last pay
*
JEN.REC<1>=PAY.END+1
WRITE JEN.REC ON CLOCK.GEN.KEYS,"NEXT.PAY.PERIOD"
CRT @(60,5):CL:RV:" <===== ":ERV:
*
USER.ADD='' ; USER.REC='' ; TODAY=DATE() ; WT=0 ; FOUND=0
SDATE=ICONV('03/26/94','D')
*
TIME.TABLE=''
START=0
FOR X = SDATE TO TODAY STEP 14
  START=START+1
  TIME.TABLE=INSERT(TIME.TABLE,1,START;X+1)    ;* first day of pay period
  TIME.TABLE=INSERT(TIME.TABLE,2,START;X+14)   ;* last day of pay period
  TIME.TABLE=INSERT(TIME.TABLE,3,START;START)  ;* period number (ref.)
  TIME.TABLE=INSERT(TIME.TABLE,4,START;X+7)    ;* last day of first wk.
NEXT X
*---- process and accrue clockfile records-----------------------*
*
*GO 2600 ;* TEMP
CLEARFILE INFO.ACCRUAL
*
EOF=0 ; T=0 ; FILE.ACCESS='CLOCK FILE'
SELECT CLOCKFILE
LOOP
  READNEXT ID ELSE EOF=1
UNTIL EOF DO
  T=T+1
  IF REM(T,2000)=0 THEN GOSUB 2900            ;* refresh totals
  USER.KEY  =OCONV(ID,'G0|1')
  CLOCK.DATE=OCONV(ID,'G1|1')
  IF CLOCK.DATE < PAY.BEGIN OR CLOCK.DATE > PAY.END THEN GO 2300
  READ CLOCK.REC FROM CLOCKFILE,ID THEN
    IF CLOCK.DATE=9582 THEN CLOCK.DATE=9583  ;* start date
    IF CLOCK.DATE < SDATE THEN GO 2300
    READ USR.REC FROM USER.FILE,USER.KEY THEN
    IF USR.REC<UR$CLOCK.SYSTEM># 'C' THEN GO 2300 ;* time clock employee
    FOUND=FOUND+1
      LOCATE(CLOCK.DATE,TIME.TABLE,1;WHR;"AR") THEN NULL
      POSITION=''
      IF CLOCK.DATE = TIME.TABLE<1,WHR> THEN
        POSITION=WHR
      END ELSE
        IF CLOCK.DATE <= TIME.TABLE<2,WHR> THEN
          POSITION=WHR-1
        END
      END
      PERIOD=TIME.TABLE<3,POSITION>
      LAST.DAY.OF.WEEK=TIME.TABLE<4,POSITION>
      *----- initialize totals with each user, each day -----*
      OUT.TIME=0 ; IN.TIME=0 ; DAILY.TIME=0 
      VAC.TOTAL=0 ; SICK.TOTAL=0 ; HOLIDAY.TOTAL=0 ; OTHER.TOTAL=0
      FUNERAL.TOTAL=0  ;  JURY.TOTAL=0 ; WORKMANS.TOTAL=0  
      PERSONAL.TOTAL=0 ; BONUS.TOTAL=0 
      *
      TIMCT=DCOUNT(CLOCK.REC<1>,VM)
      FOR TIM = 1 TO TIMCT     ;* calc daily time
        IF CLOCK.REC<2,TIM>='OFF' THEN
          OUT.TIME=CLOCK.REC<1,TIM>
          DAILY.TIME=DAILY.TIME+(OUT.TIME-IN.TIME)
        END ELSE
          JOB=''
          JOB=OCONV(CLOCK.REC<2,TIM>,'G1-1')
          JOB.TWO=JOB[2,2]'L%3'
          IF JOB[1,1]='V' THEN                    ;* compute vacation
            VAC.TOTAL=VAC.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='S' THEN                    ;* compute sick
            SICK.TOTAL=SICK.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='H' THEN                    ;* compute holiday
            HOLIDAY.TOTAL=HOLIDAY.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='P' THEN                    ;* personal    
            PERSONAL.TOTAL=PERSONAL.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='F' THEN                    ;* funeral     
            FUNERAL.TOTAL=FUNERAL.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='W' THEN                    ;* workmans comp.
            WORKMANS.TOTAL=WORKMANS.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='B' THEN                    ;* bonus day   
            BONUS.TOTAL=BONUS.TOTAL+JOB.TWO
          END
          IF JOB[1,1]='J' THEN                    ;* jury duty   
            JURY.TOTAL=JURY.TOTAL+JOB.TWO
          END
          IN.TIME=CLOCK.REC<1,TIM>
        END
      NEXT TIM      
      DAILY.TIME =(DAILY.TIME/60)/60   ;* convert seconds to hours
      DAILY.HOURS=INT(DAILY.TIME)
      DAILY.DECI =OCONV(DAILY.TIME,'G1.1')[1,3]
      TWO.DECI   =DAILY.DECI[1,2]'L%2'
      EXTRA.DECI =DAILY.DECI[3,1]
      IF EXTRA.DECI >= 5 THEN 
        IF TWO.DECI=99 THEN 
          TWO.DECI='00'
          DAILY.HOURS=DAILY.HOURS+1
        END ELSE
          TWO.DECI=TWO.DECI+1'L%2'
        END
      END ELSE
        IF TWO.DECI=99 THEN 
          TWO.DECI='00'
          DAILY.HOURS=DAILY.HOURS+1
        END
      END
      OUTPUT.HOURS=DAILY.HOURS:TWO.DECI
      READ INFO.REC FROM INFO.ACCRUAL,USER.KEY ELSE INFO.REC=''
      OTHER.TOTAL=OTHER.TOTAL+VAC.TOTAL+SICK.TOTAL+HOLIDAY.TOTAL
      OTHER.TOTAL=OTHER.TOTAL+FUNERAL.TOTAL+PERSONAL.TOTAL+BONUS.TOTAL
      OTHER.TOTAL=OTHER.TOTAL+JURY.TOTAL+WORKMANS.TOTAL
      INFO.REC<PERIOD,1>=INFO.REC<PERIOD,1>+OUTPUT.HOURS ;* add hours
      INFO.REC<PERIOD,2>=TIME.TABLE<1,POSITION> ;* beginning period date
      INFO.REC<PERIOD,3>=TIME.TABLE<2,POSITION> ;* ending period date
      INFO.REC<PERIOD,4>=INFO.REC<PERIOD,4>+VAC.TOTAL       ;* vacation hours     
      INFO.REC<PERIOD,5>=INFO.REC<PERIOD,5>+SICK.TOTAL      ;* sick hours used   
      INFO.REC<PERIOD,6>=INFO.REC<PERIOD,6>+HOLIDAY.TOTAL   ;* holiday hours 
      INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OTHER.TOTAL     ;* other hours  
      INFO.REC<PERIOD,8>=INFO.REC<PERIOD,8>+FUNERAL.TOTAL   ;* funeral hours  
      INFO.REC<PERIOD,9>=INFO.REC<PERIOD,9>+PERSONAL.TOTAL  ;* personal hours  
      INFO.REC<PERIOD,10>=INFO.REC<PERIOD,10>+BONUS.TOTAL   ;* bonus hours  
      INFO.REC<PERIOD,11>=INFO.REC<PERIOD,11>+JURY.TOTAL    ;* jury hours  
      INFO.REC<PERIOD,12>=INFO.REC<PERIOD,12>+WORKMANS.TOTAL;* work comp hours  
      *---- check for overtime in the first week --------------------*
      IF CLOCK.DATE <= LAST.DAY.OF.WEEK THEN
        IF INFO.REC<PERIOD,1>-OTHER.TOTAL > 4000 THEN
          FIRST.WEEK.OT=(INFO.REC<PERIOD,1>-OTHER.TOTAL)-4000
          INFO.REC<PERIOD,20>=FIRST.WEEK.OT
        END
      END
*CRT @(0,8):CR:
*CRT 'CLOCK DATE    ':OCONV(CLOCK.DATE,'D2/')
*CRT 'LAST DAY WK   ':OCONV(LAST.DAY.OF.WEEK,'D2/')
*CRT 'INFO.REC 1    ':INFO.REC<PERIOD,1>
*CRT 'OTHER TOTAL   ':OTHER.TOTAL
*CRT 'FIRST WK OT   ':FIRST.WEEK.OT
*CRT 'INFO REC 20   ':INFO.REC<PERIOD,20>
*INPUT ANY
      *--------------------------------------------------------------*
      WRITE INFO.REC ON INFO.ACCRUAL,USER.KEY
      WT=WT+1
    END
  END   
  2300 *
REPEAT
*
*
2400 *--- process project (programmers) records ---------------*
CRT @(60,5):CL:
CRT @(60,7):CL:RV:" <===== ":ERV:
*
GOSUB 40000  ;* verify tasks (vac, sick, funeral, etc.)
*
*
EOF=0 ; T=0 ; WT=0 ; FILE.ACCESS='PROJECT'  
*
LOCATE(PAY.BEGIN,TIME.TABLE,1;BEGIN.ATT) THEN NULL
LOCATE(PAY.END,TIME.TABLE,2;END.ATT) THEN NULL
*
SELECT CUSTOMER.TRANS
*
LOOP
  READNEXT ID ELSE EOF=1
UNTIL EOF DO
  T=T+1
  TASK.NO=ID
  IF REM(T,100)=0 THEN GOSUB 2900            ;* refresh totals
  READ CUST.REC FROM CUSTOMER.TRANS,ID ELSE GO 2460
  TRANCT=DCOUNT(CUST.REC<SS$ACTION.DATE>,VM)
  FOR XGG = 1 TO TRANCT
    ACTION.DATE=CUST.REC<SS$ACTION.DATE,XGG>
    USER.KEY=CUST.REC<SS$ACTION.OPERATOR,XGG>[2,4]
    READ QREC FROM USER.FILE,USER.KEY ELSE GO 2449
    IF QREC<UR$CLOCK.SYSTEM> # 'P' THEN GO 2449
    BILL.CODE=CUST.REC<SS$ACTION.BILL.CODE,XGG> 
    BILL.CLIENT=CUST.REC<SS$CLIENT>
    IF ACTION.DATE >= PAY.BEGIN AND ACTION.DATE <= PAY.END THEN
      IF CUST.REC<SS$ACTION.CODE,XGG>='30' THEN
        MINUTES=0
        MINUTES=CUST.REC<SS$ACTION.MINUTES,XGG>
        IF MINUTES > 0 THEN
          DAILY.TIME =MINUTES/60   ;* convert minutes to hours
          DAILY.HOURS=INT(DAILY.TIME)
          DAILY.DECI =OCONV(DAILY.TIME,'G1.1')[1,3]
          TWO.DECI   =DAILY.DECI[1,2]'L%2'
          EXTRA.DECI =DAILY.DECI[3,1]
          IF EXTRA.DECI >= 5 THEN 
            IF TWO.DECI=99 THEN 
              TWO.DECI='00'
              DAILY.HOURS=DAILY.HOURS+1
            END ELSE
              TWO.DECI=TWO.DECI+1'L%2'
            END
          END ELSE
            IF TWO.DECI=99 THEN 
              TWO.DECI='00'
              DAILY.HOURS=DAILY.HOURS+1
            END
          END
          OUTPUT.HOURS=DAILY.HOURS:TWO.DECI
          LOCATE(ACTION.DATE,TIME.TABLE,1;WHR;"AR") THEN NULL
          POSITION=''
          IF ACTION.DATE = TIME.TABLE<1,WHR> THEN
            POSITION=WHR
          END ELSE
            IF ACTION.DATE <= TIME.TABLE<2,WHR> THEN
              POSITION=WHR-1
            END
          END
          PERIOD=TIME.TABLE<3,POSITION>
          READ INFO.REC FROM INFO.ACCRUAL,USER.KEY ELSE INFO.REC=''
          BEGIN CASE
             CASE BILL.CODE=1  ;*---- billable client hours ------*
               INFO.REC<PERIOD,13>=INFO.REC<PERIOD,13>+OUTPUT.HOURS
               LOCATE(BILL.CLIENT,INFO.REC,PERIOD,16;WHRR;"AL") THEN
                 INFO.REC<PERIOD,17,WHRR>=INFO.REC<PERIOD,17,WHRR>+OUTPUT.HOURS
               END ELSE
                 INFO.REC=INSERT(INFO.REC,PERIOD,16,WHRR;BILL.CLIENT)
                 INFO.REC=INSERT(INFO.REC,PERIOD,17,WHRR;OUTPUT.HOURS)
               END
             CASE BILL.CODE=2   ;*------ service cont. client hours--*
               INFO.REC<PERIOD,14>=INFO.REC<PERIOD,14>+OUTPUT.HOURS
               LOCATE(BILL.CLIENT,INFO.REC,PERIOD,16;WHRR;"AL") THEN
                 INFO.REC<PERIOD,18,WHRR>=INFO.REC<PERIOD,18,WHRR>+OUTPUT.HOURS
               END ELSE
                 INFO.REC=INSERT(INFO.REC,PERIOD,16,WHRR;BILL.CLIENT)
                 INFO.REC=INSERT(INFO.REC,PERIOD,18,WHRR;OUTPUT.HOURS)
               END
             CASE BILL.CODE=3   ;*------ free hours-----------------*
               INFO.REC<PERIOD,15>=INFO.REC<PERIOD,15>+OUTPUT.HOURS
               LOCATE(BILL.CLIENT,INFO.REC,PERIOD,16;WHRR;"AL") THEN
                 INFO.REC<PERIOD,19,WHRR>=INFO.REC<PERIOD,19,WHRR>+OUTPUT.HOURS
               END ELSE
                 INFO.REC=INSERT(INFO.REC,PERIOD,16,WHRR;BILL.CLIENT)
                 INFO.REC=INSERT(INFO.REC,PERIOD,19,WHRR;OUTPUT.HOURS)
               END
             CASE 1  ;*--- if not 1,2 or 3 then force it 3 -------*
               INFO.REC<PERIOD,15>=INFO.REC<PERIOD,15>+OUTPUT.HOURS
          END CASE
          *
          LOCATE(TASK.NO,TASK.REC,1;FND) THEN  ;* vacation task
            INFO.REC<PERIOD,4>=INFO.REC<PERIOD,4>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,2;FND) THEN  ;* sick task
            INFO.REC<PERIOD,5>=INFO.REC<PERIOD,5>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,3;FND) THEN  ;* holiday task
            INFO.REC<PERIOD,6>=INFO.REC<PERIOD,6>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,4;FND) THEN  ;* funeral task
            INFO.REC<PERIOD,8>=INFO.REC<PERIOD,8>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,5;FND) THEN  ;* personal task
            INFO.REC<PERIOD,9>=INFO.REC<PERIOD,9>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,6;FND) THEN  ;* bonus task
            INFO.REC<PERIOD,10>=INFO.REC<PERIOD,10>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,7;FND) THEN  ;* workmans task
            INFO.REC<PERIOD,12>=INFO.REC<PERIOD,12>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          LOCATE(TASK.NO,TASK.REC,8;FND) THEN  ;* jury task
            INFO.REC<PERIOD,11>=INFO.REC<PERIOD,11>+OUTPUT.HOURS
            INFO.REC<PERIOD,7>=INFO.REC<PERIOD,7>+OUTPUT.HOURS
          END
          INFO.REC<PERIOD,1>=INFO.REC<PERIOD,1>+OUTPUT.HOURS ;* add hours
          INFO.REC<PERIOD,2>=TIME.TABLE<1,POSITION> ;* beginning period date
          INFO.REC<PERIOD,3>=TIME.TABLE<2,POSITION> ;* ending period date
          WRITE INFO.REC ON INFO.ACCRUAL,USER.KEY
          WT=WT+1
        END
      END
    END
    2449 *
  NEXT XGG
  2460 *
REPEAT
*
2600 *---- select file & determine hours accrued/used (non-manager)--*
*
EOF=0 ; T=0 ; WT=0 ; FILE.ACCESS='USER FILE'
*
LOCATE(PAY.BEGIN,TIME.TABLE,1;BEGIN.ATT) THEN NULL
LOCATE(PAY.END,TIME.TABLE,2;END.ATT) THEN NULL
*
SELECT INFO.ACCRUAL
LOOP
  READNEXT ID ELSE EOF=1
UNTIL EOF DO
  T=T+1
  IF REM(T,25)=0 THEN GOSUB 2900            ;* refresh totals
  TOTAL.HOURS=0 ; VAC.HOURS=0 ; OT.HOURS=0 ; SICK.HOURS=0
  HOL.HOURS=0 ; OTHER.HOURS=0 ; ACCRUAL.HOURS=0
  WORKED.HOURS=0  ; BONUS.HOURS=0  ; JURY.HOURS=0
  WORKMANS.HOURS=0 ; PERSONAL.HOURS=0 ; FUNERAL.HOURS=0
  FIRST.WEEK.OT=0  ; SECOND.WEEK.OT=0 ; REG.OUT.HOURS=0
  READ IREC FROM INFO.ACCRUAL,ID THEN      
    FOR XTX = BEGIN.ATT TO END.ATT        
      TOTAL.HOURS=TOTAL.HOURS+IREC<XTX,1>
      VAC.HOURS       =IREC<XTX,4>   ;* vacation hours used
      SICK.HOURS      =IREC<XTX,5>   ;* sick hours used
      HOL.HOURS       =IREC<XTX,6>   ;* holiday hours used
      OTHER.HOURS     =IREC<XTX,7>
      FUNERAL.HOURS   =IREC<XTX,8>
      PERSONAL.HOURS  =IREC<XTX,9>
      BONUS.HOURS     =IREC<XTX,10>
      JURY.HOURS      =IREC<XTX,11>
      WORKMANS.HOURS  =IREC<XTX,12>
      BILL.ONE        =IREC<XTX,13>
      BILL.TWO        =IREC<XTX,14>
      BILL.THREE      =IREC<XTX,15>
      BILL.CLIENT     =IREC<XTX,16>
      BILL.CLIENT.HRS =IREC<XTX,17>
      SERVICE.HOURS   =IREC<XTX,18>
      FREE.HOURS      =IREC<XTX,19>
      FIRST.WEEK.OT   =IREC<XTX,20>
      WORKED.HOURS=TOTAL.HOURS-OTHER.HOURS
      IF FIRST.WEEK.OT=0 OR FIRST.WEEK.OT='' THEN
        IF WORKED.HOURS > 8000 THEN
          OT.HOURS=WORKED.HOURS-8000
        END ELSE
          OT.HOURS=0
        END
      END ELSE
        SECOND.WEEK=WORKED.HOURS-FIRST.WEEK.OT
        IF SECOND.WEEK > 8000 THEN 
          SECOND.WEEK.OT=SECOND.WEEK-8000
          OT.HOURS=FIRST.WEEK.OT+SECOND.WEEK.OT
        END ELSE
          OT.HOURS=FIRST.WEEK.OT
        END
      END
      IF WORKED.HOURS >= 8000 THEN 
        ACCRUAL.HOURS=8000
      END ELSE
        ACCRUAL.HOURS=WORKED.HOURS
      END
      REG.HOLD=ACCRUAL.HOURS
      REG.OUT.HOURS=ACCRUAL.HOURS-FIRST.WEEK.OT-SECOND.WEEK.OT
      ACCRUAL.HOURS=OCONV(ACCRUAL.HOURS,'MR2')
      READU USERX FROM USER.FILE,ID THEN
*       IF USERX<UR$CLOCK.SYSTEM>='P' THEN
*         IF REG.OUT.HOURS > 8000 THEN REG.OUT.HOURS='8000'
*       END
        *---- check for probation ----------*
        USERX<UR$OFF.PROBATION>=USERX<UR$HIRE.DATE>+90
        *---- check for part time ----------*
        IF USERX<UR$TYPE.CODE>='P' THEN PART.TIME=1 ELSE PART.TIME=''
        *---- check for managers  ----------*
        IF USERX<UR$CLOCK.SYSTEM>='M' THEN GO 2699
        *---- check for inactive status-----*
        IF USERX<UR$STATUS>#'A' THEN GO 2699        
        *-----------------------------------*
        IF TODAY <= USERX<UR$HIRE.DATE>+365 THEN  ;* 0-1 year
          USERX<UR$CALC.FACTOR>='3.33'
        END
        IF TODAY >= USERX<UR$HIRE.DATE>+365 THEN  ;* 2-9 year
          USERX<UR$CALC.FACTOR>='6.67'
        END
        IF TODAY >= USERX<UR$HIRE.DATE>+3650 THEN ;* ten year
          USERX<UR$CALC.FACTOR>='10'
        END
        IF USERX<UR$TYPE.CODE>='M' THEN           ;* manager rate
          USERX<UR$CALC.FACTOR>='10'
        END
        IF PART.TIME THEN USERX<UR$CALC.FACTOR>='0'
        CALC.FACTOR=USERX<UR$CALC.FACTOR>
        *--- factors per John Longley 04/03/95 -------*
        IF CALC.FACTOR='3.33' THEN CALC.FACTOR='.020492'
        IF CALC.FACTOR='6.67' THEN CALC.FACTOR='.042735'
        IF CALC.FACTOR='10'   THEN CALC.FACTOR='.066964'
        VAC.ACCRUAL=ACCRUAL.HOURS*CALC.FACTOR
        VAC.ONE=OCONV(VAC.ACCRUAL,'G0.1')
        VAC.TWO=OCONV(VAC.ACCRUAL,'G1.1')'L%2'
        VAC.ACCRUAL=VAC.ONE:VAC.TWO[1,2]
        IF CALC.FACTOR='.066964' THEN CALC.FACTOR='.042735' ;* max sick
        SIK.ACCRUAL=ACCRUAL.HOURS*CALC.FACTOR
        SIK.ONE=OCONV(SIK.ACCRUAL,'G0.1')
        SIK.TWO=OCONV(SIK.ACCRUAL,'G1.1')'L%2'
        SIK.ACCRUAL=SIK.ONE:SIK.TWO[1,2]
        *
        GOSUB 50000 ;* round all hours to nearest .25hr
        *
*       USERX<UR$REGULAR.HOURS> =REG.HOLD
        USERX<UR$REGULAR.HOURS> =REG.OUT.HOURS
        IF PART.TIME THEN                ;* reduce but not accrue vac
          USERX<UR$OT.HOURS>      =OT.HOURS       
          USERX<UR$HOLIDAY.HOURS> =0
          USERX<UR$FUNERAL.HOURS> =0
          USERX<UR$PERSONAL.HOURS>=0
          USERX<UR$BONUS.HOURS>   =0
          USERX<UR$WORKMANS.HOURS>=0
          USERX<UR$JURY.DUTY.HOURS>=0
          USERX<UR$VACATION.HOURS>=VAC.HOURS
          USERX<UR$SICK.HOURS>    =0
          USERX<UR$TOTAL.HOURS>   =TOTAL.HOURS
          USERX<UR$OTHER.HOURS>   =OTHER.HOURS
          USERX<UR$LAST.PAY.DATE> =PAY.END
          USERX<UR$VACATION.AVAIL>=USERX<UR$VACATION.AVAIL>-VAC.HOURS
          USERX<UR$BILL.BILL>=BILL.ONE
          USERX<UR$BILL.SERVICE>=BILL.TWO
          USERX<UR$BILL.FREE>=BILL.THREE
          USERX<UR$BILL.CLIENT>=BILL.CLIENT
          USERX<UR$BILL.CLIENT.HRS>=BILL.CLIENT.HRS
          USERX<UR$SERVICE.CLIENT.HRS>=SERVICE.HOURS
          USERX<UR$FREE.CLIENT.HRS>=FREE.HOURS
        END ELSE
          USERX<UR$OT.HOURS>      =OT.HOURS
          USERX<UR$HOLIDAY.HOURS> =HOL.HOURS
          USERX<UR$VACATION.HOURS>=VAC.HOURS
          USERX<UR$SICK.HOURS>    =SICK.HOURS
          USERX<UR$TOTAL.HOURS>   =TOTAL.HOURS
          USERX<UR$FUNERAL.HOURS> =FUNERAL.HOURS
          USERX<UR$PERSONAL.HOURS>=PERSONAL.HOURS
          USERX<UR$BONUS.HOURS>   =BONUS.HOURS
          USERX<UR$WORKMANS.HOURS>=WORKMANS.HOURS
          USERX<UR$JURY.DUTY.HOURS>=JURY.HOURS
          USERX<UR$OTHER.HOURS>   =OTHER.HOURS
          USERX<UR$LAST.PAY.DATE> =PAY.END
          USERX<UR$VACATION.AVAIL>=USERX<UR$VACATION.AVAIL>+VAC.ACCRUAL-VAC.HOURS
          USERX<UR$SICK.AVAIL>=USERX<UR$SICK.AVAIL>+SIK.ACCRUAL-SICK.HOURS
          USERX<UR$BILL.BILL>=BILL.ONE
          USERX<UR$BILL.SERVICE>=BILL.TWO
          USERX<UR$BILL.FREE>=BILL.THREE
          USERX<UR$BILL.CLIENT>=BILL.CLIENT
          USERX<UR$BILL.CLIENT.HRS>=BILL.CLIENT.HRS
          USERX<UR$SERVICE.CLIENT.HRS>=SERVICE.HOURS
          USERX<UR$FREE.CLIENT.HRS>=FREE.HOURS
        END
        HIST.KEY=ID:"*":PAY.BEGIN
        WRITE USERX ON USER.FILE,ID ; WT=WT+1
        WRITE USERX ON INFO.HIST,HIST.KEY
      END
      RELEASE USER.FILE,ID
    NEXT XTX
  END
  2699 *
REPEAT
*
*
2700 *--- calculate managers totals ---------------------------*
*
CRT @(60,7):CL:
CRT @(60,9):CL:RV:" <===== ":ERV:
*
EOF=0 ; T=0 ; WT=0 ; FILE.ACCESS='MANAGER'
*
LOCATE(PAY.BEGIN,TIME.TABLE,1;BEGIN.ATT) THEN NULL
LOCATE(PAY.END,TIME.TABLE,2;END.ATT) THEN NULL
*
SELECT USER.FILE
LOOP
  READNEXT ID ELSE EOF=1
UNTIL EOF DO
  T=T+1
  IF REM(T,25)=0 THEN GOSUB 2900            ;* refresh totals
  READ MAN.REC FROM USER.FILE,ID ELSE GO 2799
  IF MAN.REC<UR$TYPE.CODE>='M' OR MAN.REC<UR$TYPE.CODE>='O' ELSE GO 2799
  TOTAL.HOURS=0 ; VAC.HOURS=0 ; OT.HOURS=0 ; SICK.HOURS=0
  HOL.HOURS=0 ; OTHER.HOURS=0 ; ACCRUAL.HOURS=0
  WORKED.HOURS=0  ; BONUS.HOURS=0  ; JURY.HOURS=0
  WORKMANS.HOURS=0 ; PERSONAL.HOURS=0 ; FUNERAL.HOURS=0
  *
  TOTAL.HOURS=OCONV(MAN.REC<UR$NEXT.TOTAL>,'MR2') 
  VAC.HOURS  =OCONV(MAN.REC<UR$NEXT.VACATION>,'MR2')
  SICK.HOURS =OCONV(MAN.REC<UR$NEXT.SICK>,'MR2')
  HOL.HOURS  =OCONV(MAN.REC<UR$NEXT.HOLIDAY>,'MR2')  
  OT.HOURS   =OCONV(MAN.REC<UR$NEXT.OT>,'MR2')
  BONUS.HOURS     =OCONV(MAN.REC<UR$NEXT.BONUS>,'MR2')
  JURY.HOURS      =OCONV(MAN.REC<UR$NEXT.JURY>,'MR2')
  WORKMANS.HOURS  =OCONV(MAN.REC<UR$NEXT.WORKMANS>,'MR2')
  PERSONAL.HOURS  =OCONV(MAN.REC<UR$NEXT.PERSONAL>,'MR2')
  FUNERAL.HOURS   =OCONV(MAN.REC<UR$NEXT.FUNERAL>,'MR2')
  OTHER.HOURS     =OCONV(MAN.REC<UR$NEXT.OTHER>,'MR2')
  *
  ACCRUAL.HOURS   =TOTAL.HOURS-OTHER.HOURS
  *---- check for inactive status-----*
  IF MAN.REC<UR$STATUS>#'A' THEN GO 2799        
  *-----------------------------------*
  IF MAN.REC<UR$CLOCK.SYSTEM> # 'M' THEN GO 2799
  *-----------------------------------*
  IF MAN.REC<UR$TYPE.CODE>='M' THEN CALC.FACTOR='.066964'
  IF MAN.REC<UR$TYPE.CODE>='O' THEN
    IF TODAY <= USERX<UR$HIRE.DATE>+365 THEN  ;* 0-1 year
      USERX<UR$CALC.FACTOR>='3.33'
    END
    IF TODAY >= USERX<UR$HIRE.DATE>+365 THEN  ;* 2-9 year
      USERX<UR$CALC.FACTOR>='6.67'
    END
    IF TODAY >= USERX<UR$HIRE.DATE>+3650 THEN ;* ten year
      USERX<UR$CALC.FACTOR>='10'
    END
    IF USERX<UR$TYPE.CODE>='M' THEN           ;* manager rate
      USERX<UR$CALC.FACTOR>='10'
    END
    IF PART.TIME THEN USERX<UR$CALC.FACTOR>='0'
    CALC.FACTOR=USERX<UR$CALC.FACTOR>
    *--- factors per John Longley 04/03/95 -------*
    IF CALC.FACTOR='3.33' THEN CALC.FACTOR='.020492'
    IF CALC.FACTOR='6.67' THEN CALC.FACTOR='.042735'
    IF CALC.FACTOR='10'   THEN CALC.FACTOR='.066964'
  END
  VAC.ACCRUAL=ACCRUAL.HOURS*CALC.FACTOR
  VAC.ONE=OCONV(VAC.ACCRUAL,'G0.1')
  VAC.TWO=OCONV(VAC.ACCRUAL,'G1.1')'L%2'
  VAC.ACCRUAL=VAC.ONE:VAC.TWO[1,2]
  IF CALC.FACTOR='.066964' THEN CALC.FACTOR='.042735' ;* max sick
  SIK.ACCRUAL=ACCRUAL.HOURS*CALC.FACTOR
  SIK.ONE=OCONV(SIK.ACCRUAL,'G0.1')
  SIK.TWO=OCONV(SIK.ACCRUAL,'G1.1')'L%2'
  SIK.ACCRUAL=SIK.ONE:SIK.TWO[1,2]
  MAN.REC<UR$REGULAR.HOURS> =MAN.REC<UR$NEXT.REG>
  MAN.REC<UR$OT.HOURS>      =MAN.REC<UR$NEXT.OT>
  MAN.REC<UR$OTHER.HOURS>   =MAN.REC<UR$NEXT.OTHER>
  MAN.REC<UR$VACATION.HOURS>=MAN.REC<UR$NEXT.VACATION>
  MAN.REC<UR$SICK.HOURS>    =MAN.REC<UR$NEXT.SICK>
  MAN.REC<UR$FUNERAL.HOURS> =MAN.REC<UR$NEXT.FUNERAL>
  MAN.REC<UR$HOLIDAY.HOURS> =MAN.REC<UR$NEXT.HOLIDAY>
  MAN.REC<UR$PERSONAL.HOURS>=MAN.REC<UR$NEXT.PERSONAL>
  MAN.REC<UR$JURY.DUTY.HOURS>=MAN.REC<UR$NEXT.JURY>
  MAN.REC<UR$BONUS.HOURS>   =MAN.REC<UR$NEXT.BONUS>
  MAN.REC<UR$WORKMANS.HOURS>=MAN.REC<UR$NEXT.WORKMANS>
  MAN.REC<UR$TOTAL.HOURS>   =MAN.REC<UR$NEXT.TOTAL>
  MAN.REC<UR$LAST.PAY.DATE> =PAY.END
  MAN.REC<UR$VACATION.AVAIL>=MAN.REC<UR$VACATION.AVAIL>+VAC.ACCRUAL-VAC.HOURS
  MAN.REC<UR$SICK.AVAIL>    =MAN.REC<UR$SICK.AVAIL>+SIK.ACCRUAL-SICK.HOURS
  *--- clear next info attributes -----*
  MAN.REC<UR$NEXT.REG>      =0
  MAN.REC<UR$NEXT.OT>       =0
  MAN.REC<UR$NEXT.HOLIDAY>  =0
  MAN.REC<UR$NEXT.VACATION> =0
  MAN.REC<UR$NEXT.SICK>     =0
  MAN.REC<UR$NEXT.TOTAL>    =0
  MAN.REC<UR$NEXT.FUNERAL>  =0
  MAN.REC<UR$NEXT.PERSONAL> =0
  MAN.REC<UR$NEXT.JURY>     =0
  MAN.REC<UR$NEXT.WORKMANS> =0
  MAN.REC<UR$NEXT.BONUS>    =0
  MAN.REC<UR$NEXT.OTHER>    =0
  HIST.KEY=ID:"*":PAY.BEGIN
  WRITE MAN.REC ON USER.FILE,ID ; WT=WT+1
  WRITE MAN.REC ON INFO.HIST,HIST.KEY
  RELEASE USER.FILE,ID
  2799 *
REPEAT
*
*
CRT @(0,22):CL:RV:" PROCESS COMPLETE <return> :":ERV:
INPUT ANY,3
IF ANY='A' THEN GO 10
RETURN

2900 *--- refrsh processing totals ----------------------------*
LINE=''
LINE=FILE.ACCESS:" RECORDS READ     :"
CRT @(20,16):CR:LINE'L#25':":":T'L,'
CRT @(20,17):CL:"RECORDS FOUND            :":WT'L,'
RETURN
*
35000 *---- verify manager records have been updated since last pay ---*
EOF=0
MAN.TABLE=''
SELECT USER.FILE
LOOP
  READNEXT MANAGER ELSE EOF=1
UNTIL EOF DO
  READ MREC FROM USER.FILE,MANAGER THEN
    IF MREC<UR$TYPE.CODE>='M' THEN
      IF MREC<UR$CLOCK.SYSTEM>='M' THEN
        IF MREC<UR$LAST.UPDATE> < PAY.BEGIN THEN
          MAN.TABLE=MAN.TABLE:" ":MREC<UR$LNAME>
        END
      END
    END
  END
REPEAT
IF MAN.TABLE# '' THEN
  CRT @(0,21):CR:BEEP:RV:STR(' ',80):ERV:
  CRT @(2,21):RV:"Manager records have not been updated for:":ERV:
  CRT @(0,22):CR:BEEP:RV:STR(' ',80):ERV:
  CRT @(1,22):RV:MAN.TABLE<1>'L#78':ERV:
  INPUT ANY,2
  GO 10
END
RETURN
*
40000 *---- load tasks into gen.keys for vac,sick,funeral etc-----*
CRT @(0,22):CL:RV:" VERIFYING TASK ASSIGNMENTS...PLEASE WAIT! ":ERV:
TASK.TABLE='' ; TASK.UPDATE=''
TASK.TABLE='VACATION':AM:'SICK':AM:'HOLIDAY':AM:'BEREAVE'
TASK.TABLE=TASK.TABLE:AM:'PERSONAL':AM:'BONUS':AM:'WORKMAN'
TASK.TABLE=TASK.TABLE:AM:'JURY DUT'
TASK.COUNT=DCOUNT(TASK.TABLE,AM)
EOF=0
T=0
SELECT CUSTOMER.TRANS
*
LOOP 
  READNEXT KEY ELSE EOF=1
UNTIL EOF DO
  T=T+1
  IF REM(T,500)=0 THEN 
    CRT @(0,22):CL:RV:" VERIFYING TASK ASSIGNMENTS...":T'L,':" ":ERV:
  END
  READ TRANS.REC FROM CUSTOMER.TRANS,KEY THEN
    STCT=DCOUNT(TRANS.REC<SS$STATEMENT>,VM)
    FOR YY = 1 TO STCT
      STATEMENT=TRANS.REC<SS$STATEMENT,YY>
      FOR ZZ = 1 TO TASK.COUNT
        TRY=INDEX(STATEMENT,TASK.TABLE<ZZ>,1)
        IF TRY > 0 THEN
          LOCATE(KEY,TASK.REC,ZZ;WHR) ELSE
            TASK.REC=INSERT(TASK.REC,ZZ,1;KEY)
            WRITE TASK.REC ON CLOCK.GEN.KEYS,"TASK.ASSIGNMENTS"
            TASK.UPDATE=1
          END
        END
      NEXT ZZ
    NEXT YY
  END
REPEAT
RETURN
*
*
50000 *--- round all hours to nearest quarter hour (.25)--------*
TABLE=REG.OUT.HOURS:VM:TOTAL.HOURS:VM:VAC.HOURS:VM:OT.HOURS:VM:SICK.HOURS
TABLE=TABLE:VM:HOL.HOURS:VM:OTHER.HOURS:VM:ACCRUAL.HOURS
TABLE=TABLE:VM:WORKED.HOURS:VM:BONUS.HOURS:VM:JURY.HOURS
TABLE=TABLE:VM:WORKMANS.HOURS:VM:PERSONAL.HOURS:VM:FUNERAL.HOURS
*
NUMCT=DCOUNT(TABLE<1>,VM)
CRT @(0,8):CR:
FOR KJ = 1 TO NUMCT
  ADJUST.TOT=TABLE<1,KJ>
CRT 'ADJUST TOTAL    ':ADJUST.TOT
  ADJUST.TOT=ADJUST.TOT'R26'
CRT 'ADJUST TOTAL    ':ADJUST.TOT
  ADJUST.ONE=OCONV(ADJUST.TOT,'G0.1')
CRT 'ADJUST ONE      ':ADJUST.ONE
  ADJUST.TWO=OCONV(ADJUST.TOT,'G1.1')
CRT 'ADJUST TWO      ':ADJUST.TWO
  IF ADJUST.TWO < 13 THEN ADJUST.TWO='00'
  IF ADJUST.TWO >= 13 AND ADJUST.TWO < 38 THEN ADJUST.TWO=25
  IF ADJUST.TWO >= 38 AND ADJUST.TWO < 63 THEN ADJUST.TWO=50
  IF ADJUST.TWO >= 63 AND ADJUST.TWO < 88 THEN ADJUST.TWO=75
  IF ADJUST.TWO >= 88 AND ADJUST.TWO <= 99 THEN 
    ADJUST.TWO='00'
    ADJUST.ONE=ADJUST.ONE+1
  END
  TABLE<1,KJ>=ADJUST.ONE:ADJUST.TWO
CRT 'ADJUST ONE      ':ADJUST.ONE
CRT 'ADJUST TWO      ':ADJUST.TWO
CRT 'NEW TOTAL       ':TABLE<1,KJ>
INPUT ANY,3
NEXT KJ
REG.OUT.HOURS=TABLE<1,1>
TOTAL.HOURS=TABLE<1,2>
VAC.HOURS  =TABLE<1,3>
OT.HOURS   =TABLE<1,4>
SICK.HOURS =TABLE<1,5>
HOL.HOURS  =TABLE<1,6>
OTHER.HOURS=TABLE<1,7>
BONUS.HOURS=TABLE<1,10>
JURY.HOURS =TABLE<1,11>
WORKMANS.HOURS=TABLE<1,12>
PERSONAL.HOURS=TABLE<1,13>
FUNERAL.HOURS =TABLE<1,14>
RETURN