Operation Scripts
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:
- Count type: Amount
- Changeable Value: enabled
- Allow Multiple: enabled
- 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:
- Min. quantity: 2
- Qty mode: For all
- 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
- The minimal receipt amount
- 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:
- Create a print layout in the user reports and a print view for this layout
- In the Options > User Interface > Forms, add the TReportPanel component to the cash form in the Form editor:
- Specify the previously created print layout in the Behavior > Document property
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;
CODE
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:
- Add a script to the operation scripts
- Assign the script to the specific user operation
- 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:
- Creating a button in the interface
- Once this button is pressed, a customer enters a promo code
- This promo code is read as the card code, there is a corresponding MCR algorithm written for it
- FarCards is called, a discount and a free dish are received. It can be indicated in some field.
- This dish is added to a table and the discount is applied to it.
Solution:
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;
CODEIn 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;
CODE
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:
- Create the MaxDelBillCnt extended property of the integer type and assign it to the restaurant
- In the properties of the restaurant, specify a value for this property
- 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;