IMPLEMENTATION MODULE SalesReps; (* * ModBase * Release 3.0 * (c) Copyright 1986 - 1991 PMI * P.O. Box 8402 * Green Bay Wi 53308 * All Rights Reserved * by Ed Ross *) FROM DBFInvoice IMPORT OpenInvoiceDBF,CloseInvoiceDBF,MoveInvoiceFromDBF, InvoiceRec,InvoiceDBF; FROM GenLists IMPORT NewList,GenList,ListLength,ListInsert,GetElmt, DisposeList,GetElmtAdr,ListDelete,ListInsertAdr,SortList; FROM ListUtils IMPORT TextFileToList,TextListToFile; FROM StrConv IMPORT RealToStr,CardinalToStr; FROM StrEdit IMPORT CAPstr,DeleteRightJustified, CrunchBlanks,Center,Append; FROM Customer IMPORT GetCustName,GetCustSalesRepCom,GetCustSalesRep; FROM DBFCustomer IMPORT OpenCustomerDBF,FindCustomerByCin,CustomerRec, MoveCustomerFromDBF; FROM DBFInvoice IMPORT OpenInvoiceDBF; FROM PMIGlobals IMPORT Config,PMIScreens,Today,TodayStr; FROM DspFiles IMPORT OpenDisplayFile; FROM DBUtils IMPORT GetDateRange; FROM DBStuff IMPORT MakeKey; FROM HandleIO IMPORT OpenFile,FileExists,CloseHandle; FROM PrinterUtils IMPORT SetupDisplayLine,DisplayLine,RemoveDisplayLine, AddPrintElemt,PrintDisplayLine,ClearDisplayLine; FROM PosUtils IMPORT Equal; FROM DateFunctions IMPORT Date,DateToStr,CompareDates,Comparison; FROM ModBase3 IMPORT ReadDBRec,Deleted,NumberRecords; FROM StringIO IMPORT WriteStr,WriteEol,PrintMessage; FROM SYSTEM IMPORT ADDRESS,ADR; FROM NumTypes IMPORT Real8; FROM ScrnUtl2 IMPORT CloseDisplayFrame,GetEdField; FROM VWindows IMPORT ClearPart, CurrentWindow, SetCursorHeight; FROM ScrnTypes IMPORT DisplayFrame,InitDisplayFrame,AFrameName,DisplayFile; FROM FramePainter IMPORT ShowDisplayFrame,RedrawField; FROM ControlUtils IMPORT Control,AddEditorField; FROM VEditor IMPORT AnEdControlRec,InitEdRec; FROM LowLevel IMPORT Fill; FROM M2Strings IMPORT CompareStr,Length,Assign; VAR MainList : GenList; SalesRepList : GenList; PrtHand : CARDINAL; Environ : ARRAY[0..60] OF CHAR; PROCEDURE SortBySalesRep(Inv1 : ADDRESS; Size1 : CARDINAL; Inv2 : ADDRESS; Size2 : CARDINAL): INTEGER; (* sort list of invoices by sales rep, by customer, by invdate*) VAR I1,I2 : POINTER TO InvoiceRec; Comp : Comparison; BEGIN I1 := Inv1; I2 := Inv2; RETURN CompareStr(I1^.SALESMAN,I2^.SALESMAN); END SortBySalesRep; PROCEDURE SortByInvNbr(Inv1 : ADDRESS; Size1 : CARDINAL; Inv2 : ADDRESS; Size2 : CARDINAL): INTEGER; (* sort list of invoices by sales rep, by customer, by invdate*) VAR I1,I2 : POINTER TO InvoiceRec; Comp : Comparison; BEGIN I1 := Inv1; I2 := Inv2; RETURN CompareStr(I1^.INVOICE,I2^.INVOICE); END SortByInvNbr; PROCEDURE SortByCustNbr(Inv1 : ADDRESS; Size1 : CARDINAL; Inv2 : ADDRESS; Size2 : CARDINAL): INTEGER; (* sort list of invoices by sales rep, by customer, by invdate*) VAR I1,I2 : POINTER TO InvoiceRec; Comp : Comparison; BEGIN I1 := Inv1; I2 := Inv2; RETURN CompareStr(I1^.CUSTID,I2^.CUSTID); END SortByCustNbr; PROCEDURE GetMainList(); (* read through the invoices and get those that are closed and within the specified date range*) VAR BeginDate,EndDate : Date; Invoice : InvoiceRec; L,NumOfRecs : LONGINT; BEGIN BeginDate := Today; BeginDate.day := 1; EndDate := Today; GetDateRange(BeginDate,EndDate,PMIScreens); OpenInvoiceDBF(FALSE); NewList(MainList); NumOfRecs := NumberRecords(InvoiceDBF); FOR L := 1 TO NumOfRecs DO ReadDBRec(InvoiceDBF,L); IF NOT Deleted(InvoiceDBF) THEN MoveInvoiceFromDBF(Invoice); CrunchBlanks(Invoice.SALESMAN); IF Length(Invoice.SALESMAN) > 1 (* only grab the ones with salesrep*) THEN IF (CompareDates(Invoice.INVDATE,BeginDate) = DateGreater) AND (CompareDates(Invoice.INVDATE,EndDate) = DateLess) THEN ListInsert(Invoice,2,MainList,1); END; END; END; (* if deleted *) END; (* end of loop *) SortList(MainList,SortBySalesRep); END GetMainList; PROCEDURE MakeSubList(SalesRep: ARRAY OF CHAR); (* Return a list of invoices for this sales rep - make the list from main list *) VAR N : CARDINAL; Inv : POINTER TO InvoiceRec; Size,Code : CARDINAL; SalesMan : ARRAY[0..10] OF CHAR; Cust : CustomerRec; BEGIN NewList(SalesRepList); MakeKey(SalesRep); FOR N := 1 TO ListLength(MainList) DO GetElmtAdr(MainList,N,Inv,Size,Code); MakeKey(Inv^.SALESMAN); MakeKey(Inv^.INVOICE); IF Equal(SalesRep,Inv^.SALESMAN) THEN ListInsert(Inv^,2,SalesRepList,1); (* insert in sublist*) END; END; (* end for *) SortList(SalesRepList,SortByInvNbr); END MakeSubList; PROCEDURE PrintHeader(SalesRep : ARRAY OF CHAR; Page : CARDINAL); VAR Line : ARRAY[0..80] OF CHAR; Str: ARRAY[0..10] OF CHAR; BEGIN WriteStr(PrtHand,12C); Line := 'Sales Commission Report'; Center(Line,80); WriteEol(PrtHand,Line); Assign( SalesRep,Line ); Center(Line,80); WriteEol(PrtHand,Line); Assign( TodayStr,Line); Append(Line,' Page '); CardinalToStr(Page,4,Str); Append(Line,Str); Center(Line,80); WriteEol(PrtHand,Line); WriteEol(PrtHand,''); WriteEol(PrtHand,''); WriteEol(PrtHand,''); WriteEol(PrtHand, ' Cust Invoice Date Net Com % Commission'); WriteEol(PrtHand, '----------------------------------------------------------------'); END PrintHeader; PROCEDURE ReportSalesRep(SalesRep: ARRAY OF CHAR); VAR CurrentCustNbr : ARRAY[0..15] OF CHAR; CurrentCustName , LastCust : ARRAY[0..60] OF CHAR; Inv : POINTER TO InvoiceRec; J, Size,Code : CARDINAL; CommPerCent : Real8; CustomerTotal : Real8; RepTotal : Real8; LineNbr : CARDINAL; Line : DisplayLine; Page : CARDINAL; B : BOOLEAN; Commision : Real8; Str : ARRAY[0..10] OF CHAR; BEGIN (* * * * * * * print output should look like this * * * * *** * * * 123456789012345678901234567890123456789012345678901234567890123456789012345 1 2 3 4 5 6 7 Customer Name Number Commission Rate xx.xx% Cust Nbr Invoice Date Net Amount Comm % Commission xxxxxxxxx xxxxxxxxxx xx-xx-xx xxxxxxx.xx xx.xx xxxxxx.xx *) MakeSubList(SalesRep); (* a list of all invoices sorted by client id*) IF ListLength(SalesRepList) = 0 THEN DisposeList(SalesRepList); RETURN; END; GetElmtAdr(SalesRepList,1,Inv,Size,Code); RepTotal := 0.0; Page := 1; LineNbr := 0; PrintHeader(SalesRep,Page); CustomerTotal := 0.0; RepTotal := 0.0; SetupDisplayLine(Line,90); FOR J := 1 TO ListLength(SalesRepList) DO INC(LineNbr); IF LineNbr > 50 THEN LineNbr := 1; INC(Page); PrintHeader(SalesRep,Page); END; GetElmtAdr(SalesRepList,J,Inv,Size,Code); AddPrintElemt(Line,Inv^.CUSTID,'S',2,8,'L'); AddPrintElemt(Line,Inv^.INVOICE,'S',10,8,'L'); AddPrintElemt(Line,Inv^.INVDATE,'D',20,8,'L'); AddPrintElemt(Line,Inv^.INVNET,'R',30,10,'L'); GetCustName(Inv^.CUSTID,CurrentCustName); GetCustSalesRepCom(CommPerCent); CommPerCent := CommPerCent / 100.0; AddPrintElemt(Line,CommPerCent,'%',45,5,'L'); AddPrintElemt(Line,CommPerCent * Inv^.INVNET,'R',60,10,'L'); PrintDisplayLine(Line,PrtHand); ClearDisplayLine(Line); RepTotal := RepTotal + (CommPerCent * Inv^.INVNET); END; (* end of sales rep invoice list *) WriteEol(PrtHand,''); WriteEol(PrtHand,''); WriteStr(PrtHand,'Total commission for Sales Rep '); WriteStr(PrtHand,SalesRep); WriteStr(PrtHand,': $'); RealToStr(RepTotal,2,10,Str); WriteEol(PrtHand, Str); (* write a list of the customers for the sales rep *) SortList(SalesRepList,SortByCustNbr); WriteStr(PrtHand,12C); WriteStr(PrtHand,' Customers for '); WriteStr(PrtHand,SalesRep); WriteEol(PrtHand,''); LineNbr := 1; LastCust := ''; FOR J := 1 TO ListLength(SalesRepList) DO GetElmtAdr(SalesRepList,J,Inv,Size,Code); GetCustName(Inv^.CUSTID,CurrentCustName); IF NOT Equal(LastCust,CurrentCustName) THEN WriteStr(PrtHand,Inv^.CUSTID); WriteStr(PrtHand,' '); WriteEol(PrtHand,CurrentCustName); LastCust := CurrentCustName; END; END; RemoveDisplayLine(Line); END ReportSalesRep; PROCEDURE ParseName(VAR Name : ARRAY OF CHAR; Str: ARRAY OF CHAR); VAR J : CARDINAL; BEGIN Fill(ADR(Name),SIZE(Name),0); J := 0; LOOP IF J > Length(Str) THEN EXIT; END; IF J > SIZE(Name) THEN EXIT; END; IF Str[J] = ' ' THEN EXIT; END; Name[J] := Str[J]; INC(J); END; (* end loop *) CAPstr(Name); END ParseName; PROCEDURE GetSalesReps(); (* read a list of the sales reps into the linked sales rep list *) VAR J : CARDINAL; Code : CARDINAL; L : LONGINT; TheList : GenList; Str : ARRAY[0..80] OF CHAR; SalesRep : ARRAY[0..15] OF CHAR; EM : CARDINAL; BEGIN EM := OpenFile(PrtHand,Config.ReportPrt); SalesRep := 'SalesRep.txt'; (* temp till file open *) NewList(TheList); EM := TextFileToList(SalesRep,TheList); GetMainList(); FOR J := 1 TO ListLength(TheList) DO GetElmt(TheList,J,Str,Code); (* get the string*) ParseName(SalesRep,Str); ReportSalesRep(SalesRep); END; DisposeList(TheList); EM := CloseHandle(PrtHand); END GetSalesReps; PROCEDURE CreateEditSalesReps(); (* sales reps are stored in a simple text file, one sales rep per line Any information after the reps invoice name is kept but ignored in the processing *) VAR TheList : GenList; DF : DisplayFrame; FileHandle : CARDINAL; EditorRec : AnEdControlRec; Str : ARRAY[0..15] OF CHAR; EM : CARDINAL; BEGIN NewList(TheList); Str := 'SalesRep.Txt'; IF FileExists(Str) THEN EM := TextFileToList(Str,TheList); END; InitEdRec(EditorRec); InitDisplayFrame(DF,CurrentWindow); AddEditorField(DF,TheList,EditorRec); Control(DF); GetEdField(DF,'',TheList); EM := TextListToFile(TheList,Str); END CreateEditSalesReps; PROCEDURE ProduceCommissions(); BEGIN OpenCustomerDBF(TRUE); GetSalesReps(); END ProduceCommissions; END SalesReps.