{***********************************************************************
 ***                                                                 ***
 ***                 STAFF PERSON - FOR MEMBERS OF YOUR COY          ***
 ***                                                                 ***
 ***********************************************************************}
{Provides a basic person object for staff members.  Users are a special
descendant of staff.  In the future can tie in to payrolls, etc}

{$I Compdirs}

unit KStaff;

INTERFACE

uses
	jimmys,
	files,
	tuiedit, views,
	devices, forms,
	address,
	global,
	drivers,
	objects,
	kdirctry;

type
	PStaff = ^TStaff;
	TStaff = object(TDirectoryItem)
		Surname : string[30];
		ForName : string[25];
		Title   : string[10];

		Alias		: string[3];     {short, fast type/access name, for display in diary, etc}
		JobTitle : string[30];
		Dept     : string[30];

		AddressPID : PLongint; {indirect pointer to TDirectoryItem.address ptr}

		NatID : string[20];

		CategoryCodes  : string[10];        {CategoryCodes codes}

		{-- Methods --}
		procedure CommonInit; virtual;
		destructor Done; virtual;

		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;

		function RecSize : word; virtual;
		function srType : word; virtual;
		constructor Load(var S : TDataStream);
		procedure   StoreFields(var S : TDataSTream); virtual;

		{indexing}
		function GetIndexKey(const ixType : byte) : string; virtual;

		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		function GetName(naType : byte; Maxlen : integer) : string; virtual;

		function GetCategories : string; virtual;

		procedure SetFormCodes(const FormCodes : PFormCodeCollection); virtual;{Sets standard Staff codes}

		procedure PrintLabel(const Device : PDeviceStream; LabelAs : word); virtual;
		procedure PrintLine(const Device : PDeviceStream); virtual;
 end;


IMPLEMENTATION

uses tuimsgs,
			scodes,
			jimhooks,
			jimindxs,
			inplist,
			inptel,
			status, kamsetup, {set who at terminal}
			tasks,
			help,
			tui, tuiapp,
			tuijimmy,
			printers,
		 {$IFDEF kusers} kusers, {$ENDIF} {for superusername}
		 app, dattime, dialogs, minilib;


{****************************************************************************
 ***                                                                      ***
 ***                THE Staff OBJECT                                     ***
 ***                                                                      ***
 ****************************************************************************}

procedure TStaff.CommonInit;
begin
	CategoryCodes := ''; {so that getindex works ok when clearing pointers}
	SurName := ''; ForName := ''; Alias := '';

	inherited CommonInit;

	AddressPID := @AddressID;

	SCodeCollection[scDirectoryCategory]^.LogOn;
end;

destructor TStaff.Done;
begin
	SCodeCollection[scDirectoryCategory]^.LogOff;
	inherited Done;
end;


{********************************************
 *** DISPLAY LINE                         ***
 ********************************************}
{Used for list views}
function TStaff.DisplayLine;
var S : string;
		SS : string;

begin
	DisplayLine := '';

	SS := Surname; if ForName<>'' then SS := SS+','+ForName;

	case lsType of
		lsDirectory,lsUsers :
			case GotbyIx of
				2,9 : S := SetLength(Alias,3)+' ('+SS+')'+SkipTab;
			else
				S := Surname +Tab+ForName;
			end;
		else
			S := SS+Tab+Alias;
		end;

	SS := JobTitle; if (SS<>'') and (Dept<>'') then SS := SS +',';
	S := S+Tab+GetTelNum(1)+Tab+SS+Dept;

	{Set}
	DisplayLine :=S + inherited DisplayLine(-1,0,0,0);
end;


function TStaff.GetName(naType : byte; Maxlen : integer) : string;
begin
	if naType = naDear then
		GetName := ForName
	else
		GetName := minilib.GetName(Surname, ForName, Title, Alias, naType, Maxlen); {use minilib calc}
end;



procedure TStaff.SetFormCodes;
var S,S1 : string;
		I : integer;
		ContactForItem : PDirectoryItem;

begin
	inherited SetFormCodes(FormCOdes);

	with FormCodes^ do begin
		{Various sorts of names}
		SetStr('NS', Surname);
		SetStr('NF', Forname);
		SetStr('NT', Title);

		SetStr('JOB', JobTitle);
		SetStr('DPT', Dept);

		SetStr('NATID', NatID);

		{TPerson uses this one}
		SetStr('COY',''); {set to nothing if not set above}
		SetStr('CONFOR', '');
	end;
end;


procedure TStaff.PrintLabel;
begin
	Device^.writeln(Getname(naAddress,0));
	if delspaceR(JobTitle)<>'' then Device^.writeln(JobTitle);
	if delspaceR(Dept)<>'' then Device^.writeln(Dept);
	inherited PrintLabel(Device,LabelAs);
end;



{****************************************************
 *** STREAMING                                    ***
 ****************************************************}
{THE LOAD AND STORE *MUST* MATCH, AS THE INDEX IS CALCULATED ASSUMING
RECORDS ALL OF THE SAME LENGTH. SEE ABOVE "TDatSIZE" CONSTANT TO SET
THE SIZE}
function TStaff.RecSize;
begin RecSize := inherited RecSize + 300; end;

const
	 {--- Required for Stream ----}
	 RStaff : TStreamRec = (
		 ObjType : srStaff;
		 VmtLink : Ofs(TypeOf(TStaff)^);
		 Load : @TStaff.Load;
		 Store : @TStaff.Store
	 );


function TStaff.srType;
begin srType := srStaff; end;

{------- LOAD MAIN DATA ----------}
constructor TStaff.Load;
var I : integer;
		Ver :byte;
		OldTel : string;

begin
	S.Read(Ver, 1); {stored in object}
	case Ver of
		1 : begin
			{new index/hook ptr storing, done by jimmy}
			CommonInit;

			S.Read(LockTerminal, 1);
			S.Read(Deleted, 1);

			S.Read(Dat2Idx, 32); {all located one after the other}

			S.Read(Ptr2History, 12);

			S.Read(AddressID, 4);

			DOReg.Load(S);


			{Surname/Forename also stored in index}
			Surname  := S.ReadStr;
			ForName  := S.ReadStr;
			Title    := S.ReadStr;
			Alias		 := S.ReadStr;

			JobTitle := S.ReadStr;
			Dept := S.ReadStr;

			for I := 1 to 4 do OldTel := S.ReadStr;

			CategoryCodes := S.ReadStr;

			NatID := S.ReadStr;

			Ptr2Contacts := -1;
			Ptr2Accounts := -1;
		end;
		2 : begin
			{added ptr2contacts & accounts to directoryitem}
			inherited Load(S);

			{Surname/Forename also stored in index}
			Surname  := S.ReadStr;
			ForName  := S.ReadStr;
			Title    := S.ReadStr;
			Alias		 := S.ReadStr;

			JobTitle := S.ReadStr;
			Dept := S.ReadStr;

			for I := 1 to 4 do OldTel := S.ReadStr;

			CategoryCodes := S.ReadStr;

			NatID := S.ReadStr;
		end;
		3 : begin
			{v4.2 moved tels to address}
			inherited Load(S);

			Surname  := S.ReadStr;
			ForName  := S.ReadStr;
			Title    := S.ReadStr;
			Alias		 := S.ReadStr;

			JobTitle := S.ReadStr;
			Dept := S.ReadStr;

			CategoryCodes := S.ReadStr;

			NatID := S.ReadStr;
		end;
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not recognised'#13#10'Loading Staff',mfError,hcInternalErrorMsg);
		fail;{}
	end; {case}
end; {proc}

{-------- STORE MAIN DATA ----------}
procedure TStaff.StoreFields;
var I : integer;
		Ver : byte;

begin
	Ver := 3; S.Write(Ver, 1);

	inherited StoreFields(S);

	S.WriteStr(@Surname);
	S.WriteStr(@ForName);
	S.WriteStr(@Title);
	S.WriteStr(@Alias);

	S.WriteStr(@JobTitle);
	S.WriteStr(@Dept);

	S.WriteStr(@CategoryCodes);

	S.WriteStr(@NatID);
end;


{----- Indexing -------}
{same as tperson}
function TStaff.GetIndexKey;
begin
	GetIndexKey := '';
	case ixType of
		1,ixArchive :	GetIndexKey := ucase(delspaceR(PadSpaceR(SurName, 30) + ForName));  {Sort by person name}
		2 					: GetIndexKey := ucase(delspaceR(Alias));
		{category subindexes}
		3,4,5,6,7		: if WordNo(GetCategories, ixType-2)<>'' then
										GetIndexKey := SetLength(WordNo(GetCategories, ixType-2),3)
											+GetIndexKey(1);
	end;
end;

function TStaff.GetCategories;
begin
	if pos('STA', CategoryCodes)=0 then
		GetCategories := 'STA '+CategoryCodes
	else
		GetCategories := CategoryCodes;
end;

{***************************************************************************
 ***                EDIT Staff                                          ***
 ***************************************************************************}
procedure TStaff.MakeEditBox;
var R : TRect;
		SurLine : PView;
begin
	{Create box}
	R.Assign(0, 0, 68, 19); {Size of box}
	CentreOnView(R, Caller);
	EditBox := New(PJimmyEditBox, Init(R, 'Staff Registration',Caller, @Self));

	with EditBox^ do begin
		inherited MakeEditBox(EditBox,Caller);

		SurLine := InsTitledBox(  11, 1,  20, 1, 'S~u~rname',30); {Sizeof(SurName)-1); {}
		PInputELine(Current)^.MustInput := True; {Force entry}
		{special case - to prevent users from changing supervisor user}
		{$IFDEF kusers} if ucase(Surname)=SuperUserName then Current^.Setstate(sfDisabled, true); {$ENDIF}
		InsTitledBox(  11, 2,  20, 1, 'Forname', 25); {Sizeof(ForName)-1); {}
		InsTitledBox(  11, 3,  10, 1, 'Title',   10); {Sizeof(Title)-1   ); {}

		InsTitledBox(  41, 1,   3, 1, 'A~l~ias',   3);
		PInputELine(Current)^.UpperCase := True;
		InsTitledBox(  41, 2,  21, 1, '~J~ob Ttle',     30);
		InsTitledBox(  41, 3,  21, 1, 'Dept',  30);

		{Address}
		Insert(New(PInputAddress, init(2,5, @Self, True)));

		InsTitledField(41,10,  20, 1, 'Nat ID', New(PInputELine, init(R, 20)));

		InsTitledField(11,12,  38, 1, '~S~earch',   New(PInputSCLine, init(R, 10, scDirectoryCategory)));

		{more about list}
		R.XYLD(11, 14, 40, 4); Insert(New(PDlgHookView,	Init(R, lsMoreAbout, 0, hkMore, @Self, PJimmyEditBox(EditBox))));
		AddLabel('~N~otes', Current);
		PHookViewer(Current)^.SetFocusKey(kbMore);
		Insert(PHookViewer(Current)^.VScrollBar);

		{Other/More About}
{		Insert(New(PHookListButton, init(18,Size.Y-3,'~N~otes',
																cmNone, bfNormal, @Self, hkMore, lsMoreAbout)));

		{History}
		Insert(New(PHookListButton, init(Size.X-12,Size.Y-7,'~H~istory',
																cmNone, bfNormal, @Self, hkHistory, lsHistory)));

		{OK/Cancel}
		Insert(New(PJimmyOKButton, 			init(Size.X-12,Size.Y-5, @Self)));
		Insert(New(PJimmyCancelButton, 	init(Size.X-12,Size.Y-3, @Self)));
	end;

	SurLine^.Focus;

end;

procedure TStaff.PrintLine;
var S : string;
		TruckID : longint;
		Add : PAddress;

begin
	S := SetLength(GetName(naReport, 30),30);

	{$IFDEF krongai}
	if (pos('DRI', CategoryCodes)>0) or (pos('TB', CategoryCodes)>0) then begin
		S := S + Setlength(NatID,20);
		{get usual truck}
		FileAdmin(fiHooks)^.LogOn;
		TruckID := HookFIle^.FindFirst(Ptr2More, srTractor);
		FileAdmin(fiHooks)^.LogOff;
		S := S + GetJimmyIDName(TruckID,naFull,0);
	end else begin
	{$ENDIF}
		S := S + GetTelNum(1)+' ';
		Add := PAddress(GetJimmy(AddressID));
		if Add<>nil then begin
			S := S+Add^.Town;
			dispose(Add, done);
		end;

	{$IFDEF krongai}
	end;
	{$ENDIF}

	Device^.writeln(S);
end;



{******************************************
 ***         CREATORS                   ***
 ******************************************}

function NewStaff(P : pointer) : pointer; far;
begin NewStaff := New(PStaff, init); end;

{function NewStaffIndex : PStream; far;
begin NewStaffIndex := New(PIndexedJimmyStream, init('Staff.IDX',TDirectoryIndexSize)); end;{}

{procedure StartStaffList; far;
var Bounds : TRect;
		List : PDirectoryListView;
begin
	Desktop^.GetExtent(Bounds);

	List := New(PDirectoryListView, Init(Bounds, lsStaff, fiStaffIdx,''));

	Desktop^.Insert(New(PIndexedJimmyListWindow, init(Bounds, 'Staff List', List)));
end;


{******************************************
 ***         UNIT INSTALLATION          ***
 ******************************************}
{unit initialisation procedure}
begin
{$IFDEF fixit} writeln('Staff...'); {$ENDIF}
	RegisterType(RStaff);{}

	RegisterCreator(cmNewStaff, NewStaff);

	{$IFDEF kstaff} {might have just users}
	RegisterNewWithList(lsDirectory, '~S~taff', cmNewStaff);{}
	{$ENDIF}

{	NewFileAdmin(fiStaffIdx, 'Staff Index',NewStaffIndex);{directory sublist STA}

{	RegisterTask(DesktopTasks, cmNewStaffList, @StartStaffList);{}
end.


