(* Component : ACCUPDATE.PAS -- Update user and work order master files. Date: January 9, 1980 -- Initial running June 13, 1980 -- List of unused WKOs. August 28, 1980 -- Sorted users list. October 8, 1980 -- Biometrics version October 20, 1980 -- User re-entry error fix October 24, 1980 -- Headings on each page, reuse space Author: Tom Mathieu Battelle-Northwest Box 999 Richland, Washington 99352 (509) 375-3711 Source: Swedish Pascal Calling Seq: RUN [11,1]ACCUPDATE Inputs: ACCMWO.DAT ACCUSERS.DAT Outputs: ACCMWO.DAT ACCUSERS.DAT Comments: *) PROGRAM UPDATE (TTY); % FUNCTION: UPDATE ACCOUNTING CONTROL FILE ACCUSERS.DAT AND ACCMWO.DAT WITH ADDITIONS/DELETIONS TO USER AND WORK ORDER LISTS. TO RUN: MCR>HEL [5,5] MCR>RUN [11,1]ACCUPDATE \ CONST LPPG=59; (** LINES PER PAGE **) TYPE WRKORD = ARRAY [1..6] OF CHAR; DTE = ARRAY [1..6] OF CHAR; USERID = ARRAY [1..3] OF CHAR; WKOPTR = ^WKLIST; USRPTR = ^USERLIST; LETTERS = 'A' .. 'Z'; LETTERSET = SET OF LETTERS; WRKORDS = RECORD WKO : WRKORD; CHBL,MKDEL : BOOLEAN; RESP : USERID; ORG : ARRAY [1.. 5] OF CHAR; DTLSTUSED : DTE (** ; CMMTS : ARRAY [1..20] OF CHAR **) END; USERS = RECORD UID : USERID; UNM : ARRAY [1..16] OF CHAR; UADR : ARRAY [1..16] OF CHAR; UPHN : ARRAY [1.. 8] OF CHAR END; USERLIST = RECORD U : USERS; UNXT,ANXT : USRPTR END; WKLIST = RECORD W : WRKORDS; WNXT : WKOPTR END; VAR CH : CHAR; F : TEXT; US,U1 : FILE OF USERS; WK,W1 : FILE OF WRKORDS; FIRSTW,NEXTW : WKOPTR; FIRSTU,FIRSTA,NEXTU : USRPTR; TITLE:ARRAY[1..25] OF CHAR; TODAY : DTE; CNC:ARRAY[BOOLEAN,1..14] OF CHAR; I : INTEGER; LPOPEN : BOOLEAN; DT : ARRAY [1..10] OF CHAR; CMMTS : ARRAY [1..20] OF CHAR; PROCEDURE ERASESCREEN; BEGIN WRITE(CHR(33B),'H',CHR(33B),'J'); BREAK; END; PROCEDURE GOTOXY(COL,ROW:INTEGER); BEGIN WRITE(CHR(33B),'Y',CHR(40B+ROW),CHR(40B+COL)); END; PROCEDURE MENUSELECT(LINE:INTEGER; CHOICES : LETTERSET; VAR CHOICE:CHAR); VAR C : CHAR; BEGIN REPEAT GOTOXY(0,LINE); WRITELN(' ':40); GOTOXY(0,LINE); WRITE('Enter selection (['); FOR C := 'A' TO 'Z' DO IF C IN CHOICES THEN WRITE(C,','); WRITE(CHR(33B),'D]) > '); BREAK; READLN; READ(CHOICE); WRITELN; IF (CHOICE>='a') AND (CHOICE<='z') THEN CHOICE := CHR(ORD(CHOICE)-ORD('a')+ORD('A')); IF NOT (CHOICE IN CHOICES) THEN WRITELN('>>> Invalid selection -- ',CHOICE,CHR(7)) ELSE WRITELN(' ':40); UNTIL CHOICE IN CHOICES; GOTOXY(0,LINE+1); END; PROCEDURE GETINT(X,Y : INTEGER; VAR INT : INTEGER); BEGIN GOTOXY(X,Y); WRITE('<':6); BREAK; GOTOXY(X,Y); BREAK; READLN; READ(INT); GOTOXY(X,Y); WRITE(INT:5,' '); BREAK; END; PROCEDURE GETSTRING (X,Y,LEN:INTEGER; VAR S : ARRAY [INTEGER] OF CHAR); VAR I : INTEGER; BEGIN GOTOXY(X,Y); WRITE('<':LEN+1); BREAK; GOTOXY(X,Y); BREAK; READLN; I := 1; WHILE NOT EOLN(TTY) AND (I<=LEN) DO BEGIN READ(S[I]); I := SUCC(I); END; FOR I := I TO LEN DO S[I] := ' '; END; PROCEDURE INSERTALPH(TU:USRPTR); (*** LINK USER IN ALPHA ORDER ***) VAR LU,NU:USRPTR; OK:BOOLEAN; BEGIN NU := FIRSTA; LU := NIL; OK := TRUE; WHILE (NU <> NIL) AND OK DO BEGIN OK := NU^.U.UNM < TU^.U.UNM; IF OK THEN BEGIN LU := NU; NU := NU^.ANXT END; END; IF LU = NIL THEN BEGIN TU^.ANXT := FIRSTA; FIRSTA := TU; END ELSE BEGIN LU^.ANXT := TU; TU^.ANXT := NU; END; END; PROCEDURE READEMIN (K : INTEGER); VAR OK : BOOLEAN; I : INTEGER; LASTU : USRPTR; LASTW : WKOPTR; BEGIN IF K = 1 THEN BEGIN (* CREATE LINKED LIST OF WKORDS *) RESET(WK,'ACCMWO.DAT'); FIRSTW := NIL; WHILE NOT EOF(WK) DO BEGIN NEW (NEXTW); NEXTW^.W := WK^; NEXTW^.WNXT := NIL; IF FIRSTW = NIL THEN (* THIS IS FIRST ONE *) BEGIN FIRSTW := NEXTW; LASTW := NEXTW; END ELSE (* ADD NEW ONE ON TO END OF LIST *) BEGIN LASTW^.WNXT := NEXTW; LASTW := NEXTW; END; GET(WK); END; (* OF READING WORK ORDERS *) END ELSE (* CREATE LINKED LIST OF USERS *) BEGIN FIRSTU := NIL; FIRSTA := NIL; RESET(US,'ACCUSERS.DAT'); WHILE NOT EOF(US) DO BEGIN NEW (NEXTU); NEXTU^.U := US^; NEXTU^.ANXT := NIL; NEXTU^.UNXT := NIL; IF FIRSTU = NIL THEN (* IT IS FIRST ONE *) BEGIN FIRSTU := NEXTU; LASTU := NEXTU; END ELSE (* ADD THIS ONE TO THE END *) BEGIN LASTU^.UNXT := NEXTU; LASTU := NEXTU; END; IF FIRSTA = NIL THEN FIRSTA := LASTU ELSE INSERTALPH(LASTU); GET(US); END; (* OF USERS - END OF FILE *) END; END; (* OF READEMIN *) PROCEDURE WRITEMOUT (K:INTEGER); VAR I : INTEGER; BEGIN IF K = 1 THEN BEGIN REWRITE (W1,'ACCMWO.DAT'); NEXTW := FIRSTW; REPEAT W1^ := NEXTW^.W; PUT(W1); NEXTW := NEXTW^.WNXT; UNTIL NEXTW = NIL; END ELSE BEGIN REWRITE(U1,'ACCUSERS.DAT'); NEXTU := FIRSTU; REPEAT U1^ := NEXTU^.U; PUT (U1); NEXTU := NEXTU^.UNXT; UNTIL NEXTU = NIL; END; END; (* OF WRITEM OUT *) PROCEDURE OPENLP; BEGIN IF LPOPEN THEN PAGE(F) ELSE REWRITE(F,' ',,'LP:'); LPOPEN := TRUE END; PROCEDURE UPD1 (VAR CH : CHAR); BEGIN ERASESCREEN; WRITELN(TITLE:30); WRITELN; WRITELN('Options available are'); WRITELN(' A = Add a new one'); WRITELN(' D = Delete one'); WRITELN(' C = Change one'); WRITELN(' L = List them'); WRITELN(' X = Stop'); MENUSELECT (10,['A','C','D','L','X'],CH); END; PROCEDURE GETUID(X,Y:INTEGER; VAR U : USERID); VAR I : INTEGER; BEGIN GETSTRING(X,Y,3,U); % FOR I := 1 TO 3 DO IF U[3] = ' ' THEN BEGIN U[3] := U[2]; U[2] := U[1]; U[1] := '0'; END; FOR I := 1 TO 3 DO IF NOT (U[I] IN ['0'..'7']) THEN U := '000'; \ GOTOXY(X,Y); WRITELN(U); END; PROCEDURE PAUSE; VAR I,J : INTEGER; BEGIN FOR I := 1 TO 24000 DO J := I+101 END; PROCEDURE UPDTWORK; (* UPDATE WORK ORDERS *) VAR C,CMD:CHAR; TW,FREEW,PREVW:WKOPTR; I,J:INTEGER; INP,OLDATE:WRKORD; CHGD,OLDONLY:BOOLEAN; FUNCTION FINDW (SEEKEE : WRKORD) : BOOLEAN; VAR BEFORE : BOOLEAN; BEGIN NEXTW := FIRSTW; PREVW := NIL; LOOP BEFORE := NEXTW = NIL; IF NOT BEFORE THEN BEFORE := NEXTW^.W.WKO >= SEEKEE; EXIT IF BEFORE OR (NEXTW^.WNXT = NIL); PREVW := NEXTW; NEXTW := NEXTW^.WNXT; END; FINDW := BEFORE; END; PROCEDURE GETTW; BEGIN IF FREEW=NIL THEN NEW(TW) ELSE BEGIN TW := FREEW; FREEW := NIL; END END; PROCEDURE PUTUPW; BEGIN ERASESCREEN; WRITELN(TITLE:30); WRITE('Selected function : '); CASE CMD OF 'A' : WRITELN('Adding'); 'D' : WRITELN('Deleting'); 'C' : WRITELN('Changing') END; WRITELN; WITH TW^.W DO BEGIN WRITELN('Available field modification options :'); WRITELN(' W = Work order number >',WKO); WRITELN(' N = Non chgbl / chgbl >',CNC[CHBL]); WRITELN(' R = Resp. person UID >',RESP); WRITELN(' O = Organization code >',ORG); WRITELN(' C = Comments >',CMMTS); WRITELN(' P = Post changes'); WRITELN(' X = Exit -- no update'); END; END; PROCEDURE LISTW(VAR F:TEXT); VAR L : INTEGER; BEGIN NEXTW := FIRSTW; L := LPPG+1; WHILE (NEXTW <> NIL) DO BEGIN IF L > LPPG THEN BEGIN L := 5; PAGE(F); WRITELN(F,'Biometrics Computer Center Work Order List',DT:23); WRITELN(F); WRITELN(F,' WKO CHG/NC WHOSE ORG Last Use COMMENTS'); WRITELN(F,'------- -------------- --- ----- ------ --------------------'); END; IF NEXTW^.W.MKDEL THEN C := '*' ELSE C := ' '; WITH NEXTW^.W DO IF (NOT OLDONLY) ! (DTLSTUSED 'P' THEN BEGIN LISTW(TTY); WRITELN; WRITE('Hit to continue >>'); BREAK; READLN; END ELSE BEGIN OPENLP; LISTW(F) END; END ELSE IF CMD IN ['C','D'] THEN BEGIN WRITE (TTY,'Enter work order number > '); BREAK; READLN(TTY); READ(INP); IF NOT (FINDW(INP) AND (NEXTW^.W.WKO=INP)) THEN BEGIN (*** ERROR ***) WRITELN('>>>> Work order not found >>> ',INP,CHR(7)); CMD := 'X'; END ELSE IF CMD = 'C' THEN BEGIN GETTW; TW^.W := NEXTW^.W; END ELSE TW := NEXTW; END ELSE IF CMD = 'A' THEN BEGIN GETTW; WITH TW^ DO WITH W DO BEGIN WKO := '......'; CHBL := TRUE; ORG := 'D7...'; RESP := '...'; WNXT := NIL; MKDEL := FALSE; CMMTS := ' '; DTLSTUSED := TODAY; END; END; IF NOT (CMD IN ['X','L']) THEN BEGIN PUTUPW; IF CMD = 'D' THEN BEGIN (** DELETE WORK ORDER **) REPEAT GOTOXY(0,20); WRITE('Delete this work order ? [Y/N] >'); BREAK; READLN; READ(C); IF C IN ['Y','N','U'] THEN WRITELN(' ':40) ELSE WRITELN('>>> Invalid selection >>> ',C,CHR(7)); UNTIL C IN ['Y','N','U']; IF C <> 'N' THEN BEGIN NEXTW^.W.MKDEL := C='Y'; CHGD := TRUE; END END ELSE (*** ADD / CHANGE ***) BEGIN REPEAT MENUSELECT(13,['C','N','P','X','W','R','O'],C); CASE C OF 'C' : GETSTRING(27,9,20, (* TW^.W. **) CMMTS); 'O' : GETSTRING(27,8, 5,TW^.W.ORG ); 'N' : BEGIN TW^.W.CHBL := NOT TW^.W.CHBL; GOTOXY(27,6); WRITELN(CNC[TW^.W.CHBL]); END; 'R' : GETUID(27,7,TW^.W.RESP); 'W' : IF CMD = 'C' THEN WRITELN('Can''t change work order number',CHR(7)) ELSE GETSTRING(27,5,6,TW^.W.WKO); 'X' : FREEW := TW; 'P' : IF CMD='C' THEN BEGIN NEXTW^.W := TW^.W; FREEW := TW; CHGD := TRUE END ELSE IF FIRSTW = NIL THEN BEGIN FIRSTW := TW; CHGD := TRUE END ELSE IF FINDW(TW^.W.WKO) THEN BEGIN IF NEXTW^.W.WKO = TW^.W.WKO THEN BEGIN WRITELN(TTY,'Work order already in file'); C := 'A'; PAUSE END ELSE IF PREVW = NIL THEN BEGIN (** ADD AT FRONT **) TW^.WNXT := FIRSTW; FIRSTW := TW; CHGD := TRUE; END ELSE BEGIN (** ADD IN MIDDLE **) TW^.WNXT := NEXTW; PREVW^.WNXT:=TW; CHGD := TRUE; END END ELSE BEGIN (* ADD AT END OF LIST *) TW^.WNXT := NIL; CHGD := TRUE; NEXTW^.WNXT := TW; END END; (* OF CASES *) UNTIL C IN ['X','P']; END; END; (* OF OK COMMAND *) END; (* OF LOOP *) IF CHGD THEN WRITEMOUT(1); END; (* OF UPDATE WORK ORDER *) PROCEDURE UPDTUSER; (* UPDATE USERS *) VAR C,CMD:CHAR; TU,FREEU,PREVU:USRPTR; I:INTEGER; INP:USERID; CHGD,OK:BOOLEAN; FUNCTION FINDU (SEEKEE : USERID) : BOOLEAN; VAR BEFORE : BOOLEAN; BEGIN NEXTU := FIRSTU; PREVU := NIL; LOOP BEFORE := NEXTU = NIL; IF NOT BEFORE THEN BEFORE := NEXTU^.U.UID >= SEEKEE; EXIT IF BEFORE OR (NEXTU^.UNXT = NIL); PREVU := NEXTU; NEXTU := NEXTU^.UNXT; END; FINDU := BEFORE; END; PROCEDURE GETTU; BEGIN IF FREEU = NIL THEN NEW(TU) ELSE BEGIN TU := FREEU; FREEU := NIL; END END; PROCEDURE PUTUPU; BEGIN ERASESCREEN; WRITELN(TITLE:30); WRITE('Selected function : '); CASE CMD OF 'A' : WRITELN('Adding'); 'D' : WRITELN('Deleting'); 'C' : WRITELN('Changing') END; WRITELN; WITH TU^.U DO BEGIN WRITELN('Available field modification options :'); WRITELN(' I = User identification >',UID); WRITELN(' N = User name >',UNM); WRITELN(' A = User address >',UADR); WRITELN(' B = User phone number >',UPHN); WRITELN(' P = Post changes'); WRITELN(' X = Exit -- no update'); END; END; PROCEDURE LISTU(VAR F:TEXT; BYALPH:BOOLEAN); VAR L : INTEGER; BEGIN IF BYALPH THEN NEXTU := FIRSTA ELSE NEXTU := FIRSTU; L := LPPG+1; WHILE NEXTU <> NIL DO BEGIN IF L > LPPG THEN BEGIN PAGE(F); WRITELN(F,'Biometrics Computing Center Users List',DT:11); WRITELN(F); WRITELN(F,'UID NAME ADDRESS PHONE'); WRITELN(F,'--- ---------------- ---------------- --------'); L := 5 END; WITH NEXTU^.U DO WRITELN(F,UID,UNM:18,UADR:18,UPHN:10); L := L+1; IF BYALPH THEN NEXTU := NEXTU^.ANXT ELSE NEXTU := NEXTU^.UNXT; END; END; BEGIN (**** UPDATE USER LIST ****) CHGD := FALSE; READEMIN(2); TITLE := 'Update master users list '; FREEU := NIL; LOOP UPD1(CMD); EXIT IF CMD = 'X'; IF CMD = 'L' THEN BEGIN WRITE('Output to terminal or printer [T/P] ? '); BREAK; READLN; READ(C); WRITE('Alpha order or User id # order [A/U]? '); BREAK; READLN; READ(CH); IF C <> 'P' THEN BEGIN LISTU(TTY,(CH='A')OR(CH='a')); WRITELN; WRITE('Hit to continue >>'); BREAK; READLN; END ELSE BEGIN OPENLP; LISTU(F,(CH='A') OR (CH='a')); END END ELSE IF CMD IN ['C','D'] THEN BEGIN WRITE (TTY,'Enter user id > '); GETUID(15,11,INP); NEXTU := FIRSTU; PREVU := NIL; IF NOT (FINDU(INP) AND (NEXTU^.U.UID=INP)) THEN BEGIN (*** ERROR ***) WRITELN('>>>> User id not found >>> ',INP,CHR(7)); CMD := 'X'; PAUSE; END ELSE IF CMD = 'C' THEN BEGIN GETTU; TU^.U := NEXTU^.U; END ELSE TU := NEXTU; END ELSE IF CMD = 'A' THEN BEGIN GETTU; WITH TU^.U DO BEGIN UID := '...'; UPHN := '...-....'; UADR := '................'; UNM := 'Last, initials '; END; END; IF NOT (CMD IN ['X','L']) THEN BEGIN PUTUPU; IF CMD = 'D' THEN (*** DELETE USER FROM FILE ***) BEGIN REPEAT GOTOXY(0,20); WRITE('Delete this user id ? [Y/N] >'); BREAK; READLN; READ(C); IF C IN ['Y','N'] THEN WRITELN(' ':40) ELSE WRITELN('>>> Invalid selection >>> ',C,CHR(7)); UNTIL C IN ['Y','N']; IF C = 'Y' THEN BEGIN PREVU^.UNXT := NEXTU^.UNXT; FREEU := NEXTU; CHGD := TRUE; PREVU := NIL; TU := FIRSTA; WHILE (TU <> NIL) AND (TU^.U.UID<> INP) DO BEGIN PREVU := TU; TU := TU^.ANXT END; IF PREVU = NIL THEN FIRSTA := FIRSTA^.ANXT ELSE IF TU = NIL THEN PREVU^.ANXT := NIL ELSE PREVU^.ANXT := TU^.ANXT; END END ELSE (*** ADD / CHANGE ***) BEGIN REPEAT MENUSELECT(12,['I','N','P','X','A','B'],C); CASE C OF 'I' : IF C = 'C' THEN WRITELN('Can''t change user id') ELSE GETUID(27,5,TU^.U.UID); 'N' : GETSTRING(27,6,16,TU^.U.UNM); 'A' : GETSTRING(27,7,16,TU^.U.UADR); 'B' : GETSTRING(27,8,8, TU^.U.UPHN); 'X' : FREEU := TU; 'P' : IF CMD='C' THEN BEGIN NEXTU^.U := TU^.U; FREEU := TU; CHGD := TRUE END ELSE IF FIRSTU = NIL THEN BEGIN FIRSTU := TU; FIRSTA := TU; CHGD := TRUE END ELSE BEGIN OK := TRUE; IF FINDU(TU^.U.UID) THEN BEGIN IF NEXTU^.U.UID = TU^.U.UID THEN BEGIN WRITELN(TTY,'User id already in file'); PAUSE; C := 'A'; OK := FALSE; END ELSE IF PREVU = NIL THEN BEGIN (** ADD AT FRONT **) TU^.UNXT := FIRSTU; FIRSTU := TU; CHGD := TRUE; END ELSE BEGIN (** ADD IN MIDDLE **) TU^.UNXT := NEXTU; PREVU^.UNXT:=TU; CHGD := TRUE; END END ELSE BEGIN (* ADD AT END OF LIST *) TU^.UNXT := NIL; CHGD := TRUE; NEXTU^.UNXT := TU; END; IF OK THEN INSERTALPH(TU); END END; (* OF CASES *) UNTIL C IN ['X','P']; END (* OF ADD/CHG *) END; (* OF OK COMMAND *) END; (* OF LOOP *) IF CHGD THEN WRITEMOUT(2); END; (* OF UPDATE WORK ORDER *) BEGIN (* MAIN LINE *) CNC[TRUE] := 'Chargeable '; CNC[FALSE] := 'Non-chargeable'; DATE(DT); FOR I := 1 TO 2 DO TODAY[I] := DT[I+2]; FOR I := 3 TO 4 DO TODAY[I] := DT[I+3]; FOR I := 5 TO 6 DO TODAY[I] := DT[I+4]; LPOPEN := FALSE; WRITE (TTY,'Update user file ? (Y or N) : '); BREAK; READLN(TTY); READ(TTY,CH); MARK; IF (CH = 'Y') OR (CH='y') THEN UPDTUSER; WRITE (TTY,'Update work order file ? (Y or N) : '); BREAK; READLN(TTY); READ(TTY,CH); RELEASE; IF (CH = 'Y') OR (CH = 'y') THEN UPDTWORK; END.