Одновременная печать пользовательского макета и сохранение заказа

Задача: Необходим скрипт, который одновременно печатает на кассе пользовательский макет и сохранять заказ. Скрипт использует функциональную клавишу, а та — пользовательский селектор.

Решение:

procedure ProcessOperation1001188(Parameter: integer);
begin

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

RK7.PostOperation(rkoSaveOrder, 0);

end;
DELPHI

Полное удаление чека

Задача: Необходимо создать скрипт, который будет полностью удалять чек.

Решение:

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

Создание функциональной клавиши «удалить все элементы меню из заказа», в том числе тарификации, но не скидки

Задача:  Необходимо создать скрипт для кнопки, которая будет удалять все содержимое, оставляя только свойства заказа и скидки\наценки\предоплаты. Для всех удаляемых элементов указывать только одну причину удаления.

Решение:

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

Создание акции «Блюдо в подарок» в будние дни при достижении суммы заказа в 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;
DELPHI

Создание акции «3 по цене 2-х»

Задача: создать акцию «3 по цене 2-х»

Решение: в менеджерской станции r_Keeper_7, в разделе «Скидки и наценки» создайте новую скидку и обязательно выберите: 

  1. тип скидки  — «сумма»,
  2. «изменяемое значение» — включено,
  3. «на блюдо» — включено,
  4. «многократно» — включено.

Назначьте данный скрипт на селектор:

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

Создание скидки 50% на каждое второе блюдо в заказе

Задача: необходим скрипт для создания 50%-ой скидки на каждое второе блюдо в заказе.

Решение: создайте новую скидку с настройками: 

  1. мин. кличество — 2
  2. кол.режим — «Для всех»
  3. процент — 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;
DELPHI


Данный скрипт делает скидку 50% на все позиции после первой,

Если необходима скидка на каждое второе блюдо то модифицируйте строки:

if a > 1 then begin

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

a := a - 2*q;
DELPHI

Создание скидки 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;
DELPHI

Создание скидки 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;
DELPHI

Два скрипта для формы редактирования чека, которые автоматически добавляют/удаляют скидку:


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


Создание акции «Детский день рождения. Скидка 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;
DELPHI
Блюду обязательно выставить свойство «Добавление в заказ» — «Отдельная строка для каждой порции».

Скрипт для применения скидки 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;
DELPHI


Результат на кассе:

Создание счастливого чека

Задача: Создать скрипт для «счастливого чека» с ограничением

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

Добавление блюда в заказ в момент перехода в режим расчета

Задача: Создать скрипт, добвляющий блюдо в заказ в момент перехода в режим расчета. процесс должен выглядеть так: в режиме быстрого чека при нажатии на кнопку «Расчет заказа» система проверят сумму заказа. Если сумма заказа больше или равно определенной сумме, то система показывает сообщение с кнопками «Да» и «Нет».

При нажатии на «Да», система добавляет блюдо с кодом 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; 
DELPHI

В данном скрипте заменить сумму «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;
DELPHI

Статусы

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

Как получить родителя комбо-элемента в скрипте

Взять у блюда свойство ComboDishUNI, найти блюдо с таким UNI.

В R_Keeper 7.5.5.035 можно сделать так:

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

В более старых версиях нет функции 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;
DELPHI

Добавление модификатора всем блюдам в заказе

Задача: Написать скрипт для селектора, добавляющий модификатор всем блюдам в заказе.

Решение:

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

Назначьте селекторам пользовательскую операцию с вышеуказанным скриптом и обязательно задайте в свойстве «Параметр для Пусто» и «Параметр» код соответствующего модификатора.

Добавление новой позиции блюда в заказ при нажатии на строку сохраненого блюда и кнопку количество

Задача:  При выделении позиции сохраненного блюда и нажатии на кнопку «количество»  необходимо добавлять дополнительную позицию внизу заказа. (Функция работала в R-keeper_6). Сейчас при нажатии на позицию с сохраненным блюдом кнопка «количество» неактивна.

Решение: 

  1. Добавить скрипт в скрипты-операции.
  2. Закрепить скрипт за конкретной пользовательской операцией.
  3. Операцию закрепить за функциональной клавишей, а клавишу назначить новому селектору.

Скрипт:

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

Добавление кнопки «Количество» с функцией «Плюс порция сохраненного блюда»

Задача: объединить функции клавиши «Количество» и «Плюс порция сохраненного блюда» (дозаказ))?

Решение:

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

Быстрая оплата рублями в 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;
DELPHI

Определение остатка предоплаты по визиту

Задача: Ресторан работает в режиме «карта на входе» через 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;
DELPHI

Ограничение скидки на категорию 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;
DELPHI

Открытие окна браузера для показа операционных отчетов касс

Задача: необходимо создать функциональную клавишу в главном меню кассы, при нажатии на которую будет выполняться команда — 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;
DELPHI

Скрипт закрепить за пользовательской операцией, которую в, свою очередь, назначить на функциональную клавишу.

Добавление блюда в заказ

Задача: После прокатывания дисконтной картой, на карту клиента должна возвращаться скидка и подарок — блюдо с определенным кодом.

Процесс должен выглядеть так:

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

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

Создание дополнительных отчетов при закрытии смены

Задача: создание скрипта для автоматического создания дополнительных отчетов при закрытии смены.

Решение:

procedure ProcessOperation1001784(Parameter: integer);

begin

RK7.PerformRefObject( RK7.FindItemByCode(rkrefMaketSchemeDetails, 184) ); // код представления документа в схемах печати

RK7.PerformOperation(rkoMMCloseCommonShift, 0); // закрытие общей смены

end;
DELPHI

Запрет на отмену пречека в одном заказе более, чем Х раз

Задача: Необходимо запретить отмену пречека в одном заказе более чем Х раз (указывать в параметре)

-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).

Суперпользователь может отменять чеки всегда, не обращая внимания на данный параметр.

Решение:

  1. Создать расширенное свойство MaxDelBillCnt типа integer и назначить ресторану.
  2. В свойствах ресторана задать значение этому свойству.
  3. Создать скрипт:
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;
DELPHI

Пользовательской операции 15 назначить пустой скрипт:

procedure ProcessOperation1001624(Parameter: integer);

begin


end;
DELPHI

Этой операции включить контроль доступа. Дать право на неё «суперпользователю».

Использование разных типов цен

Задача: необходимо, чтобы при продаже блюд через кассу обычному клиенту (не авторизованному на кассе с помощью карты), цена была «Тип Цен №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;
DELPHI


для версии R_Keeper 7.5.4.х включить параметр  «Изменить категорию заказа после создания»

Изменение основного официанта

Задача: создать скрипт для изменения основного официанта.

Решение:

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

Смена типа цены через задание порядка подачи блюдам

Задача: Необходим скрипт, который для блюд определенной категории задает порядок подачи №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;
DELPHI

Изменение суммовой скидки

Задача: Скидка привязана к карте и работает для заказов с доставкой. Необходимо, чтобы каждый десятый заказ получал скидку 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;
DELPHI

Изменение размера комбо или блюда по нажатию кнопки

Задача: Необходимо написать скрипт и сделать кнопки, при нажатии на которые будет автоматически меняется размер блюда.

Решение:

скрипт для увеличения размера

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

Скрипт для уменьшения размера

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