	*********** PAYBILLS COMMAND FILE *********
* Before this proceedure can be accessed, the check number and balance must
* be verified in the PAYMENU command file.
*	This is one of the longer files, but the individual portions of it are
* not too complicated.  Repetitive proceedures in the main loop (controlled
* by the variable "Finished") could have been put in separate command files
* to make this file easier to understand and maintain, but this way it 
* minimizes disk accesses and increases speed.
*	This file finds bills to be paid in the CostBase, generates the next
* check number, writes a check in the CheckFil, and maintains the checkbook
* balance.
*	The next check number and checkbook balance are recalled from a file
* called  Constant.MEM.  The final values for both of these are stored in the
* same file after all the bills have been paid.
*	The date is entered once at the start of the procedure, then
* is automatically inserted into each entry.  The date is checked to 
* see that it is in the YYMMDD format, and that the values are within
* possible limits (month from 1 to 12, day from 1 to 31, year=ThisYear).
*	Entries must include at least the name of the party being paid.
*	Balances are automatically computed and shown to the operator.
*	Check numbers are automatically assigned by the computer.
*	If several entries are made against a single check number (the
* operator has this option), these are added and shown as a single 
* item in the printout.
*************************************************************************

RESTORE FROM B:Constant
DO GetDate

SELECT PRIMARY
USE B:CostBase INDEX B:$Supp

* Initialize.  "New" is used to determine whether the program should generate
* a new check number or use the old one (where several bills to a single
* supplier are being paid).  "Finished" is the control variable that determines
* whether we should run through the procedure again, or are done paying bills.
STORE 'N' TO New
STORE 'N' TO Finished
DO WHILE !(Finished) <> 'F'
   STORE "C" TO Entering
   DO WHILE !(Entering) = 'C'
      ERASE
      @ 3, 0 SAY 'CHECK NUMBER: '+NextCheck+'	 BALANCE: '+STR(MBalance,9,2)
      ? CHR(7)
      @ 4,0
      ACCEPT ' 	  MAKE CHECK TO  ' TO MName
      ACCEPT 'THEIR BILL NUMBER  ' TO MBill:Nmbr
      ACCEPT '     ENTER AMOUNT  ' TO Temp
      STORE !(MName) TO MName
      STORE !(MBill:Nmbr) TO MBill:Nmbr
      STORE VAL(Temp) TO MAmount
      STORE MAmount*1.00 TO MAmount
      @  6,24 SAY '                    '
      @  6,24 SAY MName
      @  7,20 SAY '               '
      @  7,21 SAY MBill:Nmbr
      @  8,19 SAY MAmount
      @ 11, 0 SAY '	    C to CHANGE,'
      ? '     <Return> to continue.'
      WAIT TO Entering
   ENDDO Entering

   IF LEN(MName) > 10
      STORE $(MName,1,10) TO Key
   ELSE
      STORE MName TO Key
   ENDIF

   IF KEY > ' '
      STORE T TO Looking
      @ 11, 0 SAY "I'M LOOKING, I'M LOOKING!!"
      @ 12,0
      @ 13,0
      STORE 0 TO Start
      FIND &Key
      IF # = 0
	 ?
	 ? "    GEE, I CAN'T FIND THE NAME.  Please check the spelling."
	 ? "    Or maybe it hasn't been posted to the COSTBASE yet."
	 ? '<Return> to continue.'
	 WAIT
	 ERASE
      ELSE
	 DO PayFind
      ENDIF there is an unpaid bill for the supplier

      * "Start" is brought in from PayFind.CMD.  If we started at the first
      * entry for a name (had only the name), Start=0.  If we had more than
      * the name, Start contains the record number we started on. Since this
      * could be in the middle of the listing, we use "Counter" so that we can
      * come back to the top of the listing for the name once.
      IF Start > 0
	 STORE 0 TO Counter
      ELSE
	 STORE 1 TO Counter
      ENDIF 

      STORE ' ' TO Confirm
      DO WHILE !(Confirm) <> 'P' .AND. .NOT. Looking
	 @  9,0
	 ? 'RECORD       NAME                    AMOUNT  BILL #';
	   +'   DATE'
	 ?
	 DISPLAY '    '+Name, Amount, Bill:Nmbr, Bill:Date
	 ?
	 ? CHR(7)
	 ? '           P to PAY this bill,'
	 ? '           Q to QUIT without paying,'
	 ? '	    <Return> to continue.'
	 ACCEPT '           ' TO Confirm

	 IF !(Confirm) = 'Q'
	    IF !(New) = 'S'
	       STORE STR(VAL(NextCheck)+1,4) TO NextCheck
	    ENDIF
	    STORE ' ' TO New
 	    STORE T TO Looking
	 ELSE
	    IF !(Confirm) = 'P'
	       STORE STR(#,5) TO Found
	       REPLACE Check:Date WITH Date, Check:Nmbr WITH NextCheck
	       STORE (MBalance-Amount) TO MBalance

	       SELECT SECONDARY
	       USE B:CheckFil
	       APPEND BLANK
	       REPLACE Check:Date WITH P.Check:Date, Name WITH P.Name,;
	      	       Check:Nmbr WITH P.Check:Nmbr, Balance WITH MBalance,;
		       Amount WITH P.Amount, Bill:Nmbr WITH P.Bill:Nmbr
	       SELECT PRIMARY
	       ERASE
	       @ 3, 0 SAY 'CHECK WRITTEN: '+NextCheck+;
		          '     NEW BALANCE: '+STR(MBalance,9,2)
	       ?
	       DISPLAY 'PAYMENT MADE: '+Check:Date, Name, Amount, Bill:Nmbr,;
		       Bill:Date OFF
	       ?
	       ? '	 S for SAME SUPPLIER (Repeats check #)'
	       ? CHR(7)
	       ACCEPT '	    <Return> to continue.' TO New
	       IF !(New) <> 'S'
		  STORE STR(VAL(NextCheck)+1,4) TO NextCheck
	       ELSE
		  STORE ' ' TO Confirm
	       ENDIF
	    ENDIF

	    IF !(NEW) = 'S' .OR. !(CONFIRM) <> 'P'
	       * If Confirm <> 'P', we rejected the first unpaid bill that was
	       * shown.  Rather than going back to the beginning, the loop
	       * below SKIPs to the next INDEXed name until we find an unpaid
	       * bill, or go beyond the records for the name we are paying.
	       *	The same applies if we want to pay another bill to the
	       * same supplier (New='S').  Since we are in the file on the name
  	       * we want we SKIP to the next record until we find an unpaid
	       * bill or run out of records for that name.
	       *      If we had only the name and started with the first unpaid
	       * bill we stop now since we have looked at all the unpaid bills
	       * for that supplier.
	       *	If we could have entered the list of records for the
	       * supplier in the middle (more than the name provided), we look
	       * at the unpaid bills between where we are and the end of the
	       * list, then go up to the first entry for that name and check
	       * all of the unpaid bills that we had previously skipped past.
	       * This is controlled by Counter.
	       *	After the second FIND in the command file (below), we
	       * stop looking when the record number we are on is greater than
	       * or equal to the number of the record we start on (Start).

	       SKIP
	       DO WHILE Check:Nmbr <> ' ' .AND. Name=Key .AND. .NOT. EOF 
		  SKIP
	       ENDDO

	       * We enter this loop when we reach the end of the records with
	       * names that match the one we are looking for.  If we started
	       * with the first unpaid bill, the record number is greater than
	       * Start (because Start=0) and Counter=1 (because we set it to
	       * that value).  The second IF below is True and we terminate the
	       * search.
	       *	If Start>0, Counter=0 the first time we run out of
	       * records with a matching name, so the program daes the ELSE
	       * commands below.
	       *      Start is still >0 and Count is now 1, so the last term in
	       * the first IF applies.  On this second pass when we get to a 
	       * record number >=Start, we drop into the loop and do the IF to
	       * terminate the search because we have now looked at all the
	       * unpaid bills for the name we entered.
	       IF EOF .OR. Name <> Key .OR. (# >= Start .AND. Start <> 0;
					     .AND. Counter >0)
		  IF (# >= Start .AND. Counter > 0)
		     STORE T TO Looking
		     @ 4, 0
		     ? CHR(27)+CHR(74)
		     ? '    We have now looked at all the entries for '+ MName
		     ? ' <Return> to continue.'
		     ? CHR(7)
		     IF !(New)='S'
			STORE STR(VAL(NextCheck)+1,4) TO NextCheck
			STORE 'N' TO New
		     ENDIF
		     WAIT
		  ELSE
		     STORE Counter +1 TO Counter
		     @ 13, 0
		     @ 16, 0 SAY "I'M WORKING AS FAST AS I CAN -- HANG ON! "
		     FIND &Key
		     DO WHILE Check:Nmbr <> ' '
			SKIP
		     ENDDO
		  ENDIF
	       ENDIF
	    ENDIF is it the right record
	 ENDIF
      ENDDO  Confirm the record
   ENDIF
   
   IF !(New) <> 'S'
      @ 4, 0
      ? CHR(27)+CHR(74)
      ? '	 F if FINISHED,	  '
      ? CHR(7)
      ACCEPT '	   <Return> to continue.' TO Finished
   ENDIF
ENDDO Finished

RELEASE MName, MBill:Nmbr, Key, MAmount, Start, Found, Looking, New, Change,;
	Entering, Counter, Temp, Abort, Continue, Finished, Confirm, Date
SAVE TO B:Constant

USE B:CheckFil
COUNT FOR .NOT. * TO Any
ERASE
@ 3,0
IF Any=0
   ? '		No new checks in the checkfile.'
   ? '       <Return> to continue.'
   WAIT
ELSE
   ? 'There are '-STR(Any,5)+' new checks in the CheckFile.'
   ? 'Do you want to print the checkstubs now (Y or N)?'
   ?
   WAIT TO Hardcopy
   IF !(Hardcopy) = 'Y'
      DO NameTest
      DO CheckStu
   ENDIF
ENDIF

RELEASE ALL
RETURN
