SALES.MOD 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. IMPLEMENTATION MODULE Sales;
  2. (*
  3. Copyright (C) 1988,1989 Jensen & Partners International
  4. *)
  5. IMPORT FIO, Str, IO, Misc, Globals, Window, Client, Items, Btree, Lib;
  6. FROM Globals IMPORT WriteAt, PromptFore, DisplayBorder,
  7. DisplayFore, DisplayBack, GetMenu, TaxRate,
  8. DataFore, DataBack, ItemIndex, ItemData,
  9. ClientData, ClientIndex;
  10. FROM Window IMPORT GotoXY, WinType, TextColor, TextBackground,
  11. ClrEol, Use, Used, PutOnTop, Open, WinDef,
  12. Black, White, SingleFrame, DoubleFrame, SetFrame,
  13. SetTitle, CenterLowerTitle, CursorOn, CursorOff,
  14. Hide;
  15. CONST
  16. MAX_ROWS = 15;
  17. FIRST_ROW = 6;
  18. TYPE
  19. SalesRec = RECORD
  20. Item : Items.ItemRec;
  21. Qty : CARDINAL;
  22. END;
  23. VAR
  24. SaleItems : ARRAY[FIRST_ROW..MAX_ROWS] OF SalesRec;
  25. SummaryFile : FIO.File;
  26. year, month, day : CARDINAL;
  27. weekday : Lib.DayType;
  28. misc : ARRAY[0..3] OF CHAR;
  29. ok : BOOLEAN;
  30. SalesWin, lastWin : WinType;
  31. SummaryWin, psumWin : WinType;
  32. OnScreen : BOOLEAN;
  33. keyPressed : CHAR;
  34. blankItem : Items.ItemRec;
  35. CurrentTotals : TotalRec;
  36. SubTotal, GrandTotal, SalesTax : LONGREAL;
  37. PROCEDURE PressAKey( txt : ARRAY OF CHAR);
  38. VAR
  39. ch : CHAR;
  40. BEGIN
  41. TextColor(PromptFore);
  42. TextBackground(DisplayBack);
  43. WriteAt(MAX_ROWS+1,1,txt);
  44. GotoXY(30,MAX_ROWS+1);
  45. ch := IO.RdKey();
  46. GotoXY(1,MAX_ROWS+1);
  47. ClrEol();
  48. keyPressed := CAP(ch);
  49. END PressAKey;
  50. PROCEDURE Template();
  51. (*
  52. This procedure un-hides the item display window and displays
  53. the field names.
  54. *)
  55. VAR
  56. x : CARDINAL;
  57. BEGIN
  58. lastWin := Used();
  59. Use(SalesWin);
  60. PutOnTop(SalesWin);
  61. Clear();
  62. OnScreen := TRUE;
  63. IF FIO.Exists(TotalFile) THEN
  64. SummaryFile := FIO.Open(TotalFile);
  65. FIO.Seek(SummaryFile,0);
  66. x := FIO.RdBin(SummaryFile,CurrentTotals,SIZE(TotalRec));
  67. FIO.Close(SummaryFile);
  68. ELSE
  69. WITH CurrentTotals DO
  70. TotalDollars := 0.0;
  71. TotalCash := 0.0;
  72. TotalCharge := 0.0;
  73. NumTrans := 0;
  74. END;
  75. END;
  76. END Template;
  77. PROCEDURE Clear();
  78. (**
  79. Clear information off the Sales screen
  80. **)
  81. VAR
  82. i : CARDINAL;
  83. BEGIN
  84. TextColor(DataFore);
  85. TextBackground(DataBack);
  86. WriteAt(1,11," ");
  87. WriteAt(1,37," ");
  88. WriteAt(1,63," ");
  89. WriteAt(2,11," ");
  90. WriteAt(2,40," ");
  91. FOR i := FIRST_ROW TO MAX_ROWS DO
  92. WriteAt(i,3," ");
  93. WriteAt(i,16," ");
  94. WriteAt(i,45," ");
  95. WriteAt(i,53," ");
  96. WriteAt(i,66," ");
  97. END;
  98. WriteAt(MAX_ROWS+2,45," ");
  99. WriteAt(MAX_ROWS+2,66," ");
  100. END Clear;
  101. PROCEDURE DisplayClient( aClient : Client.ClientRec);
  102. VAR
  103. S : ARRAY[0..9] OF CHAR;
  104. ok : BOOLEAN;
  105. BEGIN
  106. TextColor(DataFore);
  107. TextBackground(DataBack);
  108. WriteAt(1,11," ");
  109. WriteAt(1,37," ");
  110. WriteAt(1,63," ");
  111. WriteAt(2,11," ");
  112. WriteAt(2,40," ");
  113. WITH aClient DO
  114. WriteAt(1,11,CNum);
  115. WriteAt(1,37,LName);
  116. WriteAt(1,63,FName);
  117. WriteAt(2,11,Phone);
  118. WriteAt(2,40," ");
  119. Str.FixRealToStr(Balance,2,S,ok);
  120. IF ok = FALSE THEN
  121. WriteAt(2,40,"???");
  122. ELSE
  123. WriteAt(2,40,S);
  124. END;
  125. END;
  126. END DisplayClient;
  127. PROCEDURE GetClient( VAR aClient : Client.ClientRec ) : BOOLEAN;
  128. VAR
  129. CNum : Globals.FileKey;
  130. ReEnter,
  131. GotClient : BOOLEAN;
  132. ch : CHAR;
  133. BEGIN
  134. GotClient := FALSE;
  135. CNum := "";
  136. REPEAT (* until GotClient *)
  137. ReEnter := FALSE;
  138. Clear();
  139. GotoXY(11,1); Misc.InputStr(CNum, 10);
  140. IF CNum[0] <= ' ' THEN (* cancel the transaction *)
  141. RETURN FALSE;
  142. ELSE (* a CNum was entered *)
  143. IF Btree.Find(ClientIndex,CNum,aClient) THEN
  144. DisplayClient(aClient);
  145. GotClient := TRUE;
  146. ELSIF Btree.Search(ClientIndex,CNum,aClient) THEN
  147. REPEAT
  148. DisplayClient(aClient);
  149. GetMenu("T)his One, N)ext, P)revious, or R)e-enter? ",
  150. Globals.CharSet{'T','N','P'},ch);
  151. CASE ch OF
  152. 'T' : GotClient := TRUE;
  153. | 'N' : IF Btree.Next(ClientIndex,aClient) THEN
  154. DisplayClient(aClient);
  155. ELSE
  156. Globals.Beep();
  157. END;
  158. | 'P' : IF Btree.Prev(ClientIndex,aClient) THEN
  159. DisplayClient(aClient);
  160. ELSE
  161. Globals.Beep();
  162. END;
  163. | 'R' : ReEnter := TRUE;
  164. ELSE
  165. Globals.Beep();
  166. END; (* case *)
  167. UNTIL GotClient OR ReEnter;
  168. ELSE
  169. Globals.Beep(); Globals.Beep(); Globals.Beep();
  170. PressAKey("That client is not in our records!");
  171. TextColor(DataFore);
  172. TextBackground(DataBack);
  173. END;
  174. END;
  175. UNTIL GotClient;
  176. RETURN TRUE;
  177. END GetClient;
  178. PROCEDURE DisplayItem( row : CARDINAL; anItem : Items.ItemRec );
  179. VAR
  180. ok : BOOLEAN;
  181. S : ARRAY[0..9] OF CHAR;
  182. BEGIN
  183. TextColor(DataFore);
  184. TextBackground(DataBack);
  185. WriteAt(row,16,anItem.Description);
  186. WriteAt(row,53," ");
  187. Str.FixRealToStr(anItem.Retail,2,S,ok);
  188. IF ok = FALSE THEN
  189. WriteAt(row,53,"???");
  190. ELSE
  191. WriteAt(row,53,S);
  192. END;
  193. END DisplayItem;
  194. PROCEDURE GetOneItem( row: CARDINAL;
  195. VAR anItem : Items.ItemRec ): BOOLEAN;
  196. VAR
  197. item : Globals.FileKey;
  198. ReEnter,
  199. GotItem : BOOLEAN;
  200. ch : CHAR;
  201. BEGIN
  202. GotItem := FALSE;
  203. Str.Copy(item,"");
  204. REPEAT
  205. ReEnter := FALSE;
  206. GotoXY(3,row); Misc.InputStr(item,10);
  207. IF item[0] <= ' ' THEN (* cancel the transaction *)
  208. RETURN FALSE;
  209. ELSE (* an item number was entered *)
  210. IF Btree.Find(ItemIndex,item,anItem) THEN
  211. DisplayItem(row,anItem);
  212. GotItem := TRUE;
  213. ELSIF Btree.Search(ItemIndex,item,anItem) THEN
  214. REPEAT
  215. DisplayItem(row,anItem);
  216. GetMenu("T)his One, N)ext, P)revious, or R)e-enter? ",
  217. Globals.CharSet{'T','N','P'},ch);
  218. CASE ch OF
  219. 'T' : GotItem := TRUE;
  220. | 'N' : IF Btree.Next(ItemIndex,anItem) THEN
  221. DisplayItem(row,anItem);
  222. ELSE
  223. Globals.Beep();
  224. END;
  225. | 'P' : IF Btree.Prev(ItemIndex,anItem) THEN
  226. DisplayItem(row,anItem);
  227. ELSE
  228. Globals.Beep();
  229. END;
  230. | 'R' : ReEnter := TRUE;
  231. ELSE
  232. Globals.Beep();
  233. END; (* case *)
  234. UNTIL GotItem OR ReEnter;
  235. ELSE
  236. Globals.Beep(); Globals.Beep(); Globals.Beep();
  237. PressAKey("That item is not in our records!");
  238. TextColor(DataFore);
  239. TextBackground(DataBack);
  240. END;
  241. END;
  242. UNTIL GotItem;
  243. RETURN TRUE;
  244. END GetOneItem;
  245. PROCEDURE GetSaleItem( VAR which : CARDINAL;
  246. VAR action : CARDINAL ) : BOOLEAN;
  247. VAR
  248. item : Items.ItemRec;
  249. qty : CARDINAL;
  250. qtyStr : ARRAY[0..4] OF CHAR;
  251. ok : BOOLEAN;
  252. ch : CHAR;
  253. thisTotal : LONGREAL;
  254. S : ARRAY[0..10] OF CHAR;
  255. BEGIN
  256. action := 0;
  257. ok := FALSE;
  258. qtyStr := "1";
  259. IF GetOneItem(which,item) THEN
  260. REPEAT
  261. WriteAt(which,45," ");
  262. GotoXY(45,which); Misc.InputStr(qtyStr,5);
  263. qty := CARDINAL(Str.StrToCard(qtyStr,10,ok));
  264. UNTIL ok;
  265. SaleItems[which].Qty := qty;
  266. SaleItems[which].Item := item;
  267. thisTotal := LONGREAL(qty) * item.Retail;
  268. WriteAt(which,66," ");
  269. Str.FixRealToStr(thisTotal,2,S,ok);
  270. IF ok = FALSE THEN
  271. WriteAt(which,66,"???");
  272. ELSE
  273. WriteAt(which,66,S);
  274. END;
  275. SubTotal := SubTotal + thisTotal;
  276. SalesTax := (SubTotal * TaxRate)/100.0;
  277. GrandTotal := SubTotal + SalesTax;
  278. WriteAt(MAX_ROWS+2,45," ");
  279. WriteAt(MAX_ROWS+2,66," ");
  280. Str.FixRealToStr(SalesTax,2,S,ok);
  281. IF ok = FALSE THEN
  282. WriteAt(MAX_ROWS+2,45,"???");
  283. ELSE
  284. WriteAt(MAX_ROWS+2,45,S);
  285. END;
  286. Str.FixRealToStr(GrandTotal,2,S,ok);
  287. IF ok = FALSE THEN
  288. WriteAt(MAX_ROWS+2,66,"???");
  289. ELSE
  290. WriteAt(MAX_ROWS+2,66,S);
  291. END;
  292. END;
  293. GetMenu("C)ancel item, N)o Sale, A)nother item, D)one with sale: ",
  294. Globals.CharSet{'C','N','A','D'},ch);
  295. CASE ch OF
  296. 'D' : RETURN TRUE;
  297. | 'A' : RETURN FALSE;
  298. | 'C' : DEC(which);
  299. DisplayItem(which+1,blankItem);
  300. WriteAt(which+1,45," ");
  301. WriteAt(which+1,66," ");
  302. | 'N' : action := 99;
  303. RETURN TRUE;
  304. ELSE
  305. Globals.Beep();
  306. END;
  307. RETURN FALSE;
  308. END GetSaleItem;
  309. PROCEDURE Work();
  310. (**
  311. Perform the entry of sales, information requests, etc.
  312. Template should be called first to open the window.
  313. **)
  314. VAR
  315. theClient : Client.ClientRec;
  316. ch : CHAR;
  317. transDone : BOOLEAN;
  318. choice, i,
  319. row : CARDINAL;
  320. BEGIN
  321. SubTotal := 0.0;
  322. GrandTotal := 0.0;
  323. SalesTax := 0.0;
  324. IF GetClient(theClient) THEN
  325. transDone := FALSE;
  326. FOR row := FIRST_ROW TO MAX_ROWS DO
  327. SaleItems[row].Qty := 0;
  328. END;
  329. row := FIRST_ROW;
  330. REPEAT
  331. transDone := GetSaleItem( row, choice );
  332. INC(row);
  333. UNTIL (transDone) OR (row>MAX_ROWS);
  334. IF choice = 0 THEN
  335. (* take the cash or charge *)
  336. GetMenu("Will that be C)ash or cH)arge? ",
  337. Globals.CharSet{'C','H'},ch);
  338. CASE ch OF
  339. 'C' : CurrentTotals.TotalCash :=
  340. CurrentTotals.TotalCash + GrandTotal;
  341. | 'H' : CurrentTotals.TotalCharge :=
  342. CurrentTotals.TotalCharge + GrandTotal;
  343. theClient.Balance := theClient.Balance +
  344. GrandTotal;
  345. Btree.Delete(ClientData);
  346. Btree.Add(ClientData,theClient,SIZE(Client.ClientRec));
  347. ELSE
  348. Globals.Beep();
  349. END;
  350. CurrentTotals.TotalDollars :=
  351. CurrentTotals.TotalDollars + GrandTotal;
  352. INC(CurrentTotals.NumTrans);
  353. ELSE
  354. (* cancel transaction *)
  355. Clear();
  356. END;
  357. END; (* if *)
  358. END Work;
  359. PROCEDURE Summary();
  360. (**
  361. Summarize current sales figures in a window
  362. **)
  363. VAR
  364. SummaryWin, psumWin : WinType;
  365. ch : CHAR;
  366. S : ARRAY[0..10] OF CHAR;
  367. ok : BOOLEAN;
  368. BEGIN
  369. psumWin := Used();
  370. SummaryWin := Open( WinDef( 28, 10, 52, 17,
  371. White,Black,TRUE,FALSE,TRUE,TRUE,
  372. SingleFrame,White,Black) );
  373. SetFrame(SummaryWin,DoubleFrame,DataFore,
  374. DataBack);
  375. SetTitle(SummaryWin,"Daily Totals",CenterLowerTitle);
  376. Use(SummaryWin);
  377. CursorOff();
  378. TextColor(DataFore);
  379. TextBackground(DataBack);
  380. Window.Clear();
  381. WriteAt(2,3,"Total Sales: $");
  382. WriteAt(3,3,"Cash Sales: ");
  383. WriteAt(4,3,"Charge Sales: ");
  384. WriteAt(5,3,"# Trans: ");
  385. PutOnTop(SummaryWin);
  386. (* write out the current totals *)
  387. WITH CurrentTotals DO
  388. Str.FixRealToStr(TotalDollars,2,S,ok);
  389. WriteAt(2,18,S);
  390. Str.FixRealToStr(TotalCash,2,S,ok);
  391. WriteAt(3,18,S);
  392. Str.FixRealToStr(TotalCharge,2,S,ok);
  393. WriteAt(4,18,S);
  394. GotoXY(18,5);
  395. IO.WrCard(NumTrans,4);
  396. END;
  397. ch := IO.RdKey();
  398. Window.Close(SummaryWin);
  399. PutOnTop(psumWin);
  400. Use(psumWin);
  401. CursorOn();
  402. END Summary;
  403. PROCEDURE Close();
  404. (**
  405. Remove the Sales screen from the screen
  406. **)
  407. BEGIN
  408. Hide(SalesWin);
  409. Use(lastWin);
  410. PutOnTop(lastWin);
  411. OnScreen := FALSE;
  412. (* write out summary file *)
  413. SummaryFile := FIO.Create(TotalFile);
  414. FIO.Seek(SummaryFile,0);
  415. FIO.WrBin(SummaryFile,CurrentTotals,SIZE(TotalRec));
  416. FIO.Close(SummaryFile);
  417. END Close;
  418. BEGIN (* init code *)
  419. (* set up the summary file name *)
  420. TotalFile := "000000.TOT"; (* default name *)
  421. Lib.GetDate(year,month,day,weekday);
  422. IF year > 1900 THEN year := year - 1900; END;
  423. Str.CardToStr(LONGCARD(year),misc,10,ok);
  424. IF misc[1] = 0C THEN
  425. TotalFile[4] := '0';
  426. TotalFile[5] := misc[0];
  427. ELSE
  428. TotalFile[4] := misc[0];
  429. TotalFile[5] := misc[1];
  430. END;
  431. Str.CardToStr(LONGCARD(month),misc,10,ok);
  432. IF misc[1] = 0C THEN
  433. TotalFile[0] := '0';
  434. TotalFile[1] := misc[0];
  435. ELSE
  436. TotalFile[0] := misc[0];
  437. TotalFile[1] := misc[1];
  438. END;
  439. Str.CardToStr(LONGCARD(day),misc,10,ok);
  440. IF misc[1] = 0C THEN
  441. TotalFile[2] := '0';
  442. TotalFile[3] := misc[0];
  443. ELSE
  444. TotalFile[2] := misc[0];
  445. TotalFile[3] := misc[1];
  446. END;
  447. (* create the sales window *)
  448. SalesWin := Open( WinDef( 0, 4, 79, 22,
  449. White,Black,TRUE,FALSE,TRUE,TRUE,
  450. SingleFrame,White,Black) );
  451. SetFrame(SalesWin,SingleFrame,DisplayBorder,
  452. DisplayBack);
  453. Use(SalesWin);
  454. TextColor(DisplayFore);
  455. TextBackground(DisplayBack);
  456. Window.Clear();
  457. WriteAt(1,3,"Client:");
  458. WriteAt(2,3,"Phone:");
  459. WriteAt(1,30,"Last:");
  460. WriteAt(1,55,"First:");
  461. WriteAt(2,30,"Balance:");
  462. WriteAt(4,3,"ITEM");
  463. WriteAt(4,16,"DESCRIPTION");
  464. WriteAt(4,45,"QTY");
  465. WriteAt(4,53,"EACH");
  466. WriteAt(4,66,"TOTAL");
  467. WriteAt(17,40,"TAX:");
  468. WriteAt(17,57,"TOTAL:");
  469. blankItem.Retail := 0.0;
  470. blankItem.Description := " ";
  471. END Sales.