Внешние фискальные регистраторы
Если в списке поддерживаемых моделей фискальных регистраторов (ФР) в iiko вы не нашли нужной вам модели, вы можете написать свою поддержку интересующей вас модели ФРа. Это будет плагин, подключаемый к iikoFront — внешний ФР. Cм. введение. Для плагинов, реализующих внешние ФРы, вводится специальное лицензирование.
Подключение внешнего фискального регистратора
Подключение внешнего ФРа состоит из 2 шагов.
Шаг 1: Зарегистрировать новую модель ФРа.
Для этого нужно реализовать интерфейс ICashRegisterFactory
и зарегистрировать его посредством вызова методов API:
var cashRegisterFactory = new SampleCashRegisterFactory();
PluginContext.Operations.RegisterCashRegisterFactory(cashRegisterFactory);
Это нужно для того, чтобы в iikoRMS появилась ваша новая модель ФРа, которую потом можно будет добавить и подключить как контрольно-кассовую технику (ККТ) к кассе.
Шаг 2: Добавить ФР новой модели.
Для этого нужно реализовать интерфейс ICashRegister
и создавать его экземпляр в методе ICashRegisterFactory.Create()
:
class SampleCashRegisterFactory : MarshalByRefObject, ICashRegisterFactory
{
...
public ICashRegister Create(Guid deviceId, [NotNull] CashRegisterSettings settings)
{
if (settings == null)
throw new ArgumentNullException(nameof(settings));
return new SampleCashRegister(deviceId, settings);
}
}
По нажатию «Завершить» в окне добавления ФРа (iikoOffice => «Настройки оборудования»), будет вызван метод ICashRegisterFactory.Create()
, который добавит новый ФР в список оборудования.
После этого iikoRMS сможет общаться с внешним ФРом, отправлять ему команды и принимать его ответы.
Настройки фискального регистратора CashRegisterSettings
Каждое оборудование имеет свой набор настроек IDeviceFactory.DefaultDeviceSettings
:
interface IDeviceFactory
{
...
[NotNull]
DeviceSettings DefaultDeviceSettings { get; }
}
Произвольные настройки:
В зависимости от модели ФРа, набор настроек может различаться.
Для этого предусмотрен контейнер произвольных настроек DeviceSettings.Settings
:
class DeviceSettings
{
...
List<DeviceSetting> Settings { get; set; }
}
Варианты настроек:
- bool — галочка —
DeviceBooleanSetting
- string — текстовое поле —
DeviceStringSetting
- number — числовое поле
DeviceNumberSetting
: — целоеDeviceNumberSettingKind.Integer
, — дробноеDeviceNumberSettingKind.Decimal
, — количественное, со стрелками управления —DeviceNumberSettingKind.Amount
- enum — перечисление с заданным набором значений
DeviceCustomEnumSetting
: — выпадающий список —DeviceCustomEnumSetting.IsList = true
— радиогруппа —DeviceCustomEnumSetting.IsList = false
Значение перечисления описывается типомDeviceCustomEnumSettingValue
.
Все настройки из коллекции DeviceSettings.Settings
при подключении ФРа попадают на вкладку «Дополнительные настройки»:
Обязательные настройки:
Есть настройки, которые присутствуют в любой модели ФРа. К ним относятся:
CashRegisterSettings.Font0Width
— ширина чековой ленты (вкладка «Основные настройки»).CashRegisterSettings.OfdProtocolVersion
— версия протокола формата фискальных данных, далее ФФД (вкладка «Основные настройки»). Актуально только для РФ.CashRegisterSettings.FiscalRegisterTaxItems
— список регистров ФРа, соответствующие налоговым категориям (вкладка «Налоговые категории»).
CashRegisterSettings.FiscalRegisterTaxItems
— список регистров ФРа, соответствующие типам оплат (вкладка «Типы оплат и регистры»).
class CashRegisterSettings : DeviceSettings
{
[CanBeNull]
DeviceNumberSetting Font0Width;
[CanBeNull]
DeviceCustomEnumSetting OfdProtocolVersion;
List<FiscalRegisterTaxItem> FiscalRegisterTaxItems;
List<FiscalRegisterPaymentType> FiscalRegisterPaymentTypes;
}
Взаимодействие iikoFront с внешним фискальным регистратором
Взаимодействие iikoFront с внешним ФРом происходит через интерфейс ICashRegister
.
Именно он отвечает за поведение внешнего ФРа.
К примеру, если в iikoFront происходит оплата заказа, управление придет в команду ICashRegister.DoCheque()
с необходимыми данными ChequeTask
для проведения операции на ФР. iikoFront будет ждать выполнения команды и анализировать ответ ФРа CashRegisterResult
.
Операций ФРа
1. Setup()
— установка настроек, конфигураций ФРа.
Это первая команда, выполняемая плагином.
Вызывается при добавлении нового ФРа или при редактировании настроек ФРа.
Основная задача плагина сохранить и применить новые настройки CashRegisterSettings
, которые приходят аргументом.
Чаще всего в этой команде происходит остановка драйвера ФР, применение новых настроек и запуск ФР, если ФР был запущен:
public void Setup([NotNull] DeviceSettings newSettings)
{
if (newSettings == null)
throw new ArgumentNullException(nameof(newSettings));
Stop();
Settings = (CashRegisterSettings)newSettings;
if (newSettings.Autorun && wasConnected)
Start();
}
2. Start()
— запуск ФРа.
Команда вызывается по нажатию «Запустить» в iikoOffice.
Также ФР может быть запущен автоматически, если при добавлении устройства в настройках ФР установить флаг «Запускать автоматически».
Обычно в этой команде происходит инициализация драйвера, открытие порта, соединение с устройством и тестирование соединения:
public void Start()
{
SetState(State.Starting);
try
{
driver = new Driver(); // инициализация драйвера устройства
driver.Start()
}
catch (Exception e)
{
PluginContext.Log.Error($"Failed to load driver with error: {e.Message}");
SetState(State.Stopped);
throw new DeviceException(e.Message);
}
SetState(State.Running);
}
3. Stop()
— остановка ФРа.
Команда вызывается по нажатию «Остановить» в iikoOffice.
Команда предназначена для остановки устройства, освобождения ресурсов и закрытия портов, например:
public void Stop()
{
SetState(State.Stopping);
try
{
driver?.close();
}
catch (Exception e)
{
throw new DeviceException(e.Message);
}
driver = null;
SetState(State.Stopped);
}
4. RemoveDevice()
— удаление устройства.
Команда вызывается при выборе «Удалить» в контекстном меню позиции с внешним ФРом в iikoOffice.
Объект ФР в RMS будет помечен удаленным, если выполнение команды не выбросит исключение.
5. GetDeviceInfo()
— запрос состояния ФРа.
Команда вызывается каждый раз при открытии вкладки «Администрирование» => «Настройки оборудования» или по нажатию кнопки «Обновить» на той же вкладке.
Исходя из полученного ответа DeviceInfo
, RMS понимает протокол общения с ФРом: можно ли с ним работать, какие команды можно отправлять ФРу.
Состояние ФРа описывается типом DeviceInfo
, который содержит:
State
— состояние ФРа. Это может быть «Running» (запущен), «Stopped» (остановлен) и прочее.Comment
— текстовое описание состояния ФРа.Settings
— настройки ФРаCashRegisterSettings
.
Пример реализации запроса состояния подключенного и запущенного устройства:
public DeviceInfo GetDeviceInfo()
{
return new DeviceInfo
{
State = State.Running,
Comment = "Работает",
Settings = currentCashRegisterSettings
};
}
6. DoOpenSession()
— открыть кассовую смену (КС).
Актуально для тех ФРов, драйверы которых имеют команду «Открыть смену».
Например, ФРы ФЗ-54, т.к. нужно указывать имя кассира.
Если ФР не имеет отдельной команды для открытия смены, то нужно вернуть успешный ответ CashRegisterResult.Success = true
без выполнения операции в ФР.
7. DoXReport()
— печать X-отчета или его аналога (промежуточный суточный отчет без закрытия смены).
Кассовая смена на iikoFront считается открытой если команда DoOpenSession()
выполнится без исключения, а DoXReport()
вернет успешный результат: CashRegisterResult.Success = true
.
8. DoBillCheque()
— пречек заказа или отмена пречека.
Команда выполняется на тех ФРах, которые поддерживают печать пречека CashRegisterDriverParameters.IsBillTaskSupported = true
(см. чек типа «Счёт»
).
Информация по заказу приходит в аргументе BillTask
:
Id
— уникальный номер выполняемой операции.CashierName
— имя кассира.CashierId
— GUID кассира, его идентификатор:IUser cashier = PluginContext.Operations.GetUserById(CashierId)
CashierTaxpayerId
— ИНН кассира.IsRefund
— флаг, который сигнализирует об отмене операции. Если на фронте выбрали команду «Возрат заказа», флаг будет равен “true” и тогда ФР должен будет напечатать чек возврата.IsCancellation
— аннулирование чека, актуально только для Республики Беларусь и Латвии. Аннулирование - это отмена ошибочного чека продажи. Если кассир делает возврат товара, ФР печатает чек возврата. Если кассир ошибочно пробил чек, должен напечататься чек аннулирования.Sales
— позиции заказаChequeSale
. Чаще всего это набор информации по блюдам заказа, иногда позиции группируются по НДС. Это зависит в частности от ФР, поддерживает ли он ФФД выше 1.0.СancellingSaleNumber
— номер заказа (актуально только для Республики Беларусь). Заполняется, когда идет отмена операции. Операций может быть две: пречек заказа и оплата заказа. Т.к. типChequeTask
(см. операцию закрытие заказа) включает в себя типBillTask
, все текущие поля имеют также отношение и к закрытию заказа.DiscountSum
— общая сумму скидок по всем элементам заказа. Сюда включены только некатегориальные скидки. Это те скидки, которые действуют в целом на заказа, а не на какое-то отдельное блюдо или их категорию.IncreaseSum
— общуя сумма надбавок по всем элементам заказа. Сюда также включены только надбавки, действующие на заказ в целом.DiscountPercent
— процент скидки на сумму заказа. Здесь процент скидки или надбавки приводится больше для информации, не стоит на основе их делать какие-либо расчеты, например, пересчитывать скидки.DiscountPercent = (Сумма блюд / DiscountSum) * 100
IncreasePercent
— процент надбавки на сумму заказа.IncreasePercent = (Сумма блюд / IncreaseSum) * 100
ResultSum
— итоговая сумма заказа с учетом всех скидок и надбавок. Эта сумма получается путем сложения всех стоимостей позиций заказа с учетом НДС, скидок, надбавок, округления. Можно представить в виде формулы:ResultSum = Сумма блюд - все скидки - Округление(RoundSum) + все надбавки
TableNumberLocalized
— отформатированная строка с номером стола. Если в настройках ФРа стоит флаг «Печатать номер заказа», то и с номером заказа (пример: «Стол: 10» или «Стол: 10 Заказ: 5»).OrderNumber
— номер заказа.TableNumber
— номер стола.PrintArticle
— содержит значение настройки группы торгового предприятия «Печатать артикул на чеке» («Администрирование» => «Настройки торгового предприятия» => «Группа» => «Настройка типов оплат»).TextBeforeCheque
— текст добавляемый в начало чека. Функционал добавления такого текста становится доступным после поддержки интерфейсаIChequeTaskProcessor
и его регистрации с помощью командыRegisterChequeTaskProcessor()
.TextAfterCheque
— текст добавляемый в конец чека.
Позиции заказа описываются типом ChequeSale
:
Name
— наименование позиции (товар, блюдо и прочее).Code
— артикул позиции. В некоторых случаях артикул может отсутствовать (в этом случае передается ноль). Например, печатается чек со сгруппированными по НДС позициям или чек предоплаты.Price
— цена позиции, без учета скидок и надбавок.Amount
— количество позиции.GuestName
— имя гостя, которому соответствует позиция в чеке.Vat
— сумма НДС позиции.Section
— секция ФРа, которому принадлежит блюдо, согласно карте приготовления блюд («Администрирование» => «Настройки торгового предприятия» => «Группа» => «Общие настройки» => «Общая карта приготовления блюд»).DiscountSum
— сумма категориальных скидок, которые действуют на данную позицию.IncreaseSum
— сумма категориальных надбавок, которые действуют на данную позицию.Discount
— процент скидки на позицию.Discount = (Стоимость позиции / DiscountSum) * 100
Increase
— процент надбавки на позицию.Increase = (Стоимость позиции / IncreaseSum) * 100
Sum
— итоговая стоимость позиции, с учетом всех скидок и надбавок, как на отдельную позицию, так и на весь чек (категориальные и некатегориальные скидки и надбавки).Sum = стоимость позиции - все скидки, действующие на позицию + все надбавки
IsTaxable
— облагается ли позиция налогом (проверяется наличие принадлежности к налоговой категории).TaxId
— идентификатор налоговой ставки в ФР, соответствующая той налоговой категории, которой принадлежит позиция заказа (*«Администрирование» => «Настройки оборудования» => «Настройки ФРа» => «Налоговые категории»). Если настроено сопоставление налоговых категорий iiko и ФР, то передается идентификатор налоговой ставки, которую указал пользователь. Если сопоставление не настроено (стоит значение «По умолчанию»), то передается пустая строка.TransferType
— признак способа расчета (аванс («Advance»), оплата («FullPayment») и прочее).ItemCategory
— код признака предмета расчета, который соотвествует позиции, согласно справочнику «Товары и склады» => «Признаки расчета».Contractor
— комитент/поставщик. Комитент указывается в настройках группы в таблице «Общая карта приготовления блюд» («Администрирование» => «Настройки торгового предприятия» => «Группа» => «Общие настройки» => «Общая карта приготовления блюд»).GtinCode
— 14-тизначный «Global Trade Item Number» для позиции чека.ProductId
— идентификатор блюда, товара, улуги или другое. Чтобы получить блюдо:PluginContext.Operations.GetProductById(chequeTask.Sales[0].ProductId)
После нажатия на «Пречек» на экране заказа, фронт отправляет команду ФРу и ожидает от него ответ
CashRegisterResult
, который состоит из следующего:Success
— true — операция прошла успешно, false — операция не выполнилась или прошла с ошибкой.Message
— текстовое сообщение выполнения команды ФРом. IikoFront выводит данный текст на экран, если операция прошла неуспешно.CashSum
— сумма наличности в кассе на момент запроса.TotalIncomeSum
— сумма выручки (наличные + безналичные) в кассе за текущую кассовую смену.TotalIncomeSum = сумма продаж - сумма возвратов
После закрытия КС или открытия КС
TotalIncomeSum
должна быть равна нулю.Session
— номер смены ФРа.SerialNumber
— серийный номер ФРа.DocumentNumber
— номер документа (для ФЗ-54: номер фискального документа) (документами являются открытие смены, внесение, изъятие и прочее).SaleNumber
— номер чека (чек: чек продажи, чек возврата).BillNumber
— номер заказа/счета (актульно для Республики Беларусь).RtcDateTime
— дата и время в ФР.
Так выглядит ответ на большинство команд ФРа, будь то оплата, предоплата, пречек, возврат, печать Z-отчета, печать X-отчета, внесение, изъятие.
В зависимости от содержимого ответа, iikoFront решает выполнилась ли команда на ФР и с каким результатом.
В общем случае, для любой операции с таким ответом, если результат вернулся неуспешным Success
=false, iikoFront выведет ошибку на экран с текстом сообщения Message
и iikoFront будет считать, что на ФРом команда не была выполнена.
Это не касается проверки на задвоение, которая выполняется при каждой денежной операции (оплата, возврат, внесение, изъятие, предоплата).
Задача этого механизма не дать выполнить денежную операцию повторно, на тот случай, если ФР вернул ошибку.
iikoFront перед каждой такой операцией будет пытаться выявить несоответствие денежных сумм в ФРе со своими подсчетами.
Если отрицательный ответ iikoFront обрабатывает одинаково, то успешный результат для каждой операции анализируется по-разному.
Так, в случае пречека, номер счета/заказа будет сохранен в базу iikoFront, при условии, что BillNumber
!= null.
9. DoCheque()
— закрытие заказа, предоплата, возврат.
Команда вызывается при закрытии заказа (по нажатию «Оплатить» на экране кассы) в iikoFront. Вся необходимая информация по заказу, его оплатах, кассире приходит в аргементе ChequeTask
, который включает в себя описание BillTask
и дополняет его следующими свойствами:
CashPayment
— сумма оплаты наличными.CardPayments
— список оплат по безналу. Оплата по безналуChequeCardPayment
внутри содержит: — сумму оплатыChequeCardPayment.Name
. — регистр ФРа соответствующий типу оплатыChequeCardPayment.PaymentRegisterId
. — признак по-умолчанию — если регистр ФРа не назначалсяChequeCardPayment.IsDefaultNonCash
.CreditSum
— сумма по чеку постоплатой (в кредит).ConsiderationSum
— сумма по чеку встречным предоставлением.PrepaymentSum
— сумма по чеку предоплатой (зачетом аванса и (или) предыдущих платежей).
Все вышеперечисленные виды оплат в сумме покрывают стоимость заказа.
RoundSum
— остаток от округления стоимости заказа в пользу клиента. К примеру, если заказ стоил 100 руб и 20 коп.,RoundSum
будет равен 20 коп. Округление не включается в сумму скидок на заказ или на позицию, отображается только в текущем поле.OrderId
— идентификатор заказа. Чтобы получить заказ:PluginContext.Operations.GetOrderById(chequeTask.OrderId.Value)
PrepaymentId
— guid оплаты, который позволяет однозначно определить возвращаемый чек. Используется для всех операций предоплат, и нужен для связки предоплаты с возвратом предоплаты, в любой другой операции там будет null. Плагин может вести свою локальную базу операций, записывая туда операции предоплат с необходимыми данными. Таким образом, при выполнении возврата предоплаты он сможет определить конкретную операцию предоплаты и использовать, например, уникальные идентификаторы конкретной операции выполнения возврата по ней.BillNumber
— фискальный номер чека.OperationTime
— время закрытия заказа.IsOfdElectronicChequeOnly
— только печать чека, без отправок смс и прочего.OfdPhoneNumber
— номер телефона ОФД для получения копии чека.OfdEmail
— email ОФД для получения копии чека.TaxationSystem
— система налогообложения чека.SettlementAddress
— адрес расчета. Заполняется согласно настройкам ФР «Администрирование» => «Настройки оборудования» => «Настройки ФРа» => «Дополнительная информация».SettlementPlace
— место расчета. Заполняется согласно настройкам ФР «Администрирование» => «Настройки оборудования» => «Настройки ФРа» => «Дополнительная информация».
При проведении оплат, предоплат, возвратов, внесений, изъятий iikoFront может сверять свои подсчеты денежных сумм по кассовой смене с подсчетами ФРа, это зависит от конфигурации iikoFront, по-умолчанию сверка происходит. Делается это для того, чтобы избежать возможного дублирования печати чека, который мог все-таки напечататься, даже если вернулся неуспешный результат Success
=false.
Для этого анализируются поля CashSum
и TotalIncomeSum
.
Также после оплаты iikoFront в БД сохраняет номер документа ФРа DocumentNumber
, потом этот номер можно увидеть в закрытом заказе и номер продажи SaleNumber
.
Пример реализации DoCheque()
:
public CashRegisterResult DoCheque([NotNull] ChequeTask chequeTask)
{
if (chequeTask == null)
throw new ArgumentNullException(nameof(chequeTask));
if (chequeTask.IsCancellation)
throw new DeviceException("Чек аннулирования не поддерживается");
driver.SetCashier(chequeTask.CashierName, chequeTask.CashierTaxpayerId);
//Отменяем открытие документы, если они есть
driver.ResetDevice();
//Открыть чек
if (chequeTask.isRefund)
driver.OpenRefundCheck();
else
driver.OpenSaleCheck()
//печатаем номер стола и заказа
driver.PrintText(string.IsNullOrWhiteSpace(chequeTask.TableNumberLocalized)
? string.Format("Стол: {0}, Заказ № {1}", chequeTask.TableNumber, chequeTask.OrderNumber)
: chequeTask.TableNumberLocalized);
//Печатаем дополнительные строки в начале чека
if (!string.IsNullOrWhiteSpace(chequeTask.TextBeforeCheque))
driver.PrintText(chequeTask.TextBeforeCheque);
foreach (var sale in chequeTask.Sales)
{
var taxId = GetTaxId(sale); //получаем налоговую ставку
driver.RegisterItem(sale.Name, sale.Price, sale.Amount, taxId);
//Регистрируем скидку на позицию
if (sale.DiscountSum > 0.0m)
driver.RegisterDiscount(sale.DiscountSum)
//Регистрируем надбавку на позицию
if (sale.IncreaseSum > 0.0m)
driver.RegisterIncrease(sale.IncreaseSum);
}
//Печатает подытог чека
driver.PrintSubtotal();
//Регистрируем скидку на подытог чека
if (chequeTask.DiscountSum > 0.0m)
driver.RegisterSubtotalDiscount(chequeTask.DiscountSum)
//Регистрируем надбавку на подытог чека
if (chequeTask.IncreaseSum > 0.0m)
driver.RegisterSubtotalIncrease(chequeTask.IncreaseSum);
foreach (var cardPayment in chequeTask.CardPayments)
{
var paymentRegisterId = GetPaymentRegisterId(cardPayment); //получить номер типа оплаты
driver.AddPayment(GetCardPaymentId(cardPayment), cardPayment.Sum);
}
cardPayments = chequeTask.CardPayments.Sum(cardPament=>cardPayment.Sum);
if (chequeTask.CashPayment > 0.0m || cardPayments == 0.0m)
{
//cashPaymentId - номер типа оплаты для наличных
driver.AddPayment(cashPaymentId, cardPayment.Sum);
}
//Печатаем дополнительные строки в конце чека
if (!string.IsNullOrWhiteSpace(chequeTask.TextAfterCheque))
driver.PrintText(chequeTask.TextAfterCheque);
//Закрываем чек
driver.CloseCheck();
return GetCashRegisterData();
}
10. GetCashRegisterData()
— команда запроса данных ФРа.
Вызывается всегда при фискальных операциях для получения данных по денежным суммам, для получения серийного номера ФРа (если серийный номер менялся в пределах одной КС, iikoFront попросит закрыть КС и открыть новую), или даты и времени на ФРе при открытии смены для их сверки.
Пример реализации GetCashRegisterData()
:
public CashRegisterResult GetCashRegisterData()
{
CheckState(State.Running);
var totalIncomeSum = driver.GetSalesSum() - driver.GetRefundsSum();
var cashSum = driver.GetCashSum();
var serialNumber = driver.GetSerialNumber();
var sessionNumber = driver.GetSessionNumber();
var dateTime = driver.GetDateTime();
var receiptNumber = driver.GetLastReceiptNumber();
var documentNumber = driver.GetLastDocumentNumber();
return new CashRegisterResult(cashSum, totalIncomeSum, sessionNumber, serialNumber, receiptNumber,
documentNumber, null, dateTime.ToString(CultureInfo.InvariantCulture));
}
11. GetCashRegisterStatus()
— команда запроса состояния ФРа.
Это состояние отображается в трее iikoFront.
Например, если ФР возвращает режим обслуживания RestaurantMode
и он не совпадает c режимом обслуживания iikoFront, выведется сообщение «Неверный режим ФР».
Также по SessionStatus
проверяется просроченность смены. Кроме прочего ФР может выводить сообщение в трей, если:
status.Success = false && status.Message != null
iikoFront опрашивает состояние ФР каждый раз после выполнения любой фискальной операции.
12. OpenDrawer()
— открыть денежный ящик (ДЯ).
В зависимости от настройки типа оплаты «Открывать денежный ящик», на ФР будет отправлена команда открыть денежный ящик.
13. IsDrawerOpened()
— открыт ли денежный ящик.
Если ФР не поддерживает команду получения статуса денежного ящика, то нужно вернуть true.
14. PrintText()
— печать нефикального документа.
Например, печать отчетов, печать штрихкодов для позиций.
Текст документа будет прислан в команду PrintText()
для печати его на бумаге.
15. DoPayIn()
— внесение денежной суммы в кассу.
Информацию по кассиру можно получить так:
IUser cashier = PluginContext.Operations.GetUserById(cashierId)
16. DoPayOut()
— изъятие денежной суммы из кассы.
17. DoCorrection()
— печать чека коррекции (iikoFront => «Доп» => «Чек коррекции»).
По передаваемому объекту CorrectionTask
, ФР понимает какой чек корреции нужно провести:
DocumentType
— признак расчета: —CorrectionDocumentType.Sale
— коррекция прихода, —CorrectionDocumentType.Buy
— коррекция расхода.CorrectionReason
— тип коррекции: —CorrectionReasonEnum.OwnInitiative
— самостоятельная, —CorrectionReasonEnum.Determination
— по предписанию.CashSum
— сумма по чеку наличными.NonCashSum
— электронные средства.PrepaymentSum
— предоплата.CreditSum
— оплата в кредит.ConsiderationSum
— оплата встречным предложением.DocumentDateTime
— дата документа основания для коррекции в формате ГГГГ-ММ-ДД.DocumentNumber
-номер документа основания для коррекции.DocumentName
— наименование документа-основания для коррекции.TaxationSystem
— применяемая система налогообложения.VatSum
— корректируемые суммы НДС (сумма НДС чека по ставке 18%, 10%, 18/118, 10/110, 0%, без НДС).CashRegisterVatData
:TaxAmount
— рассчитанная сумма НДС иTaxableSum
— сумма расчета (для НДС 0 и без НДС).
18. DoZReport()
— закрыть кассовую смену на ФРе.
Кассовая смена на iikoFront считается закрытой если команда DoZReport() вернет успешный результат: CashRegisterResult.Success = true.
19. GetQueryInfo()
— запрос на расширенные команды ФРа.
С помощью команд GetQueryInfo()
и DirectIo()
ФР может на свое усмотрение добавлять свои команды, которые можно будет вызывать из iikoFront «Доп» => «Команды фискальному регистратору»*.
Метод GetQueryInfo()
возвращает описание произвольных команд ФР, а DirectIo()
выполняет их.
Пример — приветствие пользователя:
public QueryInfoResult GetQueryInfo()
{
var supportedCommands = new List<SupportedCommand>
{
// команда приветствия пользователя с кодовым именем "HelloWorld"
new SupportedCommand("HelloWorld", "Приветствие")
{
// параметры ввода
Parameters = new List<RequiredParameter>
{
// поле для ввода имени пользователя
new RequiredParameter("UserName", "Имя пользователя", "Введите имя пользователя", "string")
}
}
};
var result = new QueryInfoResult
{
SupportedCommands = supportedCommands
};
return result;
}
public DirectIoResult DirectIo(CommandExecute command)
{
if (command == null)
throw new ArgumentNullException(nameof(command));
var result = new DirectIoResult { Document = new Document { Lines = new List<string>() } };
// находим команду приветствия пользователя по кодовому имени "HelloWorld"
if (command.Name == "HelloWorld")
{
// считываем данные из параметра ввода имени пользователя
const string paramName = "UserName";
var userName = command.Parameters.FirstOrDefault(item => item.Name == paramName)?.Value;
// записываем приветственное сообщение
result.Message = userName != null ? $"Привет, {userName}!" : "Привет всем!";
}
return result;
}
Выбор команды ФРа:
Ввод имени пользователя:
Приветствие пользователя:
Таким образом, плагин может запрашивать какие-то данные у пользователя, выводить сообщения, отображать на UI документы.
QueryInfoResult
:
SupportedCommands
— список поддерживаемых команды ФРа сверх протокола.SupportedCommand
содержит: —Name
— кодовое имя команды. —ResourceName
— отображаемое имя команды. —Parameters
— поля ввода информации, гдеRequiredParameter.Type
может быть: “bool”, “string”, “int”, “datetime”, “double”. От этого зависит тип ввода поля: текст, ввод целого числа, ввод дробного числа, флаг, ввод даты.
20. DirectIo()
— выполнение произвольной команды ФРа.
Если команда возвращает заполненный DirectIoResult.Document
, этот документ будет отображен на экране iikoFront.
21. GetCashRegisterDriverParameters()
— настройки драйвера ФРа.
Пример:
public CashRegisterDriverParameters GetCashRegisterDriverParameters()
{
return new CashRegisterDriverParameters
{
CanPrintText = true, \\ Поддерживает ли ККМ печать текста
SupportsPayInAfterSessionClose = true, \\ Поддерживает ли ККМ внесение при закрытой кассовой смене
CanPrintBarcode = true, \\ Поддерживает ли ККМ печать простых штрихкодов
CanPrintQRCode = true, \\ Поддерживает ли ККМ печать QR-кодов
CanUseFontSizes = true, \\ Поддерживает ли ККМ использование шрифтов для печати текста
Font0Width = 44, \\ Ширина строки шрифтом F0
Font1Width = 42,\\ Ширина строки шрифтом F1
Font2Width = 22,\\ Ширина строки шрифтом F2
IsCancellationSupported = true, \\ Поддерживает ли ФР операцию Аннулирования
ZeroCashOnClose = false, \\ Обнуляет ли ККМ сумму наличных в кассе при закрытии смены
IsBillTaskSupported = false, \\ Поддерживается ли ФР печать пречека через команду «Счет»
};
}
Как правило, эти настройки считываются с драйвера устройства после его запуска, т.к. до запуска они еще не известны. От этих настроек iikoFront понимает умеет ли ФР печатать текст, может ли вносить деньги в закрытую КС, поддерживает ли печать QR-кодов и т.д.
FAQ
1. Почему не появляется в списке моделей внешний ФР?
Вариант 1: Скорее всего регистрация внешнего ФР прошла неуспешно. Это можно проверить по логам api.log в папке с данными фронта. Наличие следующих записей говорит об успехе регистрации внешнего ФРа:
[2019-04-05 14:58:52,546] DEBUG [48] — Plugin “CashRegisterPluginFolderName” connected.
[2019-04-05 14:58:52,731] DEBUG [48] — Plugin “CashRegisterPluginFolderName” is calling RegisterCashRegisterFactory operation
[2019-04-05 14:58:52,791] INFO [48] — Device factory: "CodeName" added.
CashRegisterPluginFolderName — имя папки c плагином iikoFront/Plugins/CashRegisterPluginFolderName
CodeName — DeviceSettings.CodeName
Иначе, в логах будет зафиксировано исключение.
Вариант 2: Обновить вкладку с настройками оборудования в iikoOffice: «Администрирование» => «Настройка оборудования» => кнопка «Обновить». Если вкладка была уже открыта до запуска iikoFront, то список доступных моделей оборудования не был обновлен автоматически, его нужно обновлять вручную или переоткрыть вкладку.
2. Как по идентификатору кассира Guid cashierId получить имя кассира?
IUser user = PluginContext.Operations.GetUserById(cashierId);
var name = user.Name;
3. Как сконфигурировать типы внесений и изъятий в iikoOffice, чтобы вызывались методы ФРа DoPayIn() и DoPayOut() ?
Скорее всего настроены нефискальные внесения и изъятия.
Это просто бухгалтерские перемещения, которые не вызывают команды ФРа на их печать.
Фискальные внесения и изъятия должны иметь пустой Шеф-счёт.
См. документацию
iiko про «Типы внесений и изъятий п.4».