Simultaneous User Layout Printing and Order Saving

Task: To create a script that will simultaneously print a user layout at the cash station and save an order. The script uses a function key that runs a user selector.

Solution:

procedure ProcessOperation1001188(Parameter: integer);
begin

RK7.PerformRefObject( RK7.FindItemByCode(rkrefMaketSchemeDetails, 127) );

RK7.PostOperation(rkoSaveOrder, 0);

end;

Full Receipt Deleting

Task: To create a script that will delete fully receipts.

Solution:

procedure ProcessOperation1000522(Parameter: integer);

var it: TCheckItem;

begin

if GUI.CheckFormInPayMode then Exit;

if RK7.CashUser.ConfirmOperation(rkoCreateVoid) = False then Exit;

RK7.PerformOperation(rkoHome, 0);

while True do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TPrintCheckItem') then break;


if SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then begin

if (TDiscountItem(it).ChargeSource <> chsAuto) and (it.State = disOpened) then begin

RK7.PerformOperation(rkoDeleteLine, 1);

continue;

end;

end else if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then begin

if it.State = disOpened then begin

RK7.PerformOperation(rkoDeleteLine, 1);

continue;

end else

RKCheck.CreateCheckItem(rkrefOrderVoids, '1', FloatToStr(TDish(it).Quantity));

end;

RK7.PerformOperation(rkoDown, 0);

end;

RK7.PerformOperation(rkoCloseMode, 0);

RK7.PerformOperation(rkoPackDishes, 0);

end;

Creating the Function Key "Delete All Menu Elements from the Order" Including Tariffications But not Discounts

Task: To create a script for the button that will delete all the contents leaving only the order properties and discounts, extra charges, and prepayments. Only one delete reason should be specified for all the elements to be deleted.

Solution:

procedure ProcessOperation1000998(Parameter: integer);

var it: TCheckItem;

VoidCode, step: integer;

ed: TObject;

begin

step := 0;

if GUI.CheckFormInPayMode then Exit;

if RK7.CashUser.ConfirmOperation(rkoCreateVoid) = False then Exit;

VoidCode := -1;

ed := TObject(gui.FindComponentByName('Editor'));

if SYS.ObjectInheritsFrom(TObject(ed), 'TNumEditor') then

begin

if TNumEditor(ed).Text='' then

begin

gui.showmessage('Deletion reason code not indicated!');

Exit;

end

else

VoidCode := StrToInt(TNumEditor(ed).Text);

end;

if VoidCode<0 then Exit;


RK7.PerformOperation(rkoHome, 0);

while step< RKCheck.CurrentOrder.Sessions.LinesCount do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TPrintCheckItem') then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then

begin

if it.State = disOpened then begin

// dbg.dbgprint('delete dish');

RK7.PerformOperation(rkoDeleteLine, 1); // deletion

continue;

end else

begin

// dbg.dbgprint('void dish');

RKCheck.CreateCheckItem(rkrefOrderVoids, IntToStr(VoidCode), FloatToStr(TDish(it).Quantity)); // write-off

end;

end;

// dbg.dbgprint('move down');

step := step + 1;

RK7.PerformOperation(rkoDown, 0);

end;

end;

Creating Free Dish Special Offer for Workdays If an Order Exceeds 1000 Rubles

Task: On workdays, when an order reaches the amount of 1000 rubles and the Save Order button is pressed, an offer appears to add a free beer (brand No. 1).
If the order amount reaches 2000 rubles, the system suggests another beer (brand No. 2) or two beers of brand No. 1.

Solution: Create a script for the user operation that should be assigned for the selector instead of the standard order saving selector:

procedure ProcessOperation1002227(Parameter: integer);

var i, DishCode1,DishCode2: integer;

qnt1, qnt2, qntMax11, qntMax12, qntMax21, qntMax22: double;

checksum, LimitSum1,LimitSum2: double;

it: TCheckItem;

CurrTime, Time1, Time2: TDateTime;

begin

if not RKCheck.Valid then exit; //important checking

//********** Set parameters ***********//

DishCode1 := 45; // controlled dish1 code

DishCode2 := 46; // controlled dish2 code

qntMax11 := 1; // the maximum quantity of controlled dish1 in an order exceeding 1000 rub.

qntMax12 := 0; // the maximum quantity of controlled dish2 in an order exceeding 1000 rub.

qntMax21 := 2; // the maximum quantity of controlled dish1 in an order exceeding 2000 rub.

qntMax22 := 1; // the maximum quantity of controlled dish2 in an order exceeding 2000 rub.

Time1 := EncodeTime(10,00,00,00); // special offer start

Time2 := EncodeTime(18,00,00,00); // special offer end

LimitSum1 := 1000; // a receipt amount that, if exceeded, allows to add a bonus dish.

LimitSum2 := 2000; // a receipt amount that, if exceeded, allows to add a bonus dish.

//********** Set parameters ***********//

qnt1 := 0;

qnt2 := 0;

CurrTime := Time;

checksum := 0;

//1 = Sunday

//2 = Monday

//3 = Tuesday

//4 = Wednesday

//5 = Thursday

//6 = Friday

//7 = Saturday


begin

if (DayOfWeek(Now)>=2)and(DayOfWeek(Now)<=6) then // day of the week check

if (Time1<=CurrTime)and(CurrTime<=Time2) then

begin

checksum := RKCheck.CurrentOrder.ToPaySum;

for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do

begin

it := RKCheck.CurrentOrder.Sessions.Lines[i];

if SYS.ObjectInheritsFrom(it, 'TDish') then

begin

if TDish(it).code = DishCode1 then

qnt1 := qnt1 + TDish(it).Quantity;

if TDish(it).code = DishCode2 then

qnt2 := qnt2 + TDish(it).Quantity;

end;

end;

if (checksum >= LimitSum1) and (checksum < LimitSum2) then

begin

if (qnt1 < qntMax11) then // check limit exceed

if GUI.RKMessageDlg('Do you want to add a free dish Beer1?', 0, 3, 100000) = 6 then

begin

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(DishCode1), IntToStr(Trunc(qntMax11)));

RK7.PerformOperation(rkoSaveOrder, 0);

exit;

end;

end

else if (checksum >= LimitSum2) then

begin

if (qnt2 < qntMax22) then // check limit exceed

if GUI.RKMessageDlg('Do you want to add a free dish beer2?', 0, 3, 100000) = 6 then

begin

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(DishCode2), IntToStr(Trunc(qntMax22)));

RK7.PerformOperation(rkoSaveOrder, 0);

exit;

end

else

if (qnt1 < qntMax21) then // check limit exceed

if GUI.RKMessageDlg('Do you want to add a free dish Beer1?', 0, 3, 100000) = 6 then

begin

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(DishCode1), IntToStr(Trunc(qntMax21)));

RK7.PerformOperation(rkoSaveOrder, 0);

exit;

end;

end;

end;

end;

RK7.PerformOperation(rkoSaveOrder, 0);

end;

Creating 3 for 2 Special Offer

Task: to create the "3 for the price of 2" special offer

Solution: at the r_keeper 7 manager station, go to Money > Discounts and Markups, create a new discount with the following properties:

  1. Count type: Amount
  2. Changeable Value: enabled
  3. Allow Multiple: enabled
  4. On Dish: enabled.

Assign the following script to the selector:

procedure ProcessOperation1001326(Parameter: integer);

var i, j, k: integer;

it: TCheckItem;

d: TDish;

a, PaySum, q: double;

str: string;

info: string;

DiscCode: integer;

Categ: TClassificatorGroup;

begin

RK7.PerformOperation(rkoPackDishes, 0);

DiscCode := 11; // discount code

info := ';';

RK7.PerformOperation(rkoHome, 0);

while True do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

Categ := TClassificatorGroup(RK7.FindItemByCode(rkrefClassificatorGroups, 8)); // indicate classification code

if SYS.ObjectInheritsFrom(TObject(it), 'TEmptyLine') then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then

if Categ.IsChild(it. RefItem) then begin // if a dish belongs to the specified classification, you can move on.

d := TDish(it);

PaySum := d.PaySum;

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) and SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then begin

PaySum := PaySum - TDiscountItem(it).CalcAmount;

RKCheck.DeleteCheckItem(it);

end;

end;

i := Pos(';' + IntToStr(d.Sifr) + '=', info);

if i = 0 then a := 0

else begin

str := Copy(info, i+1, 10000);

k := Pos(';', str);

str := Copy(info, i+1, k - 1);

Delete(info, i, k);

a := StrToFloat(Copy(str, Pos('=', str)+1, 10000));

end;

a := a + d.Quantity;

if a > 2 then begin

q := int64(Trunc(a) div 3);

a := a - 3*q;

str := FloatToStr(PaySum*q/d.Quantity);

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), str);

end;

info := info + IntToStr(d.Sifr) + '=' + FloatToStr(a) + ';';

end;

RK7.PerformOperation(rkoDown, 0);

end;

end;

Creating a 50% Discount on Every Second Dish in the Order

Task: a script is required for creating a 50% discount on every second dish in the order.

Solution: create a new discount, then a new detail for it, with the following properties:

  1. Min. quantity: 2
  2. Qty mode: For all
  3. Percent: 50

Assign the following script to the selector:

procedure ProcessOperation1002352(Parameter: integer);

var i, j, k: integer;

it: TCheckItem;

d: TDish;

a, PaySum, q, perc: double;

str: string;

info: string;

DiscCode: integer;

begin

RK7.PerformOperation(rkoPackDishes, 0);

DiscCode := 11; // the code of the opened fixed amount discount on a dish

perc := 0.5; // disount %

info := ';';

RK7.PerformOperation(rkoHome, 0);

while True do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TEmptyLine') then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then begin

d := TDish(it);

PaySum := d.PaySum;

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) and SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then begin

PaySum := PaySum - TDiscountItem(it).CalcAmount;

RKCheck.DeleteCheckItem(it);

end;

end;

dbg.dbgprint('PaySum = '+floattostr(PaySum));

i := Pos(';' + IntToStr(d.Sifr) + '=', info);

if i = 0 then a := 0

else begin

str := Copy(info, i+1, 10000);

k := Pos(';', str);

str := Copy(info, i+1, k - 1);

Delete(info, i, k);

a := StrToFloat(Copy(str, Pos('=', str)+1, 10000));

end;

dbg.dbgprint('str = '+(str));

a := a + d.Quantity;

dbg.dbgprint('a = '+floattostr(a));

if a > 1 then begin

q := int64(Trunc(a) div 2);

a := a - 2*q;

str := FloatToStr(PaySum*q/d.Quantity*perc);

dbg.dbgprint('str = '+(str));

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), str);

end;

info := info + IntToStr(d.Sifr) + '=' + FloatToStr(a) + ';';

end;

RK7.PerformOperation(rkoDown, 0);

end;

end;

This script applies the 50% discount to all positions after the first one.

If you need a discount on every second dish, edit the following strings:

if a > 1 then begin

q := int64(Trunc(a) div 2);

a := a - 2*q;

Creating a100% Discount for the Second Dish of a Certain Category in the Order

Task: to create a 100% discount on the second dish of a certain category.

Solution:

procedure ProcessOperation1000695(Parameter: integer);

var i, j, k: integer;

it: TCheckItem;

d: TDish;

a, PaySum, q: double;

str: string;

info: string;

DiscCode: integer;

begin

RK7.PerformOperation(rkoPackDishes, 0);

DiscCode := 32;

info := ';';

RK7.PerformOperation(rkoHome, 0);

while True do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TEmptyLine') then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then begin

d := TDish(it);

PaySum := d.PaySum;

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) and SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then begin

PaySum := PaySum - TDiscountItem(it).CalcAmount;

RKCheck.DeleteCheckItem(it);

end;

end;


i := Pos(';' + IntToStr(d.Sifr) + '=', info);

if i = 0 then a := 0

else begin

str := Copy(info, i+1, 10000);

k := Pos(';', str);

str := Copy(info, i+1, k - 1);

Delete(info, i, k);

a := StrToFloat(Copy(str, Pos('=', str)+1, 10000));

end;

a := a + d.Quantity;

if a > 1 then begin

q := int64(Trunc(a) div 2);

a := a - 2*q;

str := FloatToStr(PaySum*q/d.Quantity);

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), str);

end;

info := info + IntToStr(d.Sifr) + '=' + FloatToStr(a) + ';';

end;

RK7.PerformOperation(rkoDown, 0);

end;

end;

Creating a 100% Discount on the First Dish from the Category

Task: To create a special flyer offer — one free dessert for the receipt amount from 500 rubles. A 100% percent discount only on the dish from the dessert category. Prices are different, a receipt can contain several desserts. A discount should be applied only once, to the dessert that is the first in the order.

Solution:

The script for adding a special offer manually:

procedure ProcessOperation1001621(Parameter: integer);

var i, j, numcateg: integer;

DiscCode: integer;

it, CurItem: TCheckItem;

SL: TStringList;

a, q, Price: double;

d: TDish;

CheckView: TCheckView;

Categ: TClassificatorGroup;

skip: boolean;

begin

CheckView := TCheckView(GUI.FindComponentByName('CheckView'));

if CheckView = Nil then Exit;

CurItem := RKCheck.CurrentCheckItem;

SL := TStringList.Create;

try

// Create list of the dishes, sorted by price

SL.Sorted := True;

DiscCode := 11;

numcateg := 8; //5 - category code

for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do

begin

it := RKCheck.CurrentOrder.Sessions.Lines[i];

Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', numcateg)); //5 - category code

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then //Check dish lines only

if Categ.IsChild(it.RefItem) then //Check category of the dish

// if (it.RefItem.MainParent.code =11 ) then // if dish from category of menu and have same code

if ((it.State = disOpened) or (it.State = disPrinted)) then

if TDish(it).Quantity > 0 then

begin

if SL.Count<1 then

begin

if (TDish(it).Quantity = 0) or (TDish(it).PRListSum = 0) then Price := TDish(it).Price

else Price := TDish(it).PRListSum/TDish(it).Quantity;

SL.AddObject(FormatFloat('00000000.00', Price) + IntToStr(TDish(it).UNI), TObject(it));

end;

end;

end;

//Magic

q:=0;


for i:= 0 to SL.Count - 1 do

begin

a:= 0;

d:= TDish(SL.Objects[i]);

q:= d.Quantity;

if (d.Quantity = 0) or (d.PRListSum = 0) then Price := d.Price

else Price := d.PRListSum/d.Quantity;

a:= a + Price;


if RKCheck.CurrentOrder.UnpaidSum-a >= 500 then

begin

// Delete discount if the sum changed

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do

begin


it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) then

begin


if abs(TDiscountItem(it).CalcAmount) = a then a := 0

else begin


RKCheck.DeleteCheckItem(it);

end;

break;

end;

end;

// Create discount to a dish

if a > 0 then

begin

CheckView.GotoItem(TObject(d));

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(a));

end;

end

else

begin

// Delete discount if the sum changed

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do

begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) then

begin

// gui.showmessage('44444');

RKCheck.DeleteCheckItem(it);

break;

end;

end;

end;

end;

finally

SL.Free();

if CurItem <> Nil then CheckView.GotoItem(CurItem);

end;

RKCheck.CurrentOrder.Recalc();

end;

Two scripts for the receipt editing form that automatically add or delete a discount:

procedure CheckViewOnAfterCheckViewEdit(Sender: TObject; AEditType: TEditType; AObjectBef, AObjectAft: TObject);
 
var i, j, numcateg, OrderTypeCode, GuestTypeIdent: integer;
 
DiscCode, HaveDisc: integer;
 
it, CurItem: TCheckItem;
 
SL: TStringList;
 
newsum, aftersum, beforesum, limitsum, topay, a, q, Price: double;
 
d: TDish;
 
CheckView: TCheckView;
 
Categ: TClassificatorGroup;
 
begin
 
CheckView := TCheckView(GUI.FindComponentByName('CheckView'));
 
if CheckView = Nil then Exit;
 
HaveDisc := 0;
 
// ******************************************************************
 
DiscCode := 11; // discount code for the special dish
 
numcateg := 8; // category code for the special dish
 
limitsum := 500; // min order amount with all discounts
 
OrderTypeCode := 1; // order type code
 
GuestTypeIdent := 1000087; // guest type id
 
// ******************************************************************
 
CurItem := RKCheck.CurrentCheckItem;
 
SL := TStringList.Create;
 
// if (RKCheck.CurrentOrder.OrderTypeCode = 2) then // for different OrderTypeCode
 
// if (RKCheck.CurrentOrder.OrderCategoryCode = 2) then // for different OrderCategoryCode
 
// if (RKCheck.CurrentOrder.Visit.GuestType = 0) then // for different GuestType
 
if (RKCheck.CurrentOrder.OrderTypeCode = OrderTypeCode) // for different OrderTypeCode
 
or(RKCheck.CurrentOrder.Visit.GuestType = GuestTypeIdent) // for different GuestType
 
then
 
try
 
// Create list of the dishes, sorted by price
 
SL.Sorted := False;
 
for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do
 
begin
 
it := RKCheck.CurrentOrder.Sessions.Lines[i];
 
Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', numcateg)); //5 - category code
 
// if SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then
 
// if TDiscountItem(it).code = 11 then
 
// gui.showmessage('111111111');
 
// if TDiscountItem(it).CalcAmount > 0 then
 
// HaveDisc := HaveDisc + 1;
 
if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then //Check dish lines only
 
if Categ.IsChild(it.RefItem) then //Check category of the dish
 
// if (it.RefItem.MainParent.code =11 ) then // if dish from categore of menu and have same code
 
if ((it.State = disOpened) or (it.State = disPrinted)) then
 
if TDish(it).Quantity > 0 then
 
begin
 
if SL.Count<1 then
 
begin
 
if (TDish(it).Quantity = 0) or (TDish(it).PRListSum = 0) then Price := TDish(it).Price
 
else Price := TDish(it).PRListSum/TDish(it).Quantity;
 
SL.AddObject(FormatFloat('00000000.00', Price) + IntToStr(TDish(it).UNI), TObject(it));
 
end;
 
end;
 
end;
 
 
//Magic
 
q:=0;
 
newsum := 0;
 
aftersum := 0;
 
beforesum := 0;
 
if SYS.ObjectInheritsFrom(AObjectAft, 'TDish') then
 
aftersum := TDish(AObjectAft).PRListSum
 
else
 
aftersum := 0;
 
if SYS.ObjectInheritsFrom(AObjectBef, 'TDish') then
 
beforesum := TDish(AObjectBef).PRListSum
 
else
 
beforesum := 0;
 
newsum := aftersum-beforesum;
 
for i:= 0 to SL.Count - 1 do
 
begin
 
a:= 0;
 
d:= TDish(SL.Objects[i]);
 
q:= d.Quantity;
 
if (d.Quantity = 0) or (d.PRListSum = 0) then Price := d.Price
 
else Price := d.PRListSum/d.Quantity;
 
a:= a + Price;
 
 
// search special discount
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
HaveDisc := HaveDisc + 1;
 
end;
 
 
if HaveDisc > 0 then
 
topay := RKCheck.CurrentOrder.UnpaidSum + a
 
else
 
topay := RKCheck.CurrentOrder.UnpaidSum;
 
 
if topay-a+newsum >= limitsum then
 
begin
 
// Delete discount, if a sum changed
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
begin
 
 
if abs(TDiscountItem(it).CalcAmount) = a then a := 0
 
else begin
 
RKCheck.DeleteCheckItem(it);
 
end;
 
break;
 
end;
 
end;
 
// Create discount to a dish
 
if a > 0 then
 
begin
 
CheckView.GotoItem(TObject(d));
 
RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(a));
 
end;
 
end
 
else
 
begin
 
// Delete discount, if a sum changed
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
begin
 
RKCheck.DeleteCheckItem(it);
 
break;
 
end;
 
end;
 
end;
 
end;
 
finally
 
SL.Free();
 
if CurItem <> Nil then CheckView.GotoItem(CurItem);
 
end;
 
RKCheck.CurrentOrder.Recalc();
 
end;
 
 
procedure CheckViewOnBeforeCheckViewEdit(Sender: TObject; AEditType: TEditType; AObjectBef, AObjectAft: TObject; var AAllow: boolean; var AMessage: string);
 
var i, j, numcateg, OrderTypeCode, GuestTypeIdent: integer;
 
DiscCode, HaveDisc: integer;
 
it, CurItem: TCheckItem;
 
SL: TStringList;
 
newsum, aftersum, beforesum, limitsum, topay, a, q, Price: double;
 
d: TDish;
 
CheckView: TCheckView;
 
Categ: TClassificatorGroup;
 
begin
 
CheckView := TCheckView(GUI.FindComponentByName('CheckView'));
 
if CheckView = Nil then Exit;
 
HaveDisc := 0;
 
// ******************************************************************
 
DiscCode := 11; // discount code for the special dish
 
numcateg := 8; // category code for the special dish
 
limitsum := 500; // min order amount with all the discounts
 
OrderTypeCode := 1; // order type code
 
GuestTypeIdent := 1000087; // guest type id
 
// ******************************************************************
 
CurItem := RKCheck.CurrentCheckItem;
 
SL := TStringList.Create;
 
// if (RKCheck.CurrentOrder.OrderTypeCode = 2) then // for different OrderTypeCode
 
// if (RKCheck.CurrentOrder.OrderCategoryCode = 2) then // for different OrderCategoryCode
 
// if (RKCheck.CurrentOrder.Visit.GuestType = 0) then // for different GuestType
 
if (RKCheck.CurrentOrder.OrderTypeCode = OrderTypeCode) // for different OrderTypeCode
 
or(RKCheck.CurrentOrder.Visit.GuestType = GuestTypeIdent) // for different GuestType
 
then
 
if AEditType = etRemove then
 
try
 
// Create list of the dishes, sorted by price
 
SL.Sorted := False;
 
for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do
 
begin
 
it := RKCheck.CurrentOrder.Sessions.Lines[i];
 
Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', numcateg)); //5 - category code
 
if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then //Check dish lines only
 
if Categ.IsChild(it.RefItem) then //Check category of the dish
 
// if (it.RefItem.MainParent.code =11 ) then // if dish from categore of menu and have same code
 
if ((it.State = disOpened) or (it.State = disPrinted)) then
 
if TDish(it).Quantity > 0 then
 
if SL.Count<1 then
 
begin
 
if (TDish(it).Quantity = 0) or (TDish(it).PRListSum = 0) then Price := TDish(it).Price
 
else Price := TDish(it).PRListSum/TDish(it).Quantity;
 
SL.AddObject(FormatFloat('00000000.00', Price) + IntToStr(TDish(it).UNI), TObject(it));
 
end;
 
end;
 
//Magic
 
q:=0;
 
newsum := 0;
 
aftersum := 0;
 
beforesum := 0;
 
if SYS.ObjectInheritsFrom(AObjectAft, 'TDish') then
 
aftersum := TDish(AObjectAft).PRListSum
 
else
 
aftersum := 0;
 
if SYS.ObjectInheritsFrom(AObjectBef, 'TDish') then
 
beforesum := TDish(AObjectBef).PRListSum
 
else
 
beforesum := 0;
 
// newsum := aftersum-beforesum;
 
newsum := -beforesum;
 
for i:= 0 to SL.Count - 1 do
 
begin
 
a:= 0;
 
d:= TDish(SL.Objects[i]);
 
q:= d.Quantity;
 
if (d.Quantity = 0) or (d.PRListSum = 0) then Price := d.Price
 
else Price := d.PRListSum/d.Quantity;
 
a:= a + Price;
 
 
// search special discount
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
HaveDisc := HaveDisc + 1;
 
end;
 
 
if HaveDisc > 0 then
 
topay := RKCheck.CurrentOrder.UnpaidSum + a
 
else
 
topay := RKCheck.CurrentOrder.UnpaidSum;
 
if topay-a+newsum >= limitsum then
 
// if RKCheck.CurrentOrder.UnpaidSum-a+newsum >= limitsum then
 
begin
 
// Delete discount, if a sum changed
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
begin
 
if abs(TDiscountItem(it).CalcAmount) = a then a := 0
 
else begin
 
RKCheck.DeleteCheckItem(it);
 
end;
 
break;
 
end;
 
end;
 
// Create discount to a dish
 
if a > 0 then
 
begin
 
CheckView.GotoItem(TObject(d));
 
RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(a));
 
end;
 
end
 
else
 
begin
 
// Delete discount, if a sum changed
 
for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do
 
begin
 
it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);
 
if (it.Code = DiscCode) then
 
begin
 
RKCheck.DeleteCheckItem(it);
 
break;
 
end;
 
end;
 
end;
 
end;
 
finally
 
SL.Free();
 
if CurItem <> Nil then CheckView.GotoItem(CurItem);
 
end;
 
RKCheck.CurrentOrder.Recalc();
 
end;

Creating a special offer "Children's Birthdays: 10% Discount + Free pizza"

Task: To arrange the "Children's Birthdays: 10% Discount + Free pizza" special offer.

To do so, set a 100% discount on the pizza category comprising two pizza types, Home Style Pizza and Children's Pizza. If an order contains two items from the pizza category, the 100% discount is applied only to the first one and the second one has the 10% discount.

Solution: Create a script for the Special Offer selector:

procedure ProcessOperation1002452(Parameter: integer);

var i, j, numcateg: integer;

DiscCode: integer;

it, CurItem: TCheckItem;

SL: TStringList;

a, q, Price: double;

d: TDish;

CheckView: TCheckView;

Categ: TClassificatorGroup;

skip: boolean;

begin

CheckView := TCheckView(GUI.FindComponentByName('CheckView'));

if CheckView = Nil then Exit;

CurItem := RKCheck.CurrentCheckItem;

SL := TStringList.Create;

try

// Create list of the dishes, sorted by price

SL.Sorted := False;

DiscCode := 12; // the changeable fixed amount discount on a dish

numcateg := 8; // category code for discount

for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do

begin

it := RKCheck.CurrentOrder.Sessions.Lines[i];

Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', numcateg));

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then //Check dish lines only

if Categ.IsChild(it.RefItem) then //Check category of the dish

if ((it.State = disOpened) or (it.State = disPrinted)) then

if TDish(it).Quantity > 0 then

begin

if SL.Count<2 then

begin

if (TDish(it).Quantity = 0) or (TDish(it).PRListSum = 0) then Price := TDish(it).Price

else Price := TDish(it).PRListSum/TDish(it).Quantity;

SL.AddObject(FormatFloat('00000000.00', Price) + IntToStr(TDish(it).UNI), TObject(it));

end;

end;

end;


q:=0;

for i:= 0 to SL.Count - 1 do

begin

a:= 0;

d:= TDish(SL.Objects[i]);

q:= d.Quantity;

if (d.Quantity = 0) or (d.PRListSum = 0) then Price := d.Price

else Price := d.PRListSum/d.Quantity;

if i=0 then

a:= a + Price; // discount 100 %

if i=1 then

a:= a + Price*0.1; // discount 10 %


begin

// Delete discount if the sum changed

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do

begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) then

begin

if abs(TDiscountItem(it).CalcAmount) = a then a := 0

else begin

RKCheck.DeleteCheckItem(it);

end;

break;

end;

end;

// Create discount to a dish

if a > 0 then

begin

CheckView.GotoItem(TObject(d));

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(a));

end;

end;

end;

finally

SL.Free();

if CurItem <> Nil then CheckView.GotoItem(CurItem);

end;

RKCheck.CurrentOrder.Recalc();

end;

The dish must have the property Adding to the Order – Separate Line for Each Serving.


The script for automatically applying a 10% discount if another category dish in the order has the 100% discount:

procedure DiscountUsage1002444(UsageParameters: TDiscountUsageParameters);

var i,j,cntDiscount, DiscountCode: integer;

it,it2: TCheckItem;

Categ: TClassificatorGroup;

begin

dbg.dbgprint('script_disc');

// if not RKCheck.Valid then exit;

DiscountCode := 12; // code of the discount "100% on a dish"

cntDiscount := 0;

Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', 8)); // category code

for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do

begin

it := RKCheck.CurrentOrder.Sessions.Lines[i];

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then

if TDish(it).Quantity > 0 then

if Categ.IsChild(it.RefItem) then //Check category of the dish

Begin

dbg.dbgprint('script_disc 1_');

dbg.dbgprint('cnt = '+inttostr(RKCheck.CheckItemCount(TObject(TDish(it).Discounts))));

for j := RKCheck.CheckItemCount(TObject(TDish(it).Discounts)) - 1 downto 0 do

begin

it2 := RKCheck.CheckItemByNumber(TObject(TDish(it).Discounts), j);

if (it2.Code = DiscountCode) then

// if abs(TDiscountItem(it2).SrcAmount)>0 then

begin

dbg.dbgprint('script_disc 2');

cntDiscount := cntDiscount + 1;

break;

end;

end;

End;

end;

dbg.dbgprint('cntDiscount = '+inttostr(cntDiscount));

if cntDiscount>0 then

UsageParameters.UsageMode := umAuto

else

UsageParameters.UsageMode := umDeny;

end;

Creating a Happy Receipt

Task: To create a script for a happy receipt limited by

  1. The minimal receipt amount
  2. The total possible number of receipts. The number of receipts depends on the revenue amount at a given moment, i. e. if the revenue is, for example, 50 000 rubles, the maximum number of happy receipts should be five.

Solution:

  1. Create a print layout in the user reports and a print view for this layout
  2. In the Options > User Interface > Forms, add the TReportPanel component to the cash form in the Form editor:
  3. Specify the previously created print layout in the Behavior > Document property
  4. Enter the script:

    procedure ProcessOperation1001035(Parameter: integer);
    
    var t1, t2: TdateTime;
    
    i,QntHO, MaxQntHappyOrd, DiscCode, DiscId: integer;
    
    it: TCheckItem;
    
    a,b,MinOrderSum,MaxOrderSum, KasSum: double;
    
    c: TVisualComponent;
    
    str: string;
    
    begin
    
    DiscCode := 5; // code discount
    
    DiscId := 1001029; // id discount
    
    KasSum := 0;
    
    c := gui.FindComponentByName('UserReportPanel1');
    
    str := TReportPanel(TObject(c)).Text;
    
    // dbg.dbgprint('str = '+str);
    
    i:=pos('revenue=',str);
    
    if i>0 then
    
    begin
    
    KasSum := StrToFloat(copy(str,i+8,length(str)-(i+8)));
    
    //dbg.dbgprint('KasSum = '+FloatToStr(KasSum));
    
    end;
    
    
    t1:=StrToTime('10:01:00'); // start lottery
    
    t2:=StrToTime('23:59:00'); // end lottery
    
    MaxOrderSum := 15000; // max sum of order the maximum order amount eligible for a happy receipt
    
    MinOrderSum := 1; // min sum of order the minimum order amount eligible for a happy receipt
    
    MaxQntHappyOrd := trunc(KasSum / 10); // quantity of happy ordets at shift
    
    
    //dbg.dbgprint('QntHO = '+FloatToStr(QntHO));
    
    //dbg.dbgprint('MaxQntHappyOrd = '+FloatToStr(MaxQntHappyOrd));
    
    QntHO:=RKCheck.GetDiscountCount(DiscId, 0, ''); // id discount
    
    if QntHO<MaxQntHappyOrd then
    
    if (t1<=Time)and(Time<=t2) then
    
    begin
    
    // calc sum of order START
    
    for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do begin
    
    it := RKCheck.CurrentOrder.Sessions.Lines[i];
    
    if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then
    
    a := a + TDish(it).PRListSum
    
    else if SYS.ObjectInheritsFrom(TObject(it), 'TChargeLine') then
    
    a := a + TChargeLine(it).CalcAmount;
    
    // if it.CODE in [5502, 1003] then
    
    // b := b + TDish(it).PRListSum;
    
    end;
    
    // calc sum of order END
    
    // dbg.dbgprint('a = '+floattostr(a));
    
    // dbg.dbgprint('random(100) = '+floattostr(random(100)));
    
    if a>MinOrderSum then // check condition of minimum ordersum
    
    if a<MaxOrderSum then // check condition of maximum ordersum
    
    begin
    
    if (random(100)>1) then // set the probability of drawing a happy receipt here: 1 is the maximum probability; 99 is the minimum probability
    
    begin
    
    RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(100)); // add discount indicate the discount amount instead of 100
    
    // dbg.dbgprint('Congratulations!!! Happy Order!!! var1');
    
    gui.ShowMessage('Congratulations!!! Happy Order!!!'); // RkCheck.GetDiscountCount
    
    end
    
    else if (QntHO=0) and (StrToInt(FormatDateTime('n',t2-Time))<=10) then // lottery at last time(minutes) when no winners
    
    begin
    
    if (random(100)>1) then // set the probability of drawing a happy receipt here: 1 is the maximum probability; 99 is the minimum probability
    
    begin
    
    RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(100)); // add discount indicate the discount amount instead of 100
    
    // dbg.dbgprint('Congratulations!!! Happy Order!!! var2');
    
    gui.ShowMessage('Congratulations!!! Happy Order!!!'); // RkCheck.GetDiscountCount
    
    end;
    
    end;
    
    end;
    
    end;
    
    RK7.PostOperation(rkoBalanceReceipt,0);
    
    end;

Adding a Dish to the Order When Switching to the Payment Mode

Task: To create a script adding a dish to the order at moment of switching to the payment mode. The process should be as follows: in the Fast Receipt mode, the system checks the order amount once the Order Payment button is pressed. If the order amount is more than or equal to a specified amount, the system displays a message with Yes and No buttons.

If Yes is clicked, the system adds a dish having the NNN code to the order and switches to the payment mode.

If No is clicked, the system switches right away to the payment mode.

Solution: Instead of the standard selector, add the Payment user selector to the fast receipt. Bind the following user operation script to this selector:

procedure ProcessOperation1001304(Parameter: integer);

begin

if not RKCheck.Valid then

exit //important checking

else

begin

if RKCheck.CurrentOrder.UnpaidSum >= 300 then // Order sum checking

if GUI.RKMessageDlg('Do You want add bonus dish?', 0, 3, 10000) = 6 then

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(39), '1'); // add dish with code 39

end;

RK7.PostOperation(rkoBalanceReceipt, 0);

end;

In this script, change 300 to the required amount and replace the 39 code of the added dish with a relevant value.

Dish Locking

Task: To replace the standard Dishes selector so that when a dish code is entered and this selector is pressed, some dishes get locked.

Solution:

procedure ProcessOperation1038483(Parameter: integer);
var ed: TObject;

begin

if not RKCheck.Valid then

exit //important checking

else

begin

ed := TObject(gui.FindComponentByName('Editor'));

if SYS.ObjectInheritsFrom(TObject(ed), 'TNumEditor') then

if (Pos('1001',TNumEditor(ed).Text)>0)

or (Pos('1002',TNumEditor(ed).Text)>0)

then

gui.showmessage('Zapreshennij simvol!!!')

else

RK7.PerformOperation(rkoCreateDish, StrToInt(TNumEditor(ed).Text));

end;

end;

Statuses

TDrawItemState = (disNone, disOpened, disLocked, disFixed, disPrinted, disPartClosed, disClosed, disDeleted);

How to Get the Combo Element Parent in the Script

Take the ComboDishUNI property of a dish and find a dish having that UNI.

In r_Keeper 7.5.5.035 this can be done as follows:

RKCheck.CurrentOrder.Sessions.FindByUNI(TDish(it).ComboDishUNI).

Older versions don't have the FindByUNI function so to find the dish having the required UNI you have to search through all the dishes in the order.

If ((TDish(it).Quantity <> 0) and (TDish(it).IsComboComp)) then //and (Categ5.IsChild(it.RefItem)))
begin

for j := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do begin

it2 := RKCheck.CurrentOrder.Sessions.Lines[j];

if SYS.ObjectInheritsFrom(TObject(it2), 'TDish') then

begin

If ((TDish(it).ComboDishUNI = TDish(it2).UNI) and (Categ5.IsChild(it2.RefItem))) then

begin

end;

end;

end;

//TDish(it).ComboDishUNI

end;

Adding a Modifier to All Dishes in the Order

Task: To write a script for the selector to add a modifier to all dishes in the order.

Solution:

procedure ProcessOperation1002489(Parameter: integer);
var i,j,CntModif:integer;

it, CurItem: TCheckItem;

CheckView: TCheckView;

begin

CheckView := TCheckView(GUI.FindComponentByName('CheckView'));

if CheckView = Nil then Exit;

CurItem := RKCheck.CurrentCheckItem;

if Parameter > 0 then

try

RK7.PerformOperation(rkoHome, 0);

while True do begin

it := RKCheck.CurrentCheckItem;

if TObject(it) = Nil then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TPrintCheckItem') then break;

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then

begin

CntModif := 0;

for j := 0 to TDish(it).Modifiers.Count - 1 do // checking by modifier

begin

if (TDish(it).Modifiers.Items[j].Code=Parameter) then

CntModif := CntModif + 1;

end;

if CntModif = 0 then

RKCheck.CreateCheckItem(rkrefModifiers, IntToStr(Parameter), '1'); // add modificator

end;

RK7.PerformOperation(rkoDown, 0);

end;


finally

if CurItem <> Nil then CheckView.GotoItem(CurItem);

end;

end;

Assign the user operation with the above-mentioned script to selectors and be sure to indicate the code of a relevant modifier in the Parameter for Empty and Parameter properties.

Adding a New Dish to the Order by Pressing the Saved Dish Line and the Quantity Button

Task: When a saved dish item is selected and the Quantity button is pressed, it is required to add a new item to the bottom of the item list. This function was available in r_keeper 6. When the saved dish item is pressed now, the Quantity button is disabled.

Solution:

  1. Add a script to the operation scripts
  2. Assign the script to the specific user operation
  3. Bind the operation to a function button and assign the button to a new selector.

Script:

procedure ProcessOperation1001322(Parameter: integer);
var i, code: integer;

CurItem: TCheckItem;

begin

if not RKCheck.Valid then

exit //important checking

else

begin

CurItem := RKCheck.CurrentCheckItem;

if SYS.ObjectInheritsFrom(TObject(CurItem), 'TDish') then

begin

code := CurItem.code;

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(code), '1'); // add dish with code 39

end;

end;

end;

Adding the Quantity Button with the "Plus One Serving of a Saved Dish" Function

Task: to merge the functions of the Quantity and Plus One Serving of a Saved Dish (additional order) buttons 

Solution:

procedure ProcessOperation1001322(Parameter: integer);

var i, code: integer;

CurItem: TCheckItem;

ed: TObject;

begin

if not RKCheck.Valid then

exit //important checking

else

begin

CurItem := RKCheck.CurrentCheckItem;

if SYS.ObjectInheritsFrom(TObject(CurItem), 'TDish') then

begin

ed := TObject(gui.FindComponentByName('Editor'));

if (TNumEditor(ed).Text='') then

begin

code := CurItem.code;

RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(code), '1'); // add dish with code

end

else

begin

RK7.PerformOperation(rkoEditAmount, 0);

end;

end;

end;

end;

Quick Payment in Rubles in r_keeper 7

Task: when the Pay in Rubles or Pay buttons are pressed in the quick receipt mode, the cash payment window should open skipping the payment type selection.

Solution:

procedure ProcessOperation1002215(Parameter: integer);

begin

if not RKCheck.Valid then

exit //important checking

else

begin

RK7.PerformRefObject(RK7.FindItemByCode(rkrefCurrencies, 1)); // 1 - currency code

end;

end;

Checking the Visit Prepayment Balance

Mission: A restaurant operates in the entry card mode via the MSR algorithm. A script is required that can display the visit prepayment balance.

Solution:

procedure ProcessOperation1001537(Parameter: integer);

var i: integer;

Limit: double;

CardCode: string;

McrPay: TMcrPay;

begin

if TObject(RKCheck.CurrentOrder) = Nil then Exit;


// Limit calculation

Limit := 0;

CardCode := '';

for i := 0 to RKCheck.CurrentOrder.Sessions.McrPays.ItemCount - 1 do begin

McrPay := TMcrPay(RKCheck.CurrentOrder.Sessions.McrPays.Items[i]);

Limit := Limit + McrPay.MaxAmount;

CardCode := McrPay.CardNum;

end;

if CardCode = '' then Exit

else

gui.Showmessage('Card '+CardCode+' balance '+FloatToStr(Limit)+' р.');

end;

Limiting the 100% Category Discount

Mission: The 100% discount should apply only to one dish item belonging to the category.

Solution:

procedure ProcessOperation1001621(Parameter: integer);

var i, j, numcateg: integer;

DiscCode: integer;

it, CurItem: TCheckItem;

SL: TStringList;

a, q, Price: double;

d: TDish;

CheckView: TCheckView;

Categ: TClassificatorGroup;

skip: boolean;

begin

CheckView := TCheckView(GUI.FindComponentByName('CheckView'));

if CheckView = Nil then Exit;

CurItem := RKCheck.CurrentCheckItem;

SL := TStringList.Create;

try

// Create list of the dishes, sorted by price

SL.Sorted := True;

DiscCode := 11;

numcateg := 8; //5 - category code

for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do

begin

it := RKCheck.CurrentOrder.Sessions.Lines[i];

Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', numcateg)); //5 - category code

if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then //Check dish lines only

if Categ.IsChild(it.RefItem) then //Check category of the dish

// if (it.RefItem.MainParent.code =11 ) then // if dish from category of menu and have same code

if ((it.State = disOpened) or (it.State = disPrinted)) then

begin

skip := false;

for j:=0 to SL.Count - 1 do

begin

d:= TDish(SL.Objects[j]);

if d.code=it.code then

Skip := True;

end;

if not(skip) then

begin

if (TDish(it).Quantity = 0) or (TDish(it).PRListSum = 0) then Price := TDish(it).Price

else Price := TDish(it).PRListSum/TDish(it).Quantity;

SL.AddObject(FormatFloat('00000000.00', Price) + IntToStr(TDish(it).UNI), TObject(it));

end;

end;

end;


//Magic

q:=0;

for i:= 0 to SL.Count - 1 do

begin

a:= 0;

d:= TDish(SL.Objects[i]);

q:= d.Quantity;

if (d.Quantity = 0) or (d.PRListSum = 0) then Price := d.Price

else Price := d.PRListSum/d.Quantity;

a:= a + Price;


// Delete discount if the sum changed

for j := RKCheck.CheckItemCount(TObject(d.Discounts)) - 1 downto 0 do

begin

it := RKCheck.CheckItemByNumber(TObject(d.Discounts), j);

if (it.Code = DiscCode) then

begin

if abs(TDiscountItem(it).SrcAmount) = a then a := 0

else RKCheck.DeleteCheckItem(it);

break;

end;

end;


// Create discount to a dish

if a > 0 then

begin

CheckView.GotoItem(TObject(d));

RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(a));

end;

end;

finally

SL.Free();

if CurItem <> Nil then CheckView.GotoItem(CurItem);

end;

RKCheck.CurrentOrder.Recalc();

end;

Opening the Browser Window for Displaying Cash Operation Reports

Task: To create a function button in the main cash menu, pressing which will execute the command: fsWeb.exe "https://172.22.4.57:8088/csthtm/overall1.html", where 172.22.4.57 is the value of an extended restaurant property

Solution:

procedure ProcessOperation1001763(Parameter: integer);

var s: string;

begin

// TRK7Restaurant(RK7.CashGroup.MainParent).genMessage_Addon_49='1'

s := TRK7Restaurant(RK7.CashGroup.MainParent).genTEL;

GUI.CmdExec('fsWeb.exe "https://'+s+':8088/csthtm/overall1.html"');

end;

Assign the script to the user operation that, in its turn, should be assigned to a function button.

Adding a Dish to the Order

Task: After swiping a discount card, a discount and a gift — a dish with a specified code — should be awarded to the customer card.

The process should be as follows:

  1. Creating a button in the interface
  2. Once this button is pressed, a customer enters a promo code
  3. This promo code is read as the card code, there is a corresponding MCR algorithm written for it
  4. FarCards is called, a discount and a free dish are received. It can be indicated in some field.
  5. This dish is added to a table and the discount is applied to it.

Solution:

  1. Create the script:

    procedure ProcessOperation1001765(Parameter: integer);
     
    var ed: TObject;
     
    DeviceID : integer;
     
    begin
     
    if not RKCheck.Valid then
     
    exit //important checking
     
    else
     
    begin
     
    DeviceID := 0; // PDS interface ID
     
    ed := TObject(gui.FindComponentByName('Editor'));
     
    if SYS.ObjectInheritsFrom(TObject(ed), 'TNumEditor') then
     
    if (Pos('1001',TNumEditor(ed).Text)>0)
     
    or (Pos('1002',TNumEditor(ed).Text)>0)
     
    then
     
    gui.showmessage('nevernii promokod!!!')
     
    else
     
    RK7.PerformMCRAlgorith('8989='+TNumEditor(ed).Text, DeviceID);
     
    //RK7.PerformOperation(rkoCreateDish, StrToInt(TNumEditor(ed).Text));
     
    end;
     
    end;
  2. In the input field of the cash terminal, a promotional code is entered. In our example, it is 1001 or 1002. If the entered promotional code matches the one stored in the script, the MCR script is called.

    The MCR script needs to be created with the following properties:

    • Main > Area: Discount

    • Main > Object: Discount Used

    • General > Device Types > Script: enabled.

      function MCR1001146(DeviceSignal: Integer; DeviceIdent: Integer; var Parameter: String): Boolean;
       
      var RestCode: integer;
       
      begin
       
      Result := False;
       
      if pos('8989=', Parameter) = 1 then begin
       
      RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(43), '1'); // adding the dish with code 43 to the order
       
      Result := True;
       
      end;
       
      end;

Checking the number of dishes from a certain category

Task: to create a script to check the number of dishes from a certain category.

Solution:

procedure ProcessOperation1001742(Parameter: integer);
 
var i, CategCode: integer;
 
it: TCheckItem;
 
iQnt : double;
 
Categ: TClassificatorGroup;
 
CurSession: TOrderSession;
 
begin
 
if (not RKCheck.Valid) then
 
exit;
 
else begin
 
CategCode := 8; //category code
 
iQnt := 0;
 
Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', CategCode));//category code
 
if SYS.ObjectInheritsFrom(TObject(RKCheck.CurrentCheckItem), 'TDish') then
 
CurSession := TDish(RKCheck.CurrentCheckItem).Session;
 
for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do
 
begin
 
it := RKCheck.CurrentOrder.Sessions.Lines[i];
 
if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then
 
begin
 
if CurSession = TDish(it).Session then
 
if (Categ.IsChild(it.RefItem)) then
 
iQnt := iQnt + Trunc(TDish(it).Quantity);
 
end;
 
end;
 
//RKCheck.CurrentOrder.Visit.GuestCnt
 
if (iQnt < 4) then
 
begin
 
GUI.Showmessage('Chua du? diê`u kiê?n a´p du?ng: ' + FloatToStr(iQnt));
 
Exit;
 
end;
 
end;
 
end;

Creating Additional Reports When Closing a Shift

Task: to create a script to automatically generate additional reports when a shift is closed.

Solution:

procedure ProcessOperation1001784(Parameter: integer);
 
begin
 
RK7.PerformRefObject( RK7.FindItemByCode(rkrefMaketSchemeDetails, 184) ); // document view code in the printing schemes
 
RK7.PerformOperation(rkoMMCloseCommonShift, 0); // common shift closing
 
end;

Forbidding to Cancel the Bill in One Order More Than X Times

Task: It is necessary to forbid canceling the guest bill in one order more than X times, specified in the parameter.

-1 (default)  — allowed to cancel unlimited number of times

0 — it is forbidden to cancel the guest bill at all

1...999 — indicates how many times you can cancel the guest bill in an order/visit

Order >> print pre-check >> cancel pre-check >> print pre-check again >> can not cancel pre-check (system warning and must not allow).

The superuser can always cancel receipts without paying attention to this parameter.

Solution:

  1. Create the MaxDelBillCnt extended property of the integer type and assign it to the restaurant
  2. In the properties of the restaurant, specify a value for this property
  3. Create a script:
procedure ProcessOperation1002346(Parameter: integer);
 
var i, CntDelBill, MaxDelBillCnt: integer;
 
it: TCheckItem;
 
begin
 
CntDelBill := 0;
 
MaxDelBillCnt := -1;
 
// if ( TRK7Restaurant(RK7.CashGroup.MainParent).genMaxDelBillCnt=1) then
 
MaxDelBillCnt := TRK7Restaurant(RK7.CashGroup.MainParent).genMaxDelBillCnt;
 
 
if MaxDelBillCnt = -1 then
 
RK7.PerformOperation(RkoUnlockBill,0);
 
 
if MaxDelBillCnt = 0 then
 
begin
 
gui.showmessage('Cancel bill forbidden!');
 
Exit;
 
end;
 
 
if MaxDelBillCnt > 0 then
 
begin
 
for i := 0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do begin
 
it := RKCheck.CurrentOrder.Sessions.Lines[i];
 
if SYS.ObjectInheritsFrom(TObject(it), 'tPrintCheckItem') then
 
if tPrintCheckItem(it).IsBill then
 
if tPrintCheckItem(it).Deleted then
 
CntDelBill := CntDelBill + 1;
 
end;
 
if CntDelBill >= MaxDelBillCnt then
 
begin
 
if RK7.PerformOperation(rkoUser15, 0)=1 then
 
RK7.PerformOperation(RkoUnlockBill,0)
 
else
 
gui.showmessage('Cancel bill forbidden!');
 
end
 
else
 
RK7.PerformOperation(RkoUnlockBill,0);
 
end;
 
dbg.dbgprint('CntDelBill = ' + IntToStr(CntDelBill));
 
dbg.dbgprint('MaxDelBillCnt = ' + IntToStr(MaxDelBillCnt));
 
end;

Assign an empty script to user operation 15:

procedure ProcessOperation1001624(Parameter: integer);
 
begin
 
 
end;

Enable the access control for this operation. Give the superuser the right for the operation.

Using Different Price Types

Task: when selling dishes at the cash register to a regular customer, not authorized at the cash register with a card, the price should be Price Type No. 1. When selling dishes to a restaurant customer, authorized with a card at the cash register, the price should be Price Type No. 2.

Solution:

procedure ProcessOperation1001986(Parameter: integer);
 
var Props: TVisitOrderInfo;
 
begin
 
Props := TVisitOrderInfo.Create();
 
try
 
Props.OrderCategoryID := 10033; // specify the order category ID
 
RKCheck.UpdateOrderProps(Props);
 
finally
 
Props.Free;
 
end;
 
end;

For version r_keeper 7.5.4.x, enable the Change order category after creation option.

Changing the Main Waiter

Task: to create a script to change the main waiter.

Solution:

procedure ProcessOperation1000813(Parameter: integer);
 
var Props: TVisitOrderInfo;
 
begin
 
Props := TVisitOrderInfo.Create;
 
try
 
Props.MainWaiterID := RK7.FindItemByCode(rkrefEmployees, 21).Ident;
 
RKCheck.UpdateOrderProps(Props);
 
finally
 
Props.Free;
 
end;
 
end;

Changing the Price Type by Setting the Order of Serving Dishes

Task: to create a script that sets serving order No. 1 for dishes of a specified category, and serving order No. 2 for all other dishes.

Solution:

procedure ProcessOperation1002417(Parameter: integer);
 
var CategCode, course1, course2: integer;
 
Categ: TClassificatorGroup;
 
it: TCheckItem;
 
begin
 
if not RKCheck.Valid then
 
exit //important checking
 
else
 
begin
 
CategCodeList := TStringList.Create;
 
//********** Set parameters ***********//
 
CategCode := 27; // code of category 1
 
course1 := 1002378; // serving order 1 ID
 
course2 := 1002379; // serving order 2 ID
 
//********** Set parameters ***********//
 
Categ := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', CategCode));//category code
 
 
while True do begin
 
it := RKCheck.CurrentCheckItem;
 
if TObject(it) = Nil then break;
 
if SYS.ObjectInheritsFrom(TObject(it), 'TPrintCheckItem') then break;
 
if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then
 
if (Categ.IsChild(TDish(it).RefItem)) then // checking category of dish
 
// if TRK7MenuItem(RK7.FindItemBySifr(rkrefMenuItems, TDish(it).Sifr)).genAstor_code = '1' then // check ext property
 
RK7.PerformOperation(rkoMoveCurrentDishToSes, course1); // ident of course
 
else
 
RK7.PerformOperation(rkoMoveCurrentDishToSes, course2); // ident of course;
 
RK7.PerformOperation(rkoDown, 0);
 
end;
 
 
end;
 
end;

Changing the Amount Discount

Task: The discount is tied to the card and works for orders with delivery. Every tenth order should receive a discount of 500 rubles, provided that the average receipt for these 10 orders was at least 500 rubles.

Solution:

procedure ProcessOperation1001902(Parameter: integer);
 
var ed: TObject;
 
it: TCheckItem;
 
begin
 
RK7.PerformOperation(rkoHome, 0);
 
while True do begin
 
it := RKCheck.CurrentCheckItem;
 
if TObject(it) = Nil then break;
 
if SYS.ObjectInheritsFrom(TObject(it), 'TPrintCheckItem') then break;
 
if SYS.ObjectInheritsFrom(TObject(it), 'TDiscountItem') then
 
if TDiscountItem(it).Code = 14 then // specify the discount code
 
if (it.State = disOpened) then // checking the unsaved status of the discount
 
begin
 
ed := TObject(gui.FindComponentByName('Editor'));
 
if SYS.ObjectInheritsFrom(TObject(ed), 'TNumEditor') then
 
begin
 
TNumEditor(ed).Text := IntToStr(trunc(100));
 
RK7.PerformOperation(rkoEditOpenPrice, 0);
 
end;
 
TNumEditor(ed).Text := '';
 
end;
 
RK7.PerformOperation(rkoDown, 0);
 
end;
 
end;

Change the Combo or Dish Size When Pressing a Button

Task: To write a script and make buttons, when pressing which the dish size will change.

Solution:

A script for enlarging the size:

procedure ProcessOperation1002094(Parameter: integer);
 
var NextCateg,Categ1,Categ2, Classif1,Classif2: TClassificatorGroup;
 
it, CurItem: TCheckItem;
 
cv: TObject;
 
mi_d,mi_s: trk7menuitem;
 
ex,i,j,MinSize,MaxSize,ClassifCode1,ClassifCode2,CurSize,NextSize,NextCategCode: integer;
 
begin
 
if not RKCheck.Valid then
 
exit //important checking
 
else
 
begin
 
MinSize := 1;
 
MaxSize := 3;
 
CurItem := RKCheck.CurrentCheckItem;
 
ClassifCode1 := 16; // code classificator of dish type
 
ClassifCode2 := 9; // code classificator of dish size
 
 
if SYS.ObjectInheritsFrom(TObject(CurItem), 'TDish') then // if current item is dish
 
if not TDish(CurItem).IsComboComp then // comment this line if need allow change size for combo-components
 
begin
 
// dbg.dbgprint('dish type');
 
Classif1 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode1));
 
// dbg.dbgprint(inttoStr(Classif1.ChildCount));
 
for i := 0 to Classif1.ChildCount - 1 do begin
 
Categ1 := TClassificatorGroup(Classif1.ChildItem(i));
 
if Categ1.IsChild(CurItem.RefItem) then begin
 
// dbg.dbgprint('Classif1.code='+IntToStr(Classif1.code)+' Categ1.code='+IntToStr(Categ1.code));
 
break;
 
end;
 
end;
 
 
// dbg.dbgprint('dish size');
 
Classif2 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode2));
 
// dbg.dbgprint(inttoStr(Classif2.ChildCount));
 
for i := 0 to Classif2.ChildCount - 1 do begin
 
Categ2 := TClassificatorGroup(Classif2.ChildItem(i));
 
if Categ2.IsChild(CurItem.RefItem) then begin
 
CurSize := Categ2.SortOrder;
 
// dbg.dbgprint('Classif2.code='+IntToStr(Classif2.code)+' Categ2.code='+IntToStr(Categ2.code)+' SortOrder='+IntToStr(Categ2.SortOrder));
 
break;
 
end;
 
end;
 
 
NextSize := CurSize + 1;
 
if NextSize > MaxSize then
 
begin
 
//************for recursy change size **************/
 
// NextSize := MinSize; // uncomment this recursion to resize
 
//************for recursy change size **************/
 
gui.showmessage('reached a maximum size dishes!'); // comment out this recursion to resize
 
exit; // comment out this recursion to resize
 
end;
 
 
// dbg.dbgprint('serch dish size');
 
Classif2 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode2));
 
// dbg.dbgprint(inttoStr(Classif2.ChildCount));
 
for i := 0 to Classif2.ChildCount - 1 do begin
 
Categ2 := TClassificatorGroup(Classif2.ChildItem(i));
 
if Categ2.SortOrder=NextSize then begin
 
NextCategCode := Categ2.Code;
 
NextCateg := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', NextCategCode));
 
// dbg.dbgprint('Classif2.code='+IntToStr(Classif2.code)+' Categ2.code='+IntToStr(Categ2.code)+' SortOrder='+IntToStr(Categ2.SortOrder));
 
break;
 
end;
 
end;
 
 
// dbg.dbgprint('serch dish type size');
 
ex := 0;
 
for i := 0 to Categ1.ChildCount - 1 do begin
 
mi_d := trk7menuitem(Categ1.ChildItem(i));
 
// dbg.dbgprint(inttostr(mi_d.code)+' '+mi_d.RightLangName+' '+inttostr(mi_d.extcode)+' '+inttostr(Categ1.SortOrder)+' '+(mi_d.name)+' ');
 
for j := 0 to Categ2.ChildCount - 1 do begin
 
mi_s := trk7menuitem(NextCateg.ChildItem(j));
 
if mi_d.code = mi_s.code then
 
begin
 
RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(mi_s.code), FloatToStr(TDish(CurItem).Quantity));
 
if CurItem <> Nil then
 
begin
 
cv := TObject(gui.FindComponentByName('CheckView'));
 
if SYS.ObjectInheritsFrom(TObject(cv), 'TCheckView') then
 
TCheckView(cv).GotoItem(CurItem);
 
end;
 
// dbg.dbgprint('BINGO '+inttostr(mi_s.ident)+inttostr(mi_s.code)+' '+mi_s.RightLangName+' '+inttostr(mi_s.extcode)+' '+inttostr(NextCateg.SortOrder)+' '+(mi_s.name)+' ');
 
ex := 1;
 
break;
 
end;
 
end;
 
if ex > 0 then break;
 
end;
 
 
end;
 
end;
 
end;

A script for reducing the size:

procedure ProcessOperation1002112(Parameter: integer);
 
var NextCateg,Categ1,Categ2, Classif1,Classif2: TClassificatorGroup;
 
it, CurItem: TCheckItem;
 
cv: TObject;
 
mi_d,mi_s: trk7menuitem;
 
ex,i,j,MinSize,MaxSize,ClassifCode1,ClassifCode2,CurSize,PrevSize,NextCategCode: integer;
 
begin
 
if not RKCheck.Valid then
 
exit //important checking
 
else
 
begin
 
MinSize := 1;
 
MaxSize := 3;
 
CurItem := RKCheck.CurrentCheckItem;
 
ClassifCode1 := 16; // code classificator of dish type
 
ClassifCode2 := 9; // code classificator of dish size
 
 
if SYS.ObjectInheritsFrom(TObject(CurItem), 'TDish') then // if current item is dish
 
if not TDish(CurItem).IsComboComp then // comment this line if need allow change size for combo-components
 
begin
 
// dbg.dbgprint('dish type');
 
Classif1 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode1));
 
// dbg.dbgprint(inttoStr(Classif1.ChildCount));
 
for i := 0 to Classif1.ChildCount - 1 do begin
 
Categ1 := TClassificatorGroup(Classif1.ChildItem(i));
 
if Categ1.IsChild(CurItem.RefItem) then begin
 
// dbg.dbgprint('Classif1.code='+IntToStr(Classif1.code)+' Categ1.code='+IntToStr(Categ1.code));
 
break;
 
end;
 
end;
 
 
// dbg.dbgprint('dish size');
 
Classif2 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode2));
 
// dbg.dbgprint(inttoStr(Classif2.ChildCount));
 
for i := 0 to Classif2.ChildCount - 1 do begin
 
Categ2 := TClassificatorGroup(Classif2.ChildItem(i));
 
if Categ2.IsChild(CurItem.RefItem) then begin
 
CurSize := Categ2.SortOrder;
 
// dbg.dbgprint('Classif2.code='+IntToStr(Classif2.code)+' Categ2.code='+IntToStr(Categ2.code)+' SortOrder='+IntToStr(Categ2.SortOrder));
 
break;
 
end;
 
end;
 
 
PrevSize := CurSize - 1;
 
if PrevSize < MinSize then
 
begin
 
//************for recursy change size **************/
 
// PrevSize := MaxSize; // uncomment this recursion to resize
 
//************for recursy change size **************/
 
gui.showmessage('reached a minimum size dishes!'); // comment out this recursion to resize
 
exit; // comment out this recursion to resize
 
end;
 
 
// dbg.dbgprint('serch dish size');
 
Classif2 := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', ClassifCode2));
 
// dbg.dbgprint(inttoStr(Classif2.ChildCount));
 
for i := 0 to Classif2.ChildCount - 1 do begin
 
Categ2 := TClassificatorGroup(Classif2.ChildItem(i));
 
if Categ2.SortOrder=PrevSize then begin
 
NextCategCode := Categ2.Code;
 
NextCateg := TClassificatorGroup(getitemBycodeNum('ClassificatorGroups', NextCategCode));
 
// dbg.dbgprint('Classif2.code='+IntToStr(Classif2.code)+' Categ2.code='+IntToStr(Categ2.code)+' SortOrder='+IntToStr(Categ2.SortOrder));
 
break;
 
end;
 
end;
 
 
// dbg.dbgprint('serch dish type size');
 
ex := 0;
 
for i := 0 to Categ1.ChildCount - 1 do begin
 
mi_d := trk7menuitem(Categ1.ChildItem(i));
 
// dbg.dbgprint(inttostr(mi_d.code)+' '+mi_d.RightLangName+' '+inttostr(mi_d.extcode)+' '+inttostr(Categ1.SortOrder)+' '+(mi_d.name)+' ');
 
for j := 0 to Categ2.ChildCount - 1 do begin
 
mi_s := trk7menuitem(NextCateg.ChildItem(j));
 
if mi_d.code = mi_s.code then
 
begin
 
RKCheck.CreateCheckItem(rkrefMenuItems, IntToStr(mi_s.code), FloatToStr(TDish(CurItem).Quantity));
 
if CurItem <> Nil then
 
begin
 
cv := TObject(gui.FindComponentByName('CheckView'));
 
if SYS.ObjectInheritsFrom(TObject(cv), 'TCheckView') then
 
TCheckView(cv).GotoItem(CurItem);
 
end;
 
// dbg.dbgprint('BINGO '+inttostr(mi_s.ident)+inttostr(mi_s.code)+' '+mi_s.RightLangName+' '+inttostr(mi_s.extcode)+' '+inttostr(NextCateg.SortOrder)+' '+(mi_s.name)+' ');
 
ex := 1;
 
break;
 
end;
 
end;
 
if ex > 0 then break;
 
end;
 
 
end;
 
end;
 
end;


  • No labels