Страница 1 из 1

Использование фискального регистратора "Феликс-РФ"

Добавлено: 09 сен 2008, 14:19
Olga T
Работаем в модуле "Розничная торговля". Можно ли как-то использовать для печати чеков фискальный регистратор из самой Галактики?

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 27 мар 2017, 14:24
spark
Для нас тоже стала актуальной тема печати на фискальный регистратор в связи с 54-ФЗ.

Есть у кого-нибудь опыт реализации такой печати?

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 27 мар 2017, 19:08
YuryN
Лет 12 назад у нас была когда-то похожая задача - работать на удаленном складе с кассовым аппаратом.

Нашли описание структуры данных и команд для этого аппарата.

Написали софтинку на DELPHI, которая выполняла несколько функций:

1) При печати накладной на отпуск шла выгрузка в dbf и вызов программы с параметром,
которая из dbf закачивала данные в аппарат и печатала чек.
2) Отчет кассира в конце смены.
3) Фискальный отчет за период.
4) Что-то еще, уже не помню.

Думаю, что-то подобное можно сделать и в вашем случае.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 12 май 2017, 15:03
Bandito_Gangsterito
spark писал(а):Для нас тоже стала актуальной тема печати на фискальный регистратор в связи с 54-ФЗ.

Есть у кого-нибудь опыт реализации такой печати?
Я реализовал печать чеков для кассового аппарата ВМ 8117 http://zabela.by/katalog/kassovoe_oboru ... _8117.html из накладной на реализацию.
Подключены сканер штрихкодов для ввода товара для продажи, табло покупателя FXP-3220 VFP http://zabela.by/katalog/oborudovanie_d ... 0_vfp.html.
Печатаются чеки продажи, чеки возврата.
Взаимодействие происходит с помощь программы Белмаг.Сервер.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 12 май 2017, 15:28
maikl
Bandito_Gangsterito писал(а):
spark писал(а):Для нас тоже стала актуальной тема печати на фискальный регистратор в связи с 54-ФЗ.

Есть у кого-нибудь опыт реализации такой печати?
Я реализовал печать чеков для кассового аппарата ВМ 8117 http://zabela.by/katalog/kassovoe_oboru ... _8117.html из накладной на реализацию.
Подключены сканер штрихкодов для ввода товара для продажи, табло покупателя FXP-3220 VFP http://zabela.by/katalog/oborudovanie_d ... 0_vfp.html.
Печатаются чеки продажи, чеки возврата.
Взаимодействие происходит с помощь программы Белмаг.Сервер.
Так нужен исходный текст, а не ссылка на модели.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 12 май 2017, 17:08
spark
maikl писал(а):
Bandito_Gangsterito писал(а):
spark писал(а):Для нас тоже стала актуальной тема печати на фискальный регистратор в связи с 54-ФЗ.

Есть у кого-нибудь опыт реализации такой печати?
Я реализовал печать чеков для кассового аппарата ВМ 8117 http://zabela.by/katalog/kassovoe_oboru ... _8117.html из накладной на реализацию.
Подключены сканер штрихкодов для ввода товара для продажи, табло покупателя FXP-3220 VFP http://zabela.by/katalog/oborudovanie_d ... 0_vfp.html.
Печатаются чеки продажи, чеки возврата.
Взаимодействие происходит с помощь программы Белмаг.Сервер.
Так нужен исходный текст, а не ссылка на модели.
Да, было бы очень интересно и полезно... Хотя я так понимаю, что эта касса конечно к 54ФЗ мало отношения имеет, но хотя бы сам принцип.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 15 май 2017, 12:46
Bandito_Gangsterito
Программа Белмаг.Сервер позволят печать чеки с помощью командных файлов (их описание есть в справке). Белмаг.Сервер с определенным интервалом проверяет содержимое файлов и при наличии в них команд, выдает их кассовому аппарату (с заполнением данных в фискальной памяти). От нас требуется заполнение командных файлов. Эти файлы в dbf-формате.

Вот команда для печати чека продажи:

Код: Выделить всё

  cmButtonNaklSale:
  {
   v_rzspdoc.c_sopr:=rzdoc.nrec;
   sPath:=sGetTune('ROZN.BELMAG');
   if(sPath='') {message('Не установлен каталог для обмена данными с БелМАГ.СЕРВЕР торгового оборудования'+chr(13)+'');exit;}  //каталог с dbf
   sPass:=sGetTune('ROZN.BELMAGPASS');
   if(sPass='') {message('не установлен пароль кассира БелМАГ.СЕРВЕР торгового оборудования'+chr(13)+'');exit;}                //пароль кассира

   if(TimeToStr(tGetAttr(30003, rzdoc.nrec, 'Время чека'), 'HH:MM')<>'00:00')
    {
      if(message('Напечатать чек повторно?', yesNo+Confirmation+mfSwapButtons )=cmNo )
      {exit;}
    }

   sFileData:='sale.dbf';               //файл со списком МЦ для продажи
   sFileCommand:='command.dbf';         //
   sFileCommandTmp:='commandTmp.dbf';   //временный файл для послед. замены command.dbf
   dSumItog:=0;                         //Итоговая сумма по чеку

   liDbfData:=DBFOpen(sPath+sFileData, stCreate);
   if(liDbfData=0) {Message('Не могу создать файл!'+chr(13)+sPath+sFileData);exit;}
   else
   {
    DBFAddfield(liDbfData, 'npp', DbNum, 2, 0);
    DBFAddfield(liDbfData, 'OperType', DbNum, 1, 0);
    DBFAddfield(liDbfData, 'plu', DbChar, 18, 0);
    DBFAddfield(liDbfData, 'pluName', DbChar, 60, 0);
    DBFAddfield(liDbfData, 'price', DbNum, 12, 2);
    DBFAddfield(liDbfData, 'q', DbNum, 13, 3);
    DBFAddfield(liDbfData, 'Summa', DbNum, 15, 2);
    iStructRes:=DBFAddfield(liDbfData, 'department', DbNum, 3, 0);
   }
   if(iStructRes<>0) {Message('Ошибка заполнения структуры файла!'+chr(13)+sPath+sFileData);exit;}

   liDbfCommand:=DBFOpen(sPath+sFileCommandTmp, stCreate);
   if(liDbfCommand=0) {Message('Не могу открыть файл!'+chr(13)+sPath+sFileCommand);exit;}
   else
   {
    DBFAddfield(liDbfCommand, 'rowid', DbNum, 10, 0);
    DBFAddfield(liDbfCommand, 'serverid', DbNum, 3, 0);
    DBFAddfield(liDbfCommand, 'eqId', DbNum, 10, 0);
    DBFAddfield(liDbfCommand, 'password', DbChar, 10, 0);
    DBFAddfield(liDbfCommand, 'commandId', DbNum, 3, 0);
    DBFAddfield(liDbfCommand, 'fileName', Dbchar, 250, 0);
    DBFAddfield(liDbfCommand, 'flag', DbNum, 1, 0);
    DBFAddfield(liDbfCommand, 'info', DbChar, 250, 0);
    iStructCom:=DBFAddfield(liDbfCommand, 'department', DbNum, 3, 0);
   }
   if(iStructRes<>0) {Message('Ошибка заполнения структуры файла!'+chr(13)+sPath+sFileCommand);exit;}

   n_pp:=1;
   v_rzspdoc._LOOP rzspdoc
   {
    DBFClearBuffer(liDbfData);
    DBFPutFieldValue(liDbfData, 'npp', string(n_pp));
    DBFPutFieldValue(liDbfData, 'OperType', string(1));
    DBFPutFieldValue(liDbfData, 'plu', v_rzspdoc.katmc.barkod);
    DBFPutFieldValue(liDbfData, 'pluName', string(v_rzspdoc.katmc.name));
    DBFPutFieldValue(liDbfData, 'price', string(v_rzspdoc.rzspdoc.pprice, 12, 2));
    DBFPutFieldValue(liDbfData, 'q', string(v_rzspdoc.rzspdoc.kol, 13, 3));
    DBFPutFieldValue(liDbfData, 'summa', string(v_rzspdoc.rzspdoc.pprice*v_rzspdoc.rzspdoc.kol, 15, 2));
    DBFPutFieldValue(liDbfData, 'department', string(1));  //наличные
    DBFInsertRecord (liDbfData);
    dSumItog:=dSumItog+v_rzspdoc.rzspdoc.pprice*v_rzspdoc.rzspdoc.kol;
    n_pp++;
   }

    DBFClearBuffer(liDbfData);
    DBFPutFieldValue(liDbfData, 'npp', string(n_pp));
    DBFPutFieldValue(liDbfData, 'OperType', string(3));
    DBFPutFieldValue(liDbfData, 'summa', string(dSumItog, 15, 2));
    DBFInsertRecord (liDbfData);
    n_pp++;
    DBFClearBuffer(liDbfData);
    DBFPutFieldValue(liDbfData, 'npp', string(n_pp));
    DBFPutFieldValue(liDbfData, 'OperType', string(4));
    DBFPutFieldValue(liDbfData, 'department', string(0)); //нал
    DBFPutFieldValue(liDbfData, 'summa', string(dSumItog, 15, 2));
    DBFInsertRecord (liDbfData);

    DBFPutFieldValue(liDbfCommand, 'rowid', string(1,10,0));
    DBFPutFieldValue(liDbfCommand, 'serverId', string(1,3,0));
    DBFPutFieldValue(liDbfCommand, 'eqId', string(1,10,0));
    DBFPutFieldValue(liDbfCommand, 'password', sPass);
    DBFPutFieldValue(liDbfCommand, 'commandId', '100');
    DBFPutFieldValue(liDbfCommand, 'fileName', 'sale.dbf');
    DBFPutFieldValue(liDbfCommand, 'flag', '0');
    DBFInsertRecord (liDbfCommand);

    DbfClose(liDbfData);
    DbfClose(liDbfCommand);
    bFileReplace:=false;
    for(i:=0;i<=1000;i:=i+1)
    {
     bFileReplace:=CopyMoveFile(sPath+sFileCommandTmp, sPath+sFileCommand, true, 4 );
     if(bFileReplace) break;
    }
    if(NOT bFileReplace) {Message('Ошибка создания команды кассовому аппарату.');exit;}
    DeleteFile(sFileCommandTmp);

    piExAttr.dSetAttr(30003, rzdoc.nrec, 'Дата чека', Cur_Date);  //Установить дату чека - вн. аттр.
    piExAttr.tSetAttr(30003, rzdoc.nrec, 'Время чека', Cur_Time); //Установить время чека - вн. аттр.
    UPDATE CURRENT rzdoc SET typeplat:=word(1);
    ReReadRecord(#rzdoc); ReReadRecord(#RZSPDOC);
    ShowInfoOnTablo(0, '', 0, 0);
  }
дату и время печати чека я храню во внешних атрибутах.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 26 май 2017, 19:14
spark
Итак... что удалось накопать... Во-первых вот неплохое ПО для интеграции с кассами - https://kkmserver.ru/KkmServer

Там ставится простенький веб-сервер, на который передается специально подготовленный json и на выходе получается чек. Очень все компактно, быстро и аккуратно. И не дорого.
Мы из галактики запускаем файл скрипта на PowerShell, которому передаем nrec накладной. PowerShell лезет в MSSQL базу галактики, собирает там все нужные данные, формирует json и передает этому ккмсерверу. На выходе получаем чек. И не нужны драйвера касс даже.
Код в галактике вот такой:

Код: Выделить всё

cmFiscality:
{
 var aDosCode, aErrorCode: integer;
 aDosCode:= ExecProgram('powershell' , '-file %StartPath%\RegisterCheck.ps1 -nrec ' + katsopr.nrec , 'Печать чека', pfSilent, aErrorCode);
 if aDosCode <> 0
 {
  Message('Программа не запустилась !', mfError);
 }
} 
Также проработали запасной вариант с драйвером. Для тестов используем фискальный регистратор Атол 25Ф.
Код в галактике вот такой:

Код: Выделить всё

cmFiscality:
{
 var DrvOle           : pointer;
 DrvOle := OleCreate('AddIn.FPrnM45');
 if LongInt(DrvOle) = 0 then Exit;
/* OleCall0(DrvOle, ocProc, 'AddDevice');
 OleCall1(DrvOle, ocPut, 'Model', 57);
 OleCall1(DrvOle, ocPut, 'UseAccessPassword', 1);
 OleCall1(DrvOle, ocPut, 'DefaultPassword', 30);
 OleCall1(DrvOle, ocPut, 'PortNumber', 99);
 OleCall1(DrvOle, ocPut, 'BaudRate', 18);
 OleCall1(DrvOle, ocPut, 'DeviceEnabled', 1);
 OleCall1(DrvOle, ocPut, 'HostAddress', '192.168.3.215:5555');
 OleCall1(DrvOle, ocPut, 'Password', 30);
*/
// OleCall0(DrvOle, ocProc, 'ShowProperties');
 OleCall1(DrvOle, ocPut, 'DeviceEnabled', 1);
 OleCall0(DrvOle, ocProc, 'Beep');

 OleCall1(DrvOle, ocPut, 'Mode', 1);
 OleCall0(DrvOle, ocProc, 'SetMode');
 OleCall0(DrvOle, ocProc, 'NewDocument');
 OleCall1(DrvOle, ocPut, 'AttrNumber', 1021);
 OleCall1(DrvOle, ocPut, 'AttrValue', 'Старший кассир Фискалов Ф.Ф.');
 OleCall0(DrvOle, ocProc, 'WriteAttribute');
 OleCall0(DrvOle, ocProc, 'OpenSession');
 OleCall1(DrvOle, ocPut, 'CheckType', 1);
 OleCall1(DrvOle, ocPut, 'CheckMode', 1);
 OleCall0(DrvOle, ocProc, 'OpenCheck');
 OleCall1(DrvOle, ocPut, 'AttrNumber', 1055);
 OleCall1(DrvOle, ocPut, 'AttrValue', 4);
 OleCall0(DrvOle, ocProc, 'WriteAttribute');
 OleCall1(DrvOle, ocPut, 'AttrNumber', 1008);
 OleCall1(DrvOle, ocPut, 'AttrValue', 'aa@aa.ru');
 OleCall0(DrvOle, ocProc, 'WriteAttribute');

  OleCall1(DrvOle, ocPut, 'Caption', 'Просто строка в чеке');
  OleCall0(DrvOle, ocProc, 'PrintString');
 _loop spsopr
 {
  if getfirst katmc where ((spsopr.cmcusl==katmc.nrec)) = tsok {}
  OleCall1(DrvOle, ocPut, 'Name', katmc.name);
  OleCall1(DrvOle, ocPut, 'Price', spsopr.rprice);
  OleCall1(DrvOle, ocPut, 'Quantity', spsopr.kolfact);
  OleCall1(DrvOle, ocPut, 'Department', 2);
  OleCall0(DrvOle, ocProc, 'Registration');
 }

 OleCall1(DrvOle, ocPut, 'Destination', 0);
 OleCall1(DrvOle, ocPut, 'Summ',0);
 OleCall0(DrvOle, ocProc, 'SummDiscount')

 OleCall1(DrvOle, ocPut, 'Summ', katsopr.summa);
 OleCall1(DrvOle, ocPut, 'TypeClose', 0);
 OleCall0(DrvOle, ocProc, 'Payment');
 OleCall0(DrvOle, ocProc, 'CloseCheck');

 //OleCall0(DrvOle, ocProc, 'ShowProperties');
 OleCall0(DrvOle, ocProc, 'Beep');//Гудок
 if Message('Закрыть смену?', yesNo+Confirmation+mfSwapButtons) = cmYes
 {
  OleCall1(DrvOle, ocPut, 'Mode', 3);
  OleCall0(DrvOle, ocProc, 'SetMode');
  OleCall0(DrvOle, ocProc, 'NewDocument');
  OleCall1(DrvOle, ocPut, 'AttrNumber', 1021);
  OleCall1(DrvOle, ocPut, 'AttrValue', 'Старший кассир Фискалов Ф.Ф.');
  OleCall0(DrvOle, ocProc, 'WriteAttribute');
  OleCall1(DrvOle, ocPut, 'ReportType', 1);
  OleCall0(DrvOle, ocProc, 'Report');
 }
 OleDestroy(DrvOle); //уничтожить объект
} 
Эти коды вырваны из контекста. На самом деле пока это пункты контекстного меню в накладной, поэтому подразумевается, что цикл по spsopr проходит в контексте накладной.

Написал это все для истории и для того, чтобы обратить внимание тех, кто страдает с этим 54ФЗ как и мы... =)
Готов ответить на вопросы по деталям работы этого всего. Хотя сами мы в фискальном режиме с этим всем еще не работали, готовимся к 1 июля...
Давайте дружить Галактиками :smile:

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 31 май 2017, 00:55
LaaLaa
Не имею опыта работы с фискальными регистраторами. Предполагаю что можно пробовать делать печатные формы на FastReport. В частности может быть сработает матричный стиль отчетов FastReport.

Еще на FastScript в отчете можно делать CreateOleObject получать таким образом вариантную ссылку на объекты и работать дальше прозрачно с этими объектами.

Может быть эта информация комуто поможет подружить отчеты с фискалными регистраторами.

Re: Использование фискального регистратора "Феликс-РФ"

Добавлено: 20 июл 2017, 18:42
2dragon2
У меня практически получилось описать печать чека но только товары без НДС.
Может кто подскажет как правильно передавать НДС ? у меня Штрих-М ККТ
В драйвере используется TAX1..4. как правильно ими пользоваться