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; |
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; |
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; |
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; |
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:

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; |
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:
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; |
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; |
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; |
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; |
Task: To create a script for a happy receipt limited by
Solution:


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; |
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.
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; |
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.
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:
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; |
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; |
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; |
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; |
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 POS Operation Reports
Mission: It is required to create a function button in the main POS menu that when pressed 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
Mission: After swiping a discount card, a discount, and a gift (a dish having a certain code) should be awarded to the customer card.
The process is as follows:
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 identifier
ed := TObject(gui.
Scripts for Using Discounts Scripts in Forms