750 lines
27 KiB
Plaintext
Executable File
750 lines
27 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.
|
|
*-------------------------------------------------------------------*
|
|
*
|
|
$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 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 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
|
|
IF USR.REC<UR$CLOCK.SYSTEM># 'C' THEN GO 2300 ;* time clock employee
|
|
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
|
|
ACCRUAL.HOURS=4000*NUMBER.WEEKS
|
|
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<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> =USERX<UR$NEXT.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> =USERX<UR$NEXT.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,7):CL:
|
|
CRT @(60,9):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>='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> =MAN.REC<UR$NEXT.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$TYPE.CODE>='M' OR MREC<UR$TYPE.CODE>='O' 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:"Manual 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
|
|
*
|
|
*
|
|
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
|