Введение

В статье описана настройка "избранного" — списка блюд, к которому можно обращаться с кассовой станции. Там же можно из списка добавлять и удалять блюда. При нажатии кнопки Получить избранное — блюда добавляются к текущему заказу.

Для работы схемы понадобятся XML-интерфейс на сервере справочников, доступный с кассы.

Если версия r_keeper — 7.7.0.222 или выше, о настройке избранных блюд читайте в статье Избранные блюда.

Настройка расширенного свойства

  1. Создайте расширенное свойство с системным именем xmladress
  2. В поле Список типов выберите Система > Ресторан
  3. Название — Адрес XML-интерфейса
  4. Тип свойства — ANSI string
  5. Сохраните изменения

Настройка XML-интерфейса

Создаем XML-интерфейс на сервере справочников.

  1. Перейдите в меню Настройки > OLAP отчеты > Серверы отчетов
  2. Выберите требуемый сервер и в разделе XML Интерфейс укажите свободный порт, который должен быть доступен с кассовой станции.
    Если порт будет недоступен — работать все равно будет, но редактировать избранное на кассе будет нельзя.
  3. Сохраните изменения и перезапустите сервер справочников
  4. Проверьте, что порт доступен и слушается удобным способом, например, с помощью Telnet. Если все хорошо, переходите к следующему пункту

Далее необходимо заполнить расширенное свойство

  1. Перейдите в меню Сервис > Кассовые станции и устройства
  2. Выберите требуемый ресторан, откройте вкладку Свойства
  3. В разделе Расширенные свойства укажите IP-адрес:порт XML-интерфейса в созданном ранее свойстве Адрес XML-интерфейса. Например, 192.16.0.1:583
  4. Сохраните изменения

Настройка классификации

  1. Перейдите в Меню > Классификации блюд и создайте классификацию Классификация для избранного
  2. Внутри этой классификации создайте категорию Избранное

  3. Запомните или запишите Код созданной категории — далее его необходимо указать в теле скриптов
  4. Сохраните изменения

Настройка скриптов

  1. Перейдите в меню Сервис > Скрипты
  2. Выберите группу Операции и создайте скрипты:
  3. Создайте скрипт с названием Пустая и заполните текстом ниже:

    begin
    end;
    CODE
  4. Выберите группу Операции и создайте 3 скрипта, их текст ниже
  5. Не забудьте в тексте скриптов указать код категории Избранное вместо 4097 и код Классификации вместо 4096
  6. Сохраните изменения

Получить избранное

Перед вставкой скрипта, укажите код категории Избранное

procedure ProcessOperation1007303(Parameter: integer);
var
zapros,resp, idents:string;  
dishes:TStringList;
dishstart,dishend:boolean; 
i,k, step:integer;
it:tcheckitem;
begin
     if httppost('https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress,'saasd',resp)<>0 then
       begin       
         gui.showmessage('Сервер справочников по адресу: '+'https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress+' не отвечает.');
         exit;
       end;
     k:=gui.MessageDlgEx('Текущий заказ будет очищен и будет загружено "Избранное"?', mtInformation, mbYes+mbNo, 'Да;Нет');
     if k=6 then 
       begin
         rk7.performoperation(rkoDishSelector,0);
         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      
               RK7.PerformOperation(rkoDeleteLine, 0);                                         
               continue;      
               RK7.PerformOperation(rkoHome, 0);
             end;
           step := step + 1;
           RK7.PerformOperation(rkoDown, 0);
       end;
dishes:=TStringList.Create;    
zapros:='<RK7Query><RK7CMD CMD="GetRefData" RefName="ClassificatorGroups" PropMask="RIChildItems.(code)" WithChildItems="2" RefItemIdent="4097"></RK7CMD></RK7Query>'; // вместо 4097 укажите код своей категории избранное
dishes.Add(zapros);
dishes.SaveToFile('.\test.xml');
dishes.free;
GUI.CmdExecWithFlags('.\runxml.bat', SW_HIDE, false);
dishes:=TStringList.Create;
dishes.LoadFromFile('.\Restest.xml');
for i:= 0 to dishes.Count - 1 do
    begin
      if pos('</RIChildItems>', dishes.strings[i])<>0 then dishend:=true;
      if (dishstart=true) and (dishend<>true) then
        begin 
          idents:=copy(dishes.strings[i],26, length(dishes.strings[i])-28);
          RKCheck.CreateCheckItem(rkrefMenuItems, idents, '1');          
        end;
        if pos('<RIChildItems>', dishes.strings[i])<>0 then dishstart:=true;
    end;
dishes.free;
gui.showmessage('"Избранное" загружено в текущий заказ.');
end;
end;
CODE

Записать избранное

procedure ProcessOperation1007306(Parameter: integer);
var
dishes:TStringList;
idents,cats, cats1,zapros, resp:string;
i,k:integer;
dishstart,dishend:boolean;
it:tcheckitem;
begin
if httppost('https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress,'saasd',resp)<>0 then
       begin      
         gui.showmessage('Сервер справочников по адресу: '+'https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress+' не отвечает.');
         exit;
    end;
if RKCheck.CurrentOrder.ToPaySum=0 then
k:=gui.MessageDlgEx('Текущий заказ пуст, очистить "Избранное"?', mtInformation, mbYes+mbNo, 'Да;Нет'); 
if RKCheck.CurrentOrder.ToPaySum<>0 then k:=gui.MessageDlgEx('Записать блюда текущего заказа в "Избранное"?', mtInformation, mbYes+mbNo, 'Да;Нет');
if k=6 then
begin
dishes:=TStringList.Create;
zapros:='<RK7Query><RK7CMD CMD="GetRefData" RefName="ClassificatorGroups" PropMask="RIChildItems.(ident)" WithChildItems="2" RefItemIdent="4097"></RK7CMD></RK7Query>'; // вместо 4097 укажите код своей категории избранное
dishes.Add(zapros);
dishes.SaveToFile('.\test.xml');
dishes.clear;
dishes.free;
GUI.CmdExecWithFlags('.\runxml.bat', SW_HIDE, false);
dishes:=TStringList.Create;
dishes.LoadFromFile('.\Restest.xml');
for i:= 0 to dishes.Count - 1 do
    begin
      if pos('</RIChildItems>', dishes.strings[i])<>0 then dishend:=true;
      if (dishstart=true) and (dishend<>true) then
        begin
          idents:=copy(dishes.strings[i],27, length(dishes.strings[i])-29);
          cats:=cats+'<Item Ident="'+idents+'" CLASSIFICATORGROUPS-4096="0"></Item>'; // вместо 4096 укажите код своей классификации избранное
        end;
        if pos('<RIChildItems>', dishes.strings[i])<>0 then dishstart:=true;
    end;
dishes.clear;   
cats1:='<?xml version="1.0" encoding="utf-8"?><RK7Query><RK7Command CMD="SetRefData" RefName="MENUITEMS"><Items>'+cats+'</Items></RK7Command></RK7Query>';
dishes.Add(cats1);
dishes.SaveToFile('.\test1.xml');
dishes.free;
GUI.CmdExecWithFlags('.\runxmldel.bat', SW_HIDE, false);
dishes.clear;   
dishes.free;
dishes:=TStringList.Create;
for i:=0 to RKCheck.CurrentOrder.Sessions.LinesCount - 1 do
begin
it:=RKCheck.CurrentOrder.Sessions.Lines[i];
      if SYS.ObjectInheritsFrom(it, 'TDish') then
      if Tdish(it).quantity>0 then
      begin
      idents:=inttostr(TRk7MenuItem(getitemBycodeNum('MenuItems',TDish(it).Code)).ident);
      cats:=cats+'<Item Ident="'+idents+'" CLASSIFICATORGROUPS-4096="4097"></Item>'; // вместо 4096 - код классификации "Классификация для избранного", вместо 4097 - код категории "избранное"
      end;
end;
cats1:='<?xml version="1.0" encoding="utf-8"?><RK7Query><RK7Command CMD="SetRefData" RefName="MENUITEMS"><Items>'+cats+'</Items></RK7Command></RK7Query>';
dbg.dbgprint('!!-!! '+cats1);
dishes.Add(cats1);
dishes.SaveToFile('.\test.xml');
dishes.free;
GUI.CmdExecWithFlags('.\runxml.bat', SW_HIDE, false);
gui.showmessage('Блюда текущего заказа сохранены, как "Избранное".');
end;
end;
CODE

Очистить избранное

procedure ProcessOperation1007309(Parameter: integer);
var
dishes:TStringList;
idents,cats, cats1,zapros,resp:string;
i:integer;
dishstart,dishend:boolean;
it:tcheckitem;
VoidCode, step: integer;
begin
if httppost('https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress,'saasd',resp)<>0 then
       begin      
         gui.showmessage('Сервер справочников по адресу: '+'https://'+TRK7Restaurant(RK7.CashGroup.MainParent).genxmladress+' не отвечает.');
         exit;
       end;
if gui.MessageDlgEx('Очистить "Избранное"?', mtInformation, mbYes+mbNo, 'Да;Нет')=6 then
begin
dishes:=TStringList.Create;
zapros:='<RK7Query><RK7CMD CMD="GetRefData" RefName="ClassificatorGroups" PropMask="RIChildItems.(ident)" WithChildItems="2" RefItemIdent="4097"></RK7CMD></RK7Query>'; // вместо 4097 укажите код своей категории избранное

dishes.Add(zapros);
dishes.SaveToFile('.\test.xml');
dishes.clear;
dishes.free;
GUI.CmdExecWithFlags('.\runxml.bat', SW_HIDE, false);
dishes:=TStringList.Create;
dishes.LoadFromFile('.\Restest.xml');
for i:= 0 to dishes.Count - 1 do
    begin
      if pos('</RIChildItems>', dishes.strings[i])<>0 then dishend:=true;
      if (dishstart=true) and (dishend<>true) then
        begin
          idents:=copy(dishes.strings[i],27, length(dishes.strings[i])-29);
          cats:=cats+'<Item Ident="'+idents+'" CLASSIFICATORGROUPS-4096="0"></Item>';  // вместо 4096 укажите код своей классификации избранное       
        end;
        if pos('<RIChildItems>', dishes.strings[i])<>0 then dishstart:=true;
    end;
dishes.clear;   
cats1:='<?xml version="1.0" encoding="utf-8"?><RK7Query><RK7Command CMD="SetRefData" RefName="MENUITEMS"><Items>'+cats+'</Items></RK7Command></RK7Query>';
dishes.Add(cats1);
dishes.SaveToFile('.\test.xml');
dishes.free;
GUI.CmdExecWithFlags('.\runxml.bat', SW_HIDE, false);
dishes.free;
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
        RK7.PerformOperation(rkoDeleteLine, 0);
        continue;
      end else
      begin
        RKCheck.CreateCheckItem(rkrefOrderVoids, IntToStr(VoidCode), FloatToStr(TDish(it).Quantity));
      end;
      RK7.PerformOperation(rkoHome, 0);
    end;
    step := step + 1;
    RK7.PerformOperation(rkoDown, 0);
  end;
gui.showmessage('"Избранное" очищено.');
end; 
end;
CODE

Настройка операций

Привязка скриптов к операциям

После создания скриптов, их необходимо привязать к пользовательским операциям. Операцию с пустым скриптом назовите Вызов избранного.

  1. Перейдите в меню Сервис > Операции 
  2. Выберите раздел Пользовательские операции 
  3. Операцию, к которой привяжете пустой скрипт, назовите Вызов избранного и обязательно поставьте галочку Изм. страницу
  4. Выберите 4 незанятые операции и назначьте им созданные ранее скрипты. Для удобства назовите операции аналогично скриптам
  5. Сохраните изменения

Привязка операций к кнопкам

Назначьте операции функциональным клавишам.

  1. Перейдите в меню Настройки > Графический интерфейс > Функциональные клавиши
  2. Создайте функциональные клавиши, привязанные к ранее созданным скриптам
  3. Перейдите в меню Настройки > Графический интерфейс > Селекторы и выберите раздел Заказ > Чек: Главный селектор > Пользовательский
  4. Создайте страницу селектора с названием Избранное
  5. Добавьте на селектор категорию Избранное из классификации для избранного
  6. Вернитесь к селектору Избранное и в свойствах назначьте операцию Вызов избранного
  7. Перейдите в меню Настройки > Графический интерфейс > Использование селекторов
  8. В левом верхнем выпадающем меню выберите пункт Чек: Главный селектор
  9. Перетащите отредактированный — пользовательский селектор из левого поля в правое
  10. Перейдите в меню Селекторы > Селектор операций > Быстрый чек: Селектор операций
  11. Сделайте копию селектора Быстрый чек: операции
  12. Отредактируйте страницы селектора, разместив на них функциональные клавиши которые создали ранее.
  13. Для примера мы создали отдельную страницу селектора Настройка избранного в котором разместили клавиши для записи, чтения и очистки избранного
  14. Ссылку на созданную страницу поместили на страницу Доп.
  15. Функциональную клавишу Избранное, которая будет вызывать само избранное разместили на странице Селектор операций, чтобы она была доступна на старте
  16. Перейдите в меню Настройка > Графический интерфейс > Использование селекторов
  17. В левом выпадающем меню выберите Быстрый чек: Селектор операций
  18. Перетащите созданный селектор из правого поля в левое
  19. Сохраните изменения

Настройка кассовой станции

  1. Скачайте приложенный к статье архив
  2. В bat-файле runxml.bat измените IP-адрес и порт на текущие адрес и порт XML-интерфейса сервера справочников. моем случае это — 583
  3. Поместите файлы runxml.bat и xmltest.exe в папку из которой запускается касса
  4. Готово, настройка завершена. Можно запускать кассовую станцию и пользоваться функционалом.