Скрипты на операции
Одновременная печать пользовательского макета и сохранение заказа
Задача: Необходим скрипт, который одновременно печатает на кассе пользовательский макет и сохранять заказ. Скрипт использует функциональную клавишу, а та — пользовательский селектор.
Решение:
procedure ProcessOperation1001188(Parameter: integer);
begin
RK7.PerformRefObject( RK7.FindItemByCode(rkrefMaketSchemeDetails, 127) );
RK7.PostOperation(rkoSaveOrder, 0);
end;
Полное удаление чека
Задача: Необходимо создать скрипт, который будет полностью удалять чек.
Решение:
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;
Создание функциональной клавиши «удалить все элементы меню из заказа», в том числе тарификации, но не скидки
Задача: Необходимо создать скрипт для кнопки, которая будет удалять все содержимое, оставляя только свойства заказа и скидки\наценки\предоплаты. Для всех удаляемых элементов указывать только одну причину удаления.
Решение:
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('Не указан код причины списания!');
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); // удаление
continue;
end else
begin
// dbg.dbgprint('void dish');
RKCheck.CreateCheckItem(rkrefOrderVoids, IntToStr(VoidCode), FloatToStr(TDish(it).Quantity)); // списание
end;
end;
// dbg.dbgprint('move down');
step := step + 1;
RK7.PerformOperation(rkoDown, 0);
end;
end;
Создание акции «Блюдо в подарок» в будние дни при достижении суммы заказа в 1000 р
Задача: Необходимо, чтобы в будние дни при достижении суммы заказа в 1000 р и при нажатии кнопки «Сохранить заказ» высвечивалось предложение о добавление бесплатного пива (сорт №1).
Если же сумма заказа достигает 2000р — система предлагает другое пиво (сорт №2), либо два пива сорта №1.
Решение: Создайте скрипт для пользовательской операции, которую надо назначить на селектор вместо стандартного селектора сохранения заказа:
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; // код контролируемого блюда1
DishCode2 := 46; // код контролируемого блюда2
qntMax11 := 1; // максимальное количество контролируемого блюда1 в заказе более 1000.
qntMax12 := 0; // максимальное количество контролируемого блюда2 в заказе более 1000.
qntMax21 := 2; // максимальное количество контролируемого блюда1 в заказе более 2000.
qntMax22 := 1; // максимальное количество контролируемого блюда2 в заказе более 2000.
Time1 := EncodeTime(10,00,00,00); // начало периода акции
Time2 := EncodeTime(18,00,00,00); // конец периода акции
LimitSum1 := 1000; // сумма чека превысив которую будет разрешено добавить бонусное блюдо.
LimitSum2 := 2000; // сумма чека превысив которую будет разрешено добавить бонусное блюдо.
//********** Set parameters ***********//
qnt1 := 0;
qnt2 := 0;
CurrTime := Time;
checksum := 0;
//1 = воскресенье
//2 = понедельник
//3 = вторник
//4 = среда
//5 = четверг
//6 = пятница
//7 = суббота
begin
if (DayOfWeek(Now)>=2)and(DayOfWeek(Now)<=6) then // проверка дня недели
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('Добавить подарочное блюдо Пиво1?', 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('Добавить подарочное блюдо Пиво2?', 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('Добавить подарочное блюдо Пиво1?', 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;
Создание акции «3 по цене 2-х»
Задача: создать акцию «3 по цене 2-х»
Решение: в менеджерской станции r_Keeper_7, в разделе «Скидки и наценки» создайте новую скидку и обязательно выберите:
- тип скидки — «сумма»,
- «изменяемое значение» — включено,
- «на блюдо» — включено,
- «многократно» — включено.
Назначьте данный скрипт на селектор:
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; // код скидки
info := ';';
RK7.PerformOperation(rkoHome, 0);
while True do begin
it := RKCheck.CurrentCheckItem;
if TObject(it) = Nil then break;
Categ := TClassificatorGroup(RK7.FindItemByCode(rkrefClassificatorGroups, 8)); // указать код классификации
if SYS.ObjectInheritsFrom(TObject(it), 'TEmptyLine') then break;
if SYS.ObjectInheritsFrom(TObject(it), 'TDish') then
if Categ.IsChild(it. RefItem) 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 > 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;
Создание скидки 50% на каждое второе блюдо в заказе
Задача: необходим скрипт для создания 50%-ой скидки на каждое второе блюдо в заказе.
Решение: создайте новую скидку с настройками:
- мин. кличество — 2
- кол.режим — «Для всех»
- процент — 50
Назначьте данный скрипт на селектор:
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; // код суммовой открытой скидки на блюдо
perc := 0.5; // % скидки
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;
Данный скрипт делает скидку 50% на все позиции после первой,
Если необходима скидка на каждое второе блюдо то модифицируйте строки:
if a > 1 then begin
q := int64(Trunc(a) div 2);
a := a - 2*q;
Создание скидки 100% на второе блюдо в заказе определенной категории
Задача: создать 100%-ую скидку на второе блюдо определенной категории
Решение:
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;
Создание скидки 100% на первое блюдо из категории
Задача: Создать акцию по флайеру — 1 десерт в подарок. Сумма чека от 500 рублей. Скидка 100% только на одно блюдо из категории «десерты». Цены разные, в чеке может быть несколько десертов. Скидку необходимо дать только один раз на десерт, который попал в заказ первым.
Решение:
скрипт для ручного добавления акции
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 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;
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 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
// 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;
Два скрипта для формы редактирования чека, которые автоматически добавляют/удаляют скидку:
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; // код скидки для акционного блюда
numcateg := 8; // код категории акционного блюда
limitsum := 500; // минимальная сумма заказа в учетом всех скидок
OrderTypeCode := 1; // код типа заказа
GuestTypeIdent := 1000087; // идентификатор типа гостя
// ******************************************************************
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; // код скидки для акционного блюда
numcateg := 8; // код категории акционного блюда
limitsum := 500; // минимальная сумма заказа в учетом всех скидок
OrderTypeCode := 1; // код типа заказа
GuestTypeIdent := 1000087; // идентификатор типа гостя
// ******************************************************************
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;
Создание акции «Детский день рождения. Скидка 10% + Пицца в подарок»
Задача: необходимо настроить акцию «Детский день рождение. Скидка 10% + Пицца в подарок».
Для этого нужно настроить 100%-ую скидку на категорию «пицца», в которой находятся два вида Пицца Домашняя и Пицца Детская. Если в заказе стоят две пиццы из категории "пицца", то 100% скидка действует только на одну пиццу, а на вторую 10%.
Решение: Создайте крипт для селектора «Акция»:
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; // суммовая изменяемая скидка на блюдо
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 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;
end;
finally
SL.Free();
if CurItem <> Nil then CheckView.GotoItem(CurItem);
end;
RKCheck.CurrentOrder.Recalc();
end;
Скрипт для применения скидки 10% автоматически при наличии в заказе у блюда категории скидки 100% :
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; // код скидки "100% на блюдо"
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;
Результат на кассе:
Создание счастливого чека
Задача: Создать скрипт для «счастливого чека» с ограничением
1) по минимальной сумме чека;
2) по общему возможному количеству чеков. Количество чеков зависимости от суммы выручки на данный момент, т.е. если выручка, например, 50 тысяч, то счастливых чеков может быть максимум 5 шт.
Решение:
1) Создайте макет печати в пользовательских отчётах, также, для макета надо создать представление печати.
2) В кассовой форме необходимо добавить компонент TReportPanel:
3) В свойстве «Поведение -- Document» указать ранее созданный макет печати.
4) Вписать скрипт:
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('выручка=',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 максимальная сумма заказа до которой будет разыгрываться счастливый чек
MinOrderSum := 1; // min sum of order минимальная сумма заказа при которой будет разыгрываться счастливый чек
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 //здесь задаётся вероятность срабатывания счастливого чека: 1 - максимальная вероятность; 99 - минимальная вероятность
begin
RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(100)); // add discount вместо 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 //здесь задаётся вероятность срабатывания счастливого чека: 1 - максимальная вероятность; 99 - минимальная вероятность
begin
RKCheck.CreateCheckItem(rkrefDiscounts, IntToStr(DiscCode), FloatToStr(100)); // add discount вместо 100 указать сумму скидки
// dbg.dbgprint('Congratulations!!! Happy Order!!! var2');
gui.ShowMessage('Congratulations!!! Happy Order!!!'); // RkCheck.GetDiscountCount
end;
end;
end;
end;
RK7.PostOperation(rkoBalanceReceipt,0);
end;
Добавление блюда в заказ в момент перехода в режим расчета
Задача: Создать скрипт, добвляющий блюдо в заказ в момент перехода в режим расчета. процесс должен выглядеть так: в режиме быстрого чека при нажатии на кнопку «Расчет заказа» система проверят сумму заказа. Если сумма заказа больше или равно определенной сумме, то система показывает сообщение с кнопками «Да» и «Нет».
При нажатии на «Да», система добавляет блюдо с кодом NNN в заказ и переходит в режим расчета.
При нажатии на «Нет» система сразу переходит в режим расчета
Решение: В быстрый чек добавить пользовательский селектор «Оплата» вместо стандартного. К этому селектору привязать пользовательскую операцию со скриптом:
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;
В данном скрипте заменить сумму «300» на требуемую, а также сменить код добавляемого блюда «39» на актуальное значение.
Блокировка блюд
Задача: Необходимо заменить стандартный селектор «Блюда», чтобы при вводе кода блюда и нажатии этого селектора, блокировались некоторые блюда.
Решение:
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;
Статусы
TDrawItemState = (disNone, disOpened, disLocked, disFixed, disPrinted, disPartClosed, disClosed, disDeleted);
Как получить родителя комбо-элемента в скрипте
Взять у блюда свойство ComboDishUNI, найти блюдо с таким UNI.
В R_Keeper 7.5.5.035 можно сделать так:
RKCheck.CurrentOrder.Sessions.FindByUNI(TDish(it).ComboDishUNI).
В более старых версиях нет функции FindByUNI и для поиска блюда с нужным UNI нужно выполнять перебор по всем блюдам заказа
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;
Добавление модификатора всем блюдам в заказе
Задача: Написать скрипт для селектора, добавляющий модификатор всем блюдам в заказе.
Решение:
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;
Назначьте селекторам пользовательскую операцию с вышеуказанным скриптом и обязательно задайте в свойстве «Параметр для Пусто» и «Параметр» код соответствующего модификатора.
Добавление новой позиции блюда в заказ при нажатии на строку сохраненого блюда и кнопку количество
Задача: При выделении позиции сохраненного блюда и нажатии на кнопку «количество» необходимо добавлять дополнительную позицию внизу заказа. (Функция работала в R-keeper_6). Сейчас при нажатии на позицию с сохраненным блюдом кнопка «количество» неактивна.
Решение:
- Добавить скрипт в скрипты-операции.
- Закрепить скрипт за конкретной пользовательской операцией.
- Операцию закрепить за функциональной клавишей, а клавишу назначить новому селектору.
Скрипт:
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;
Добавление кнопки «Количество» с функцией «Плюс порция сохраненного блюда»
Задача: объединить функции клавиши «Количество» и «Плюс порция сохраненного блюда» (дозаказ))?
Решение:
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;
Быстрая оплата рублями в R_Keeper_7
Задача: при нажатии в режиме быстрого чека на клавиши «Оплатить рубли» или «Оплатить» открывалось сразу окно оплаты наличными, минуя экран выбора типа оплаты.
Решение:
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;
Определение остатка предоплаты по визиту
Задача: Ресторан работает в режиме «карта на входе» через msr-алгоритм. Необходим скрипт, который бы выводил остаток суммы предоплаты по визиту.
Решение:
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('На карте '+CardCode+' остаток '+FloatToStr(Limit)+' р.');
end;
Ограничение скидки на категорию 100%
Задача: Скидка 100% должна примениться к блюдам, попадающим в категорию, только в количестве 1 позиции.
Решение:
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 categore 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 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).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;
Открытие окна браузера для показа операционных отчетов касс
Задача: необходимо создать функциональную клавишу в главном меню кассы, при нажатии на которую будет выполняться команда — fsWeb.exe "https://172.22.4.57:8088/csthtm/overall1.html", где 172.22.4.57 значение расширенного свойства ресторана
Решение:
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;
Скрипт закрепить за пользовательской операцией, которую в, свою очередь, назначить на функциональную клавишу.
Добавление блюда в заказ
Задача: После прокатывания дисконтной картой, на карту клиента должна возвращаться скидка и подарок — блюдо с определенным кодом.
Процесс должен выглядеть так:
1. Создание кнопки в интерфейсе
2. При нажатии на эту кнопку клиент вводит промокод
3. Этот промокод воспринимается как код карты, на него написан соответствующий MCR-алгоритм.
4. Происходит вызов FarCards, получение скидки и кода подарочного блюда. Его можно вернуть в каком-нибудь поле.
5. Это блюдо добавляется в стол и на стол ставится скидка.
Решение:
1) создать скрипт
procedure ProcessOperation1001765(Parameter: integer);
var ed: TObject;
DeviceID : integer;
begin
if not RKCheck.Valid then
exit //important checking
else
begin
DeviceID := 0; // идентификатор интерфейса ПДС
ed := TObject(gui.FindComponentByName('Editor'));
if SYS.ObjectInheritsFrom(TObject(ed), 'TNumEditor') then
if (Pos('1001',TNumEditor(ed).Text)>0)
or (Pos('1002',TNumEditor(ed).Text)>0)
then
gui.showmessage('nevernii promokod!!!')
else
RK7.PerformMCRAlgorith('8989='+TNumEditor(ed).Text, DeviceID);
//RK7.PerformOperation(rkoCreateDish, StrToInt(TNumEditor(ed).Text));
end;
end;
2) В поле ввода кассового терминала вводится промокод (1001 или 1002 в примере). При совпадении введённого промокода с сохранённым в скрипте вызывается MCR-скрипт.
MCR-скрипт нужно создать с такими настройками:
- Основное-Область: Скидка
- Основное-Объект: Скидка использована
Основное-Типы устройств-Скрипт: поставить галочку
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'); // добавление в заказ блюда с кодом 43 Result := True; end; end;
DELPHI
Проверка количества блюд из определенной категории
Задача: Необходим скрипт для проверки количества блюд из определенной категории.
Решение:
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;
Создание дополнительных отчетов при закрытии смены
Задача: создание скрипта для автоматического создания дополнительных отчетов при закрытии смены.
Решение:
procedure ProcessOperation1001784(Parameter: integer);
begin
RK7.PerformRefObject( RK7.FindItemByCode(rkrefMaketSchemeDetails, 184) ); // код представления документа в схемах печати
RK7.PerformOperation(rkoMMCloseCommonShift, 0); // закрытие общей смены
end;
Запрет на отмену пречека в одном заказе более, чем Х раз
Задача: Необходимо запретить отмену пречека в одном заказе более чем Х раз (указывать в параметре)
-1 (по умолчанию) — разрешено отменять бесчисленно
0 — запрещено вообще отменять пречек
1...999 — столько раз можно отменить пречек в заказе/визите
Order >> print pre-check >> cancel pre-check >> print pre-check again >> can not cancel pre-check (system warning and must not allow).
Суперпользователь может отменять чеки всегда, не обращая внимания на данный параметр.
Решение:
- Создать расширенное свойство MaxDelBillCnt типа integer и назначить ресторану.
- В свойствах ресторана задать значение этому свойству.
- Создать скрипт:
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;
Пользовательской операции 15 назначить пустой скрипт:
procedure ProcessOperation1001624(Parameter: integer);
begin
end;
Этой операции включить контроль доступа. Дать право на неё «суперпользователю».
Использование разных типов цен
Задача: необходимо, чтобы при продаже блюд через кассу обычному клиенту (не авторизованному на кассе с помощью карты), цена была «Тип Цен №1», а при продаже блюд клиенту ресторана (авторизованному картой на кассе) — цена была «Тип Цен №2»
Решение:
procedure ProcessOperation1001986(Parameter: integer);
var Props: TVisitOrderInfo;
begin
Props := TVisitOrderInfo.Create();
try
Props.OrderCategoryID := 10033; // указать идентификатор категории заказа
RKCheck.UpdateOrderProps(Props);
finally
Props.Free;
end;
end;
Изменение основного официанта
Задача: создать скрипт для изменения основного официанта.
Решение:
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;
Смена типа цены через задание порядка подачи блюдам
Задача: Необходим скрипт, который для блюд определенной категории задает порядок подачи №1, а для всех остальных — порядок подачи №2.
Решение:
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; // код Категории 1
course1 := 1002378; // идентификатор порядка подачи 1
course2 := 1002379; // идентификатор порядка подачи 2
//********** 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;
Изменение суммовой скидки
Задача: Скидка привязана к карте и работает для заказов с доставкой. Необходимо, чтобы каждый десятый заказ получал скидку 500 рублей, при условии если средний чек по этим 10 заказам был не меньше 500 р.
Решение:
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 // указать код скидки
if (it.State = disOpened) then // проверка несохранённого статуса скидки
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;
Изменение размера комбо или блюда по нажатию кнопки
Задача: Необходимо написать скрипт и сделать кнопки, при нажатии на которые будет автоматически меняется размер блюда.
Решение:
скрипт для увеличения размера
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;
Скрипт для уменьшения размера
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;