****************************************************************
** GET_CUST.PRG - generalized customer record function
** J Osako    29 Jan 1996	'This code is cursed'
** Copyright 1996 The Used Computer Store, All Rights Reserved
**
**	REVISION HISTORY
**	----------------
**		29 Mar 1996 - fixed checkless bug
**	V.1.01 : released 26 Mar 1996
**		26 Mar 1996 - fixed no-name bug 
**	v.1.00 : released 25 Mar 1996
**
****************************************************************

**********
** get_cust() - inputs the information the customers.
** This, and its validation function knownp(), are 
** somewhat complex, in part because of the need for
** tolerance - we have to allow records of varying 
** degrees of completeness, and for changes in the data - 
** and in part because of a few timesaving tricks
** I've added to knownp() to try and check if the 
** customer is already on file. 
** get_cust() returns false if the operation was 
** aborted, true otherwise.

FUNCTION get_cust

	cus_p = .F.
	SELECT Customer
	SET ORDER TO rube
	GOTO TOP
	** customer records data
	DEFINE WINDOW Cust_Info FROM 0,0 TO 7,79; 
		TITLE ' Customer Record '
	ACTIVATE WINDOW cust_info
	
	fini = NULL
	SCATTER MEMVAR
	
	DO WHILE (fini != 'Back') AND (fini != 'Done' AND ((M.check > 0) AND EMPTY(M.cdl))) 
	** continues looping until the operations is aborted, or the
	** operation is finished - but it can only finish if either
	** there's no check payment, or the CDL is filled out.

		IF cus_p
			SCATTER MEMVAR
		ENDIF
		fini = NULL	
		** begin the READ here
		** the first line reads the name, driver's license #,
		** and phone # of the customer, if available, and
		** tries to determine (via knownp()) if there's an 
		** existing record of the person.	
		@1,1 SAY 'Name' GET M.cust_name; 
			VALID knownp()
		@1,COL() SAY ' CDL' GET M.cdl;
			SIZE 1,9;
			VALID knownp()
		@1,COL() SAY ' Phone ('
		@1,COL() GET M.area_code 
		@1,COL() SAY ')';
			GET M.phone_pre
		@1,COL() SAY '-'
		@1,COL() GET M.phone_rest;
			VALID knownp()
		** second line of input, getting Addr., city, state 
		** and zipcode, if available.  No checking against 
		** this is done, on the assumption that if the rest 
		** is accurate, then its more likely that the cust. 
		** moved than that there is an overlap.
		@3,1 SAY 'Address' GET M.address;
		 	SIZE 1,20
		@3,COL() SAY ' City' GET M.city; 
			SIZE 1,15
		@3,COL() SAY ' State' GET M.state 
		@3,COL() SAY ' ZIP' GET M.zip; 
			SIZE 1,6
		@5,10 GET fini FUNCTION '*H Done;Back'
		READ
	ENDDO
	DEACTIVATE WINDOW cust_info
	IF fini = 'Back'
		RETURN .F.
	ENDIF
	IF paperhangr AND M.check > 0		&& does the cust. bounce checks?
		ACTIVATE WINDOW S_O_L
		@1,1 SAY 'This customer has a'
		@2,1 SAY 'bad check history.'
		@3,1 SAY 'Continue anyway?'
		@4,2 GET ynm DEFAULT 'No' FUNCTION '*H No;Yes'
		READ CYCLE
		DEACTIVATE WINDOW S_O_L
		IF ynm = 'No' 
			RETURN .F.
		ENDIF
	ENDIF
	
	** Now save the information
	** if there is no existing record of the customer, then
	** the Customer DB is explicitly locked, the highest
	** numbered customer N is found, and the new record
	** is assigned the number N+1
	IF cus_p 
		GATHER MEMVAR
	ELSE
		IF EOF() AND FLOCK()
			M.cust_num = RECNO()-1
			INSERT INTO Customer FROM MEMVAR
			UNLOCK
		ENDIF 
	ENDIF
			
RETURN .T.

**********
** knownp() - check if the customer is on record.
** This does not actually test validity, 
** but checks to see if their is an existing
** record of the customer in the database.
** 
** What it is doing is checking to see if the customer's
** CDL is available; if it is, it checks if it is on
** record. If the CDL is available and on record, it 'returns'
** (via the global variable cus_p) true and sets the the 
** record pointer. If the CDL isn't on record, or unavailable, 
** it checks to see if the name and phone # are - if not, it
** returns false, otherwise returns true and sets the pointer. 
** 
**	The default here is Customer Zero - a blank customer record
** with just a number. Any transaction in which the info goes
** to dev/null is assigned to Customer Zero.
** 
** Right now there is only two hole in the design; first if 
**there are two people with the same name and we don't have the
** phone number or CDL of at least one of them. In practice
**  this shouldn't happen, since it is policy to get the
** phone # if we get the name but it's possible and must 
** be documented... I could close the hole, by testing
** the address, but that would present problems with CoA
** cases - and besides, if we don't have the phone #,
** how likely is it we'll have an address? The few cases 
** of that happening aren't likely to conflict, and some
** conflicts can't be avoided anyway. Second, if the
** customer changes phone #, the record gets duplicated.
** As long as we don't make a mailing list or something,
** this isn't a major problem, but its there.
**********

FUNCTION knownp
	
	M.cust_name = PROPER(M.cust_name)
	SET ORDER TO mark	
	cus_p = (SEEK(M.cdl) OR cus_p)
	IF !cus_p
		SET ORDER TO sucker
		vnet = M.area_code + M.phone_pre + M.phone_rest
		phonet = area_code + phone_pre + phone_rest
		cus_p = (SEEK(M.cust_name) AND (vnet = phonet))
	ENDIF
** why the '!cus_p' statement? Well, if the check on M.cdl
** was valid, then there's no need to continue - we already
** have this info, no point in wasting more time. OTOH, 
** since its easier to enter the CDL first in most cases, 
** we want to be able to pull up the info with just that 
** one variable to save time.
	SET ORDER TO rube	&& reset to old index
RETURN .T.    

** this is always true, since all customer names are valid.
** IWBNI I could use this, but it would be more trouble 
** than its worth. As it is, I can at least check things
** thoroughly this way.