{*********************************************************************
 ***                                                               ***
 ***                                                               ***
 ***                   RONGAI WORKSHOPS (DELIVERY/ETC)             ***
 ***                                                               ***
 ***                                                               ***
{*********************************************************************}
{provides invoice/order items suitable for Rongai workshops, Nakuru, Kenya}
{$I compflgs}
unit KRongOrd;

INTERFACE

uses views, files, multcurr, dattime, scodes,
		forms, devices,
		dialogs,
		jimprint,
		ordproc, tuiedit, global, jimmys;


type
	{----- Quantity Order  ---------------}
	PQtyRongaiOrderItem = ^TQtyRongaiOrderItem;
	TQtyRongaiOrderItem = object(TOrderItem)

		Ptr2DiaryIdx : longint;
		Date : TDate;

		CustRef : string[10];

		TakeFrom : longint; {depot address}
		TakeTo : longint;   {depot address}
		Destination : string[10]; {eg UK, New York, New York, etc}

		{for xport}
		ContainerType : string[10];
		Qty : byte;
		Ship : longint; {for export}

		Goods : TSCode;
		Rate : TMoney;
		WeightQty : string[10];

		OutstandingNumCont : byte;
		OutstandingWt : integer;

		constructor Init(Param : PJimmyInitParam);
		procedure CommonInit; virtual;
		destructor Done; virtual;

		{--- Viewing -----}
		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;
		function GetName(naType : byte; Maxlen : integer) : string; virtual; {used for various displays/prints -{}
		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		{--- Database ----}
		function RecSize : word; virtual; {space to be reserved in jimmy file}
		function srType : word; virtual; {descendants set as fixed, so can be
																			used to identify jimmy for file operations, etc}

		procedure Storefields(var S : TDataStream); virtual;
		constructor Load(var S : TDataStream);

		{for fixit, etc}
		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}

		{--- Indexing ----}
		function NumixTypes : byte; virtual;
		procedure GetIndex(const ixType : byte; var IdxRec : Plongint; var fiType : byte); virtual;
		function GetIndexKey(const ixType : byte) : string; virtual;

		{-- Hooking to others -----}
		{change key}
		procedure GetHookTo(const htType : byte; var HookToID,SubHookToID : PLongint;
												var hkType : byte; var Key : longint; var InsertBias : boolean); virtual;

		procedure DoRepeater(const NewDate : TDate; const DeltaDays : integer); virtual;
	end;

type
	{----- Petrol invoice item - price/km/l  ---------------}
	PRongaiPetrolItem = ^TRongaiPetrolItem;
	TRongaiPetrolItem = object(TOrderItem)

		Date : TDate;

		TakeFrom : longint;
		TakeTo : longint;
		CustRef : string[10];

		Goods : TSCode;
		Rate : TMoney;
		Qty : word;
		km : word;

		constructor Init(Param : PJimmyInitParam);
		procedure CommonInit; virtual;
		destructor Done; virtual;

		{--- Viewing -----}
		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;
		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		{--- Database ----}
		function RecSize : word; virtual; {space to be reserved in jimmy file}
		function srType : word; virtual; {descendants set as fixed, so can be
																			used to identify jimmy for file operations, etc}

		procedure Storefields(var S : TDataStream); virtual;
		constructor Load(var S : TDataStream);

		{for fixit, etc}
		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}

		{-- Hooking to others -----}
		{change key}
		procedure GetHookTo(const htType : byte; var HookToID,SubHookToID : PLongint;
												var hkType : byte; var Key : longint; var InsertBias : boolean); virtual;
	end;


	{----- Rongai Delivery Note ---------------}
	PRongaiDelivery = ^TRongaiDelivery;
	TROngaiDelivery = object(TOrder)

		From : longint; {order created from, eg sales order}

		Ptr2DiaryIdx : longint;
		Ptr2DiaryInIdx : longint; {sort on stopover in date}
		Ptr2DiaryOutIdx : longint; {sort on stopover out date}

		CustRef : string[10];

		TakeFrom : longint; {depot address}
		TakeTo : longint;   {depot address}

		RongaiIn : TDate;   {stopover at Rongai}
		RongaiOut : TDate;

		Goods : TSCode;
		Qty : string[10];

		TractorID : longint;
		TrailerID : longint;
		DriverID : longint;
		TurnboyID : longint;

		ContainerID : longint;
		SealNum : string[15];

		Destination : string[10]; {eg UK, New York, New York, etc}
		ShipID : longint;
		AgentID : longint;
		ShippingCoyID : longint;
		CarrierID : longint;
		ContactID : longint;

		ReceivedDate : TDate;
		ReceivedBy : string[10];


		constructor Init(Param : PJimmyInitParam);
		procedure CommonInit; virtual;
		destructor Done; virtual;

		{--- Viewing -----}
		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;
		function GetName(naType : byte; Maxlen : integer) : string; virtual; {used for various displays/prints -{}
		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		{--- Printing ----}
		procedure PrintFull(Const Device : PDeviceStream; const PrintAs : word); virtual;
		procedure GetDefaultPrintType(var PrintType : TJimmyPrintType; var PrintAs : PSItem; var PrintAsLink : pointer); virtual;
		procedure SetFormCodes(const FormCodes: PFormCodeCollection); virtual;

		{--- Database ----}
		function RecSize : word; virtual; {space to be reserved in jimmy file}
		function srType : word; virtual; {descendants set as fixed, so can be
																			used to identify jimmy for file operations, etc}

		function PtrOffset : byte; virtual;

		procedure Storefields(var S : TDataStream); virtual;
		constructor Load(var S : TDataStream);

		{for fixit, etc}
		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}

		{--- Indexing ----}
		function NumixTypes : byte; virtual;
		procedure GetIndex(const ixType : byte; var IdxRec : Plongint; var fiType : byte); virtual;
		function GetIndexKey(const ixType : byte) : string; virtual;

		{-- Hooking to others -----}
		function NumHookTo : byte; virtual;
		procedure GetHookTo(const htType : byte; var HookToID,SubHookToID : PLongint;
												var hkType : byte; var Key : longint; var InsertBias : boolean); virtual;

		procedure OnStoreing(const DiskJImmy : PJimmy); virtual;    {extra storing method, done by storeself}
	end;


IMPLEMENTATION

uses
			krongai,
			objects,
			tasks,
			inpjimmy,
			idindex,
			kdirctry,
			tui,
			printers,
			menus,
			kdiary,
			tuimsgs,
			tuiboxes,
			notes,
			kusers,
			jimindxs,
			inpdnt,
			tuijimmy,
			app,
			minilib;

{*********************************************************************
 ***                                                               ***
 ***                     ORDER SPECIALS                            ***
 ***                                                               ***
{*********************************************************************}

constructor TQtyRongaiOrderItem.Init;
var SalesORder : POrder;
begin
	inherited Init(Param);
	Ptr2DiaryIdx := -1;
	Date.SetToToday;
	TakeFrom := -1;
	TakeTo := -1;
	Ship := -1;

	if ForOrder<>-1 then begin
		SalesOrder := POrder(GetJimmy(ForOrder));
		if SalesOrder<>nil then begin
			TakeFrom := SalesOrder^.ForWho;
			TakeTo := TakeFrom;
			dispose(SalesOrder, done);
		end;
	end;
end;

procedure TQtyRongaiOrderItem.CommonInit;
begin
	inherited COmmonInit;
	Rate.Init;
	SCodeCollection[scGoods]^.LogOn;
end;

destructor TQtyRongaiOrderItem.Done;
begin
	SCodeCollection[scGoods]^.LogOff;
	inherited Done;
end;

function TQtyRongaiORderItem.DisplayLine;
var S,SS : string;
begin
	case lsType of
		lsSalesItems : begin
			SS := ' '+PriceGroup.Price.Text(mtRound+mtSymbol+mtBlankZero);

			S := Date.Digit8 + ' ';
			if CustRef<>'' then S := S + CustRef+' ';
			if Goods<>'' then S := S + ExpandScode(scGoods, Goods)+' ';
			if WeightQty<>'' then S := S + WeightQty;
			if OutstandingWt>0 then S := S+' ('+N2Str(OutstandingWt)+') ';

			if (Qty<>0) then S := S + ContainerType+' x'+N2Str(Qty) else S := S + ContainerType;
			if OutstandingNumCOnt>0 then S := S +' ('+N2Str(OutstandingNumCont)+')';

			S := SetLength(S, maxlen-length(SS))+SS;
		end;
		lsDiary : begin
			S := 'ORDER: '+ExpandSCode(scGoods, Goods);
			if WeightQty<>'' then S := S + ' '+WeightQty;
			if OutstandingWt>0 then S:=S+' ('+N2Str(OutstandingWt)+')';
			if TakeFrom<>-1 then S := S+' From '+GetJimmyIDName(TakeFrom, naRef,0);
			if TakeTo<>-1 then S := S +' To '+GetJimmyIDName(TakeTo, naRef,0);
			if (Qty<>0) then SS := ContainerType+' x'+N2Str(Qty) else SS := ContainerType;
			if OutstandingNumCont>0 then SS := SS +' ('+N2Str(OutstandingNumCont)+')';

			if (Ship<>-1) then
				S := S+#13+space(9)+SS+' '+GetJimmyIDName(Ship, naDisplay, 0)
			else
				S := S+' '+SS;
		end;
	end;

	{$IFDEF fixit}
		S := S + #13+'   TEK:'+N2Str(recNo)+' DiaIdx'+N2Str(Ptr2DiaryIdx)+' ForOrder'+N2Str(ForOrder);
	{$ENDIF}

	DisplayLine := S;
end;

function TQtyRongaiOrderItem.GetName;
var S : string;
begin
	if CustRef<>'' then S := 'Order '+CustRef+': ' else S := 'Order: ';

	if delspaceR(ContainerType)<>'' then
		if Qty<>0 then
			S := S + ContainerType+' x'+N2Str(Qty)+' ('+N2Str(OutstandingNumCont)+') '
		else
			S := S + ContainerType+' ';

	S := S + ExpandScode(scGoods, Goods)+' '+WeightQty;

	if naType = naFull then begin
		S := S + ' '+GetJimmyIDName(TakeFrom, naRef, 0)+' To '+GetJimmyIDName(TakeTo, naRef,0);
	end;

	GetName := S;
end;

procedure TQtyRongaiORderItem.DoRepeater;
begin
	inherited DoRepeater(NewDate,DeltaDays);
	{reset outstanding}
	OutstandingNumCont := Qty;
	OutstandingWt := S2Num(WeightQty);
	Date.AddDays(DeltaDays);
end;

{**************************************************
 ***             EDIT BOX                       ***
 **************************************************}
const
	svRate = 1;
	svWtQty = 2;
	tvOrderGroup = 1;

procedure LinkPrice(const Linker : PInputLinker; const CallingView : PView); far;
var Rate : TMoney;
		WtQty : string;
		SR : Single;
		Price : TMoney;
begin
	PInputMoney(Linker^.SourceView[svRate])^.GetData(Rate);
	PInputELine(Linker^.SourceView[svWtQty])^.GetData(WtQty);

	SR := S2Real(WtQty);
	Rate.MultiplyBy(SR);

	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.SetData(Rate);
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.DrawView;
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.ForceLink;
end;

const
	svNumCont = 3;
	tvNumCont = 1;
	tvWt = 2;

procedure LinkOutstanding(const Linker : PInputLinker; const CallingView : PView); far;
var NumCont : byte;
		Wt : word;
		WtQty : string;
begin
	Linker^.SourceView[svWtQty]^.GetData(WtQty); Wt := S2Num(WtQty);
	Linker^.SOurceView[svNumCont]^.GetData(NumCont);

	Linker^.TargetView[tvWt]^.SetData(Wt); Linker^.TargetView[tvWt]^.DrawView;
	Linker^.TargetView[tvNumCont]^.SetData(NuMCont); Linker^.TargetView[tvNumCont]^.DrawView;
end;

procedure TQtyRongaiOrderItem.MakeEditBox;
var	R: TRect;
		PriceLinker, ScodeLinker, OutLinker : PINputLinker;
		Dateline : PView;

begin
	R.Assign(0, 0, 45, 21);
	CentreOnView(R, Caller);
	EditBox := New(PJimmyEditBox, Init(R, 'Qty Transport',Caller, @Self));

	New(ScodeLinker, init(nil, EditBox));
	New(PriceLinker, init(@LinkPrice, EditBox));
	New(OutLinker, init(@LinkOutstanding, EditBox));

	with EditBox^ do begin

		Insert(New(PSkipBytes, init(Sizeof(TJimmy))));

		{from/following/order buttons}
		Insert(New(PAccessJimmyButton, init(13, Size.Y-3, '~O~rder', 0,@Self))); {owning order}
		Insert(New(PSkipBytes, init(4))); {parent item id}
		Insert(New(PAccessJimmyButton, init(23, Size.Y-5, 'Trail '#17, 0,@Self))); {from}
		Insert(New(PAccessJimmyButton, init(23, Size.Y-3, 'Trail '#16, 0,@Self))); {following}

{		Insert(New(PSKipBytes, init(2))); {skip OPsrtype}

		Insert(New(PInputPriceGroup, init(2,15, EditBox))); {for prices, vat, etc}
		PriceLinker^.SetTargetView(Current, tvOrderGroup);

		Insert(New(PSKipBytes, init(sizeof(TSCode)))); {skip nomcat}

		{-- Buttons --}
{		if (ForOrder<>-1) and (RecNo<>-1) then Insert(New(PItemToOrderButton, init(22,Size.Y-3, '~O~rder', @Self)));{}
		Insert(New(PJimmyOKButton, Init(33,Size.Y-5, @Self)));
		Insert(New(PjimmyCancelButton, init(33,Size.Y-3, @Self)));
		{put here so that smoothe flow from qty below to inputpricegroup}

		Insert(New(PSKipBytes, init(4))); {skip diary index pointer}

		DateLine := InsTitledField(12,  1,10, 1, '~D~ate', New(PinputDate, init(R)));
		InsTitledField(12,  2,10, 1, 'Cust ~R~ef', New(PInputELine, init(R, 10)));

		InsTitledField(12,  4,30, 1, '~F~rom',  New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));
		InsTitledField(12,  5,30, 1, '~T~o',  New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));

		InsTitledField(12,  6,10, 1, 'D~e~st', 	New(PInputELine, init(R, 10)));

		InsTitledField(12,  7,10, 1, 'C~o~ntainer', New(PInputELine, init(R, 10)));
		InsTitledField(12,  8, 3, 1, 'Qty', New(PInputByte, init(R, 3)));
		OutLinker^.SetSourceView(Current, svNumCont);
		InsTitledField(12,  9,30, 1, '~S~hip', New(PInputIndexedJimmy, init(R, 30, fiShipIdx, lsShips, '')));

		InsTitledField(12, 11,30, 1, '~G~oods', New(PInputScode, init(R, scGoods)));
		SCodeLinker^.SetSourceView(Current, 1);
		InsTitledField(12, 12,10, 1, 'R~a~te',  New(PInputSCodePrice, init(R)));
		ScodeLinker^.SetTargetView(Current, 1);
		PriceLinker^.SetSourceView(Current, svRate);
		InsTitledField(12, 13,10, 1, '~Q~ty', 	New(PInputELine, init(R, 10)));
		PriceLinker^.SetSourceView(Current, svWtQty);
		OutLinker^.SetSourceView(Current, svWtQty);

		{outstanding}
		InsTitledField(20,  8, 3, 1, '', New(PinputByte, init(R, 3)));
		Current^.SetState(sfDisabled, True);
		OutLinker^.SetTargetView(Current, tvNumCont);
		InsTitledField(25, 13, 5, 1, '', New(PinputWord, init(R, 6)));
		Current^.SetState(sfDisabled, True);
		OutLinker^.SetTargetView(Current, tvWt);

		EndInit;

		DateLine^.Focus;
	end;
end;

{*****************************************
 ***     STREAMING DEFINITIONS         ***
 *****************************************}

const
	{--- Required for Stream ----}
	RQtyRongaiOrderItem : TStreamRec = (
		ObjType : srRongaiQtyOrderItem;
		VmtLink : Ofs(TypeOf(TQtyRongaiOrderItem)^);
		Load : @TQtyRongaiOrderItem.Load;
		Store : @TQtyRongaiOrderItem.Store
	);

function TQtyRongaiOrderItem.RecSize;
begin RecSize := 100; end;

function TQtyRongaiOrderItem.srType;
begin srType := srRongaiQtyOrderItem; end;


constructor TQtyRongaiOrderItem.Load(var S : TDataStream);
var	Ver : byte;

begin
	S.Read(Ver, 1);

	case Ver of
		1 : begin
			inherited Load(S);

			Date.Load(S);

			S.Read(TakeFrom, 4);
			S.Read(TakeTo, 4);

			Destination := S.ReadStr;

			S.Read(Goods, 4);
			Rate.Load(S);
			WeightQty := S.ReadStr;

			S.Read(Ship, 4);
			ContainerType := S.REadStr;
			CustRef := S.REadStr;
			S.Read(Qty, 1);

			S.Read(OutstandingNumCont, 1);
			S.Read(OutstandingWt, 2);
		end;
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not understood'#13#10'TQtyRongaiOrderItem.Load',mfError,hcNoContext);
		fail;
	end;
end;

procedure TQtyRongaiOrderItem.StoreFields(var S : TDataStream);
var	Ver : byte;

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

	inherited StoreFields(S);

	Date.Store(S);

	S.Write(TakeFrom, 4);
	S.Write(TakeTo, 4);

	S.WriteStr(@Destination);
	S.Write(Goods, 4);
	Rate.Store(S);
	S.WriteStr(@WeightQty);

	S.Write(Ship, 4);
	S.Writestr(@ContainerType);
	S.WriteStr(@CustRef);

	S.Write(Qty, 1);

	S.Write(OutstandingNumCont, 1);
	S.Write(OutstandingWt, 2);
end;

{****************************************************
 ***               POINTERS TO OTHER JIMMYS       ***
 ****************************************************}
function TQtyRongaiOrderItem.NumIDs;
begin
	NumIDs := 7;
end;

function TQtyRongaiOrderItem.GetJImmyID;
begin
	case jiType of
		5 : GetJimmyID := @TakeFrom;
		6 : GetJimmyID := @TakeTo;
		7 : GetJimmyID := @Ship;
	else
		GetJimmyID := inherited GetJImmyID(jiType);
	end;
end;

{**************************************
 ***       DATABASE                 ***
 **************************************}
function TQtyRongaiOrderItem.NumixTypes;
begin NumixTypes := 1; end;

procedure TQtyRongaiOrderItem.GetIndex;
begin
	inherited GetIndex(ixType, IdxRec, fiType);

	case ixType of
		1 : begin IdxRec := @Ptr2DiaryIdx; fiType := fiDiaryToDoIdx; end;
	end;
end;

function TQtyRongaiOrderItem.GetIndexKey;
begin
	GetIndexKey := '';
	case ixType of
		1 :	if (OutstandingNumCont>0) or (OutstandingWt>0) then
					GetIndexKey := Date.AsKey+space(4)+PakLint(TakeFrom)+PakLint(TakeTo);{}
	end;
end;

procedure TQtyRongaiOrderItem.GetHookTo;
begin
	inherited GetHookTo(htType, HookToID,SubHookToID, hkType, Key, InsertBias);

	if Date.Blank then
		Key := 1   {appear in line with non-dated items - paymentnode uses 0 to make sure it appears at start}
	else
		Key := Date.Days; {date order}
end;


{*********************************************************************
 ***                                                               ***
 ***                   PETROL INVOICE ITEM                         ***
 ***                                                               ***
{*********************************************************************}

constructor TRongaiPetrolItem.Init;
var SalesORder : POrder;
begin
	inherited Init(Param);
	Date.SetToToday;
	TakeFrom := -1;
	TakeTo := -1;
end;

procedure TRongaiPetrolItem.CommonInit;
begin
	inherited COmmonInit;
	Rate.Init;
	SCodeCollection[scGoods]^.LogOn;
end;

destructor TRongaiPetrolItem.Done;
begin
	SCodeCollection[scGoods]^.LogOff;
	inherited Done;
end;

function TRongaiPetrolItem.DisplayLine;
var S,SS : string;
begin
	case lsType of
		lsSalesItems : begin
			SS := inherited DisplayLine(ListFOrWho, lsType, Maxlen, View);

			S := Date.Digit8 + ' ';
			if Goods<>'' then S := S + ExpandScode(scGoods, Goods)+' ';
			if Qty<>0 then S := S + N2Str(Qty)+'l ';
			if km<>0 then S := S + N2Str(km)+'km ';

			S := SetLength(S, maxlen-length(SS))+SS;
		end;
	end;

	DisplayLine := S;
end;


{**************************************************
 ***             EDIT BOX                       ***
 **************************************************}
const
	svPetrolRate = 1;
	svPetrolQty = 2;
	svPetrolKm = 3;
{	tvOrderGroup = 1;{}

procedure LinkPetrolPrice(const Linker : PInputLinker; const CallingView : PView); far;
var Rate : TMoney;
		Qty,km : word;
		SR : Single;
		Price : TMoney;
begin
	PInputMoney(Linker^.SourceView[svPetrolRate])^.GetData(Rate);
	PInputWord(Linker^.SourceView[svPetrolQty])^.GetData(Qty);
	PInputWord(Linker^.SourceView[svPetrolkm])^.GetData(km);

	if (Qty<>0) then Rate.MultiplyBy(Qty); {if left blank, copy as fixed rate}
	if (km<>0) then Rate.MultiplyBy(km); {if left blank, copy as fixed rate}

	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.SetData(Rate);
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.DrawView;
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.ForceLink;
end;

procedure TRongaiPetrolItem.MakeEditBox;
var	R: TRect;
		PriceLinker, Linker : PINputLinker;
		Dateline : PView;

begin
	R.Assign(0, 0, 45, 16);
	CentreOnView(R, Caller);
	EditBox := New(PJimmyEditBox, Init(R, 'Petrol Transport',Caller, @Self));

	New(Linker, init(nil, EditBox));
	New(PriceLinker, init(@LinkPetrolPrice, EditBox));

	with EditBox^ do begin

		Insert(New(PSkipBytes, init(Sizeof(TJimmy))));

		Insert(New(PSKipBytes, init(16))); {skip from, following, etc}

		Insert(New(PInputPriceGroup, init(2,11, EditBox))); {for prices, vat, etc}
		PriceLinker^.SetTargetView(Current, tvOrderGroup);

		Insert(New(PSkipBytes, init(sizeof(TSCode)))); {skip nom cat}

		{-- Buttons --}
		if (ForOrder<>-1) and (RecNo<>-1) then Insert(New(PItemToOrderButton, init(23,Size.Y-3, '~O~rder', @Self)));
		Insert(New(PJimmyOKButton, Init(33,Size.Y-5, @Self)));
		Insert(New(PjimmyCancelButton, init(33,Size.Y-3, @Self)));
		{put here so that smoothe flow from qty below to inputpricegroup}

		DateLine := InsTitledField(12,  1,10, 1, '~D~ate', New(PinputDate, init(R)));

		InsTitledField(12,  3,30, 1, '~F~rom', New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));
		InsTitledField(12,  4,30, 1, '~T~o', New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));

		InsTitledField(12,  5,10, 1, '~R~ef', New(PInputELine, init(R, 10)));

		InsTitledField(12,  7,30, 1, '~G~oods', New(PInputScode, init(R, scGoods)));
		Linker^.SetSourceView(Current, 1);
		InsTitledField(12,  8, 9, 1, 'R~a~te',  New(PInputSCodePrice, init(R)));
		Linker^.SetTargetView(Current, 1);
		PriceLinker^.SetSourceView(Current, svPetrolRate);
		InsTitledField(12,  9, 9, 1, '~Q~ty', 	New(PInputWord, init(R, 9)));
		PriceLinker^.SetSourceView(Current, svPetrolQty);
		InsTitledField(12, 10, 9, 1, 'k~m~', 	New(PInputWord, init(R, 9)));
		PriceLinker^.SetSourceView(Current, svPetrolkm);

		EndInit;

		DateLine^.Focus;
	end;
end;

{*****************************************
 ***     STREAMING DEFINITIONS         ***
 *****************************************}

const
	{--- Required for Stream ----}
	RRongaiPetrolItem : TStreamRec = (
		ObjType : srRongaiPetrolItem;
		VmtLink : Ofs(TypeOf(TRongaiPetrolItem)^);
		Load : @TRongaiPetrolItem.Load;
		Store : @TRongaiPetrolItem.Store
	);

function TRongaiPetrolItem.RecSize;
begin RecSize := 100; end;

function TRongaiPetrolItem.srType;
begin srType := srRongaiPetrolItem; end;


constructor TRongaiPetrolItem.Load(var S : TDataStream);
var	Ver : byte;

begin
	S.Read(Ver, 1);

	case Ver of
		1 : begin
			inherited Load(S);

			Date.Load(S);

			S.Read(TakeFrom, 4);
			S.Read(TakeTo, 4);
			CustREf := S.REadStr;

			S.Read(Goods, 4);
			Rate.Load(S);
			S.Read(Qty,2);
			S.Read(km, 2);
		end;
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not understood'#13#10'TRongaiPetrolItem.Load',mfError,hcNoContext);
		fail;
	end;
end;

procedure TRongaiPetrolItem.StoreFields(var S : TDataStream);
var	Ver : byte;

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

	inherited StoreFields(S);

	Date.Store(S);

	S.Write(TakeFrom, 4);
	S.Write(TakeTo, 4);
	S.WriteStr(@CustRef);

	S.Write(Goods, 4);
	Rate.Store(S);
	S.Write(Qty, 2);
	S.Write(km, 2);
end;

{****************************************************
 ***               POINTERS TO OTHER JIMMYS       ***
 ****************************************************}
function TRongaiPetrolItem.NumIDs;
begin
	NumIDs := 6;
end;

function TRongaiPetrolItem.GetJImmyID;
begin
	case jiType of
		5 : GetJimmyID := @TakeFrom;
		6 : GetJimmyID := @TakeTo;
	else
		GetJimmyID := inherited GetJImmyID(jiType);
	end;
end;

{**************************************
 ***       DATABASE                 ***
 **************************************}
procedure TRongaiPetrolItem.GetHookTo;
begin
	inherited GetHookTo(htType, HookToID,SubHookToID, hkType, Key,InsertBias);

	if Date.Blank then
		Key := 1   {appear in line with non-dated items - paymentnode uses 0 to make sure it appears at start}
	else
		Key := Date.Days; {date order}
end;

{*********************************************************************
 ***                                                               ***
 ***                     DELIVERY NOTE                             ***
 ***                                                               ***
{*********************************************************************}

constructor TRongaiDelivery.Init;
var Focused : PJimmy;
		Order : POrder;
begin
	inherited Init(Param);

{$IFDEF kuser} {if CUrrentUser<>nil then ByWho := CurrentUser^.RecNo;{} {$ENDIF}

	From := -1;
	Ptr2DiaryIdx := -1;
	Ptr2DiaryInIdx := -1;
	Ptr2DiaryOutIDx := -1;
	TakeFrom := ForWho;
	TakeTo := ForWho;
	ROngaiIn.Clear;
	RongaiOut.Clear;
	DriverID := -1;
	TractorID := -1;
	TrailerID := -1;
	TurnBoyID := -1;
	ShipID := -1;
	ContainerID := -1;

	AgentID := -1;
	ShippingCoyID := -1;
	CarrierID := -1;
	ContactID := -1;

	{now, if Param.FOcused is set on a sales order, we ought to be able to
	pre-fill most of the fields.}
	if (Param<>nil) then begin

		if (Param^.FocusedID<>-1) then begin
			Focused := GetJimmy(Param^.FocusedID);
			if typeof(Focused^)=typeof(TQtyRongaiOrderItem) then begin
				{rongai order item (ie Diary), so  copy fields}
				From := Param^.FocusedID;

				Date.SetToDate(PQtyRongaiOrderItem(Focused)^.Date);
				CustRef := PQtyRongaiOrderItem(Focused)^.CustRef;
				TakeFrom := PQtyRongaiOrderItem(Focused)^.TakeFrom;
				TakeTo := PQtyRongaiOrderItem(Focused)^.TakeTo;
				Destination := PQtyRongaiOrderItem(Focused)^.Destination;
				ShipID := PQtyRongaiOrderItem(Focused)^.Ship;
				Goods := PQtyRongaiOrderItem(Focused)^.Goods;
{				Rate.SetTo(PQtyRongaiOrderItem(Focused)^.Rate);{}
				Qty := PQtyRongaiOrderItem(Focused)^.WeightQty;

				Order := POrder(GetJimmy(PQtyRongaiOrderItem(Focused)^.ForOrder));
				if Order<>nil then begin
					ForWho := Order^.ForWho;
					dispose(Order, done);
				end else
					ForWho := TakeFrom;
				{and update order items "following" pointer.  Note this does
				not update if the item is on-screen...}
{	      PQtyRongaiOrderItem(Focused)^.Following := recno not set yet...}
			end;
			dispose(Focused, done);
		end;
	end;

end;


procedure TRongaiDelivery.COmmonInit;
begin
	inherited CommonINit;
{	Rate.Init;{}
	SCodeCollection[scGoods]^.LogOn;
end;

destructor TRongaiDelivery.Done;
begin
	SCodeCollection[scGoods]^.LogOff;
	inherited Done;
end;

function TRongaiDelivery.DisplayLine;
var S,SS : string;
begin
	S := 'DELIVERY #'+N2Str(ref);

	case lstype of
		lsHistory : begin
			SS := ' '+TotallerGroup.SubTotal.Text(mtRound+mtSymbol+mtBlankZero);

			S := Date.Digit8 + ' '+S+' ';
			if CustRef<>'' then S := S + CustRef+' ';
			if Goods<>'' then S := S + ExpandScode(scGoods, Goods)+' ';
			if Qty<>'' then S := S + Qty+' ';

			S := SetLength(S+GetJimmyIDName(ContainerID, naRef, 0), maxlen-length(SS))+SS;
		end;
		lsMoreAbout : begin
			S := 'CURRENT DELIVERY '+Date.Digit8+' '
							+GetJimmyIDName(TakeFrom, naRef, 0)
							+' To '+GetJimmyIDName(TakeTo, naRef,0);
		end;
		lsDiary : begin
			S := S + ' '+GetJimmyIDNAme(TractorID, naRef, 0);
			case gotbyix of
				1 : begin
					S := S+{}' '+ExpandSCode(scGoods, Goods);
					if Qty<>'' then S := S + ' '+Qty;
					if TakeFrom<>-1 then S := S+' '+GetJimmyIDName(TakeFrom, naRef,0);
					if TakeTo<>-1 then S := S +' To '+GetJimmyIDName(TakeTo, naRef,0);
					if (ShipID<>-1) then
						S := S+#13+space(9)+GetJimmyIDName(ContainerID,naRef,0)+' '+GetJimmyIDName(ShipID, naDisplay, 0)
					else
						S := S+' '+GetJimmyIDNAme(ContainerID,naRef,0);
				end;
				2 : begin
					S:= S + ' '+ExpandSCode(scGoods, Goods)+' IN From '+GetJimmyIDName(TakeFrom, naRef, 0);
				end;
				3 : begin
					S:= S + ' '+ExpandSCode(scGoods, Goods)+' OUT To '+GetJimmyIDName(TakeTo, naRef, 0);
				end;
			end;
		end;
	end;
	{$IFDEF fixit}
		S := S +#13+'   TEK: '+N2Str(RecNo)+' DiaIdx'+N2Str(Ptr2DIaryIdx)
											+' InIdx'+N2Str(Ptr2DIaryInIdx)+' OutIdx'+N2Str(Ptr2DIaryOutIdx)+' From'+N2Str(From);
	{$ENDIF}

	DisplayLine := S;
end;

function TRongaiDelivery.GetName;
begin
	GetName := 'DELIVERY #'+N2Str(Ref)+' '+Date.Digit8;
end;


{**************************************************
 ***             EDIT BOX                       ***
 **************************************************}
{const
	svRate = 1;
	svQty = 2;
	tvOrderGroup = 1;{already defined for qtyorderitem}

{procedure LinkDeliveryPrice(const Linker : PInputLinker; const CallingView : PView); far;
var Rate : TMoney;
		WtQty : string;
		SR : Single;
		Price : TMoney;
begin
	PInputMoney(Linker^.SourceView[svRate])^.GetData(Rate);
	PInputELine(Linker^.SourceView[svWtQty])^.GetData(WtQty);

	SR := S2Real(WtQty);
	Rate.MultiplyBy(SR);

	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.SetData(Rate);
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.DrawView;
	PInputPriceGroup(Linker^.TargetView[tvOrderGroup])^.PriceLine^.ForceLink;
end;{}

procedure LinkRongaiContainer(Const Linker : PInputLinker; const CallingView : PView); far;
begin
	if (PInputJimmy(CallingView)^.GetJimmy<>nil) and (PInputJImmy(CallingView)^.GetJimmy^.RecNo = 0) then begin
		{set container line to rongai container indexes}
		with PInputIndexedJimmy(Linker^.TargetView[1])^ do begin
			FileAdmin(fiType)^.logOff; {log off old index file}
			fiType := fiROngaiContainerIdx;
			FileAdmin(fiType)^.LogOn;
		end;
	end else begin
		{set container line to general container index}
		with PInputIndexedJimmy(Linker^.TargetView[1])^ do begin
			FileAdmin(fiType)^.logOff; {log off old index file}
			fiType := fiContainerIdx;
			FileAdmin(fiType)^.LogOn;
		end;
	end;
end;

procedure LinkDriver(const Linker : PInputLinker; const CallingView : PView); far;
var Tractor : PTractor;
begin
	Tractor := PTractor(PInputJImmy(CallingView)^.GetJimmy);
	if Tractor<>nil then begin
		Linker^.TargetView[1]^.SetData(Tractor^.Driver);
		Linker^.TargetView[1]^.DrawView;
	end;
end;


procedure LinkRongaiDates(const Linker : PInputLinker; const CallingView : PView); far;
var Date : TDate;
begin
	CallingView^.GetData(Date);
	if not Date.Blank then begin
		Date.AddDay(True);
		Linker^.TargetView[1]^.SetData(Date);
		Linker^.TargetView[1]^.DrawView;
	end;
end;




procedure TRongaiDelivery.MakeEditBox;
var	R: TRect;
{		PriceLinker,{} RDateLinker, ContainerLinker, {Linker,{}DriverLinker : PINputLinker;
		RecDateLine, ForLine, DestLine, Dateline,TractorLine : PView;

begin
	R.Assign(0, 0, 65, 23);
	CentreOnView(R, Caller);
	EditBox := New(PJimmyEditBox, Init(R, 'Delivery Order',Caller, @Self));

{	New(Linker, init(nil, EditBox));{}
	New(ContainerLinker, init(@LinkROngaiContainer, EditBox));
	New(DriverLinker, init(@LinkDriver, EditBox));{}
	New(RDateLinker, init(@LinkRongaiDates, EditBox));

	with EditBox^ do begin
		Insert(New(PSkipBytes, init(Sizeof(TJimmy))));

		{Trail back button}
		Insert(New(PSkipBytes, init(4+sizeof(TDate)+1+sizeof(TTotallerGroup))));

		{-- Buttons --}
		Insert(New(PJimmyOKButton, Init(43,Size.Y-3, @Self)));
		Insert(New(PjimmyCancelButton, init(53,Size.Y-3, @Self)));


		InsTitledField(12,  1, 5, 1, 'Ref', New(PInputRefNum, init(R,5, srRongaiDelivery)));
		Insert(New(PSkipBytes, init(4))); {oldref}
		DateLine := InsTitledField(25, 1,10, 1, '~D~ate', New(PinputDate, Init(R)));

		ForLine := InsTitledField(12,  3,25, 1, '~F~or',  New(PInputDirectory, init(R, 30,  fiFullDirIdx, lsDirectory,'')));
		PInputELine(ForLine)^.MustInput := True;

		Insert(New(PSkipBytes, init(sizeof(PString)))); {skip forwhoref}
		Insert(New(PSkipBytes, init(4))); {skip bywho}

		Insert(New(PSkipBytes, init(Sizeof(PFreeTextData)))); {skip notes}

		InsTitledField(12, 4, 20, 1, 'Order', New(PInputJimmy, init(R, 20, 0)));
		Current^.SetState(sfDisabled, True);

		Insert(New(PSKipBytes, init(12))); {skip  ptr2diaryidx's}

		InsTitledField(44, 3, 7, 1, '~R~ef', New(PInputELine, init(R,10)));

		{it's a from line not button at the moment}
{		Insert(New(PJimmyButton, init(33, Size.Y-3, 'Trail '#17, bfNormal, 0)));{}

		InsTitledField(12, 5,27, 1, 'Fro~m~',  New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));
		ContainerLinker^.SetSourceView(Current,1);
		PInputELine(Current)^.MustInputToClose := True;
{		if From<>-1 then Current^.SetState(sfDisabled, True); {if working from order item, must do as it said}

		InsTitledField(12, 6,27, 1, 'To', 		New(PInputDirectory, init(R, 30, fiFullDirIdx, lsDIrectory, '')));
		PInputELine(Current)^.MustInputToClose := True;{}
{		if From<>-1 then Current^.SetState(sfDisabled, True); {if working from order item, must do as it said}

		InsTitledField(12, 7,10, 1, 'Ro~n~gai In', New(PinputDate, init(R)));
		RDateLinker^.SetSourceView(Current, 1);
		InsTitledField(29, 7,10, 1, 'Out', New(PinputDate, init(R)));
		RDateLinker^.SetTargetView(Current, 1);

		InsTitledField(12, 9,27, 1, '~G~oods', New(PInputScode, init(R, scGoods)));
{		Linker^.SetSourceView(Current, 1);{}
{		InsTitledField(12,10,10, 1, 'Rate',  New(PInputSCodePrice, init(R)));
		Linker^.SetTargetView(Current, 1);
{		PriceLinker^.SetSourceView(Current, svRate);{}
		InsTitledField(12,11,10, 1, '~Q~ty', 	New(PInputELine, init(R, 10)));
{		PriceLinker^.SetSourceView(Current, svWtQty);{}

		InsTitledField(12,13,20, 1, '~T~ractor',  New(PInputIndexedJimmy, init(R, 25, fiVehicleIdx, lsVehicles, '')));
		TractorLine := Current;
		DriverLinker^.SetSourceView(Current,1);
		InsTitledField(12,14,20, 1, 'Trailer',  New(PInputIndexedJimmy, init(R, 25, fiVehicleIdx, lsVehicles, '')));
		InsTitledField(12,15,20, 1, 'Dri~v~er',  New(PInputDirectory, init(R, 25, fiCatDirIdx, lsDirectory, 'DRI')));
		DriverLinker^.SetTargetView(Current,1);
		InsTitledField(12,16,20, 1, 'T~u~rnboy',  New(PInputDirectory, init(R, 25, fiCatDirIdx, lsDirectory, 'TB ')));

		InsTitledField(12,17,17, 1, 'C~o~ntainer',  New(PInputIndexedJimmy, init(R, 20, fiContainerIdx, lsContainers, '')));
		COntainerLinker^.SetTargetView(Current,1);
		InsTitledField(12,18,15, 1, '~S~eal #',  New(PInputELine, init(R, 15)));

		{export stuff}
		DestLine := InsTitledField(42,13,10, 1, 'Dest.', New(PInputELine, init(R,10)));
		InsTitledField(42,14,20, 1, 'S~h~ip', New(PInputIndexedJimmy, init(R, 25, fiShipIdx, lsShips, '')));
		InsTitledField(42,15,20, 1, '~A~gent', New(PInputDirectory, init(R, 25, fiCatDirIdx, lsDirectory, 'AGE')));
		InsTitledField(42,16,20, 1, 'Shipper', New(PInputDirectory, init(R, 25, fiFullDirIdx, lsDirectory, '')));
		InsTitledField(42,17,20, 1, 'Carrier', New(PInputDirectory, init(R, 25, fiFullDirIdx, lsDirectory, '')));
		InsTitledField(42,18,20, 1, 'Contact', New(PInputDirectory, init(R, 25, fiFullDirIdx, lsDirectory, '')));

		{received details}
		RecDateLine := InsTitledField(12,20,10, 1, 'R~e~ceived', New(PinputDate, Init(R)));
		InsTitledField(28,20, 9, 1, 'B~y~',  New(PInputELine, init(R, 10)));{}

		EndInit;

		if (delspaceR(Goods)<>'') and (TractorID=-1) then {data already entered, probably from sales order}
			if Qty='' then
				DestLine^.Focus
			else
				TractorLine^.Focus
		else
			if DriverID<>-1 then
				recDateLine^.Focus {driver entered - so focus on received/signed by}
			else
				DateLine^.Focus;
	end;
end;

{*****************************************
 ***     STREAMING DEFINITIONS         ***
 *****************************************}

const
	{--- Required for Stream ----}
	RRongaiDelivery : TStreamRec = (
		ObjType : srRongaiDelivery;
		VmtLink : Ofs(TypeOf(TRongaiDelivery)^);
		Load : @TRongaiDelivery.Load;
		Store : @TRongaiDelivery.Store
	);

function TRongaiDelivery.RecSize;
begin RecSize := 200; end;

function TRongaiDelivery.srType;
begin srType := srRongaiDelivery; end;

function TRongaiDelivery.PtrOffset;
begin PtrOffset := inherited PtrOffset + 1; end; {extra ver}

constructor TRongaiDelivery.Load(var S : TDataStream);
var	Ver : byte;
		RateDummy : TMoney; {rate no longer used}

begin
	S.Read(Ver, 1);
	RateDummy.Init;

	case Ver of
		3 : begin
			{added stopover date}
			inherited Load(S);

			CustRef := S.ReadStr;

			S.Read(Goods, 4);
			RateDummy.Load(S);
			Qty := S.ReadStr;

			S.Read(TakeFrom, 4);
			S.Read(TakeTo, 4);
			RongaiIn.Load(S);
			RongaiOut.Load(S);
			Destination := S.ReadStr;
			S.Read(ShipID, 4);

			S.Read(DriverID, 4);
			S.Read(TurnBoyID, 4);
			S.Read(TractorID, 4);
			S.Read(TrailerID, 4);

			S.Read(ContainerID, 4);
			SealNum := S.ReadStr;

			ReceivedDate.Load(S);
			ReceivedBy := S.ReadStr;

			S.Read(From, 4);

			S.Read(AgentID, 4);
			S.Read(ShippingCoyID, 4);
			S.Read(CarrierID, 4);
			S.Read(ContactID, 4);

		end;
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not understood'#13#10'TRongaiDelivery.Load',mfError,hcNoContext);
		fail;
	end;
end;

procedure TRongaiDelivery.StoreFields(var S : TDataStream);
var	Ver : byte;
		RateDummy : TMoney;

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

	inherited StoreFields(S);

	S.WriteStr(@CustRef);

	S.Write(Goods, 4);
	RateDummy.Init; RateDummy.Store(S);
	S.WriteStr(@Qty);

	S.Write(TakeFrom, 4);
	S.Write(TakeTo, 4);
	RongaiIn.Store(S);
	RongaiOut.Store(S);

	S.WriteStr(@Destination);
	S.Write(ShipID, 4);

	S.Write(DriverID, 4);
	S.Write(TurnBoyID, 4);
	S.Write(TractorID, 4);
	S.Write(TrailerID, 4);

	S.Write(ContainerID,4);
	S.WriteStr(@SealNum);

	ReceivedDate.Store(S);
	S.WriteStr(@ReceivedBy);

	S.Write(From, 4);

	S.Write(AgentID, 4);
	S.Write(ShippingCoyID, 4);
	S.Write(CarrierID, 4);
	S.WRite(ContactID, 4);
end;

{****************************************************
 ***               POINTERS TO OTHER JIMMYS       ***
 ****************************************************}
function TRongaiDelivery.NumIDs;
begin
	NumIDs := 15;
end;

function TRongaiDelivery.GetJImmyID;
begin
	case jiType of
		3 : GetJimmyID := @TakeFrom;
		4 : GetJimmyID := @TakeTo;
		5 : GetJimmyID := @ShipID;
		6 : GetJimmyID := @DriverID;
		7 : GetJimmyID := @TurnBoyID;
		8 : GetJimmyID := @TractorID;
		9 : GetJimmyID := @TrailerID;
	 10 : GetJimmyID := @ContainerID;
	 11 : GetJimmyID := @From;
	 12 : GetJimmyID := @AgentID;
	 13 : GetJimmyID := @ShippingCoyID;
	 14 : GetJimmyID := @CarrierID;
	 15 : GetJimmyID := @ContactID;
	else
		GetJimmyID := inherited GetJImmyID(jiType);
	end;
end;

{**************************************
 ***       DATABASE                 ***
 **************************************}
function TRongaiDelivery.NumixTypes;
begin NumixTypes := 3; end;

function TRongaiDelivery.NumHookTo;
begin NumHookTo := 6; end;

procedure TRongaiDelivery.GetIndex;
begin
	inherited GetIndex(ixType, IdxRec, fiType);

	case ixType of
		1 : begin IdxRec := @Ptr2DiaryIdx; fiType := fiDiaryIdx; end;
		2 : begin IdxRec := @Ptr2DiaryInIdx; fiType := fiDiaryIdx; end;
		3 : begin IdxRec := @Ptr2DiaryOutIdx; fiType := fiDiaryIdx; end;
	end;
end;

function TRongaiDelivery.GetIndexKey;
begin
	GetIndexKey := '';
	case ixType of
		1: GetIndexKey := Date.AsKey+space(3)+char(0)+PakLint(Ref);
		2: if not RongaiIn.Blank then GetIndexKey := RongaiIn.AsKey+space(3)+char(1)+PakLint(ref);
		3: if not RongaiOut.Blank then GetIndexKey := RongaiOut.AsKey+space(3)+char(2)+PakLint(Ref);
	end;
end;

{hooks if current onto driver & turnboy more-about lists}
{could simply add to their histories}
procedure TRongaiDelivery.GetHookTo;
begin
	inherited GetHookTo(htType, HookToID,SubHookToID, hkType, Key,InsertBias);

	case htType of
		{1 is used by inherited for forwho history}
		2 : begin HookToID := @DriverID; 	hkType := hkHistory; end;
		3 : begin HookToID := @TurnBoyID; 	hkType := hkHistory; end;
		{for current delivery}
		4 : begin HookToID := @DriverID; if ReceivedDate.Blank then hkType := hkMore; end;
		5 : begin HookToID := @TurnBoyID;if ReceivedDate.Blank then hkType := hkMore; end;
		6 : begin HookTOID := @TakeFrom; 	hkType := hkHistory; end;
	end;
end;



{=========== ON STOREING ================}
procedure TRongaiDelivery.OnStoreing;
var Container : PContainer;
		Trailer : PTrailer;
		Tractor : PTractor;
		FromOrder : PQtyRongaiOrderItem;
		NC, Q : byte;

begin
	inherited OnStoreing(DiskJimmy);

	{if "from" set to order item, subtract from outstanding...}
	if From<>-1 then begin
		FromOrder := PQtyRongaiOrderItem(GetJimmy(From));
		if (FromOrder^.srtype=srRongaiQtyOrderItem) and (FromOrder^.TakeFrom = TakeFrom) then begin

			{if FromOrder^.Following=-1 then{} FromOrder^.Following := RecNo;

			{from a rongai qty item... subtract...}
			if DiskJimmy=nil then begin
				{if self is new, subtract one container and the qty}
				if FromOrder^.OutstandingNumCont>0 then	dec(FromOrder^.OutstandingNumCont); {one less container}
				if FromOrder^.OutstandingWt>0 then dec(FromOrder^.OutstandingWt, S2Num(Qty)); {subtract weight}
				FromOrder^.StoreSelf;
			end else begin
				{if it's been changed, just subtract the difference in weight}
				{restore prev & subtract current}
				if S2Num(PRongaiDelivery(DiskJimmy)^.Qty)<>S2Num(Qty) then begin
					FromOrder^.OutstandingWt := FromOrder^.OutstandingWt
																				+ S2Num(PRongaiDelivery(DiskJimmy)^.Qty)
																				- S2Num(Qty);
					FromOrder^.StoreSelf;
				end;
			end;

		end;
		dispose(FromOrder, done);
	end;

	{set "current" backpointers}
	Container := PContainer(GetJimmy(ContainerID));
	Trailer := PTrailer(GetJImmy(TrailerID));
	Tractor := PTractor(GetJimmy(TractorID));

	{received date not set - ie delivery still in progress}
	if ReceivedDate.Blank then begin
		{--- container - last at -----}
		if Container<>nil then Container^.LastAt := -1; {clear - in transit}
		if Tractor<>nil then Tractor^.CurrentDelivery := RecNo;
		if Trailer<>nil then Trailer^.CurrentDelivery := Recno;
	end else begin
		if Container<>nil then Container^.LastAt := TakeTo;
		if Tractor<>nil then Tractor^.CurrentDelivery := -1;
		if Trailer<>nil then Trailer^.CurrentDelivery := -1;
	end;

	if Container<>nil then begin
		Container^.StoreSelf;
		dispose(Container, done);
	end;

	if Tractor<>nil then begin
		Tractor^.StoreSelf;
		dispose(Tractor, done);
	end;

	if Trailer<>nil then begin
		Trailer^.StoreSelf;
		dispose(Trailer, done);
	end;

	{change of container - check diskjimmy for any changes and remove/clear, etc
	diskjimmy ones}
	if DiskJimmy<>nil then begin
		if PRongaiDelivery(DiskJimmy)^.COntainerID<>ContainerID then begin
			Container := PContainer(GetJimmy(PRongaiDelivery(DiskJimmy)^.ContainerID));
			if Container<>nil then begin
				Container^.LastAt := -1; {clear}
				Container^.StoreSelf;
				dispose(Container, done);
			end;
		end;

		if PRongaiDelivery(DiskJimmy)^.TractorID<>TractorID then begin
			Tractor := PTractor(GetJimmy(PRongaiDelivery(DiskJimmy)^.TractorID));
			if Tractor<>nil then begin
				Tractor^.CurrentDelivery := -1; {clear}
				Tractor^.StoreSelf;
				dispose(Tractor, done);
			end;
		end;

		if PRongaiDelivery(DiskJimmy)^.TrailerID<>TrailerID then begin
			Trailer := PTrailer(GetJimmy(PRongaiDelivery(DiskJimmy)^.TrailerID));
			if Trailer<>nil then begin
				Trailer^.CurrentDelivery := -1; {clear}
				Trailer^.StoreSelf;
				dispose(Trailer, done);
			end;
		end;
	end;
end;



{**************************************
 ***       PRINTING                 ***
 **************************************}
procedure TRongaiDelivery.SetFormCodes(const FormCodes: PFormCodeCollection);
begin
	inherited SetFormCodes(FOrmCodes);

	with FOrmCodes^ do begin
    SetStr('TYPE','DELIVERY');

		SetStr('CUSTREF', CustRef);

		Insert(New(PJimmyFormCode, init('FROM', TakeFrom)));
		Insert(New(PJimmyFormCode, init('TO', TakeTo)));

		SetDate('RIDT', RongaiIn);
		SetDate('RODT', RongaiOut);

		SetStr('GOODS', ExpandScode(scGoods, Goods));
{    SetStr('RATE'}
		SetStr('QTY', Qty);

		Insert(New(PJimmyFormCode, init('TRACTOR', TractorID)));
		Insert(New(PJimmyFormCode, init('TRAILER', TrailerID)));

		Insert(New(PJimmyFormCode, init('DRIVER', DriverID)));
		Insert(New(PJimmyFormCode, init('TURNBOY', TurnBoyID)));

		Insert(New(PJimmyFormCode, init('CONT', ContainerID)));

		SetStr('SEAL', SealNum);
		SetStr('DEST', Destination);

		Insert(New(PJimmyFormCode, init('SHIP', ShipID)));
		Insert(New(PJimmyFormCode, init('AGENT', AgentID)));
		Insert(New(PJimmyFormCode, init('SHCOY', ShippingCoyID)));
		Insert(New(PJimmyFormCode, init('CARRIER', CarrierID)));

		Insert(New(PJimmyFormCode, init('CONTACT', ContactID)));

		Insert(New(PJimmyFormCode, init('USER', CurrentUser^.RecNo)));

		SetDate('RECDT', ReceivedDate);
		SetStr('RECBY', ReceivedBy);
	end;

end;

const
	DeliveryPrintType : TJimmyPrintType =
		(Editor : edInternal;
		 Target : ptPrint;
		 DeviceName : '';
		 PrintAs : 0;
		 FormName : '';
		 NumCopies : 1;
		 PlusLabel : False);

procedure LinkDelivery(const Linker : PInputLinker; const CallingView : PView); far;
var PrintAs : word;
		NumCopies : byte;
		FormName : string;
begin
	CallingView^.GetData(PrintAs);

	case PrintAs of
		0 : begin FormName := 'LOADORDR'; NumCopies := 2; end;
		1 : begin FOrmName := 'INTERCHA'; NumCopies := 3; end;
		3 : begin FormName := 'CUSTOMS'; NumCopies := 3; end;
		4 : begin FOrmName := 'RONGENV'; NumCopies := 1; end;
	else
		FormName := 'DELIVERY';
		NumCOpies := 1;
	end;

	Linker^.TargetView[1]^.SetData(FOrmName);
	Linker^.TargetView[1]^.DrawView;

	Linker^.TargetView[2]^.SetData(NumCopies);
	Linker^.TargetView[2]^.DrawView;
end;


procedure TRongaiDelivery.GetDefaultPrintType
										(var PrintType : TJimmyPrintType; var PrintAs : PSItem; var PrintAsLink : pointer);
begin
	PrintAs := 	NewSItem('~L~oading Order',
							NewSItem('In~t~erchange',
							NewSItem('~D~elivery Note',
							NewSItem('C~u~stoms Decl',
							NewSItem('En~v~elope', nil)))));
	PrintType := DeliveryPrintType;
	PrintAsLink := @LinkDelivery;
end;


procedure TRongaiDelivery.PrintFull(const Device : PDeviceStream; const PrintAs : word);
begin

	Device^.writeln(GetJimmyIDName(TractorID,naReport,0)+' '+ExpandScode(scGoods, Goods)
			+GetJimmyIDName(DriverID, naFullInformal,0)+' & '+GetJimmyIDName(TurnBoyID, naFullInformal, 0));
end;


{**********************************
 ***     LOCATE BY ID           ***
 **********************************}
procedure FindDelivery; far;
var ID,L : longint;
		Control : word;
		Delivery : PROngaiDelivery;

begin
	L := 0;
	COntrol := InputLintBox('Find Delivery','Delivery #', L);

	if Control =cmOK then begin

		ID := GetIDPtr(srROngaiDelivery, L);

		Delivery := PROngaiDelivery(GetJimmy(ID));

		if Delivery<>nil then begin
			Delivery^.Edit(Desktop, nil);
		end else begin
			PauseMessage('FIND','No Delivery #'+N2Str(L),hcNoContext);
			FindDelivery;
		end;
	end;
end;


function CreateRongaiQtyOrderItem(P : pointer) : pointer; far;
begin CreateRongaiQtyOrderItem := New(PQtyRongaiOrderItem, init(P)); end;

function CreateRongaiPetrolItem(P : pointer) : pointer; far;
begin CreateRongaiPetrolItem := New(PRongaiPetrolItem, init(P)); end;

function CreateRongaiDelivery(P : pointer) : pointer; far;
begin CreateRongaiDelivery := New(PRongaiDelivery, init(P)); end;

begin
	{--- "Find" ----}
	RegisterTask(DesktopTasks, cmFindDelivery, @FindDelivery);

	RegisterType(RQtyRongaiOrderItem);
	RegisterType(RRongaiDelivery);
	RegisterType(RRongaiPetrolItem);

	RegisterCreator(cmNewRongaiQtyOrderitem, CreateRongaiQtyORderItem);
	RegisterCreator(cmNewRongaiPetrolItem, CreateRongaiPetrolItem);
	RegisterCreator(cmNewRongaiDelivery, CreateRongaiDelivery);

	{register objects with lists}
	RegisterNewWithList(lsSalesItems, 'Transport ~Q~ty', cmNewRongaiQtyOrderItem);
	RegisterNewWithList(lsSalesItems, '~P~etrol Transport', cmNewRongaiPetrolItem);
	RegisterNewWithList(lsHistory, '~D~elivery Order', cmNewRongaiDelivery);

	RegisterNewWithList(lsDesktop, '~D~elivery Order', cmNewRongaiDelivery);
	RegisterNewWithList(lsDiary, '~D~elivery Order', cmNewRongaiDelivery);
end.

