1 ! OUTBILL.BAS [1,100] - PROGRAM TO PRODUCE BILLS FOR BIOMEDICAL COMPUTATION ! BILLS PRODUCED ARE FOR SPECIFIED PROJECTS: ! CHARGES ARE GENERATED AND LISTED ON MONTHLY BASIS FOR A ! SPECIFIED FISCAL YEAR ! ! CHARGES ARE FOR PROGRAMMER, CONNECT, AND STORAGE TIME ! ! RUNS UNDER BA5 50 DEF FNRM(A,B)=A-INT(A/B)*B 60 DEF FNSU(PJ,MO,PG)=(PJ*13+MO)*11+PG 80 DEF FNV(S0$)=VAL(SBS$(S0$,1,3)+SBS$(S0$,5,2)+SBS$(S0$,8,2)+SBS$(S0$,11,2)) : ! LOG TIME W/O : 90 DEF FNF$(X)=FRMT$(X,10,2) : ! FORMAT # TO 2 DIGITS TO RT OF ., SIG. DIGS. ONLY, & RJS IT IN FIELD OF 10 100 ! ! VARIABLE DEFINITIONS, DIMENSIONS ! 110 DIM R$[60]V ! RECORD STRING FOR LOGFILES, CONNECT FILES, STORAGE FILES 111 DIM L$[60]V ! INPUT VARIABLE FOR USER DESCRIPTION FILES 115 DIM FF$[50]V ! FOR MASTER FILE NAME 120 DIM AN$[60]V ! ACCOUNT NAME (DEPT) 125 DIM NF$[9]V ! USER DESCRIPTION FILE NAME 130 DIM UN$[9]V, UN& ! USER NAME(S), # OF USER NAMES FOR ACCOUNT 135 DIM ST$[9]V ! NAME OF STORAGE FILE FOR EACH USER 140 DIM DP$[4]V ! MASK FOR MATCHING ACCOUNT TO LOG FILE CODING 150 DIM M$[3](12) ! MONTH NAMES 170 DIM H(12,4) ! HOURS PER DAY FOR 6 USERS, 3 CATEGORIES EACH (PGMR, CONNTECT, STORAGE, ADJ PGMR) 180 DIM C&(3) ! CHARGES FOR EACH CATEGORY 185 DIM E(4) ! CONVERSION FACTORS FOR TIME INTO HOURS 190 DIM PF(10) ! PROGRAMMER FACTORS 195 DIM S$[16]V ! DUMMY STRING 199 DIM #16,PR%(9394) 200 P1=2 : P2=6 ! LOWER, UPPER BOUNDS ON PROGRAMMER SUBSCRIPTS 210 OVERLAY "PROJNUM/RT" 300 ! ! USERS ACCOUNTS INFO ! ! EACH DATA STMT DESCRIBES THE USER AS FOLLOWS ! NAME OF DEPT (OR OF USER) ! NAME OF BLOCK STORAGE FILE ! MASK DESCRIBING ITS CODE IN PROGRAMMER LOG FILE ! # OF ACCTS (USER NAMES) USER HAS ! LIST OF ACCTS (USER NAMES) FOR USER ! 310 ! PROGRAMMER SENIORITY FACTORS ! PROGRAMMER NUMBERS AS FOLLOWS ! 1 = UNUSED ! 2 = BONNIE ! 3 = DEANA ! 4 = LARRY ! 5 = BEVERLY ! 6 = DAN 320 DATA 1,.7,1.5,.7,1 330 FOR I=P1 TO P2 : READ PF(I) : NEXT I 430 M$(1)="JAN" : M$(2)="FEB" : M$(3)="MAR" : M$(4)="APR" : M$(5)="MAY" : M$(6)="JUN" : M$(7)="JUL" : M$(8)="AUG" : M$(9)="SEP" : M$(10)="OCT" : M$(11)="NOV" : M$(12)="DEC" ! NAMES OF MONTHS 440 C&=3 : ! # OF CATEGORIES OF CHARGES : C&(1)=24.50 : ! $24.50/HR PROGRAMMER TIME : C&(2)=20 : ! $ 20/HR CONNECT TIME : C&(3)=5 : ! $ 5/100 BLOCK-MONTH STORAGE 450 ! E MAY BE USED AS WORK VARIABLE : E(1)=1/3600 : ! CONVERT SECONDS TO HOURS : E(2)=1/60 : ! CONVERT MINUTES TO HOURS : E(3)=1 : ! CONVERT HOURS TO HOURS : E(4)=24 : ! CONVERT DAYS TO HOURS 460 BC=((C&(3)/100)*12)/365 ! DAILY BLOCK CHARGE (1 BLOCK-DAY) : S$=FRMT$(BC,8,6) ! MAKE CHARGE $ X.XXXXXX : BC=VAL(S$) 600 ! ASK USER FOR FISCAL YEAR OF STATEMENT 610 INPUT "FISCAL YEAR (YY) "; YY 630 FY&=YY ! FISCAL YEAR 650 D1=DCEN("07/01/"+STR$(FY&-1)) ! FIRST DAY OF YEAR D2=DCEN("06/30/"+STR$(FY&)) ! LAST DAY OF YEAR 670 ! OPEN #16,"YEAR"+STR$(FY&)+".VPG/BL/RO/SH" 680 INPUT "FILE NAME FOR OUTPUT",FF$: OPEN #5,FF$+"/WR/LN:84" 700 INPUT "FILE NAME FOR USERS ",FF$: IF TRM$(FF$)="" THEN FF$="USERS.NAM/RO/SH/EN:900" ELSE FF$=FF$+"/RO/SH/EN:900" 705 OPEN #6,FF$ : PRINT 710 INPUT LINE #6,AN$ : PRINT AN$ 720 NF$=PIECE$(AN$,",",1): FF$=PIECE$(AN$,",",2): AN$=PIECE$(AN$,",",3,60) 740 FOR J=0 TO 12 : FOR K=0 TO 4 : H(J,K)=0 : NEXT K,J 750 OPEN #7,"PRF.PRF/RO/SH/EN:850" 753 INPUT LINE #7,L$ 755 IF SBS$(L$,3)=NF$+".PRF" THEN 770 757 GOTO 753 760 INPUT LINE #7,L$ 770 IF LEFT(L$,1)=";" THEN 760 ELSE IF LEFT(L$,1)="*" THEN 800 780 DP$=L$ 790 GOSUB 1000 ! GET PROGRAMMER TIME GOTO 760 800 INPUT LINE #7,L$ 810 IF LEFT(L$,1)=";" THEN 800 ELSE IF LEFT(L$,1)="*" THEN 830 820 UN$=L$: GOSUB 1200 ! GET CONNECT TIME GOTO 800 830 INPUT LINE #7,L$: IF LEFT(L$,1)=";" THEN 830 ELSE IF LEFT(L$,1)="*" THEN 880 840 ST$=L$ : GOSUB 1300 ! GET BLOCK STORAGE GOTO 830 880 CLOSE 7 : GOSUB 2000 890 GOTO 710 900 CLOSE 910 PRINT 920 EXIT 1000 ! SUBROUTINE TO ACCUMULATE PROGRAMMER TIME ! FOR ONE USER FROM ACCUMULATED VIRTUAL ARRAY ! ON ENTRY: ! YEARYY.VPG OPEN ON LUN 16 WHERE YY IS FISCAL YEAR ! PR% IS VIRTUAL ARRAY OF PROGRAMMER TIME AS DEFINED ! IN PROGMON.BAS ! DP$ HAS MASK FOR THIS USER RETURN 1010 GOSUB 8000 ! GET PROJECT NUMBER DP% FROM DP$ 1020 FOR NI=1 TO 12 1030 FOR K=P1 TO P2 1040 H(NI,1)=H(NI,1)+PR%(FNSU(DP%,NI,K))/100: H(NI,4)=H(NI,4)+PR%(FNSU(DP%,NI,K))*PF(K)/100 1050 NEXT K,NI 1090 RETURN 1200 ! ! CONNECT TIME ! 1215 L&=2 ! THE 2ND OF EACH USER'S 3 CATEGORIES IS CONNECT TIME 1230 OPEN #3, UN$+".L"+STR$(FY&)+"/LN:56/RN/RO/SH" ! OPEN CONNECT TIME FILE 1240 FOR K=NRC(3) TO 6 STEP -1 ! 1ST 6 RECS ARE HEADINGS 1250 INPUT LINE #3@K, R$ ! CONNECT TIME RECORD 1260 D=DCEN(SBS$(R$,20,8)) ! DATE LOGGED OFF 1270 IF DD2 THEN 1390 ! DIDN'T GET TO RIGHT DATE SECTION YET 1365 S$=DAT$(D) 1370 DR&=VAL(SBS$(S$,1,2)) ! MONTH OF YEAR 1374 H(DR&,L&)=H(DR&,L&)+VAL(SBS$(R$,27,8)) ! # OF BLOCKS FOR THAT DAY (ONLY 1 REC OF BLKS PER DAY) 1390 NEXT K 1399 CLOSE 3 : RETURN 2000 ! ! PRINT BILL FOR EACH PROJECT ! 2205 PRINT #5, CHR$(12) 2210 PRINT #5, TAB(24); "MICHAEL REESE HOSPITAL AND MEDICAL CENTER" : PRINT #5, TAB(24); " DEPARTMENT OF MEDICAL PHYSICS " : PRINT #5 : PRINT #5 2220 PRINT #5, " BIOMEDICAL COMPUTATION DIVISION";TAB(74); DDAT$(0) : PRINT #5 : PRINT #5 2230 PRINT #5, " BILL FOR FISCAL YEAR 19";STR$(FY&);" -- ";AN$ : PRINT #5, TAB(5);STRING$("-",30+LEN(AN$)) 2240 PRINT #5 : PRINT #5 2250 PRINT #5, TAB(29); "HOURS";TAB(48);"HOURS" 2260 PRINT #5, TAB(23); "PROGRAMMER TIME"; TAB(44); "CONNECT TIME"; TAB(64); "STORAGE BLOCKS" 2270 PRINT #5 2300 ! ! PRINT HOURS ! JL=7 : JH=12 2310 FOR J=JL TO JH 2315 PRINT #5, TAB(5);M$(J); 2320 PRINT #5, TAB(20); : IF H(J,4)<>0 THEN PRINT #5, FRMT$(H(J,4),6,2); ! PROGRAMMING TIME ADJUSTED PRINT #5,TAB(30);"(";FRMT$(H(J,1),6,2);")"; !PROGRAMMING TIME UNADJUSTED 2330 PRINT #5, TAB(44); : IF H(J,2)<>0 THEN PRINT #5, FNF$(H(J,2)); ! CONNECT TIME 2340 PRINT #5, TAB(64); : IF H(J,3)<>0 THEN PRINT #5, RJS$(STR$(H(J,3)),10) ! STORAGE BLOCKS ELSE PRINT #5 2360 H(0,1)=H(0,1)+H(J,1) ! TOTAL # OF PROGRAMMER HRS H(0,4)=H(0,4)+H(J,4) ! TOTAL # OF ADJUSTED PROGRAMMER HRS 2370 H(0,2)=H(0,2)+H(J,2) : ! TOTAL # OF CONNECT HRS 2380 IF H(J,3)>0 THEN H(0,3)=H(0,3) + (INT(H(J,3)/100)+1)*100 * BC : ! KEEP RUNNING TOTAL OF DAILY BLOCK CHARGES : ! BLOCKS ARE CHARGES IN UNITS OF 100, SO ROUND UP TO NEXT 100 2399 NEXT J : IF JL=1 THEN 2400 ELSE JL=1 : JH=6 : GOTO 2310 2400 ! ! FIGURE CHARGES FOR ENTIRE MONTH; PRINT THEM ! 2410 PRINT #5 2420 PRINT #5, TAB(5);"TOTAL HOURS"; TAB(20); : IF H(0,1)<>0 THEN PRINT #5, FRMT$(H(0,4),6,2); ! PROGRAMMER TIME ADJUSTED PRINT #5,TAB(30);"(";FRMT$(H(0,1),6,2);")"; ! PROGRAMMER TIME UNADJUSTED 2422 PRINT #5, TAB(44); : IF H(0,2)<>0 THEN PRINT #5, FNF$(H(0,2)) ELSE PRINT #5 ! CONNECT TIME 2425 PRINT #5 2430 PRINT #5, TAB(23); "PROGRAMMER TIME"; TAB(44); "CONNECT TIME"; TAB(64); "STORAGE BLOCKS" 2440 PRINT #5, TAB(24); "@ $";C&(1);"/ HR"; TAB(44);"@ $";C&(2);"/ HR"; TAB(59);"@ $";C&(3);"/ 100 BLOCK-MONTH" 2442 PRINT #5, TAB(57); "= @ $";BC;"/ BLOCK-DAY" 2445 PRINT #5 2448 H=0 ! GRAND TOTAL OF CHARGES 2450 PRINT #5, TAB(5);"$ CHARGE"; TAB(24); : IF H(0,4)<>0 THEN S$=FNF$(C&(1)*H(0,4)) : PRINT #5, S$; : H=VAL(S$) ! GRAND TOTAL ! PROGRAMMER CHARGES 2452 PRINT #5, TAB(44); : IF H(0,2)<>0 THEN S$=FNF$(C&(2)*H(0,2)) : PRINT #5, S$; : H=H+VAL(S$) ! GRAND TOTAL : ! CONNECT CHARGES 2454 PRINT #5, TAB(64); : IF H(0,3)<>0 THEN S$=FNF$(H(0,3)) : PRINT #5, S$ : H=H+VAL(S$) ELSE PRINT #5 ! STORAGE CHARGES (RUNNING TOTAL KEPT BY STMT 2380 2460 PRINT #5 : PRINT #5 : PRINT #5, TAB(34); "-----" : PRINT #5, TAB(34); "TOTAL $";FRMT$(H,8,2) 2470 PRINT #5, TAB(34); "-----" 2599 RETURN 3200 ! ! CONVERT TIME TO # OF HOURS ! 3201 ! WORKS ON O1, WHICH IS SET BY CALLING STMT ! RETURNS H 3202 ! ! USES O1, O2, L 3220 H=0 : IF O1=0 THEN 3299 3240 FOR L=1 TO 4 3250 O2=INT(O1/100) 3260 H=H+(O1-O2*100)*E(L) 3270 O1=O2 3280 NEXT L 3299 RETURN