Библиотека lnrfrcomax.dll предоставляет OLE интерфейс для работы с ФР МАРС-80-Ф через COM порт.
Перед использованием библиотеки необходимо зарегистрировать ее с помощью команды regsvr32.
Перед регистрацией библиотки необходимо установить vc_redist.x86.exe или vc_redist.x64.exe (какой будет в архиве с библиотекой)

Описание интерфейсов, экспортируемых библиотекой.

1. Налог. 

	dispinterface ITax
	{
	properties:
		[id(1)] unsigned char type; // тип налога 0 - без налога; 1 - выделяемый; 2 - начисляемый.
		[id(2)] hyper rate; // налоговая ставка в сотых долях процента. число от 0 до 10000 (5000 - 50%)
		[id(3)] BSTR name; //наименование налога

	methods:
	};
Интерфейс реализуется классом lnrfrcomax.Tax

Объект возвращается объектом класса RegData в методе getTax.

2. Счетчики итогов по типу операции
	dispinterface IReceiptCounters
	{
	properties:
		[id(1), readonly] unsigned char type; //Тип операции: 0 - продажа; 1- покупка; 2 - возврат продажи; 3 - возврат покупки
		[id(2), readonly] unsigned int receipts; //Количество чеков указанного типа
		[id(3), readonly] hyper totalAmount; //Общая сумма по чекам указанного типа (в копейках)
		[id(4), readonly] hyper cash; //Сумма наличными по чекам указанного типа(в копейках)
		[id(5), readonly] hyper card; //Сумма безналичными  по чекам указанного типа (в копейках)
		[id(6), readonly] hyper tax1; //Сумма налога 1 по чекам указанного типа (если налоговая ставка 0 - то необлагаемая сумма)
		[id(7), readonly] hyper tax2; //Сумма налога 2 по чекам указанного типа (если налоговая ставка 0 - то необлагаемая сумма)
		[id(8), readonly] hyper tax3;//Сумма налога 3 по чекам указанного типа (если налоговая ставка 0 - то необлагаемая сумма)
		[id(9), readonly] hyper tax4;//Сумма налога 4 по чекам указанного типа (если налоговая ставка 0 - то необлагаемая сумма)
		[id(10), readonly] hyper tax5;//Сумма налога 5 по чекам указанного типа (если налоговая ставка 0 - то необлагаемая сумма)

	methods:
	};
	
Интерфейс реализуется классом lnrfrcomax.ReceiptCounters
Интерфейс ICounters имеет свойства типа ReceiptCounters:
		[id(8), readonly] ReceiptCounters* saleCounters; //счетчики по продажам
		[id(9), readonly] ReceiptCounters* purchaseCounters; //счетчики по покупкам
		[id(10), readonly] ReceiptCounters* saleReturnCounters; //счетчики по вовзвратам продажа
		[id(11), readonly] ReceiptCounters* purchaseReturnCounters; //счетчики по возвратам покупок
		
3. Счетчики гросс итогов по типу операции

	dispinterface IReceiptGrossCounters
	{
	properties:
		[id(1), readonly] unsigned char type; //Тип операции: 0 - продажа; 1- покупка; 2 - возврат продажи; 3 - возврат покупки
		[id(2), readonly] unsigned int receipts; //Количество чеков указанного типа
		[id(3), readonly] hyper totalAmount; //Общая сумма по чекам указанного типа (в копейках)
		[id(4), readonly] hyper cash; //Сумма наличными по чекам указанного типа(в копейках)
		[id(5), readonly] hyper card; //Сумма безналичными  по чекам указанного типа (в копейках)

	methods:
	};
Интерфейс реализуется классом lnrfrcomax.ReceiptGrossCounters
Интерфейс IПкщыыCounters имеет свойства типа ReceiptGrossCounters:
		[id(8), readonly] ReceiptGrossCounters* saleCounters; //счетчики по продажам
		[id(9), readonly] ReceiptGrossCounters* purchaseCounters; //счетчики по покупкам
		[id(10), readonly] ReceiptGrossCounters* saleReturnCounters; //счетчики по вовзвратам продажа
		[id(11), readonly] ReceiptGrossCounters* purchaseReturnCounters; //счетчики по возвратам покупок
		
		
4. Информация об ФР
	dispinterface IModelData
	{
	properties:
		[id(1)] int model; //код модели
		[id(2)] BSTR modelName; //наименование модели
		[id(3)] BSTR serial; //заводской номер ФР

	methods:
	};
Интерфейс реализуется классом lnrfrcomax.ModelData
Объект класса ModelData возвращается интерфейсом IAxFrWrapper в методе getSerial

5. Статус ФР
	dispinterface IFrStatus
	{
	properties:
		[id(1), readonly] BSTR serial; //ЗН ФР
		[id(2), readonly] unsigned short flags; //флаги состояния ФР
		[id(3), readonly] unsigned char curDocType; //тип открытого документа
		[id(4), readonly] unsigned int lastDoc; //Номер последнего документа
		[id(5), readonly] DATE lastDocDt; //Дата последнего документа
		[id(6), readonly] unsigned short cycle; //номер текущей или последней закрытой смены
		[id(7), readonly] unsigned short receipt; //номер последнего чека в смене
		[id(8), readonly] unsigned int docsAvailable; //примерное количество документов, которое может поместиться в хранилище
		[id(9), readonly] unsigned char regsCount; //количество выполненных перерегистраций
		[id(10), readonly] unsigned char totalRegsCount; //разрешенное количество перерегистраций
		[id(11), readonly] unsigned char avalilableRegsCount; //доступное количество перерегистраций
		[id(12), readonly] BSTR descr; //текстовое описание статуса

	methods:
	};
Интерфейс реализуется классом lnrfrcomax.FrStatus	
Объект класса FrStatus возвращается интерфейсом IAxFrWrapper в методе getFrStatus

Флаги состояния ФР представляют собой битовую маску
0 бит: наличие SD карты (1 — есть, 0 — нет);
1 бит: флаг фискализации (1 — ФР активирован; 0 — нет);
2 бит: флаг использования SD карты, активированной в составе другого ФР (1 — чужая карта, 0 — своя; имеет смысл только при наличии SD карты);
3 бит: флаг статуса смены (1 — открыта; 0 — закрыта);
4 бит: флаг наличия ошибок хранилища на SD карте (1 — ошибки есть; 0 — ошибок нет);
5 бит: флаг состояния архива (1 — закрыт; 0 — открыт или SD карта не активирована);
6 бит: флаг наличия ошибок EEPROM (1 — ошибки есть; 0 — ошибок нет);
12 бит: флаг наличия связи с принтером чеков(1- принтер не отвечает; 0 — принтер отвечает);
13 бит: флаг статуса датчика количества бумаги (1 — лента скоро может закончиться;0 — все норм. Не информативен) 
14 бит: флаг отсутствия бумаги (1 — лента закончилась; 0 — лента присутствует)

Тип открытого документа:
0 — если нет открытого документам
Активация/перерегистрация = 0x01u,
ZОтчет= 0x02u,
Чек = 0x03u,
Документ закрытия архива = 0x04u,
Внесение наличных = 0x05u,
Изъятие наличных= 0x06u,
Открытие смены= 0x07u,

6. Статус текущей или последней закрытой смены
	dispinterface ICycleStatus
	{
	properties:
		[id(1), readonly] VARIANT_BOOL isOpen; //True - открыта; False - закрыта
		[id(2), readonly] unsigned short cycle; //Номер смены
		[id(3), readonly] unsigned short receipt; //Номер последнего чека
		[id(4), readonly] unsigned int firstCycleDoc;//Номер первого документа в смене
		[id(5), readonly] DATE openDt; //Дата открытия смены
		[id(6), readonly] unsigned int lastCycleDoc; //Номер последнего документа в смене
		[id(7), readonly] DATE closeDt; //Дата закрытия смены (если смена закрыта)
		[id(8), readonly] hyper cash; //наличность в кассе (в копейках)
		[id(9), readonly] BSTR descr; //текстовое описание статуса

	methods:
	};
Интерфейс реализуется классом lnrfrcomax.CycleStatus
Объект класса CycleStatus возвращается интерфейсом IAxFrWrapper в методе getCycleStatus

7. Регистрационные данные ФР

	dispinterface IRegData
	{
	properties: 
		[id(1)] BSTR regNumber; //регистрационный (фискальный) номер
		[id(2)] BSTR inn; //инн организации
		[id(3)] BSTR orgName; //наименование организации
		[id(4)] BSTR orgType; //тип организации
		[id(5)] BSTR orgAddress; //адрес организации или расчетов
		[id(6), readonly] DATE regTime; //дата регистрации/перерегистрации
		[id(7), readonly] VARIANT_BOOL hasValidTax; //признак наличия хотя бы одного валидного налога
		[id(8), readonly] BSTR descr; //текстовое описание рег. данных
	methods:
	//получение налога по индексу  p_idx из [0;4] (0 - 1 налог, 1 - 2-й и т.д)
		[id(9)] Tax* getTax([in] int p_idx);
	//Запись налога по индексу
		[id(10)] void setTax([in] int p_idx, [in] Tax* p_tax);
	};
Интерфейс реализуется классом lnrfrcomax.RegData
Объект класса RegData возвращается интерфейсом IAxFrWrapper в методе readCurrentRegData

8. Счетчики итогов смены и счетчики с момента последней перерегистрации
	dispinterface ICounters
	{
	properties:
		[id(1), readonly] unsigned short cycle; //номер последней смены (для счетчиков итогов смены) или количество смен (для счетчиков с момента последней перерегистрации)
		[id(2), readonly] unsigned short introductions; //количество внесений
		[id(3), readonly] unsigned short payouts; //количество изъятий
		[id(4), readonly] hyper introductionsAmount; //общая сумма внесений
		[id(5), readonly] hyper payoutsAmount; //общая сумма изъятий
		[id(6), readonly] unsigned int receipts; //количество чеков всех типов
		[id(7), readonly] unsigned hyper totalCash; //наличность в кассе
		[id(8), readonly] ReceiptCounters* saleCounters; //счетчики итого впродаж
		[id(9), readonly] ReceiptCounters* purchaseCounters; //счетчики итогов покупок
		[id(10), readonly] ReceiptCounters* saleReturnCounters; //счетчики итогов возвратов продаж
		[id(11), readonly] ReceiptCounters* purchaseReturnCounters; //счетчики итогов вовзвратов покупок
		[id(12), readonly] BSTR cycleCountersDescr; //текстовое описание для счетчиков смены
		[id(13), readonly] BSTR regCountersDescr; //текстовое описание для счетчиков с момента последней перерегистрации

	methods:
	};
	
Интерфейс  реализуется классом lnrfrcomax.Counters
Объект класса Counters возвращается интерфейсом IAxFrWrapper в методах
 getCycleCounters (счетчики итогов смены)
 getRegCounters (счетчики итогов с последней перерегистрации)
 
9. Счетички гросс итогов
 	dispinterface IGrossCounters
	{
	properties:
		[id(1), readonly] unsigned short cycle; //количество смен
		[id(2), readonly] unsigned short introductions;//количество внесений
		[id(3), readonly] unsigned short payouts;//количество изъятий
		[id(4), readonly] hyper introductionsAmount;//общая сумма внесений
		[id(5), readonly] hyper payoutsAmount;//общая сумма изъятий
		[id(6), readonly] unsigned int receipts; //количество чеков всех типов
		[id(7), readonly] ReceiptGrossCounters* saleCounters;//счетчики итого впродаж
		[id(8), readonly] ReceiptGrossCounters* purchaseCounters; //счетчики итогов покупок
		[id(9), readonly] ReceiptGrossCounters* saleReturnCounters;//счетчики итогов возвратов продаж
		[id(10), readonly] ReceiptGrossCounters* purchaseReturnCounters;//счетчики итогов вовзвратов покупок
		[id(11), readonly] BSTR descr; //текстовое описание счетчиков

	methods:
	};
	
Интерфейс реализуется классом lnrfrcomax.GrossCounters
Объект класса GrossCounters возвращается интерфейсом IAxFrWrapper в методе getTotalCounters
	
10. Счетчики итогов по отделам.
	dispinterface ISectionCounters
	{
	properties:

	methods:
		//возвращает сумму по типу чека p_recType в секцию p_section
		//p_recType из [0;3] p_section из [1;20]
		[id(1)] hyper getAmount([in] unsigned char p_recType, [in] unsigned char p_section);
	};	
Интерфейс реализуется классом lnrfrcomax.SectionCounters
Объект класса SectionCounters возвращается интерфейсом IAxFrWrapper в методе getSectionsCounters

11. Операция по чеку
	dispinterface IReceiptOperation
	{
	properties:
		[id(1)] BSTR mainCode; //код товара до 128 символов
		[id(2)] BSTR barcode; //штрих-код до 128 символов
		[id(3)] BSTR name; //наименование товара до 128 символов
		[id(4)] BSTR unitName; //единица измерения до 16 символов
		[id(5)] unsigned char section; //номер секции [1;20]
		[id(6)] unsigned char taxNumber; //номер налога [1;5] налог с указанным номером должен быть предварительно добавлен при регисрации/перерегистрации
		[id(7)] unsigned char discountNumber; //номер скидки [1;20]
		[id(8)] hyper price; //цена единицы товара в копейках
		[id(9)] hyper discount; //скидка в копейках (только с версии ПО ФР 0.0.3)
		[id(10)] double quantity; //количество товара
		[id(11)] BSTR quantityStr; //количество товара строкой
	methods:
	};
Интерфейс реализуется классом lnrfrcomax.ReceiptOperation
Обхект класса создается для каждой позиции в чеке и передается в ККТ в методе addReceiptOperation интерфейса IAxFrWrapper

Внимание! количество указывается один раз для объекта.
Либо в свойство quantity как вещественное число,
либо в свойство quantityStr как строка, содержащая число с фиксированной точкой. разделитель дробной и целой частей -  точка

12. Главный интерфейс библиотеки	

	dispinterface IAxFrWrapper
	{
	properties:
		[id(1)] BSTR portName; // Имя ком порта ("COM1", "COM2" и пр.)
		[id(2)] int cashierNumber; //номер кассира для команд, в которых необходима авторизация
		[id(3)] unsigned int cashierPassword; //пароль кассира для команд, в которых необходима авторизация
		[id(4), readonly] BSTR lastCommandError; //текст ошибки на последнюю команду (если команда прошла успешно, то текст тоже возвращается)
		[id(5), readonly] BSTR libVersion; //версия библиотеки lnrfrcomax.dll в виде "x.y.z"

	methods:
//Все методы возвращают код ошибки (см. описание протокола)
		[id(6)] int getVersion([in,out] BSTR *p_version); //получение версии ПО ФР (в виде "x.y.z"); соответствует команде 33H
		[id(7)] int getSerial([in] ModelData* p_md); //Получение информации о ЗН и модели ФР; соответствует команде 31H
		[id(8)] int getFrStatus([in] FrStatus* p_st); //Получение статуса ФР; соответствует команде 30H
		[id(9)] int getCycleStatus([in] CycleStatus* p_st); //Получение статуса текущей смены; соответствует команде 10H
		[id(10)] int cancelDoc();//отмена открытого документа; соответствует команде 06H
		[id(11)] int sendDocData([in] SAFEARRAY(BYTE) p_data); отправка данных в открытый документ; соответствует команде 07H
		[id(12)] int readRegTlv([in] unsigned short p_tag, [in,out] unsigned int *p_outTag, [in,out] unsigned int *p_outLen, [in,out] SAFEARRAY(BYTE) *p_outValue); //чтение параметра регистрационных данных ; соответствует команде 44H
		[id(13)] int readCurrentRegData([in] RegData* p_rd); //чтение  текущих регисрационных данных; соответствует вызоыу команде 44H для всех параметров рег. данных
		[id(14)] int getCycleCounters([in] Counters* p_c); //получение счетчиков итогов смены ; соответствует команде 36H
		[id(15)] int getRegCounters([in] Counters* p_c); //получение счетчиков итогов с момента последней перерегистрации; соответствует команде 37H
		[id(16)] int getTotalCounters([in] GrossCounters* p_c);//получение счетчиков гросситогов; соответствует команде 38H
		[id(17)] int getSectionsCounters([in] SectionCounters* p_c); //получение счетчиков по отделам; соответствует команде 39H
		[id(18)] int startFiscalization([in] BSTR p_cashier);//Открыть документ о регистрации перерегистрации (ФИО кассира до 256 символов); соответствует команде 08H
//сформировать документ о регистрации/перерегистрации.
//необходимо передать инн (10 обязательных символов) и фискальный номер (10 обязательных символов)
//из метода возвращаются номер сформированного документа, фискальный признак и дата сформированого документа
//соответствует команде 09H
		[id(19)] int completeFiscalization([in] BSTR p_inn, [in] BSTR p_regNumber, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fisc, [in,out] DATE *p_dt);
//Открыть документ об открытии смены (ФИО кассира до 256 символов); соответствует команде 11H
		[id(20)] int startCycleOpening([in] BSTR p_cashier);
//сформировать документ об открытии смены
//из метода возвращаются номер открытой смены, номер сформированного документа, фискальный признак и дата сформированого документа
//соответствует команде 12H
		[id(21)] int completeCycleOpening([in,out] unsigned int *p_cycle, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] DATE *p_dt);
//Открыть документ о внесении наличныъ (ФИО кассира до 256 символов); соответствует команде A2H
		[id(22)] int startIntroduction([in] BSTR p_cashier);
//сформировать документ о внесении наличных
//необходимо передать сумму наличных в копейках
//из метода возвращаются номер текущей смены, номер сформированного документа, фискальный признак и дата сформированого документа, наличность в кассе
//соответствует команде A3H
		[id(23)] int completeIntroduction([in] hyper p_amount, [in,out] unsigned int *p_cycle, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] DATE *p_dt, [in,out] hyper *p_cash);
//Открыть документ об изъятии наличныъ (ФИО кассира до 256 символов); соответствует команде A4H
		[id(24)] int startPayout([in] BSTR p_cashier);
//сформировать документ об изъятии наличных
//необходимо передать сумму наличных в копейках
//из метода возвращаются номер текущей смены, номер сформированного документа, фискальный признак и дата сформированого документа, наличность в кассе
//соответствует команде A5H
		[id(25)] int completePayout([in] hyper p_amount, [in,out] unsigned int *p_cycle, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] DATE *p_dt, [in,out] hyper *p_cash);
//Открыть документ закрытия смены (Z отчет) (ФИО кассира до 256 символов); соответствует команде 13H
		[id(26)] int startCycleClosing([in] BSTR p_cashier);
//сформировать документ о закрытии смены
//из метода возвращаются номер закрытой смены, номер сформированного документа, фискальный признак и дата сформированого документа
//соответствует команде 09H
		[id(27)] int completeCycleClosing([in,out] unsigned int *p_cycle, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] DATE *p_dt);
//Открыть документ о закрытии архива(ФИО кассира до 256 символов); соответствует команде 18H
		[id(28)] int startArchiveClosing([in] BSTR p_cashier);
//сформировать документ о закрытии архива
//из метода возвращаются номер сформированного документа, фискальный признак и дата сформированого документа
//соответствует команде 19H
		[id(29)] int completeArchiveClosing([in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] DATE *p_dt);
//Открыть чек. в метод передается тип чека (0 - продажа, 1 - покупка, 2 - возврат продажи, 3 - возврат покупки)(ФИО кассира до 256 символов); соответствует команде 15H
		[id(30)] int startReceipt([in] unsigned char p_type, [in] BSTR p_cashier);
//Добавление позиции в чек. Метод вызывается для каждой позиции. На входе получает сформированный объект позиции чека. соответствует команде 07H		
		[id(31)] int addReceiptOperation([in] ReceiptOperation* p_op);
//сформировать чек.
//необходимо передать сумму наличных и безналичных для оплат чека в копейках (если оплата только безналом - наличные 0, если только налом - безналичные 0)
//из метода возвращаются номер смены, номер сформированного документа, фискальный признак, номер чека в смене, дата сформированого документа, итог по чеку и сумма сдачи
//соответствует команде 16H
		[id(32)] int completeReceipt([in] hyper p_cash, [in] hyper p_card, [in,out] unsigned int *p_cycle, [in,out] unsigned int *p_fd, [in,out] unsigned int *p_fiscCode, [in,out] unsigned int *p_receipt, [in,out] DATE *p_dt, [in,out] hyper *p_amount, [in,out] hyper *p_change);
//Получение данных открытого документа. соответсвует команде B0H.
//для всех документов актуален возвращаемый тип документа.
//Для чеков: тип документа, тип чека, номер чека в смене, количество операций в чеке, итог по чеку		
		[id(33)] int getOpenedDocData([in,out] unsigned int *p_docType, [in,out] unsigned int *p_recType, [in,out] unsigned int *p_receipt, [in,out] unsigned int *p_operations, [in,out] hyper *p_amount);
//Чтение объекта из справочника. соответствует команде 01H		
		[id(34)] int readCatalogEntity([in] unsigned char p_type, [in] unsigned char p_number, [in,out] SAFEARRAY(BYTE) *p_out_);
//Запись объета в справочник. соответствует команде 02H		
		[id(35)] int writeCatalogEntity([in] unsigned char p_type, [in] SAFEARRAY(BYTE) p_in);
//Чтение текущей даты в ФР; соответсвует команде 03H		
		[id(36)] int readDt([in,out] DATE *p_dt);
//Установка даты в ФР; соответсвует команде 04H				
		[id(37)] int writeDt([in] DATE p_dt);
//Чтение настройки принтера; соответсвует команде С1H				
		[id(38)] int readPrinterParam([in] unsigned char p_type, [in,out] SAFEARRAY(BYTE) *p_out_);
//Запись настройки принтера; соответсвует команде С2H				
		[id(39)] int writePrinterParam([in] unsigned char p_type, [in] SAFEARRAY(BYTE) p_in);
//Печать произвольной строки с форматированием; соответсвует команде С3H				
		[id(40)] int printLine([in] char p_ls, [in] char p_just, [in] char p_font, [in] char p_flags, [in] BSTR p_text);
//Передача произвольной команды принтеру; соответсвует команде С43H				
		[id(41)] int printRaw([in] SAFEARRAY(BYTE) p_raw);
//Команда принтеру обрезать ленту ; соответсвует команде С5H				
		[id(42)] int printCut();
//Печать отчета; соответсвует команде B1H				
//Передаются тип отчета и сериалиализованные данные для него (если нужны)
		[id(43)] int printReport([in] int p_type, [in] SAFEARRAY(BYTE) p_params);
//Печать X отчета; соответсвует команде B1H						
		[id(44)] int printXReport();
//Печать отчета по итогам с момента последней перерегистрации; соответсвует команде B1H						
		[id(45)] int printRegReport();
//Печать отчета по гросс итогам; соответсвует команде B1H						
		[id(46)] int printGrossReport();
//Печать отчета по отделам; соответсвует команде B1H						
		[id(47)] int printSectionsReport();
//Печать отчета за период; соответсвует команде B1H				
		[id(48)] int printPeriodicReport([in] DATE p_from, [in] DATE p_to);
//Печать отчета по диапазону смен; соответсвует команде B1H						
		[id(49)] int printReportByCycles([in] unsigned short p_from, [in] unsigned short p_to);
//Печать копии документа; соответсвует команде B2H. Входной параметр - номер документа
		[id(50)] int printDocCopy([in] int p_fd);
//Печать контрольной ленты; соответсвует команде 3AH		
//Для печати ленты с начала можно передавать 0 или любой номер документа, не больший номера документа открытия смены
//Если в процессе печати контрольной ленты кончилась бумага, то для продолжения достаточно вызвать этот метод, передав номер документа, с которого необходимо продолжить печать контрольной ленты				
//Номер последнего удачно распечатанного документа возвращается в p_outFd
		[id(51)] int printControlTape([in] int p_fd, [in,out]unsogned int *p_outFd);
	};