SUBROUTINE MSD.TIME.ACCRUAL * * AUTHOR: SCOTT REDMOND * DATE: 03/20/95 * PURPOSE: CALC HOURS WORKED AND PAYROLL ACCRUAL TOTALS FROM: * * STEP 1 - CLOCK FILE USER RECORDS (IDM & MICAHTEK) * SUB 2200 (BUILD RECORD IN INFO.ACCRUAL FILE) * STEP 2 - PROJECT FILE RECORDS (MIS) * SUB 2400 (BUILD RECORD IN INFO.ACCRUAL FILE) * STEP 3 - LOOP INFO.ACCRUAL FILE (CLOCKFILE & PROJECT USERS) * SUB 2600 (TOTAL HOURS & UPDATE 'USER' FILE) * STEP 4 - PROCESS MANAGER'S RECORDS (HOURS ARE MANUALLY * ENTERED BY PAYROLL; M-0-14-4 OR MSD.USER.MAINT) * SUB 2700 (TOTAL MGR HOURS & UPDATE 'USER' FILE) * * UPDATED: STR - 05/31/95, MODIFY PROCESS TO INCORPORATE PERSONAL * TIME ACCRUAL WHICH REPLACES SICK TIME ACCRUAL. * CHANGE VACATION ACCRUAL SCHEDULE PER PAYROLL DEPT. *-------------------------------------------------------------------* * $INCLUDE GEN.COMMON $INCLUDE USER $INCLUDE SUPPORT.RECORD * *-------------------------------------------------------------------* * OPEN 'PC.CLIENT' TO PC.CLIENT ELSE ABORT 201, 'PC.CLIENT' OPEN 'SCOTT.WORK' 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 'SCOTT.WORK2' 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 'PERFECT.WORK' TO INFO.HIST ELSE ABORT 201, 'INFO.HIST' * *-------------------------------------------------------------------* * USER.ADD='' ; USER.REC='' ; TODAY=DATE() * * *---- vacation cap exceptions -------------------------------------* VACEX='7777':VM:'0640';* al surles, don bell have no vacation cap * MAX.VAC='16000' ;* maximum vacation hours = 160 MAX.PER='19200' ;* maximum personal accrual hours = 192 * PCALC='.011538' ;* personal time calc factor/hour for everyone * ;* .011538 X 2080 = 3 days per year *-------------------------------------------------------------------* 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.PERFECT" ELSE * * NOTE: IF CLOCK.GEN.KEYS ITEM "NEXT.PAY.PERIOD" IS MISSING: * 1.) FIND THE LATEST 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'):" :":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.PERFECT" CRT @(60,5):CL:RV:" <===== ":ERV: * USER.ADD='' ; USER.REC='' ; TODAY=DATE() ; WT=0 ; FOUND=0 SDATE=ICONV('03/26/94','D') * INIT='' 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 2200 *---- process and accrue clockfile records-----------------------* * 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 READ USR.REC FROM USER.FILE,USER.KEY THEN IF USR.REC# '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> IF CLOCK.DATE <= LAST.DAY.OF.WEEK THEN WEEK.NUM=1 END ELSE WEEK.NUM=2 END *----- 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 FUNERAL.TOTAL=0 ; JURY.TOTAL=0 ; WORKMANS.TOTAL=0 PERSONAL.TOTAL=0 ; BONUS.TOTAL=0 ; OTHER.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'R%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='' INFO.REC<1,WEEK.NUM>=INFO.REC<1,WEEK.NUM>+OUTPUT.HOURS ;* add hours INFO.REC<2,WEEK.NUM>=TIME.TABLE<1,POSITION> ;* beginning period date INFO.REC<3,WEEK.NUM>=TIME.TABLE<2,POSITION> ;* ending period date INFO.REC<4,WEEK.NUM>=INFO.REC<4,WEEK.NUM>+VAC.TOTAL ;* vacation hours INFO.REC<5,WEEK.NUM>=INFO.REC<5,WEEK.NUM>+SICK.TOTAL ;* sick hours used INFO.REC<6,WEEK.NUM>=INFO.REC<6,WEEK.NUM>+HOLIDAY.TOTAL ;* holiday hours * SKIP OTHER TOTAL (CALCULATE IN SUB 2600) INFO.REC<8,WEEK.NUM>=INFO.REC<8,WEEK.NUM>+FUNERAL.TOTAL ;* funeral hours INFO.REC<9,WEEK.NUM>=INFO.REC<9,WEEK.NUM>+PERSONAL.TOTAL ;* personal hours INFO.REC<10,WEEK.NUM>=INFO.REC<10,WEEK.NUM>+BONUS.TOTAL ;* bonus hours INFO.REC<11,WEEK.NUM>=INFO.REC<11,WEEK.NUM>+JURY.TOTAL ;* jury hours INFO.REC<12,WEEK.NUM>=INFO.REC<12,WEEK.NUM>+WORKMANS.TOTAL;* work comp hours *--------------------------------------------------------------* 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 LAST.DAY.OF.WEEK=TIME.TABLE<4,BEGIN.ATT> * 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,VM) FOR XGG = 1 TO TRANCT ACTION.DATE=CUST.REC USER.KEY=CUST.REC[2,4] READ QREC FROM USER.FILE,USER.KEY ELSE GO 2449 IF QREC # 'P' THEN GO 2449 BILL.CODE=CUST.REC BILL.CLIENT=CUST.REC IF ACTION.DATE >= PAY.BEGIN AND ACTION.DATE <= PAY.END THEN IF CUST.REC='30' THEN IF ACTION.DATE <= LAST.DAY.OF.WEEK THEN WEEK.NUM=1 END ELSE WEEK.NUM=2 END MINUTES=0 MINUTES=CUST.REC 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'R%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=INIT BEGIN CASE CASE BILL.CODE=1 ;*---- billable client hours ------* INFO.REC<13>=INFO.REC<13>+OUTPUT.HOURS LOCATE(BILL.CLIENT,INFO.REC,16;WHRR) THEN INFO.REC<17,WHRR>=INFO.REC<17,WHRR>+OUTPUT.HOURS END ELSE INFO.REC<16,WHRR>=BILL.CLIENT INFO.REC<17,WHRR>=OUTPUT.HOURS END CASE BILL.CODE=2 ;*------ service cont. client hours--* INFO.REC<14>=INFO.REC<14>+OUTPUT.HOURS LOCATE(BILL.CLIENT,INFO.REC,16;WHRR) THEN INFO.REC<18,WHRR>=INFO.REC<18,WHRR>+OUTPUT.HOURS END ELSE INFO.REC<16,WHRR>=BILL.CLIENT INFO.REC<18,WHRR>=OUTPUT.HOURS END CASE BILL.CODE=3 ;*------ free hours-----------------* INFO.REC<15>=INFO.REC<15>+OUTPUT.HOURS LOCATE(BILL.CLIENT,INFO.REC,16;WHRR) THEN INFO.REC<19,WHRR>=INFO.REC<19,WHRR>+OUTPUT.HOURS END ELSE INFO.REC<16,WHRR>=BILL.CLIENT INFO.REC<19,WHRR>=OUTPUT.HOURS END CASE 1 ;*--- if not 1,2 or 3 then force it 3 -------* INFO.REC<15>=INFO.REC<15>+OUTPUT.HOURS END CASE * LOCATE(TASK.NO,TASK.REC,1;FND) THEN ;* vacation task INFO.REC<4,WEEK.NUM>=INFO.REC<4,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,2;FND) THEN ;* sick task INFO.REC<5,WEEK.NUM>=INFO.REC<5,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,3;FND) THEN ;* holiday task INFO.REC<6,WEEK.NUM>=INFO.REC<6,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,4;FND) THEN ;* funeral task INFO.REC<8,WEEK.NUM>=INFO.REC<8,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,5;FND) THEN ;* personal task INFO.REC<9,WEEK.NUM>=INFO.REC<9,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,6;FND) THEN ;* bonus task INFO.REC<10,WEEK.NUM>=INFO.REC<10,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,7;FND) THEN ;* workmans task INFO.REC<12,WEEK.NUM>=INFO.REC<12,WEEK.NUM>+OUTPUT.HOURS END LOCATE(TASK.NO,TASK.REC,8;FND) THEN ;* jury task INFO.REC<11,WEEK.NUM>=INFO.REC<11,WEEK.NUM>+OUTPUT.HOURS END INFO.REC<1,WEEK.NUM>=INFO.REC<1,WEEK.NUM>+OUTPUT.HOURS ;* add hours INFO.REC<2>=TIME.TABLE<1,POSITION> ;* beginning period date INFO.REC<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)--* * * for clockfile users and project users * 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 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.OT=0 ; SECOND.OT=0 ; REG.OUT.HOURS=0 VAC.ACCRUAL=0 ; PER.ACCRUAL=0 ; SICK.HOURS=0 VCALC=0 * READ IREC FROM INFO.ACCRUAL,ID THEN TOTAL.HOURS =SUM(IREC<1>) VAC.HOURS =SUM(IREC<4>) ;* vacation hours used SICK.HOURS =SUM(IREC<5>) ;* sick hours used HOL.HOURS =SUM(IREC<6>) ;* holiday hours used FUNERAL.HOURS =SUM(IREC<8>) PERSONAL.HOURS =SUM(IREC<9>) BONUS.HOURS =SUM(IREC<10>) JURY.HOURS =SUM(IREC<11>) WORKMANS.HOURS =SUM(IREC<12>) FIRST.OTHER =IREC<4,1>+IREC<5,1>+IREC<6,1>+IREC<8,1> FIRST.OTHER =FIRST.OTHER+IREC<9,1>+IREC<10,1>+IREC<11,1>+IREC<12,1> FIRST.REG =IREC<1,1>-FIRST.OTHER *--- total hours that apply to perfect attendence ------* PERFECT.ONE =IREC<1,1>-(IREC<12,1>+IREC<11,1>+IREC<9,1>+IREC<5,1>) PERFECT.TWO =IREC<1,2>-(IREC<12,2>+IREC<11,2>+IREC<9,2>+IREC<5,2>) *--- figure first week overtime ------------------------* IF FIRST.REG > 4000 THEN FIRST.OT=FIRST.REG-4000 FIRST.REG=4000 END ELSE FIRST.OT=0 END *--- figure second week overtime ----------------------* SECOND.OTHER =IREC<4,2>+IREC<5,2>+IREC<6,2>+IREC<8,2> SECOND.OTHER =SECOND.OTHER+IREC<9,2>+IREC<10,2>+IREC<11,2>+IREC<12,2> SECOND.REG =IREC<1,2>-SECOND.OTHER IF SECOND.REG > 4000 THEN SECOND.OT=SECOND.REG-4000 SECOND.REG=4000 END ELSE SECOND.OT=0 END IF FIRST.OT < 13 THEN FIRST.OT='00' ;* less than .25 hr = 0 IF SECOND.OT < 13 THEN SECOND.OT='00' ;* less than .25 hr = 0 OTHER.HOURS=FIRST.OTHER+SECOND.OTHER OT.HOURS=FIRST.OT+SECOND.OT * GOSUB 50000 ;* round all hours to nearest .25 * IF TOTAL.HOURS # FIRST.REG+SECOND.REG+OT.HOURS+OTHER.HOURS THEN TOTAL.HOURS=FIRST.REG+SECOND.REG+OT.HOURS+OTHER.HOURS END * BILL.ONE =IREC<13> BILL.TWO =IREC<14> BILL.THREE =IREC<15> BILL.CLIENT =IREC<16> BILL.CLIENT.HRS =IREC<17> SERVICE.HOURS =IREC<18> FREE.HOURS =IREC<19> * WORKED.HOURS=TOTAL.HOURS-OT.HOURS ;* accrue on all except OT * WORKED.HOURS=FIRST.REG+SECOND.REG WORKED.HOURS=FIRST.REG+SECOND.REG+OTHER.HOURS REG.OUT.HOURS=FIRST.REG+SECOND.REG IF WORKED.HOURS >= 8000 THEN ACCRUAL.HOURS=8000 END ELSE ACCRUAL.HOURS=WORKED.HOURS END ACCRUAL.HOURS=OCONV(ACCRUAL.HOURS,'MR2') READU USERX FROM USER.FILE,ID THEN VCALC=0 *---- check for probation ----------* USERX=USERX+90 *---- check for part time ----------* IF USERX='P' THEN PART.TIME=1 ELSE PART.TIME='' *---- check for managers ----------* IF USERX='M' THEN GO 2699 *---- check for inactive status-----* * IF USERX#'A' THEN GO 2699 ;* PER JOHN (CALC INACTIVE) * *--- figure vacation accrual factor ------------------------* IF TODAY <= USERX+365 THEN ;* 0-1 year IF TODAY >= USERX + 90 THEN ;* after probation USERX='4.5' VCALC='.0173' END ELSE USERX='0' END END IF TODAY >= USERX+365 THEN ;* 2 year USERX='7.0' VCALC='.0270' END IF TODAY >= USERX+730 THEN ;* 3 year USERX='8.0' VCALC='.0308' END IF TODAY >= USERX+1095 THEN ;* 4 year USERX='9.0' VCALC='.0346' END IF TODAY >= USERX+1460 THEN ;* 5-9 year USERX='10.0' VCALC='.0385' END IF TODAY >= USERX+3285 THEN ;* 10+ year USERX='15.0' VCALC='.0577' END IF USERX='M' THEN ;* manager rate USERX='15.0' ;* with clock system VCALC='.0577' ;* other than manger END IF PART.TIME THEN ;* no accrual for part-time USERX='0' VCALC='0' END *--- calculate vaction accrual ---------------* USERX=VCALC VAC.ACCRUAL=ACCRUAL.HOURS*VCALC VAC.ONE=OCONV(VAC.ACCRUAL,'G0.1') VAC.TWO=OCONV(VAC.ACCRUAL,'G1.1')'L%2' VAC.ACCRUAL=VAC.ONE:VAC.TWO[1,2] *--- calculate personal accrual --------------* IF USERX < 1 THEN HIRE=USERX GOSUB 65000 ;* find first date employee accrues personal USERX=BEGIN.PERSONAL.ACCRUAL END IF TODAY >= USERX THEN IF NOT(PART.TIME) THEN PER.ACCRUAL=ACCRUAL.HOURS*PCALC PER.ONE=OCONV(PER.ACCRUAL,'G0.1') PER.TWO=OCONV(PER.ACCRUAL,'G1.1')'L%2' PER.ACCRUAL=PER.ONE:PER.TWO[1,2] END END *---------------------------------------------* * GOSUB 50000 ;* round all hours to nearest .25hr * IF TOTAL.HOURS # FIRST.REG+SECOND.REG+OT.HOURS+OTHER.HOURS THEN * TOTAL.HOURS=FIRST.REG+SECOND.REG+OT.HOURS+OTHER.HOURS * END * *--- update user record with current pay period info---* USERX =REG.OUT.HOURS IF PART.TIME THEN ;* reduce but not accrue vac USERX =OT.HOURS USERX =HOL.HOURS USERX =FUNERAL.HOURS USERX=PERSONAL.HOURS USERX =BONUS.HOURS USERX=WORKMANS.HOURS USERX=JURY.HOURS USERX=VAC.HOURS USERX =SICK.HOURS USERX =TOTAL.HOURS USERX =OTHER.HOURS USERX =PAY.END USERX=USERX-VAC.HOURS USERX=USERX-PERSONAL.HOURS-BONUS.HOURS USERX =BILL.ONE USERX =BILL.TWO USERX =BILL.THREE USERX =BILL.CLIENT USERX=BILL.CLIENT.HRS USERX=SERVICE.HOURS USERX=FREE.HOURS END ELSE USERX =OT.HOURS USERX =HOL.HOURS USERX=VAC.HOURS USERX =SICK.HOURS USERX =TOTAL.HOURS USERX =FUNERAL.HOURS USERX=PERSONAL.HOURS USERX =BONUS.HOURS USERX=WORKMANS.HOURS USERX=JURY.HOURS USERX =OTHER.HOURS USERX =PAY.END USERX=USERX+VAC.ACCRUAL-VAC.HOURS USERX=USERX+PER.ACCRUAL-PERSONAL.HOURS-BONUS.HOURS USERX =BILL.ONE USERX =BILL.TWO USERX =BILL.THREE USERX =BILL.CLIENT USERX=BILL.CLIENT.HRS USERX=SERVICE.HOURS USERX=FREE.HOURS USERX=PERFECT.ONE ;* perfect attnd. totals USERX=PERFECT.TWO END *--- cap on vacation (20 days) and personal (24 days) --* LOCATE(ID,VACEX,1;FND) ELSE ;* vacation cap exceptions IF USERX > MAX.VAC THEN USERX=MAX.VAC END END IF USERX > MAX.PER THEN USERX=MAX.PER END * *--- write user file and history (reports run from history) 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 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='M' OR MAN.REC='O' ELSE GO 2799 TOTAL.HOURS=0 ; VAC.HOURS=0 ; OT.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 VAC.ACCRUAL=0 ; PER.ACCRUAL=0 ; SICK.HOURS=0 * REG.HOURS =OCONV(MAN.REC,'MR2') TOTAL.HOURS =OCONV(MAN.REC,'MR2') VAC.HOURS =OCONV(MAN.REC,'MR2') SICK.HOURS =OCONV(MAN.REC,'MR2') HOL.HOURS =OCONV(MAN.REC,'MR2') OT.HOURS =OCONV(MAN.REC,'MR2') BONUS.HOURS =OCONV(MAN.REC,'MR2') JURY.HOURS =OCONV(MAN.REC,'MR2') WORKMANS.HOURS =OCONV(MAN.REC,'MR2') PERSONAL.HOURS =OCONV(MAN.REC,'MR2') FUNERAL.HOURS =OCONV(MAN.REC,'MR2') OTHER.HOURS =OCONV(MAN.REC,'MR2') * ACCRUAL.HOURS =TOTAL.HOURS-OT.HOURS *---- check for inactive status-----* IF MAN.REC#'A' THEN GO 2799 *-----------------------------------* IF MAN.REC # 'M' THEN GO 2799 *-----------------------------------* IF MAN.REC='M' THEN MAN.REC='15.0' VCALC='.0577' END IF MAN.REC='O' THEN ;* others using mgr clock system IF TODAY <= MAN.REC+365 THEN ;* 0-1 year IF TODAY >= MAN.REC + 90 THEN ;* after probation MAN.REC='4.5' VCALC='.0173' END ELSE MAN.REC='0' END END IF TODAY >= MAN.REC+365 THEN ;* 2 year MAN.REC='7.0' VCALC='.0270' END IF TODAY >= MAN.REC+730 THEN ;* 3 year MAN.REC='8.0' VCALC='.0308' END IF TODAY >= MAN.REC+1095 THEN ;* 4 year MAN.REC='9.0' VCALC='.0346' END IF TODAY >= MAN.REC+1460 THEN ;* 5-9 year MAN.REC='10.0' VCALC='.0385' END IF TODAY >= MAN.REC+3285 THEN ;* 10+ year MAN.REC='15.0' VCALC='.0577' END END IF PART.TIME THEN MAN.REC='0' VCALC=0 END CALC.FACTOR=MAN.REC MAN.REC=VCALC *--- calculate vaction accrual ---------------* MAN.REC=VCALC VAC.ACCRUAL=ACCRUAL.HOURS*VCALC VAC.ONE=OCONV(VAC.ACCRUAL,'G0.1') VAC.TWO=OCONV(VAC.ACCRUAL,'G1.1')'L%2' VAC.ACCRUAL=VAC.ONE:VAC.TWO[1,2] *--- calculate personal accrual --------------* IF MAN.REC < 1 THEN HIRE=MAN.REC GOSUB 65000 ;* find first date employee accrues personal MAN.REC=BEGIN.PERSONAL.ACCRUAL END IF TODAY >= MAN.REC THEN IF NOT(PART.TIME) THEN PER.ACCRUAL=ACCRUAL.HOURS*PCALC PER.ONE=OCONV(PER.ACCRUAL,'G0.1') PER.TWO=OCONV(PER.ACCRUAL,'G1.1')'L%2' PER.ACCRUAL=PER.ONE:PER.TWO[1,2] END END *--- update manager's record with current pay period totals ----* MAN.REC =MAN.REC MAN.REC =MAN.REC MAN.REC =MAN.REC MAN.REC=MAN.REC MAN.REC =MAN.REC MAN.REC =MAN.REC MAN.REC =MAN.REC MAN.REC=MAN.REC MAN.REC=MAN.REC MAN.REC =MAN.REC MAN.REC=MAN.REC MAN.REC =MAN.REC MAN.REC =PAY.END IBONUS.HOURS =ICONV(BONUS.HOURS,'MR2') IVAC.HOURS =ICONV(VAC.HOURS,'MR2') IPER.HOURS =ICONV(PERSONAL.HOURS,'MR2') MAN.REC=MAN.REC+VAC.ACCRUAL-IVAC.HOURS MAN.REC=MAN.REC+PER.ACCRUAL-IPER.HOURS-IBONUS.HOURS *--- clear 'next' attributes for next pay period -----* MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 MAN.REC =0 *----- cap on vacation (20 days) and personal time (24 days) ---* LOCATE(ID,VACEX,1;FND) ELSE ;* vacation cap exceptions IF MAN.REC > MAX.VAC THEN MAN.REC=MAX.VAC END END IF MAN.REC > MAX.PER THEN MAN.REC=MAX.PER END *--- write on user file & history (reports run from history file) 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 :":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='M' OR MREC='O' THEN IF MREC='M' THEN IF MREC < PAY.BEGIN THEN MAN.TABLE=MAN.TABLE:" ":MREC 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-----* * * NOTE: This is for project/MIS * CRT @(0,22):CL:RV:" VERIFYING TASK ASSIGNMENTS...PLEASE WAIT! ":ERV: TASK.TABLE='' ; TASK.UPDATE='' ; NEW.TABLE='' 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,VM) FOR YY = 1 TO STCT STATEMENT=TRANS.REC FOR ZZ = 1 TO TASK.COUNT TRY=INDEX(STATEMENT,TASK.TABLE,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 NEW.TABLE=NEW.TABLE:" ":KEY END END NEXT ZZ NEXT YY END REPEAT IF TASK.UPDATE THEN CRT @(0,22):CL:BEEP:RV:" VERIFY NEW TASKS ADDED : ":NEW.TABLE:" ":ERV: INPUT ANY,2 END 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 TABLE=TABLE:VM:FIRST.REG:VM:SECOND.REG * NUMCT=DCOUNT(TABLE<1>,VM) FOR KJ = 1 TO NUMCT ADJUST.TOT=TABLE<1,KJ> ADJUST.TOT=ADJUST.TOT'R26' ADJUST.ONE=OCONV(ADJUST.TOT,'G0.1') ADJUST.TWO=OCONV(ADJUST.TOT,'G1.1') 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 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> FIRST.REG =TABLE<1,15> SECOND.REG =TABLE<1,16> RETURN * 65000 *-- determine first date employee qualifies for personal time--* * * If user begins on the first possible working day of that month * then their personal time begins accruing after three full months. * * If user begins later than the first possible working day (m-f) then * their personal time begins accruing after three 'full' months. * * i.e. begin... may 1st = accrue aug 1st. * begin... may 4th = accrue sept 1st. * FIRST.POSS='' BEGIN.PERSONAL.ACCRUAL='' HIRE.DATE =OCONV(HIRE,'D2/') HIRE.MONTH=HIRE.DATE[1,2] HIRE.YEAR =HIRE.DATE[7,2] HIRE.DAY =HIRE.DATE[4,2] FOR RR = 1 TO 7 TEST.DATE=ICONV(HIRE.MONTH'R%2':'/':RR'R%2':'/':HIRE.YEAR'R%2','D') IF OCONV(TEST.DATE,'DW') >= 1 AND OCONV(TEST.DATE,'DW') <= 5 THEN FIRST.POSS=TEST.DATE GO 65700 END NEXT RR 65700 * IF FIRST.POSS >= HIRE THEN TERMS=3 ;* begin accruing per time = hire month + 3 END ELSE TERMS=4 ;* begin accruing personal time = hire month + 4 END ;* (must work full month to accrue time) * NEW.MONTH=HIRE.MONTH NEW.YEAR =HIRE.YEAR * FOR QQ = 1 TO TERMS NEW.MONTH=NEW.MONTH+1 IF NEW.MONTH > 12 THEN NEW.MONTH=1 NEW.YEAR=NEW.YEAR+1 END NEXT QQ NEW.DATE=NEW.MONTH'R%2':'/01/':NEW.YEAR'R%2' BEGIN.PERSONAL.ACCRUAL=ICONV(NEW.DATE,'D') RETURN