{*****************************************************
 ***             JOB HISTORY REPORT                ***
 *****************************************************}
{$I compflgs}
{Returns number of jobs done by each invoice to ID in date range}

unit KJobRpts;

INTERFACE

procedure JobReport;

IMPLEMENTATION

uses kamapp, tasks, global, displays,
			objects, messages, datTime, files, khrdware, kjob,
		 edit, inpdnt, views, dialogs, app, minilib, menus,
		 kdirctry,
     jimhooks,
		jimmys, indexes,
		 khistory, printout, pchains;


type
  PReportCollItem = ^TReportCollItem;
  TReportCollItem = object(TObject)
     SortKey : string;
  end;

  PReportCollection = ^TReportCollection;
  TReportCollection = object(TSortedCollection)
	function Compare(Key1, Key2 : pointer) : integer; virtual;
  end;

  function TReportCollection.Compare;
  begin
    if PReportCollItem(Key1)^.SortKey = PReportCollItem(Key2)^.SortKey then Compare := 0
    else if PReportCollItem(Key1)^.SortKey > PReportCollItem(Key2)^.SortKey then Compare := 1
    else Compare := -1;
  end;

type
  PJobRptCollItem = ^TJobRptCollItem;
  TJobRptCollItem = object(TReportCollItem)
      Ptr2Per : longint;
			NoJobs : word;
  end;


procedure JobReport;
var
  ProBox : PProgressBox;
	Rec : longint;
	Person,InvTo : PDirectoryItem;
	Job : PJob;
	EditBox : PObjectEditBox;
	R : Trect;
	Control : word;
	PersonPrinted : boolean;
	S : string;
	Range : TDateRange;
	RptColl : TReportCollection;
	RptCollItem : PJobRptCollItem;
	I : integer;
	TotalJobs : word;
	Result : byte;

begin
	{******************************
	 ***    ASK FOR CHECK DATE  ***
	 ******************************}
	R.Assign(20,10,46,18);
	New(EditBox, Init(R,'JOB REPORT',nil));

	EditBox^.InsTitledField(11,2,10, 1, 'For Date', New(PInputDate, Init(R)));
	EditBox^.InsTitledField(11,3,10, 1, 'To',       New(PInputDate, Init(R)));

	EditBox^.InsButton(12,5,8,'~O~K', cmOK, bfdefault);
	EditBox^.SelectNext(False);

	{Set range to cover last month}
	Range.Start.SetToToday; Range.Start.AddMonth(False);
	Range.Finish.SetToToday;

	EditBox^.SetData(Range); {SetData expects an object derivitive}

  Control := Desktop^.ExecView(EditBox);

  if Control = cmCancel then Exit;

  EditBox^.GetData(Range);

	Dispose(EditBox, Done);


  {********************************
   ***      PRODUCE REPORT      ***
	 ********************************}
  ProBox := NewProgressBox('JOB REPORT',space(40),'');

 	FileAdmin(fiFullDirIdx)^.LogOn;
 	FileAdmin(fiJimmys)^.LogOn;
	FileAdmin(fiHooks)^.LogOn;


  {===== FIRST BUILD INDEX/COLLECTION ==============}
  RptColl.init(50,10);  {Initialise collection}

  Rec := 0;
	while (ProBox^.COmmand<>cmCancel) and (Rec<Stream(fiFullDirIdx)^.NoRecs-1) do begin
		ProBox^.Update('Building Report','Doing Person ',Rec, Stream(fiFullDirIdx)^.NoRecs-1);
		Person := PDirectoryItem(PIndexStream(Stream(fiFullDirIdx))^.GetJimmyAtIdx(Rec));
		PersonPrinted := False;  {Flag to mark whether printed yet}

		if Person <> nil then begin

			Job := PJob(HookFile^.FindFirst(Person^.GetFirstHookID(hkHistory), srJob));

			while Job<>nil do begin

				{---- Check if out of date ---}
				if (Job^.VisitDate.Days>=Range.Start.Days) and
						 (Job^.VisitDate.Days<=Range.Finish.Days) then begin

					{Add to position in collection}
					inc(PJobRptCollItem(RptColl.At())^.NoJobs);
					{something not quite right with this report...  who wants it anyway?}
				end;

				Dispose(Job, Done);

				Job := PJob(HookFile^.FindNext);

			end;  {while not end of chain}
			Dispose(Person, Done);
		end; {if not nil/hole}
		Rec := Rec +1;
  end; {while}

  {======= PRINT REPORT =============}
  if (RptColl.Count>0) and (ProBox^.Command<>cmCancel) then begin
     ProBox^.Update('Printing...','',0,0);
     PrintStream.ClearCodes;
		 PrintStream.SetCode('DTS',Range.Start.Digit10);
		 PrintStream.SetCode('DTE',Range.Finish.Digit10);
		 PrintStream.SetCode('RANGE',Range.Start.Digit10+' - '+Range.Finish.Digit10);

		 PrintStream.StartRpt('NUMJOBS');
     TotalJobs := 0;

     for I :=0 to RptColl.Count-1 do begin
{       ProBox^.Update('','',I,RptColl.Count-1); {}
       RptCollItem := PJobRptCollItem(RptColl.At(I));
       if RptCollItem^.Ptr2Per = -1 then
		 PrintStream.writeln(SPace(8)+
			       PadSpaceR('Uncontracted:',50) +
			       PadSpaceL(L2Str(RptCollitem^.NoJobs),4)
			       )
       else begin
					 InvTo := PDirectoryItem(JimmyStream^.GetAt(RptCollItem^.Ptr2Per));
		 PrintStream.Writeln(PadSpaceR('('+L2Str(RptCollItem^.Ptr2Per)+')',8) +
						 PadSpaceR(InvTo^.GetName(naReport,0),50) +
			       PadSpaceL(L2Str(RptCollItem^.NoJobs),4)
			       );
	   Dispose(InvTo, done);
       end;
       TotalJobs := TotalJobs + RptCollItem^.NoJobs;
     end;

     PrintStream.Writeln('');
     PrintStream.Writeln(PadSpaceR('TOTAL',58)+PadSpaceL(L2Str(TotalJobs),4));
     PrintStream.EndPrint; {}
	end else
     PauseMessage('Nothing to Print!','');

  Desktop^.Delete(Probox);
  Dispose(ProBox, done);

  RptColl.Done;

 	FileAdmin(fiFullDirIdx)^.LogOff;
 	FileAdmin(fiJimmys)^.LogOff;
	FileAdmin(fiHooks)^.LogOff;
end;

begin
	AppMenuBar^.Add2EndMenu(mnReports, NewItem('~J~obs Done', '', kbNone, cmJobReport, hcNoContext, nil));
	RegisterTask(DesktopTasks, cmJobReport, JobReport);{}
end.
