tldm-universe/CMS/BP.CLOCK/MSD.TIME.ACCRUAL
2024-09-10 15:25:06 -04:00

757 lines
28 KiB
Plaintext
Executable File

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 - LOOP INFO.ACCRUAL FILE (CLOCKFILE USERS)
* SUB 2600 (TOTAL HOURS & UPDATE 'USER' FILE)
* STEP 3 - PROCESS PROJECT/MANAGER'S RECORDS (HOURS 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.
* UPDATED: STR - 01/25/95, MODIFY PROCESS FOR 1ST AND 15TH OF THE
* MONTH (24 PERIOD) SCHEDULE. CHANGE PROJECT USER'S TO
* PROCESS HOURS MANUALLY ENTERED THE SAME AS MANAGERS
*-------------------------------------------------------------------*
*
$INCLUDE GEN.COMMON
$INCLUDE USER
$INCLUDE SUPPORT.RECORD
$INCLUDE CLOCK.PAY.DATES
*
*-------------------------------------------------------------------*
*
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'
OPEN 'CLOCK.PAY.DATES' TO CLOCK.PAY.DATES ELSE ABORT 201, 'CLOCK.PAY.DATES'
*
*-------------------------------------------------------------------*
*
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,7):CL:RV:" STEP 2 - PROCESS PROJECT/MANAGERS ":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
*
JEN.REC.HOLD=JEN.REC<1>
PAY.PER=OCONV(JEN.REC<1>,"D2/")
CPERIOD=PAY.PER[7,2]:PAY.PER[1,2]
READ DATE.REC FROM CLOCK.PAY.DATES,CPERIOD ELSE
CRT @(0,22):CL:BEEP:RV:" SERIOUS ERROR - CLOCK.PAY.DATES (PAY PERIOD DATES MISSING)! ":ERV:
INPUT ANY,3
STOP
END
LOCATE(JEN.REC<1>,DATE.REC,CPD$PAY.DATE;PPD.FND) ELSE
CRT @(0,22):CL:BEEP:RV:" DATA FOR PAY PERIOD IS MISSING! (CLOCK.PAY.DATES) ":ERV:
INPUT ANY,3
STOP
END
*
PAY.BEGIN=DATE.REC<CPD$PERIOD.BEGIN,PPD.FND>
ACTUAL.PAY.DATE=DATE.REC<CPD$PAY.DATE,PPD.FND>
PASSWORD=CHAR(73):CHAR(88):CHAR(79):CHAR(89):CHAR(69)
*
2010 *--- display pay period data to screen --------------------*
*
CRT @(20,10):CL:RV:" PAY PERIOD DATE :":ERV:" ":OCONV(ACTUAL.PAY.DATE,'D')
CRT @(20,12):CL:RV:" PAY PERIOD BEGIN DATE :":ERV:" ":OCONV(PAY.BEGIN,'D')
PAY.END=DATE.REC<CPD$PERIOD.END,PPD.FND>
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 ENTER MSD.INFO.ACCRUAL
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 project/manager records updated since last pay
*
*--- write the next pay period date to gen.keys item -----------*
*
JEN.REC<1>=DATE.REC<CPD$PAY.DATE,PPD.FND+1> ;* next pay period
IF JEN.REC<1> >1 ELSE
READ NEXT.DATE.REC FROM CLOCK.PAY.DATES,DATE.REC<CPD$NEXT.PERIOD> THEN
JEN.REC<1>=NEXT.DATE.REC<CPD$PAY.DATE,1>
END ELSE
CRT @(0,22):CL:BEEP:RV:" Next pay period dates missing! <return> :":ERV:
INPUT ANY,4
STOP
END
END
NEXT.PAY.DATE=JEN.REC<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
*
*---- determine week 1,2 & 3 for overtime calc -----------------*
INIT=''
LAST.DAY.WEEK.ONE =DATE.REC<CPD$WEEK.ONE.END,PPD.FND>
LAST.DAY.WEEK.TWO =DATE.REC<CPD$WEEK.TWO.END,PPD.FND>
LAST.DAY.WEEK.THREE=DATE.REC<CPD$WEEK.THREE.END,PPD.FND>
NUMBER.WEEKS =DATE.REC<CPD$NUM.WEEKS,PPD.FND>
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
READ USR.REC FROM USER.FILE,USER.KEY THEN
*---- check for time clock employee only -------------*
IF USR.REC<UR$CLOCK.SYSTEM>='C' ELSE GO 2300
*
FOUND=FOUND+1
IF CLOCK.DATE <= LAST.DAY.WEEK.ONE THEN
WEEK.NUM=1
END
IF CLOCK.DATE > LAST.DAY.WEEK.ONE AND CLOCK.DATE <= LAST.DAY.WEEK.TWO THEN
WEEK.NUM=2
END
IF CLOCK.DATE > LAST.DAY.WEEK.TWO AND CLOCK.DATE <= LAST.DAY.WEEK.THREE THEN
WEEK.NUM=3
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>=PAY.BEGIN ;* beginning period date
INFO.REC<3,WEEK.NUM>=PAY.END ;* 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
*
*
2600 *---- select file & determine hours accrued/used (non-manager)--*
*
* for clockfile users
*
EOF=0 ; T=0 ; WT=0 ; FILE.ACCESS='USER FILE'
*
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 ; THIRD.OT=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
*--- 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
*--- figure third week overtime ----------------------*
THIRD.OTHER =IREC<4,3>+IREC<5,3>+IREC<6,3>+IREC<8,3>
THIRD.OTHER =THIRD.OTHER+IREC<9,3>+IREC<10,3>+IREC<11,3>+IREC<12,3>
THIRD.REG =IREC<1,3>-THIRD.OTHER
IF THIRD.REG > 4000 THEN
THIRD.OT=THIRD.REG-4000
THIRD.REG=4000
END ELSE
THIRD.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
IF THIRD.OT < 13 THEN THIRD.OT='00' ;* less than .25 hr = 0
OTHER.HOURS=FIRST.OTHER+SECOND.OTHER+THIRD.OTHER
OT.HOURS=FIRST.OT+SECOND.OT+THIRD.OT
*
GOSUB 50000 ;* round all hours to nearest .25
*
TOTAL.HOURS=FIRST.REG+SECOND.REG+THIRD.REG+OT.HOURS+OTHER.HOURS
*
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=FIRST.REG+SECOND.REG+THIRD.REG+OTHER.HOURS
REG.OUT.HOURS=FIRST.REG+SECOND.REG+THIRD.REG
IF WORKED.HOURS >= 4000*NUMBER.WEEKS THEN ;* accrue based on
ACCRUAL.HOURS=4000*NUMBER.WEEKS ;* 40 hours times the
END ELSE ;* number of weeks
ACCRUAL.HOURS=WORKED.HOURS
END
ACCRUAL.HOURS=OCONV(ACCRUAL.HOURS,'MR2')
READU USERX FROM USER.FILE,ID THEN
VCALC=0
*---- 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 ;* PER JOHN (CALC INACTIVE)
*
*--- figure vacation accrual factor ------------------------*
IF TODAY <= USERX<UR$HIRE.DATE>+365 THEN ;* 0-1 year
IF TODAY >= USERX<UR$HIRE.DATE> + 90 THEN ;* after probation
USERX<UR$CALC.FACTOR>='4.5'
VCALC='.0173'
END ELSE
USERX<UR$CALC.FACTOR>='0'
END
END
IF TODAY >= USERX<UR$HIRE.DATE>+365 THEN ;* 2 year
USERX<UR$CALC.FACTOR>='7.0'
VCALC='.0270'
END
IF TODAY >= USERX<UR$HIRE.DATE>+730 THEN ;* 3 year
USERX<UR$CALC.FACTOR>='8.0'
VCALC='.0308'
END
IF TODAY >= USERX<UR$HIRE.DATE>+1095 THEN ;* 4 year
USERX<UR$CALC.FACTOR>='9.0'
VCALC='.0346'
END
IF TODAY >= USERX<UR$HIRE.DATE>+1460 THEN ;* 5-9 year
USERX<UR$CALC.FACTOR>='10.0'
VCALC='.0385'
END
IF TODAY >= USERX<UR$HIRE.DATE>+3285 THEN ;* 10+ year
USERX<UR$CALC.FACTOR>='15.0'
VCALC='.0577'
END
IF USERX<UR$TYPE.CODE>='M' THEN ;* manager rate
USERX<UR$CALC.FACTOR>='15.0' ;* with clock system
VCALC='.0577' ;* other than manger
END
IF PART.TIME THEN ;* no accrual for part-time
USERX<UR$CALC.FACTOR>='0'
VCALC='0'
END
*--- calculate vaction accrual ---------------*
USERX<UR$INTERNAL.CALC>=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<UR$PERSONAL.BEGIN> < 1 THEN
HIRE=USERX<UR$HIRE.DATE>
GOSUB 65000 ;* find first date employee accrues personal
USERX<UR$PERSONAL.BEGIN>=BEGIN.PERSONAL.ACCRUAL
END
IF TODAY >= USERX<UR$PERSONAL.BEGIN> 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
*
*--- update user record with current pay period info---*
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> =HOL.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$VACATION.HOURS>=VAC.HOURS
USERX<UR$SICK.HOURS> =SICK.HOURS
USERX<UR$TOTAL.HOURS> =TOTAL.HOURS
USERX<UR$OTHER.HOURS> =OTHER.HOURS
USERX<UR$LAST.PAY.DATE> =ACTUAL.PAY.DATE
USERX<UR$VACATION.AVAIL>=USERX<UR$VACATION.AVAIL>-VAC.HOURS
USERX<UR$PERSONAL.AVAIL>=USERX<UR$PERSONAL.AVAIL>-PERSONAL.HOURS-BONUS.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> =ACTUAL.PAY.DATE
USERX<UR$VACATION.AVAIL>=USERX<UR$VACATION.AVAIL>+VAC.ACCRUAL-VAC.HOURS
USERX<UR$PERSONAL.AVAIL>=USERX<UR$PERSONAL.AVAIL>+PER.ACCRUAL-PERSONAL.HOURS-BONUS.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
*--- cap on vacation (20 days) and personal (24 days) --*
LOCATE(ID,VACEX,1;FND) ELSE ;* vacation cap exceptions
IF USERX<UR$VACATION.AVAIL> > MAX.VAC THEN
USERX<UR$VACATION.AVAIL>=MAX.VAC
END
END
IF USERX<UR$PERSONAL.AVAIL> > MAX.PER THEN
USERX<UR$PERSONAL.AVAIL>=MAX.PER
END
USERX<UR$NEXT.PAY.DATE>=NEXT.PAY.DATE
*
*--- 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,5):CL:
CRT @(60,7):CL:RV:" <===== ":ERV:
*
EOF=0 ; T=0 ; WT=0 ; FILE.ACCESS='MANAGER'
*
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$CLOCK.SYSTEM>='M' 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<UR$NEXT.REG>,'MR2')
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-OT.HOURS
*---- check for inactive status-----*
IF MAN.REC<UR$STATUS>#'A' THEN GO 2799
*-----------------------------------*
IF MAN.REC<UR$TYPE.CODE>='P' THEN PART.TIME='1' ELSE PART.TIME=''
IF MAN.REC<UR$TYPE.CODE>='M' THEN
MAN.REC<UR$CALC.FACTOR>='15.0'
VCALC='.0577'
END ELSE ;* others using mgr clock system
IF TODAY <= MAN.REC<UR$HIRE.DATE>+365 THEN ;* 0-1 year
IF TODAY >= MAN.REC<UR$HIRE.DATE> + 90 THEN ;* after probation
MAN.REC<UR$CALC.FACTOR>='4.5'
VCALC='.0173'
END ELSE
MAN.REC<UR$CALC.FACTOR>='0'
END
END
IF TODAY >= MAN.REC<UR$HIRE.DATE>+365 THEN ;* 2 year
MAN.REC<UR$CALC.FACTOR>='7.0'
VCALC='.0270'
END
IF TODAY >= MAN.REC<UR$HIRE.DATE>+730 THEN ;* 3 year
MAN.REC<UR$CALC.FACTOR>='8.0'
VCALC='.0308'
END
IF TODAY >= MAN.REC<UR$HIRE.DATE>+1095 THEN ;* 4 year
MAN.REC<UR$CALC.FACTOR>='9.0'
VCALC='.0346'
END
IF TODAY >= MAN.REC<UR$HIRE.DATE>+1460 THEN ;* 5-9 year
MAN.REC<UR$CALC.FACTOR>='10.0'
VCALC='.0385'
END
IF TODAY >= MAN.REC<UR$HIRE.DATE>+3285 THEN ;* 10+ year
MAN.REC<UR$CALC.FACTOR>='15.0'
VCALC='.0577'
END
END
IF PART.TIME THEN
MAN.REC<UR$CALC.FACTOR>='0'
VCALC=0
END
CALC.FACTOR=MAN.REC<UR$CALC.FACTOR>
MAN.REC<UR$INTERNAL.CALC>=VCALC
*--- calculate vaction accrual ---------------*
MAN.REC<UR$INTERNAL.CALC>=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<UR$PERSONAL.BEGIN> < 1 THEN
HIRE=MAN.REC<UR$HIRE.DATE>
GOSUB 65000 ;* find first date employee accrues personal
MAN.REC<UR$PERSONAL.BEGIN>=BEGIN.PERSONAL.ACCRUAL
END
IF TODAY >= MAN.REC<UR$PERSONAL.BEGIN> 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<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> =ACTUAL.PAY.DATE
IBONUS.HOURS =ICONV(BONUS.HOURS,'MR2')
IVAC.HOURS =ICONV(VAC.HOURS,'MR2')
IPER.HOURS =ICONV(PERSONAL.HOURS,'MR2')
MAN.REC<UR$VACATION.AVAIL>=MAN.REC<UR$VACATION.AVAIL>+VAC.ACCRUAL-IVAC.HOURS
MAN.REC<UR$PERSONAL.AVAIL>=MAN.REC<UR$PERSONAL.AVAIL>+PER.ACCRUAL-IPER.HOURS-IBONUS.HOURS
*--- clear 'next' attributes for next pay period -----*
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
*----- cap on vacation (20 days) and personal time (24 days) ---*
LOCATE(ID,VACEX,1;FND) ELSE ;* vacation cap exceptions
IF MAN.REC<UR$VACATION.AVAIL> > MAX.VAC THEN
MAN.REC<UR$VACATION.AVAIL>=MAX.VAC
END
END
IF MAN.REC<UR$PERSONAL.AVAIL> > MAX.PER THEN
MAN.REC<UR$PERSONAL.AVAIL>=MAX.PER
END
MAN.REC<UR$NEXT.PAY.DATE>=NEXT.PAY.DATE
*--- 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 <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$CLOCK.SYSTEM>='M' THEN
IF MREC<UR$NEXT.REG> > 0 ELSE
MAN.TABLE=MAN.TABLE:" ":MANAGER
END
END
END
REPEAT
IF MAN.TABLE# '' THEN
CRT @(0,21):RV:" Manual records have not been updated for:":ERV:
CRT @(0,22):CL:MAN.TABLE<1>:
INPUT ANY,2
CRT @(0,21):CL:
CRT @(0,22):CL:RV:" Override? - Run this process anyway (Y/N) :":ERV:
INPUT OVERANS,9
IF OVERANS[1,1]='Y' ELSE
GO 10
END
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:VM:THIRD.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>
THIRD.REG =TABLE<1,17>
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