/*
 * Для каз. фискальников с функцией передачи на сервер:
 *
 * FPG-1000 = ПОРТ FPG-1000 ФKZ (Бумага с боку)
 * FPG-350 = ПОРТ FPG-350 ФKZ (Переносной)
 * FPG-60 = ПОРТ FPG-60 ФKZ
 * DPG-150 = ПОРТ DPG-150 ФKZ
 * DPG-35 = ПОРТ DPG-35 ФKZ
 * DPG-25 = ПОРТ DPG-25 ФKZ
 * DP-25 = ПОРТ MP-55B ФKZ ОФД
 *
  *  Created on: 11 сент. 2015 г.
 *      Author: Igor Ivanov !

 Для того чтобы войти в ражим настройки пароль: 30
 */

//---------------------------------------------------------------------------
#pragma hdrstop
//#include "stdafx.h"
//---------------------------------------------------------------------------
#include "DP25.h"

//#include "tools.h"
#include "lib/stdTools.h"
#include "lib/mathTools.h"
#include "lib/ascii.h"
//#include "mathTools.h"

#ifdef _WIN32
	//#define WIN32_LEAN_AND_MEAN //По моему это для выбора функции поиска файлов по умолчанию
	//#define NOMINMAX
	#include <windows.h>
	//#include <minwinbase.h>
	#include <winnt.h>
	//#include <fileapi.h>
#else

#endif
#include <iostream>
#include <sstream>
#include <string.h>

#include <cmath>

//---------------------------------------------------------------------------
#if defined(WIN32) || defined(_WINDOWS) || defined(_BORLAND)
	#include <windows.h>
	#include <process.h>
	void usleep(__int64 usec)
	{
		void* timer;
		LARGE_INTEGER ft;
		ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time
		timer = CreateWaitableTimer(NULL, TRUE, NULL);
		SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
		WaitForSingleObject(timer, INFINITE);
		CloseHandle(timer);
	}
#else
	#include <unistd.h>    //write
#endif
//---------------------------------------------------------------------------
//Вернёт значение бита на заданной позиции
///pos - Позиция 7..0
/*bool getBitVal(unsigned char bit,unsigned char pos)
{
	unsigned char v=1;
	v=v<<pos;
	return (bit & v) == v;
}*/
//---------------------------------------------------------------------------
///Постройка CRC специального для этого принтера
//BufStart - С какого байта начинать подсчёт
//BufEnd - По какой байт считать (не длина)
/*unsigned int MakeCRC_DP25(unsigned char* Buf, unsigned int BufStart,unsigned int BufEnd)
{
	unsigned int cs=0;
	for(unsigned int i=BufStart;i<BufEnd;i++)
		cs+=Buf[i];

	unsigned int result=0;
	unsigned char *mas=(unsigned char *)&result;
	mas[0]=((cs >> 0x0C) & 0x0F) + 0x30;
	mas[1]=((cs >> 0x08) & 0x0F) + 0x30;
	mas[2]=((cs >> 0x04) & 0x0F) + 0x30;
	mas[3]=((cs >> 0x00) & 0x0F) + 0x30;
	return result;
}*/
//---------------------------------------------------------------------------
std::string sp3()
{
#if defined _WIN32 || defined __CYGWIN__
	return "\\";
#else
	return "/";
#endif
}
//---------------------------------------------------------------------------
///Постройка CRC специального для этого принтера
//start - С какого байта начинать подсчёт
//len - кол-во байт
unsigned int MakeCRC(unsigned char* Buf, unsigned int start, unsigned int len)
{
	unsigned int cs = 0;
	for (unsigned int i = start; i<start + len; i++)
		cs += Buf[i];
	return cs;
}
//---------------------------------------------------------------------------
unsigned int MakeCRC(unsigned int val)
{
	unsigned char* Buf = (unsigned char*)&val;
	unsigned int start = 0;
	unsigned int len = 4;
	unsigned int cs = 0;

	for (unsigned int i = start; i<len; i++)
		cs += Buf[i];
	return cs;
}
//---------------------------------------------------------------------------
//Из 2х байт делаем 4
unsigned int MakeINT(unsigned int len)
{
	unsigned int result = 0;
	unsigned char *mas = (unsigned char *)&result;
	mas[0] = ((len >> 0x0C) & 0x0F) + 0x30;
	mas[1] = ((len >> 0x08) & 0x0F) + 0x30;
	mas[2] = ((len >> 0x04) & 0x0F) + 0x30;
	mas[3] = ((len >> 0x00) & 0x0F) + 0x30;
	return result;
}
//---------------------------------------------------------------------------
//Из 4х байт делаем 2 байта
unsigned int uMakeINT(unsigned int len)
{
	unsigned short ch1 = (len >> 24) & 0x0F;
	unsigned short ch2 = (len >> 16) & 0x0F;
	unsigned short ch3 = (len >> 8) & 0x0F;
	unsigned short ch4 = (len >> 0) & 0x0F;

	unsigned int result = (ch1 << 0) | (ch2 << 4) | (ch3 << 8) | (ch4 << 12);
	return result;
}
//---------------------------------------------------------------------------
DP25::DP25()
{
	csPort =new ComPort();

	Status=new StatusDP25();
	PrintColumns = "40";
	FrameSeqNumber=0x20;
	CommandName=0;
	m_Dots=0;
	m_SaveLog=true;
	Sw1=false; Sw2=false; Sw3=false; Sw4=false; Sw5=false; Sw6=false; Sw7=false; Sw8=false; //Заполняются при вызове DiagnosticInfo
	m_OpCode=0;
	m_TillNmb=0;

	TimeOut=80; //Меньше 70 не ставить!!!
	CuttingPluName = 0;

	m_activated1=0;
}
//---------------------------------------------------------------------------
DP25::~DP25()
{
	delete csPort;
	delete Status;
}
//---------------------------------------------------------------------------
MyError DP25::PrinterInit()
{
	std::string str="";
	MyError error = Programming(std::string("DecimalPoint"),std::string("0"),str);
	if(error.ErrorCode==0)
	{
		m_Dots=Utility::StdStrToInt(str); //Заполняем глобальную переменную

		std::string Name,FwRev,FwDate,FwTime,Checksum,Sw,DevNumber;
		error = DiagnosticInfo(Name,FwRev,FwDate,FwTime,Checksum,Sw,DevNumber);
	}

	PrintColumns = "";
	Programming("PrintColumns", "0", PrintColumns);

	return error;
};
//---------------------------------------------------------------------------
StatusDP25::StatusDP25()
{
	for(int i=0;i<8;i++)
		for(int j=0;j<6;j++) stat[j][i]=false;
}
//---------------------------------------------------------------------------
void StatusDP25::SetStatus(unsigned char* status)
{
	//переписываем статус в переменные для удобства
	//Байт 0: Общее предназначение
	stat[0][7]=getBitVal(status[0],7); //0.7 Резерв.
	stat[0][6]=getBitVal(status[0],6); //0.6 Открыт чек возврата.
	stat[0][5]=getBitVal(status[0],5); //0.5 Признак ошибки (флаги, помеченные знаком # в байтах 0, 1, 2).
	stat[0][4]=getBitVal(status[0],4); //0.4 # Печатающее устройство неисправно.
	stat[0][3]=getBitVal(status[0],3); //0.3 Не подключен клиентский дисплей.
	stat[0][2]=getBitVal(status[0],2); //0.2 Таймер не установлен.
	stat[0][1]=getBitVal(status[0],1); //0.1 #	Неправильный код полученной команды.
	stat[0][0]=getBitVal(status[0],0); //0.0 #	Синтаксическая ошибка в полученных данных.

	//Байт 1: Общее предназначение
	stat[1][7]=getBitVal(status[1],7); //1.7 Резерв.
	stat[1][6]=getBitVal(status[1],6); //1.6 Электронная контрольная лента напечатана.
	stat[1][5]=getBitVal(status[1],5); //1.5 Крышка принтера открыта.
	stat[1][4]=getBitVal(status[1],4); //1.4 # После включения принтера обнаружены нарушения данных в ОЗУ.
	stat[1][3]=getBitVal(status[1],3); //1.3 # Батарея разряжена (Таймер реального времени в состоянии RESET).
	stat[1][2]=getBitVal(status[1],2); //1.2 # ОЗУ обнулено.
	stat[1][1]=getBitVal(status[1],1); //1.1 # Команда не может быть выполнена в данном фискальном режиме.
	stat[1][0]=getBitVal(status[1],0); //1.0 Переполнение суммы. Статус 1.1 также будет установлен и команда не поменяет данные в принтере.

	//Байт 2: Общее предназначение
	stat[2][7]=getBitVal(status[2],7); //2.7 Резерв.
	stat[2][6]=getBitVal(status[2],6); //2.6 Электронная контрольная лента не пуста.
	stat[2][5]=getBitVal(status[2],5); //2.5 Открыт служебный чек.
	stat[2][4]=getBitVal(status[2],4); //2.4 Электронная контрольная лента заполнена на 90%.
	stat[2][3]=getBitVal(status[2],3); //2.3 Открыт фискальный чек или чек возврата.
	stat[2][2]=getBitVal(status[2],2); //2.2 Электронная контрольная лента заполнена.
	stat[2][1]=getBitVal(status[2],1); //2.1 Недостаточно ленты.
	stat[2][0]=getBitVal(status[2],0); //2.0 # Закончилась лента. Если флаг установлен во время выполнения команды печати, то выполнение команды будет остановлено и статус принтера не изменится.

	//Байт 3: Состояние конфигурационных переключателей
	stat[3][7]=getBitVal(status[3],7); //3.7 Резерв.
	stat[3][6]=getBitVal(status[3],6); //3.6 =1 Если переключатель Sw7 в положении ON. Скорость передачи данных в серийный порт.
	stat[3][5]=getBitVal(status[3],5); //3.5 =1 Если переключатель Sw6 в положении ON. Скорость передачи данных в серийный порт.
	stat[3][4]=getBitVal(status[3],4); //3.4 =1 Если переключатель Sw5 в положении ON. Не используется.
	stat[3][3]=getBitVal(status[3],3); //3.3 =1 Если переключатель Sw4 в положении ON. Работа дисплея в кодовой таблице 1251 (Windows Cyrillic).
	stat[3][2]=getBitVal(status[3],2); //3.2 =1 Если переключатель Sw3 в положении ON. Задает режим "прозрачный дисплей".
	stat[3][1]=getBitVal(status[3],1); //3.1 =1 Если переключатель Sw2 в положении ON. Не используется.
	stat[3][0]=getBitVal(status[3],0); //3.0 =1 Если переключатель Sw1 в положении ON. Разрешает автоматическую обрезку бумаги.

	//Байт 4: Фискальная память
	stat[4][7]=getBitVal(status[4],7); //4.7 Резерв.
	stat[4][6]=getBitVal(status[4],6); //4.6 Резерв.
	stat[4][5]=getBitVal(status[4],5); //4.5 Признак ошибки (флаги, помеченные знаком * в байтах 4 и 5).
	stat[4][4]=getBitVal(status[4],4); //4.4 * Фискальная память заполнена.
	stat[4][3]=getBitVal(status[4],3); //4.3 В фискальной памяти осталось меньше 50 свободных полей.
	stat[4][2]=getBitVal(status[4],2); //4.2 Запрограммирован заводской номер принтера.
	stat[4][1]=getBitVal(status[4],1); //4.1 Запрограммированы налоговые номера.
	stat[4][0]=getBitVal(status[4],0); //4.0 * Ошибка записи в фискальную память.

	//Байт 5: Фискальная память
	stat[5][7]=getBitVal(status[5],7); //5.7 Резерв.
	stat[5][6]=getBitVal(status[5],6); //5.6 Резерв.
	stat[5][5]=getBitVal(status[5],5); //5.5 Не используется.
	stat[5][4]=getBitVal(status[5],4); //5.4 Задана хотя бы одна налоговая ставка.
	stat[5][3]=getBitVal(status[5],3); //5.3 Фискальный режим включен.
	stat[5][2]=getBitVal(status[5],2); //5.2 * Последняя запись в фискальную память не успешна.
	stat[5][1]=getBitVal(status[5],1); //5.1 Фискальная память отформатирована.
	stat[5][0]=getBitVal(status[5],0); //5.0 * Фискальная память установлена в режим ТОЛЬКО ЧТЕНИЕ (заблокирована).
}
//---------------------------------------------------------------------------
//Получить статусы в виде строки
std::string StatusDP25::getStatus()
{
	std::string str="";
	for(int i=0;i<8;i++)
		for(int j=0;j<6;j++)
			if(stat[j][i]) str+="1"; else str+="0";
	return str;
}
//---------------------------------------------------------------------------
//Получить следующий порядковый номер запроса.
unsigned char DP25::getNextSeq()
{
	FrameSeqNumber++;
	if(FrameSeqNumber >= 0x20 + 30) FrameSeqNumber = 0x20;
	if(FrameSeqNumber < 0x20) FrameSeqNumber = 0x20;
	return FrameSeqNumber;
}
//---------------------------------------------------------------------------
//Новая версия похожая на RU
int DP25::SendPMessage(unsigned int cmd, unsigned char* msg, int size, std::string &answer)
{
	if (csPort == NULL)
		return ERRIO;

	bool rez = false; //true Если получили пакет ответ о принтера

	//Буфер под ответ
	unsigned char buffer[1024 * 100];
	memset(buffer, 0, sizeof(buffer));
	//int bufferS = 0; //Позиция в которую записываются данные в буфер

	CommandName = cmd; //Сохраняем номер последней команды для повтора в случае ошибки
	getNextSeq(); //Генерим новый FrameSeqNumber

	if (csPort->isOpen())
	{
		for (int i = 0; i < 5; i++) //Если после 5 попыток нет ответа то принтер не исправен...
		{
			memset(buffer, 0, sizeof(buffer));

			if (m_SaveLog && i>0) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","REPEAT SENDING", true);

			//Отправляю запрос на принтер "<01><LEN><SEQ><CMD><DATA><05><BCC><03>"
			usleep(5); //Эксперимент
			csPort->WriteChar(0x01); //Признак начала сообшения
			usleep(5); //Эксперимент
			csPort->WriteUInt(MakeINT(0x20 + size + 10)); //Размер данных
			usleep(5); //Эксперимент
			csPort->WriteUChar(FrameSeqNumber); //Инкреминтальный идентификатор сообщения
			usleep(5); //Эксперимент
			csPort->WriteUInt(MakeINT(cmd)); //Номер команды
			usleep(5); //Эксперимент
			csPort->Write(msg, size); //Отправляем данные
			usleep(5); //Эксперимент
			csPort->WriteUChar(0x05); //Конец данных
			usleep(5); //Эксперимент
			csPort->WriteUInt(MakeINT(MakeCRC(MakeINT(0x20 + size + 10)) + FrameSeqNumber + MakeCRC(MakeINT(cmd)) + MakeCRC(msg, 0, size) + 0x05)); //Контрольная сумма
			usleep(5); //Эксперимент
			csPort->WriteUChar(0x03); //Признак конца сообщения
			usleep(5); //Эксперимент
			

			//Пытаюсь принять ответ из принтера "<01><LEN><SEQ><CMD><DATA><04><STATUS><05><BCC><03>"
			char ch = 0;
			int cntRead = 0;
			while (true) {
				int len = csPort->Read(&ch, 1);
				if (len == 1)
				{
					if (ch == 0x16) {
						cntRead = 0; 
					}
					if (ch == 0x15)
					{
						if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","NACK");
						cntRead = 1000; //Запрос заново
					}
					if (ch == 0x01) {
						break;
					}
				}
				if (cntRead > 5) {
					break; //Задержка на чтение 100мс, согласно документации принтер должен отправить не позднее 500мс данные поэтому тут 5
				}
				cntRead++;
			}
			if (cntRead > 5) continue; //Данных нет повторяем запрос

			if (ch == 0x01) {
				//Принтер подготовил данные читаем их...
				unsigned int tmpSize = 0;
				unsigned int size = 0;
				int len = csPort->Read(&tmpSize, 4);
				if (len > 0)
				{
					size = uMakeINT(tmpSize) - 0x20;
					//Пытаюсь скачать оставшиеся данные
					len = csPort->Read(buffer, size+1);
					if (size+1 == len) {
						if (buffer[0] != FrameSeqNumber) 
							break; //Если инкриментальный идентификатор другой то отправляем команду её заново
						unsigned short rCmd = uMakeINT(*((unsigned int*)&buffer[1]));
						if (rCmd != CommandName)
							break; //Если пришел ответ не на отправленную команду отправляем её заново
						//Проверяем ответ на CRC
						unsigned int crc0 = 0;
						crc0 += MakeCRC(tmpSize);
						crc0 += MakeCRC(buffer, 0, size-4);
						crc0 = MakeINT(crc0);
						unsigned int crc1 = *((unsigned int*)&buffer[size - 4]);
						if (crc0 != crc1) {
							Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","CRC ERROR");
							memset(buffer, 0, sizeof(buffer));
							//break;
						}
						else {
							Status->SetStatus(&buffer[size - 13]); //читаем статус
							answer.assign((char*)&buffer[5], size - 19); //Добавляем ответ в результат
							rez = true;
							break;
						}
					}
					else {
						Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","NOT READ ALL DATA", true);
					}
				}
			}
		}
	}
	else {
		Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Port is closed!", true);
	}

	if (answer.length() == 0)
		rez = false;

	if (rez) {
		return 0;
	}
	else {
		return ERRIO;
	}
}
//---------------------------------------------------------------------------
/*
int DP25::SendPMessage(unsigned int cmd, unsigned char* msg, int size, std::string &answer)
{
	if (csPort == NULL)
		return ERRIO;

	bool rez = false; //true Если получили пакет ответ о принтера

	//Буфер под ответ
	unsigned char *bufS=new unsigned char[size+1024];
	memset(bufS, 0, size + 1024);
	//Буфер под запрос
	unsigned char buffer[1024 * 100];
	memset(buffer, 0, sizeof(buffer));
	int bufferS = 0; //Позиция в которую записываются данные в буфер

	CommandName = cmd; //Сохраняем номер последней команды для повтора в случае ошибки
	getNextSeq(); //Генерим новый FrameSeqNumber

	
	if (csPort->isOpen())
	{
		for (int i = 0; i<5; i++) //Если после 5 попыток нет ответа то принтер не исправен...
		{
			memset(buffer, 0, sizeof(buffer));

			if (m_SaveLog && i>0) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","REPEAT SENDING",true);

			//Отправляю запрос на принтер "<01><LEN><SEQ><CMD><DATA><05><BCC><03>"
			csPort->WriteChar(0x01); //Признак начала сообшения
			csPort->WriteUInt(MakeINT(0x20 + size + 10)); //Размер данных
			csPort->WriteUChar(FrameSeqNumber); //Инкреминтальный идентификатор сообщения
			csPort->WriteUInt(MakeINT(cmd)); //Номер команды
			csPort->Write(msg, size); //Отправляем данные
			csPort->WriteUChar(0x05); //Конец данных
			csPort->WriteUInt(MakeINT(MakeCRC(MakeINT(0x20 + size + 10)) + FrameSeqNumber + MakeCRC(MakeINT(cmd)) + MakeCRC(msg, 0, size) + 0x05)); //Контрольная сумма
			csPort->WriteUChar(0x03); //Признак конца сообщения

            //Пытаюсь принять ответ из принтера "<01><LEN><SEQ><CMD><DATA><04><STATUS><05><BCC><03>"
			bufferS = 0;
			for (int jj = 0; jj<10; jj++) //Тайм аут приёма байта установлен в 100мс и если 100мс * 10 = 1 секунды макс время макс время для ожидания данных (Из доков: Хост должен иметь тайм-аут 500 мс для получения сообщения от Slave.)
			{
				//Задержка именно в 70 миллисекунд(сзапасом) так как принтер должен ответить не позднее чем 60 мс после отправки пакета
				int BytesRead = csPort->Read(&buffer[bufferS], sizeof(buffer) - bufferS);
				if (BytesRead<0) BytesRead = 0;
				//if (BytesRead>0) jj = 0; //Чтобы начать ждать по новой (может быть бесконечный цикл убрать!!!!)

				//Проверяю есть ли в скаченом NACK ошибка CRC
				if (bufferS + BytesRead>1 && buffer[0] != 0x01)
				{
					bool NACK = false;
					for (int k = bufferS; k<bufferS + BytesRead; k++)
					{
						if (buffer[k] == 0x15)
						{
							usleep(1500);
							NACK = true;
							break;
						}
					}
					if (NACK) break; //Ошибка CRC отправляю запрос заново

					bool WAIT = false;
					for (int k = bufferS; k<bufferS + BytesRead; k++)
					{
						if (buffer[k] == 0x16)
						{
							WAIT = true;
						}
						if (buffer[k] == 0x01) //Нечего больше ждать данные пришли
						{
							WAIT = false;
							break;
						}
					}
					if (WAIT)
					{
						usleep(1500); //Жду секунду
					}
				}

				bufferS += BytesRead;

				//Ищу первую позицию с 0x01 если она есть то сдвигаю массив
				int pos = -1;
				for (int k = 0; k<bufferS; k++)
				{
					pos = k;
					if (buffer[k] == 0x01) break; //Чтобы не задёрло данные
				}

				if (pos>0)
				{
					//Сдвигаю массив
					for (int k = 0; k<bufferS - pos; k++)
					{
						buffer[k] = buffer[k + pos];
					}
					bufferS -= pos; //Корректирую размер принятого
					//Так как мог попасться байт 0x16 SYN комманда подождать данные посылается каждые 60ms то немного жду...
					usleep(30 * 1200);
				}

				//начало пакета
				if (bufferS >= 5 && buffer[0] == 0x01) //Начало пакета
				{
					unsigned short size = uMakeINT(*((unsigned int*)&buffer[1])) - 0x20;
					if (size>bufferS - 6) continue; //Если принято не всё то дожидаемся остальных данных
					if (buffer[5] != FrameSeqNumber) break; //Если инкриментальный идентификатор другой то отправляем команду её заново
					unsigned short rCmd = uMakeINT(*((unsigned int*)&buffer[6]));
					if (rCmd != CommandName) break; //Если пришел ответ не на отправленную команду отправляем её заново

					//Проверяем ответ на CRC
					//unsigned int crc0 = MakeINT(MakeCRC(buffer, 1, size));
					//unsigned int crc1 = *((unsigned int*)&buffer[size + 1]);
					unsigned int crc0 = MakeCRC(buffer, 1, size);
					unsigned int crc1 = uMakeINT(*((unsigned int*)&buffer[size + 1]));
					if (crc0 != crc1)
					{
						memset(buffer, 0, sizeof(buffer));
						pos = 0;
					}
					else
					{
						Status->SetStatus(&buffer[size - 8]); //читаем статус
						answer.assign((char*)&buffer[10], size - 19); //Добавляем ответ в результат
						rez = true;
					}
					break;
				}

			}
			if (!rez) {
				usleep(1500); //Жду секунду
				continue; //Ошибка повторяем запрос
			}
			break; //всё в порядке
		}
	}
	delete bufS;

	if (answer.length() == 0) rez = false;

	//dwStart = GetTickCount() - dwStart;
	//if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Time = "+Utility::IntToStdStr(dwStart));

	if (rez){
		return 0;
	}else{
		return ERRIO;
	}
}*/
//---------------------------------------------------------------------------
//Старая версия KZ
/*MyError DP25::SendPMessage(unsigned char* msg,int size,std::string &answer)
{
	bool rez=false; //true Если получили пакет ответ о принтера

	//Буфер под ответ
	unsigned char buffer[1024*100];
	memset(buffer,0,sizeof(buffer));
	int bufferS=0; //Позиция в которую записываются данные

	if(size>3)
	{
		CommandName=msg[3]; //Сохраняем номер последней команды
	
		getNextSeq(); //Генерим новый FrameSeqNumber
		if(csPort->isOpen())
		{
			for(int i=0;i<6;i++) //Если после 5 попыток нет ответа то принтер не исправен...
			{
				//Если есть мусор в порте то читаю его
				int len=csPort->Read(buffer,sizeof(buffer));
				if(len>0)
				{
					if(m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","WASTE IN SERIAL! "+toHexString(buffer,len));
					std::cout << "WASTE! "+toHexString(buffer,len) << std::endl;
				}
				memset(buffer,0,sizeof(buffer));

				if(m_SaveLog && i>0) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","REPEAT");
				if(i>0) std::cout << "REPEAT SEND!" << std::endl;

				//Отправляю запрос на принтер
				msg[1]=0x20+size-1; //Размер
				msg[2]=FrameSeqNumber;
				unsigned int crc= MakeCRC_DP25(msg,1,size);
				csPort->Write(msg,size); //Отправляем данные
				csPort->Write(&crc,4); //Контрольная сумма
				csPort->WriteChar(0x03); //Признак конца сообщения

				//std::cout << "Start read ans!" << std::endl;

				//Пытаюсь принять ответ из принтера
				bufferS=0;
				for(int jj=0;jj<10;jj++) //100мс * 10 = 1 секунды макс время макс время для ожидания данных
				{
					int BytesRead=csPort->Read(&buffer[bufferS],sizeof(buffer)-bufferS);
					if(BytesRead>0) jj=0; //Чтобы начать ждать по новой

					//Проверяю есть ли в скаченом NACK ошибка CRC
					if(bufferS+BytesRead>1 && buffer[0]!=0x01)
					{
						bool NACK=false;
						for(int k=bufferS;k<bufferS+BytesRead;k++)
						{
							if(buffer[k]==0x15)
							{
								if(m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","NACK");
								usleep(1200);
								NACK=true;
								break;
							}
						}
						if(NACK) break;
					}

					bufferS+=BytesRead;

					//Ищу первую позицию с 0x01 если она есть то сдвигаю массив
					int pos=-1;
					for(int k=0;k<bufferS;k++)
					{
						pos=k;
						if(buffer[k]==0x01) break; //Чтобы не затёрло данные
						//if(buffer[j]==0x16 && m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","WAIT"); //SYN комманда подождать данные посылается каждые 60ms
					}

					if(pos>0)
					{
						//Сдвигаю массив
						for(int k=0;k<bufferS-pos;k++)
						{
							buffer[k]=buffer[k+pos];
						}
						bufferS-=pos; //Корректирую размер принятого
						//Так как мог попасться байт 0x16 SYN комманда подождать данные посылается каждые 60ms то немного жду...
						usleep(20*1200);
					}

					//начало пакета
					if(bufferS>=2 && buffer[0]==0x01 && bufferS >= buffer[1]-0x20 + 6) //Начало пакета
					{
						unsigned short size=buffer[1]-0x20 + 6;
						//Проверяем ответ на CRC
						unsigned int crc0= MakeCRC_DP25(buffer,1,size-5);
						unsigned int crc1=*((unsigned int*)&buffer[size-5]);
						if(crc0!=crc1) 
						{
							memset(buffer,0,sizeof(buffer));
							pos=0;
						}else
						{
							Status->SetStatus(&buffer[size-12]); //читаем статус
							answer.assign((char*)&buffer[4],size-17); //Добавляем ответ в результат
							rez=true;
						}
						break;
					}
				}
				if(!rez)
					continue; //Ошибка повторяем запрос
				break; //всё в порядке
			}
		}
		if(answer.length()==0) rez=false;
	}

	MyError result;
	if(rez)
	{
		result.ErrorCode=0;
		result.ErrorMessage="";
		return result;
	}else
	{
		result.ErrorCode=ERRIO; //ERR_IO
		result.ErrorMessage=toKAZASCII(L"Ошибка связи!");
		return result;
	}
}*/
//---------------------------------------------------------------------------
bool DP25::OpenSerial(std::string ComNumber, int BaudRate)
{
	if (csPort != NULL) { csPort->Close(); delete csPort; }

	bool result = true;

	ComPort* port = new ComPort();
	port->ComNumber = ComNumber;
	port->BaudRate = BaudRate;
	port->Close();
	if (port->Open(port->ComNumber))
	{
		if (port->Setup(0) && port->SetTimeout(TimeOut))
		{
		}
		else
			result = false;
	}
	else result = false;

	csPort = port;
	return result;
}
//---------------------------------------------------------------------------
bool DP25::CloseCOMPort()
{
	if (csPort != NULL)
	{
		csPort->Close();
		delete csPort;
		Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Close Serial.", true);
	}
	csPort = NULL;
	return true;
}
//---------------------------------------------------------------------------
//Отркыть соединение по сокету
bool DP25::OpenSocket(std::string host, int port)
{
	if (csPort != NULL) { csPort->Close(); delete csPort; csPort = NULL; }
	bool result = true;
	SocketPort* sPort = new SocketPort();
	if (sPort->Open(host.c_str(), port))
	{
		if (sPort->SetTimeout(TimeOut))
		{
		}
		else
			result = false;
	}
	else
		result = false;

	csPort = sPort;
	return result;
}
//---------------------------------------------------------------------------
bool DP25::CloseSocket()
{
	if (csPort != NULL)
	{
		csPort->Close();
		delete csPort;
		csPort = NULL;
		Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Close Socket.", true);
	}
	return true;
}
//---------------------------------------------------------------------------
///Команда очищает дисплей.
///Если открыт фискальный чек и Sw3 в положении OFF, очищается только нижняя строка.
MyError DP25::DisplayClear()
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Start DisplayClear();");

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcDisplayClear, NULL, 0, answer);

	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){
		}
		else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	
	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DisplayClear()";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Вывод текста в нижнюю строку дисплея
//Text - До 20 символов текста
MyError DP25::DisplayLower(std::string Text)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start DisplayLower();");

	std::string msg;
	msg += fromASCIItoDOS(Text) + '\t'; //кракозябры так
	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcDisplayLower, (unsigned char*)msg.c_str(), (int)msg.size(), answer);

	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DisplayLower(Text=" << Text << ")";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Открытие нефискального чека
MyError DP25::OpenServiceInv(int& ShiftNumber,int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start OpenServiceInv();");

	ShiftNumber = 0; DocNumber = 0;

	std::string msg;

	//Параметр extend нужен для того ???

	std::string answer;
	MyError result;
	result.ErrorCode=SendPMessage(fcOpenServiceInv,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			ShiftNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			DocNumber = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "OpenServiceInv(ShiftNumber=" << ShiftNumber << ",DocNumber="<< DocNumber <<")";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Закрытие нефискального чека
///Ответ: Текущий номер чека
MyError DP25::CloseServiceInv(int& ShiftNumber, int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start CloseServiceInv();");

	ShiftNumber = 0; DocNumber = 0;
	std::string msg;

	std::string answer;
	MyError result;
	result.ErrorCode=SendPMessage(fcCloseServiceInv,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			ShiftNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			DocNumber = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "CloseServiceInv(ShiftNumber=" << ShiftNumber << ",DocNumber="<< DocNumber <<")";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Добавлена команда для записи и передачи дополнительных реквизитов покупателя
//Перед открытием нового чека данные покупателя следует очистить.Для этого необходимо выполнить команду 57 (39h) с параметром '2' - erase client data.
// 0 - телефон покупателя
// 1 - e-mail покупателя
// 2 - очистка данных покупателя
// 3 - ИИН/БИН покупателя
MyError DP25::SetFiscalInvParam(int Type, std::string Data)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Start SetFiscalInvParam();");

	std::string msg;
	msg += Utility::IntToStdStr(Type); msg += '\t';
	if (Type == 0){ // '0' phone number up to 19 symbols;
		msg.append(Data, 0, 19);
	}else if (Type == 1){ // '1' email address up to 64 symbols;
		msg.append(Data, 0, 64);
	}else if (Type == 2){ // '2' no matter can be empty;
		Data = "";
	}else if (Type == 3){ // '3' INN/BIN number up to 12 digits;
		msg.append(Data, 0, 12);
	}else {
		Data = "";
	}
	msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcSetFiscalInvParam, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else {
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetFiscalInvParam(Type=" << Type << ",Data=" << Data << ")";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Печать свободного текста в нефискальном чеке
// Text – текст от 0 до 46 символов;
//Bold - flag 0 or 1, 1 = print bold text; empty field = normal text;
//Italic - flag 0 or 1, 1 = print italic text; empty field = normal text;
//DoubleH - flag 0 or 1, 1 = print double height text; empty field = normal text;
//Underline - flag 0 or 1, 1 = print underlined text; empty field = normal text;
//Alignment - 0, 1 or 2. 0=left alignment, 1=center, 2=right; empty field = left alignment;
MyError DP25::PrintFreeTextInServiceInv(std::string Text,char Bold,char Italic,char Height,char Underline,char Alignment)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintFreeTextInServiceInv();");

	std::string msg;

	msg.append(Text,0, Utility::StdStrToInt(PrintColumns));
	msg+='\t';
	msg+=Bold;
	msg+='\t';
	msg+=Italic;
	msg+='\t';
	msg+= Height;
	msg+='\t';
	msg+=Underline;
	msg+='\t';
	msg+=Alignment;
	msg+='\t';


	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintFreeTextInServiceInv,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintFreeTextInServiceInv(Text=" << Text << ",Bold="<< (int)Bold << ",Italic=" << (int)Italic << ",DoubleH=" << (int)Height << ",Underline=" << (int)Underline << ",alignment=" << (int)Alignment <<")";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Диагностическая информация с контрольной суммой ПО;
// Name – Наименование устройства (до 32 символов);
// FwRev – Версия ПО. 6 символов;
// FwDate – Дата ПО. DDMMMYY. 7 символов;
// FwTime – Время ПО. hhmm. 4 символа.
// Checksum – Контрольная сумма ПО. 4 символа;
// Sw - Переключатели с Sw1 по Sw8. 8 символов (не используется в этом устройстве, всегда 00000000);
// DevNumber – Заводской номер устройства (Две цифры (01) и десять цифр (xxxxxxxxxx=уникальный заводской номер: 01xxxxxxxxxx) );
MyError DP25::DiagnosticInfo(std::string& Name,std::string& FwRev,std::string& FwDate,std::string& FwTime,std::string& Checksum,std::string& Sw,std::string& DevNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start DiagnosticInfo();");

	std::string msg;
	msg+='1'; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcDiagnosticInfo,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			Name=Utility::CutBeforeFirst(answer,'\t');
			FwRev=Utility::CutBeforeFirst(answer,'\t'); //Версия
			FwDate=Utility::CutBeforeFirst(answer,'\t'); //Дата
			FwTime=Utility::CutBeforeFirst(answer,'\t'); //Время
			Checksum=Utility::CutBeforeFirst(answer,'\t'); //Контрольная сумма ПО
			Sw=Utility::CutBeforeFirst(answer,'\t');
			DevNumber=Utility::CutBeforeFirst(answer,'\t');

			PrinterName=Name;
			PrinterVersion=FwRev;
			PrinterVersion+=' '+FwDate;
			PrinterVersion+=' '+FwTime;
			Sw8=Sw[0]=='1';
			Sw7=Sw[1]=='1';
			Sw6=Sw[2]=='1';
			Sw5=Sw[3]=='1';
			Sw4=Sw[4]=='1';
			Sw3=Sw[5]=='1';
			Sw2=Sw[6]=='1';
			Sw1=Sw[7]=='1';
			PrinterNumber=DevNumber;
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DiagnosticInfo(Name="+Name+",FwRev="+FwRev+",FwDate="+FwDate+",FwTime"+FwTime+",Checksum"+Checksum+",Sw="+Sw+",DevNumber="+DevNumber+"); v3.13.0.14";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
///Протяжка ленты
///\param count Количество строк
MyError DP25::FeedPaper(int count)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start FeedPaper();");

	std::string msg;
	msg+=Utility::IntToStdStr(count); msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFeedPaper,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "FeedPaper(count="+Utility::IntToStdStr(count)+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Проверяет режим соединения с ПК
MyError DP25::CheckConnection()
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start CheckConnection();");

	std::string msg;
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcCheckConnection,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else {
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "CheckConnection();";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
///< 0 - disable printout
MyError DP25::EnablePrinting(bool val) {
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info","Start EnablePrinting();");

	std::string msg;
	if(val)
		msg += "1\t";
	else
		msg += "0\t";

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcCheckConnection, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else {
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "EnablePrinting(val="<< val <<");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3() + "log.txt","main","info", ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
///Обрезка ленты
MyError DP25::CutPaper()
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start CutPaper();");

	std::string msg;
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcCutPaper,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "CutPaper();";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Вывод текста в верхнюю строку дисплея
///Text - До 20 символов текста
MyError DP25::DisplayUpper(std::string Text)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start DisplayUpper();");

	std::string msg;
	msg+=Text+"\t";
	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcDisplayUpper,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DisplayUpper(Text="+Text+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Открытие фискального (клиентского) чека
///OpCode - Номер оператора (1...30);
///OpPwd - Пароль оператора (Строка цифр в кодировке Ascii, длиной от 1 до 8);
///TillNmb - Номер точки продаж от 1 до 99999;
///ReceiptType - Тип чека. '0' – Чек продажи; '1' – Чек возврата;
///SlipNumber – Текущий номер чека продажи или чека возврата (1...99999999);
MyError DP25::OpenFiscalInv(int OpCode,std::string OpPwd,int TillNmb,char ReceiptType,int& ShiftNumber,int& SlipNumber,int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start OpenFiscalInv();");

	SlipNumber=0;

	std::string msg;
	msg+=Utility::IntToStdStr(OpCode)+"\t"+OpPwd+"\t"+Utility::IntToStdStr(TillNmb)+"\t"+ReceiptType+'\t';
	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcOpenFiscalInv,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			ShiftNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			SlipNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			DocNumber = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "OpenFiscalInv(OpCode="+Utility::IntToStdStr(OpCode)+",OpPwd="+OpPwd+",TillNmb="+Utility::IntToStdStr(TillNmb)+",ReceiptType="+std::string("")+ReceiptType + ",ShiftNumber=" + Utility::IntToStdStr(ShiftNumber)+",SlipNumber="+Utility::IntToStdStr(SlipNumber)+",DocNumber="+ Utility::IntToStdStr(DocNumber) +");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Регистрация продажи
///{PluName}<SEP>{TaxCode}<SEP>{Price}<SEP>{Quantity}<SEP>{DiscountType}<SEP>{DiscountValue}<SEP>{Department}<SEP>{MarkStamp}<SEP>{Sum}<SEP>{UnitCode}<SEP>
///PluName – Наименование товара (до 32 символов);
///TaxCode – Номер ставки НДС (1-А, 2-Б, 3-В);
///Price – Цена товара (0.01...9999999.99). Знак '-' (минус) означает операцию аннуляции;
///Quantity – Количество товара (0.001...99999.999). По умолчанию: 1.000;
///DiscountType – тип дисконта. '0' или пусто – без скидки; '1' – наценка в процентах; '2' – скидка в процентах; '3' – наценка суммой; '4' – скидка суммой;
///DiscountValue – значение дисконта. Число от 0.00 до 21474836.47 Если {DiscountType} ноль или пусто, то этот параметр должен быть пустым.
///Department - Department number(1...16).Default: 16;
///MarkStamp - Mark stamp read with a 2D - code scanner(up to 168 symbols).The sale of a marked item must contain{ MarkStamp }; Note The control of the item being marked or not marked, must be performed by the computer program;
///Sum - Sum printed instead of{ Price } *{Quantity} in the receipt(0.00...999, 999, 999, 999.99);
///UnitCode - Code of the unit, which will be printed in sales after the sold quantity(1...999).Default: The code of first programmed unit;
/// SlipNumber – Текущий номер чека продажи или чека возврата (1...99999999);
///DocNumber - Global number of all documents ( 1...99999999 );
MyError DP25::RegisterSale(std::string PluName, char TaxCode, double Price, double Quantity, char DiscountType, double DiscountValue, int Department, std::string MarkStamp, double RoundPrice, int UnitCode, std::string ProductID, std::string BarCode, int& SlipNumber, int& DocNumber)
{
	if (DiscountType == 0) DiscountType = '0';
	if (DiscountType == 1) DiscountType = '1';
	if (DiscountType == 2) DiscountType = '2';
	if (DiscountType == 3) DiscountType = '3';
	if (DiscountType == 4) DiscountType = '4';
	if(PluName=="") //Получаем наименование отдела если нет имени товара
	{	
		std::string Value;
		Programming("Dept_name",Utility::IntToStdStr(Department-1), PluName);
	}

	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start RegisterSale();");

	if(Price > 100.0f && !(m_activated1==147443647)) //Устанавливается время от времени (2147443647 если то - активированно)
	{
		MyError result;
		result.ErrorCode=ERRActivation;

		result.ErrorMessage=toKAZASCII(L"Без лицензии сумма не может быть больше 100!");
		m_LastErrorCode=result.ErrorCode;
		m_LastErrorDescription=result.ErrorMessage;
		return result;
	}

	SlipNumber=0;
	PluName = Utility::replaceStrings(PluName, "\n", " "); //Избавляемся от переходов на новую строку
	PluName = Utility::replaceStrings(PluName, "\t", " "); //Избавляемся от табуляции на новую строку

	std::string msg;

	int len=128;
	if (CuttingPluName > 0 && CuttingPluName<len) len=CuttingPluName; //Если переданна настройка из сторонней программы

	msg.append(PluName,0,len);

	msg+="\t";
	msg+= TaxCode;
	msg+="\t";
	msg+=Utility::FloatToStdStr(Price,2,'.');
	msg+="\t";
	msg+=Utility::FloatToStdStr(Quantity,3,'.');
	msg+="\t";

	MyError result;

	if(std::abs(DiscountValue)<0.000001) 
		DiscountType='0';

	if(PrinterName=="DPG-35" && (DiscountType=='1' || DiscountType=='2' ||DiscountType=='3' ||DiscountType=='4'))
	{
		result.ErrorCode = ERRDiscounts;
		result.ErrorMessage = toKAZASCII(L"Данный принтер не поддерживает скидки и наценки!");
	}else
	{
		msg+=DiscountType;
		msg+="\t";
		if(DiscountType!='0') 
			msg+=Utility::FloatToStdStr(DiscountValue,2,'.');
		msg+="\t";
		if(Department>0)
			msg+=Utility::IntToStdStr(Department);
		msg+="\t";
		msg += MarkStamp + "\t";
		if(RoundPrice>0.0099)
			msg+=Utility::FloatToStdStr(RoundPrice,2,'.');
		msg += "\t";
		if(UnitCode > 0 && UnitCode < 1000)
			msg += Utility::IntToStdStr(UnitCode);
		msg += "\t";

		msg += ProductID + "\t";
		msg += BarCode + "\t";

		std::string str="";
		std::string answer;

		result.ErrorCode =SendPMessage(fcRegisterSale,(unsigned char*)msg.c_str(),msg.size(),answer);
		if(result.ErrorCode==0)
		{
			std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
			if (ErrorCode == "0")
			{
				std::string num = Utility::CutBeforeFirst(answer, '\t');
				SlipNumber = Utility::StdStrToInt(num);
				num = Utility::CutBeforeFirst(answer, '\t');
				DocNumber = Utility::StdStrToInt(num);
			}
			else
			{
				result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
			}
		}

		m_LastErrorCode = result.ErrorCode;
		m_LastErrorDescription = result.ErrorMessage;
		if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
		{
			std::string rErrorMessage;
			int rECode;
			ReadingError(result.ErrorCode, rECode, rErrorMessage);
			m_LastErrorDescription = rErrorMessage;
			result.ErrorMessage = rErrorMessage;
			m_LastErrorCode = result.ErrorCode;
		}

	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "RegisterSale(PluName=\""+PluName+"\", TaxCd='"+ TaxCode +"', Price="+Utility::FloatToStdStr(Price,2,'.')+", Quantity="+Utility::FloatToStdStr(Quantity,3,'.')<<", DiscountType="<< DiscountType << ", DiscountValue=" << Utility::FloatToStdStr(DiscountValue, 2, '.') <<", Department="+Utility::IntToStdStr(Department)+", MarkStamp='"+ MarkStamp +"', RoundPrice="+Utility::FloatToStdStr(RoundPrice,2,'.')+", UnitCode="<< UnitCode  << ", ProductID=" << ProductID << ", BarCode=" << BarCode << ", SlipNumber=" << SlipNumber << ", DocNumber=" << DocNumber << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Возвращает активные ставки НДС
// nZreport – Номер первого Z-отчета (1...3800);
// TaxX – Ставка НДС; 0.00...99.99 - активна; 100.00 – не облагается; 100.01 - запрещена;
// EntryDate – Дата ввода (формат "DD-MM-YY");
MyError DP25::ReportOnTaxRates(int& NZreport,double& TaxA,double& TaxB,double& TaxC,std::string& EntryDate) ///<Отчет по налоговым ставкам и положению десятичной точки за период
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportOnTaxRates();");

	NZreport=0; TaxA=0; TaxB=0; TaxC=0; EntryDate="";

	std::string msg;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportOnTaxRates,(unsigned char *)msg.c_str(),(int)msg.size(),answer);
	//b=b && !Status->s[0][5]; //Признак ошибки
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			NZreport = Utility::StdStrToInt(num);

			num = Utility::CutBeforeFirst(answer, '\t');
			TaxA = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TaxB = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TaxC = Utility::StdStrToDouble(num, 0);
			EntryDate = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportOnTaxRates(NZreport="+Utility::IntToStdStr(NZreport)+",TaxA="+Utility::FloatToStdStr(TaxA,2,'.')+",TaxB="+Utility::FloatToStdStr(TaxB,2,'.')+",TaxC="+Utility::FloatToStdStr(TaxC,2,'.')+",EntryDate="+EntryDate+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
int DP25::ReadingError(int Code, int& ECode, std::string& ErrorMessage)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info","Start ReadingError();");

	ECode = 0;
	std::string msg;
	msg += '-' + Utility::IntToStdStr(Code); msg += "\t";

	std::string answer;
	int result;
	result = SendPMessage(fcReadingError, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			ECode = Utility::StdStrToInt(num);
			//ErrorMessage = fromDOStoASCII(Utility::CutBeforeFirst(answer, '\t'));
			ErrorMessage = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	std::wstring tmpMsg;
/*
	if (Code == ERRActivation && ErrorMessage == "") ErrorMessage = "ВНИМАНИЕ!!! Драйвер будет работать в демонстрационном режиме! Максимальная цена товарной позиции в чеке не может превышать 100 руб. Для получения ключа защиты необходимо приобрести лицензионную копию программного продукта.";
*/
	if (Code == 100001 && ErrorMessage == "") tmpMsg = L"Ошибка ввода/вывода, устройство не отвечает";
/*	if (Code == 100002 && ErrorMessage == "") ErrorMessage = "Ошибочная контрольная сумма";
	if (Code == 100003 && ErrorMessage == "") ErrorMessage = "Конец данных";
	if (Code == 100004 && ErrorMessage == "") ErrorMessage = "Элемент не найден";
	if (Code == 100005 && ErrorMessage == "") ErrorMessage = "Нет записей";
	if (Code == 100006 && ErrorMessage == "") ErrorMessage = "Операция прекращена";

	if (Code == 100100 && ErrorMessage == "") ErrorMessage = "ФП занята";
	if (Code == 100101 && ErrorMessage == "") ErrorMessage = "Ошибка записи в ФП";
	if (Code == 100102 && ErrorMessage == "") ErrorMessage = "Запись в ФП запрещена";
	if (Code == 100103 && ErrorMessage == "") ErrorMessage = "Ошибочный адрес в ФП";
	if (Code == 100104 && ErrorMessage == "") ErrorMessage = "Некорректный размер ФП";
	if (Code == 100105 && ErrorMessage == "") ErrorMessage = "ФП не подключена";
	if (Code == 100106 && ErrorMessage == "") ErrorMessage = "Неверная контрольная сумма в ФП";
	if (Code == 100107 && ErrorMessage == "") ErrorMessage = "Пустой блок в ФП";
	if (Code == 100108 && ErrorMessage == "") ErrorMessage = "Достигнуто максимальное количество записей в ФП";
	if (Code == 100109 && ErrorMessage == "") ErrorMessage = "Неверный диапазон в ФП";
	if (Code == 100110 && ErrorMessage == "") ErrorMessage = "Пустой диапазон в ФП";
	if (Code == 100111 && ErrorMessage == "") ErrorMessage = "Новая ФП";
	if (Code == 100112 && ErrorMessage == "") ErrorMessage = "ФП не пустая";
	if (Code == 100113 && ErrorMessage == "") ErrorMessage = "ФП заменена";
	if (Code == 100114 && ErrorMessage == "") ErrorMessage = "ФП заполнена";
	if (Code == 100115 && ErrorMessage == "") ErrorMessage = "Замените ФП";
	if (Code == 100116 && ErrorMessage == "") ErrorMessage = "Фискальная память заблокирована";

	if (Code == 100400 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Низкое напряжение ( 3,3 V )";
	if (Code == 100401 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Низкое напряжение ( 24V or 8V )";
	if (Code == 100402 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Принтер перегрелся";
	if (Code == 100403 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Нет бумаги";
	if (Code == 100404 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Крышка открыта";
	if (Code == 100405 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Конец бумаги близко";
	if (Code == 100406 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Mark sensor - not used";
	if (Code == 100407 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Ошибка отрезчика бумаги";
	if (Code == 100408 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";
	if (Code == 100409 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";
	if (Code == 100410 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";
	if (Code == 100411 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";
	if (Code == 100412 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";
	if (Code == 100413 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Не используется";

	if (Code == 100500 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка структуры памяти";
	if (Code == 100501 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка RAM";
	if (Code == 100502 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка Flash-памяти";
	if (Code == 100503 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка SD карты";
	if (Code == 100504 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Неверный файл сообщения";
	if (Code == 100505 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка фискальной памяти (ошибка чтения или записи)";
	if (Code == 100506 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Отсутствует батарея RAM";
	if (Code == 100507 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка SAM модуля";
	if (Code == 100508 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка часов реального времени";
	if (Code == 100509 && ErrorMessage == "") ErrorMessage = "Системная ошибка: Ошибка памяти";

	if (Code == 101000 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Нет динамической памяти";
	if (Code == 101001 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Ошибка обработки файла";
	if (Code == 101003 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Операция отклонена из-за ошибки";
	if (Code == 101004 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Неверный ввод. Переданные парамерты или данные некорректные";
	if (Code == 101005 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Ошибка IAP";
	if (Code == 101006 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Выполнение операции невозможно";
	if (Code == 101007 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Таймаут. Время ожидания истекло";
	if (Code == 101008 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Неверное время";
	if (Code == 101009 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Операция отменена";
	if (Code == 101010 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Неверный формат";
	if (Code == 101011 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Неверные данные";
	if (Code == 101012 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Ошибка синтаксического анализа данных";
	if (Code == 101013 && ErrorMessage == "") ErrorMessage = "Логическая ошибка: Ошибка настройки оборудования";

	if (Code == 102000 && ErrorMessage == "") ErrorMessage = "Низкий заряд аккумулятора";
	if (Code == 102001 && ErrorMessage == "") ErrorMessage = "Зарядите аккумулятор";
	if (Code == 102002 && ErrorMessage == "") ErrorMessage = "Ошибка оператора: Неверный пароль кассира";
	if (Code == 102003 && ErrorMessage == "") ErrorMessage = "Ошибка кассы: ЗНМ не задан";
	if (Code == 102004 && ErrorMessage == "") ErrorMessage = "Ошибка Bluetooth: Устройство Bluetooth не найдено";
	if (Code == 102005 && ErrorMessage == "") ErrorMessage = "Ошибка дисплея: Дисплей не подключен";
	if (Code == 102006 && ErrorMessage == "") ErrorMessage = "Ошибка принтера: Принтер не подключен";
	if (Code == 102007 && ErrorMessage == "") ErrorMessage = "Ошибка SD карты: SD карта не вставлена";
	if (Code == 102008 && ErrorMessage == "") ErrorMessage = "Ошибка SD карты: SD карта 2 не вставлена";

	if (Code == 103000 && ErrorMessage == "") ErrorMessage = "Ошибка базы данных товаров: База товаров не найдена";
	if (Code == 103001 && ErrorMessage == "") ErrorMessage = "Ошибка базы данных товаров: Товар с таким кодом уже существует";
	if (Code == 103002 && ErrorMessage == "") ErrorMessage = "Ошибка базы данных товаров: Такой штрихкод существует";
	if (Code == 103003 && ErrorMessage == "") ErrorMessage = "Ошибка базы данных товаров: База товаров заполнена";
	if (Code == 103004 && ErrorMessage == "") ErrorMessage = "Ошибка базы данных товаров: Товар имеет накопления";

	if (Code == 104000 && ErrorMessage == "") ErrorMessage = "Сервисная ошибка: Необходимо закрыть смену";
	if (Code == 104001 && ErrorMessage == "") ErrorMessage = "Сервисная ошибка: Необходимо установить сервисную перемычку";
	if (Code == 104002 && ErrorMessage == "") ErrorMessage = "Сервисная ошибка: Необходим ввод сервисного пароля";
	if (Code == 104003 && ErrorMessage == "") ErrorMessage = "Сервисная ошибка: Операция запрещена";
	if (Code == 104004 && ErrorMessage == "") ErrorMessage = "Сервисная ошибка: Требуется сервисное обслуживание";

	if (Code == 105000 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Нет записей в ЭЖ";
	if (Code == 105001 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Невозможно добавить в журнал";
	if (Code == 105002 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Ошибка подписи SAM модуля";
	if (Code == 105003 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Версия ключа подписи изменена -> невозможно проверить";
	if (Code == 105004 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Ошибка записи в ЭЖ";
	if (Code == 105005 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Ошибка генератора подписей (не возможно сгенерировать подпись)";
	if (Code == 105006 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Неверный тип документа для подписи";
	if (Code == 105007 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Документ уже подписан";
	if (Code == 105008 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: ЭЖ н не от этого устройства";
	if (Code == 105009 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: ЭЖ почти заполенен";
	if (Code == 105010 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: ЭЖ заполнен";
	if (Code == 105011 && ErrorMessage == "") ErrorMessage = "Ошибка ЭЖ: Неверный формат ЭЖ";

	if (Code == 110100 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Ошибка связи";
	if (Code == 110101 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Неверный формат структуры";
	if (Code == 110102 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Установлен флаг ST";
	if (Code == 110103 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Неверные данные";
	if (Code == 110104 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Аппарат не фискализирован";
	if (Code == 110105 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Аппарат уже фискализирован";
	if (Code == 110106 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Аппарат в находится в сервисном режиме";
	if (Code == 110107 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Дата сервисного обслуживания прошла";
	if (Code == 110108 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Смена открыта";
	if (Code == 110109 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Смена закрыта";
	if (Code == 110110 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Номер смены не совпадает с номером Z-отчета";
	if (Code == 110111 && ErrorMessage == "") ErrorMessage = "Ошибка устройства: Разрешено только администратору";

	if (Code == 110200 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Ошибка открытия сессии";
	if (Code == 110201 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Ошибка подготовки данных для сервера";
	if (Code == 110202 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Имеются не отправленные данные";
	if (Code == 110203 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Ошибка отправки данных";
	if (Code == 110204 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Пустые данные";
	if (Code == 110205 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Отрицательный ответ сервера";
	if (Code == 110206 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Неверный формат ответа";
	if (Code == 110207 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Сервер HOSTDI равен нулю";
	if (Code == 110208 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Server exception";
	if (Code == 110209 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Не зарегистрирован на сервере";
	if (Code == 110210 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Соединение заблокировано";
	if (Code == 110211 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Ошибка модема";
	if (Code == 110212 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Сервер занят";
	if (Code == 110213 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Зарегестрирован";
	if (Code == 110214 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Wrong PS type";
	if (Code == 110215 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Снят с регистрации на сервере";
	if (Code == 110216 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Wrong IMSI number";
	if (Code == 110217 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Аппарат заблокирован (достигнуто максимальное кол-во Z-отчетов)";
	if (Code == 110218 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Неверный тип фискального устройства";
	if (Code == 110219 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Аппарат заблокирован сервером";
	if (Code == 110220 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Аппарат заблокирован - ошибка сервера";
	if (Code == 110221 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Отсутствуе адрес сервера ОФД";
	if (Code == 110222 && ErrorMessage == "") ErrorMessage = "Ошибка сервера: Регистрация не возможна";

	if (Code == 110300 && ErrorMessage == "") ErrorMessage = "Рабочая ошибка: Неверный файл";
	if (Code == 110301 && ErrorMessage == "") ErrorMessage = "Рабочая ошибка: Неверные параметры";

	if (Code == 110400 && ErrorMessage == "") ErrorMessage = "Ошибка соединеия: Ошибка инициализации подключения";
	if (Code == 110401 && ErrorMessage == "") ErrorMessage = "Connection error: Неверные параметры";
	if (Code == 110402 && ErrorMessage == "") ErrorMessage = "Connection error: Нет GPRS соединения";

	if (Code == 110500 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Ошибка подключения модема к аппарату";
	if (Code == 110501 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Нет SIM карты";
	if (Code == 110502 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Неверный PIN код SIM карты";
	if (Code == 110503 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Не зарегистрирован в мобильной сети";
	if (Code == 110504 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Отсутствует PPP соединение (нет связи)";
	if (Code == 110505 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Неверные настройки модема (например: не введен APN)";
	if (Code == 110506 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Ошибка инициализации модема";
	if (Code == 110507 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Модем не готов";
	if (Code == 110508 && ErrorMessage == "") ErrorMessage = "Ошибка модема: SIM карта удалена";
	if (Code == 110509 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Поиск сети";
	if (Code == 110510 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Сеть не найдена";
	if (Code == 110511 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Failed lot days";

	if (Code == 110601 && ErrorMessage == "") ErrorMessage = "Ошибка модема: Аппарат не подключен к точке доступа";

	if (Code == 110700 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Не удается соединиться с адресом";
	if (Code == 110701 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Не удается открыть сокет для связи с сервером";
	if (Code == 110702 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Ошибка соединения (не удается соединиться с сервером)";
	if (Code == 110703 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Ошибка настроек соединения (например: не указан адрес сервера)";
	if (Code == 110704 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Подключение уже открыто";
	if (Code == 110705 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Ошибка SSL соединения (Что-то пошло не так в криптографическом протоколе)";
	if (Code == 110706 && ErrorMessage == "") ErrorMessage = "Ошибка сети: Ошибка HTTP соединения (Что-то пошло не так в http-протоколе)";

	if (Code == 110900 && ErrorMessage == "") ErrorMessage = "Нет ошибок";
	if (Code == 110901 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неизвестная команда, неверный формат или неизвестные параметры";
	if (Code == 110902 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверное состояние ФН";
	if (Code == 110903 && ErrorMessage == "") ErrorMessage = "Ошибка ФН";
	if (Code == 110904 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка криптографического сопроцессора";
	if (Code == 110905 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Закончен срок эксплуатации ФН";
	if (Code == 110906 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Архив ФН переполнен";
	if (Code == 110907 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверные дата и/или время";
	if (Code == 110908 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Запрошенных данных нет";
	if (Code == 110909 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверное значение параметров команды";
	if (Code == 110916 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Превышение размеров TLV данных";
	if (Code == 110917 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Нет транспортного соединения";
	if (Code == 110918 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Исчерпан ресурс криптографического сопроцессора";
	if (Code == 110919 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Исчерпан ресурс";
	if (Code == 110920 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Исчерпан ресурс документов для ОФД";
	if (Code == 110921 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Исчерпан ресурс ожидания передачи данных";
	if (Code == 110922 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Смена превысила 24 часа";
	if (Code == 110923 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверная разница во времени между двумя операциями";
	if (Code == 110932 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Данные из OFD не могут быть получены";
	if (Code == 110960 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неизвестная ошибка";
	if (Code == 110961 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверная фаза ФН";
	if (Code == 110962 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Неверный номер ФН";
	if (Code == 110971 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - не отправлено";
	if (Code == 110972 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - нет ответа";
	if (Code == 110973 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - превышение времени";
	if (Code == 110974 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - недостаточно данных";
	if (Code == 110975 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - неверная длина данных";
	if (Code == 110976 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - неверная контрольная сумма";
	if (Code == 110979 && ErrorMessage == "") ErrorMessage = "Ошибка ФН: Ошибка связи с ФН - неизвестная ошибка";

	if (Code == 111000 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Общая ошибка, за которой следует удаление всех данных для команды";
	if (Code == 111001 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Общая ошибка, за которой следует частичное удаление данных для команды";
	if (Code == 111002 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ошибка синтаксиса. Проверьте параметры команды";
	if (Code == 111003 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Операция невозможна";
	if (Code == 111004 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Код товара не существует";
	if (Code == 111005 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ставка НДС запрещена";
	if (Code == 111006 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Переполнение Цена*Количличество";
	if (Code == 111007 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет цены";
	if (Code == 111008 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Группа товаров не входит в диапазон";
	if (Code == 111009 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Отдел не входит в диапазон";
	if (Code == 111010 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Штрихкод не найден";
	if (Code == 111011 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Переполнение оборота по товару";
	if (Code == 111012 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Переполнение количества по товару";
	if (Code == 111013 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Переполнение дневного регистра";
	if (Code == 111014 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Переполнение регистра суммы в чеке";
	if (Code == 111015 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Чек открыт";
	if (Code == 111016 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Чек закрыт";
	if (Code == 111017 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Недостаточно наличности в кассе";
	if (Code == 111018 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Оплата началась";
	if (Code == 111019 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Превышено максимальное количество продаж в чеке";
	if (Code == 111020 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет продаж/покупок";
	if (Code == 111021 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Возможен отрицательный оборот";
	if (Code == 111022 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Оплата в иностранной валюте со сдачей";
	if (Code == 111023 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет продаж/покупок в чеке";
	if (Code == 111024 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Смена превысила 24 часа. Закройте смену";
	if (Code == 111025 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Неверный диапазон";
	if (Code == 111026 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Операция отменена оператором";
	if (Code == 111027 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Операция подтверждена POS терминалом";
	if (Code == 111028 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Операция не подтверждена POS терминалом";
	if (Code == 111029 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ошибка связи с POS терминалом";
	if (Code == 111030 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Количество * Цена = 0";
	if (Code == 111031 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Превышение значения";
	if (Code == 111032 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ошибочное значение";
	if (Code == 111033 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Превышение цены";
	if (Code == 111034 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ошибочная цена";
	if (Code == 111035 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Выбрана операция отмены чека";
	if (Code == 111036 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Возможна только операция отмены чека";
	if (Code == 111040 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет свободного места для других покупок";
	if (Code == 111041 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет свободного места для новой учетной записи.";
	if (Code == 111042 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Учетная запись уже открыта";
	if (Code == 111043 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Неверный индекс";
	if (Code == 111044 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Учетная запись не найдена";
	if (Code == 111045 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Разрешено только администратору";
	if (Code == 111046 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Открыт служебный чек";
	if (Code == 111047 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Открыт фискальный чек";
	if (Code == 111048 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Buyers TIN is already entered";
	if (Code == 111049 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Buyers TIN is not entered";
	if (Code == 111050 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Оплата не произведена";
	if (Code == 111051 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Несоответствие типа чека";
	if (Code == 111052 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Достигнут лимит суммы чека";
	if (Code == 111053 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма не делится на минимальную денежную единицу";
	if (Code == 111054 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма должна быть меньше или равна сумме оплаты";
	if (Code == 111055 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма сертификата должна быть введена при оплате сертификатом";
	if (Code == 111056 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма доплаты разницы между суммой сертификата и суммой оплаты должна быть сделана при оплате сертификмтом, и сумма оплаты должна быть > итоговой суммы чека";
	if (Code == 111057 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Оплата иностранной валютой отключена";
	if (Code == 111058 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Оплата иностарнной валютой не возможна";
	if (Code == 111059 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма должна быть больше или равна сумме оплаты";
	if (Code == 111060 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Открытие денежного ящика отключено";
	if (Code == 111061 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Запрещенный платеж";
	if (Code == 111062 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Клавиши скидок/надбавок запрещены";
	if (Code == 111063 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Введенная сумма больше суммы оплаты";
	if (Code == 111064 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Введенная сумма меньше суммы чека";
	if (Code == 111065 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Фискальный регистратор: Сумма чека 0. Аннулируйте чек";
	if (Code == 111066 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Фискальный регистратор: Выполняется операция аннулирования. Необходимо закрыть чек";
	if (Code == 111067 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Открыт чек возврата";
	if (Code == 111068 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Сумма не введена";
	if (Code == 111069 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Неверный тип цены";
	if (Code == 111070 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Связанная наценка запрещена";
	if (Code == 111071 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Отрицательная цена запрещена";
	if (Code == 111072 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Не допускается более 1й ставки НДС в одном чеке";
	if (Code == 111073 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Ошибка подкючения банковского терминала";
	if (Code == 111074 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Неверные данные покупателя";
	if (Code == 111080 && ErrorMessage == "") ErrorMessage = "Ошибка режима регистрации: Нет в остатке";

	if (Code == 112000 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Неверная команда";
	if (Code == 112001 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Неверный синтаксис";
	if (Code == 112002 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Команда не разрешена";
	if (Code == 112003 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Переполнение регистра";
	if (Code == 112004 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Неверная дата и время";
	if (Code == 112005 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Требуется подключение к ПК";
	if (Code == 112006 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Нет бумаги";
	if (Code == 112007 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Открыта крышка";
	if (Code == 112008 && ErrorMessage == "") ErrorMessage = "Ошибка фискального регистратора: Ошибка печатного механизма";
*/
	if (Code == 111100 && ErrorMessage == "") tmpMsg = L"Продажи запрещены. Обратитесь в сервис!"; //ERR_R_SALES_FORBIDDEN


	if(tmpMsg.length()>0) ErrorMessage=toKAZASCII(tmpMsg);
	m_LastErrorCode = result;

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReadingError(ECode=" << ECode << ",ErrorMessage=" << ErrorMessage << ");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
///Закрытие фискального чека
//SlipNumber - Текущий номер чека продажи или чека возврата (1...99999999);
//{ErrorCode}<SEP>{FiscalSignType}<SEP>{FiscalSign}<SEP>{ShiftNumber}<SEP>{SlipNumber}<SEP>{DocNumber}<SEP>
MyError DP25::CloseFiscalInv(int& FiscalSignType,std::string& FiscalSign,int& ShiftNumber,int& SlipNumber,int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start CloseFiscalInv();");

	SlipNumber=0;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcCloseFiscalInv,NULL,0,answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			FiscalSignType = Utility::StdStrToInt(num);
			FiscalSign = Utility::CutBeforeFirst(answer, '\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			ShiftNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			SlipNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			DocNumber = Utility::StdStrToInt(num);
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "CloseFiscalInv(FiscalSignType="<< FiscalSignType<<",FiscalSign=" << FiscalSign<< ",ShiftNumber="<< ShiftNumber <<",SlipNumber="+Utility::IntToStdStr(SlipNumber)+",DocNumber="<< DocNumber <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Регистрация продажи запрограммированного товара
// PluCode - Код товара. От 1 до 3000
// Quanity: Количество товара. Пример: 1.000; Максимально: 999999.999;
// DiscountType – тип дисконта. '0' или пусто – без дисконта; '1' – наценка в процентах; '2' – скидка в процентах; '3' – наценка суммой; '4' – скидка суммой;
// DiscountValue – значение дисконта. Число от 0.00 до 21474836.47 Если {DiscountType} ноль или пусто, то этот параметр должен быть пустым.
// SlipNumber - Текущий номер чека продажи или чека возврата (1...99999999);
MyError DP25::RegisterArticleSale(int PluCode, double Quantity, double Price, char DiscountType, double DiscountValue, std::string MarkStamp, int& SlipNumber, int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start RegisterArticleSale();");

	SlipNumber=0;

	std::string msg;

	msg+=Utility::IntToStdStr(PluCode)+"\t";
	msg+=Utility::FloatToStdStr(Quantity,3,'.'); msg+="\t";
	msg += Utility::FloatToStdStr(Price, 2, '.'); msg += "\t";
	msg+=DiscountType; msg+="\t";
	if(DiscountType!='0')
	{
		msg+=Utility::FloatToStdStr(DiscountValue,2,'.');
	}
	msg += "\t";
	msg += MarkStamp; msg += "\t";
	
	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcRegisterArticleSale,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer,'\t');
			SlipNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			DocNumber = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "RegisterArticleSale(PluCode="+Utility::IntToStdStr(PluCode)+",Quantity="+Utility::FloatToStdStr(Quantity,3,'.')+",DiscountType="+DiscountType+",DiscountValue="+Utility::FloatToStdStr(DiscountValue,2,'.')+",MarkStamp="<< MarkStamp <<"SlipNumber="+Utility::IntToStdStr(SlipNumber)<<",DocNumber="<< DocNumber <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
///Аннуляция (сторно) фискального чека
MyError DP25::CancelFiscalInv(int& ShiftNumber, int& DocNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start CancelFiscalInv();");

	ShiftNumber = 0; DocNumber = 0;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcCancelFiscalInv,NULL,0,answer);
	//b=b && !Status->s[0][5]; //Признак ошибки
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0") {
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			if (num != "") ShiftNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			if (num != "") DocNumber = Utility::StdStrToInt(num);
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "CancelFiscalInv(ShiftNumber="+Utility::IntToStdStr(ShiftNumber)+",DocNumber="<< Utility::IntToStdStr(DocNumber) <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Информация о последней фискальной записи
// Type – Тип возвращаемых данных. По умолчанию: 0; '0' – Обороты продаж по группам НДС; '1' – Оборот возвратов по группам НДС; '2' – Сумма НДС в чеках продажи по группам НДС; '3' – Сумма НДС в чеках возврата по группам НДС;
// NRep – Номер Z-отчета (1...3800);
// SumX – Оборот или сумма НДС группы X определенного в Type типа ( 0.00...9999999.99 );
// Date – Дата фискальной записи (формат "DD-MM-YY");
MyError DP25::LatestFiscalRecord(char Type, int& NRep, double& SumA,double& SumB,double& SumC,std::string& Date)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start LatestFiscalRecord();");

	NRep=0; SumA=0; SumB=0; SumC=0;

	std::string msg;
	msg+=Type; msg+="\t";
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcLatestFiscalRecord,(unsigned char*)msg.c_str(),(int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			NRep = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			SumA = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			SumB = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			SumC = Utility::StdStrToDouble(num);
			Date = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "LatestFiscalRecord(Type="+std::string("")+Type+",NRep="+Utility::IntToStdStr(NRep)+",SumA="+Utility::FloatToStdStr(SumA,2,'.')+",SumB="+Utility::FloatToStdStr(SumB,2,'.')+",SumC="+Utility::FloatToStdStr(SumC,2,'.')+",Date="+Date+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
///Информация о налогах за текущий день
// Type - Тип возвращаемых данных. По умолчанию: 0; '0' – Обороты продаж по группам НДС; '1' – Оборот возвратов по группам НДС; '2' – Сумма НДС в чеках продажи по группам НДС; '3' – Сумма НДС в чеках возврата по группам НДС;
// nRep - Номер Z-отчет (1...3800);
// SumX - Оборот или сумма НДС группы X определенного в Type типа (0.00...9999999.99);
MyError DP25::AmountOfSavingsPerDay(char Type, int& NRep, double& SumA,double& SumB,double& SumC)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start AmountOfSavingsPerDay();");

	NRep=0; SumA=0; SumB=0; SumC=0;

	std::string msg;
	msg+=Type; msg+="\t";
	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcAmountOfSavingsPerDay,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer,'\t');
			NRep = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumA = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumB = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumC = Utility::StdStrToDouble(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "AmountOfSavingsPerDay(Type="+std::string("")+Type+",NRep="+Utility::IntToStdStr(NRep)+",SumA="+Utility::FloatToStdStr(SumA,2,'.')+",SumB="+Utility::FloatToStdStr(SumB,2,'.')+",SumC="+Utility::FloatToStdStr(SumC,2,'.')+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::TurnoversOfSavingsPerDay(int& nRep, double& DailySales, double& DailyRetOfSales, double& DailyPurchases, double& DailyRetOfPurchases, double& NonNullSales, double& NonNullRetOfSales, double& NonNullPurchases, double&  NonNullRetOfPurchases)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start TurnoversOfSavingsPerDay();");

	nRep=0;DailySales=0;DailyRetOfSales=0;DailyPurchases=0;DailyRetOfPurchases=0;NonNullSales=0;NonNullRetOfSales=0;NonNullPurchases=0;NonNullRetOfPurchases=0;

	std::string msg;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcTurnoversOfSavingsPerDay,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer,'\t');
			nRep = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			DailySales = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			DailyRetOfSales = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			DailyPurchases = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			DailyRetOfPurchases = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NonNullSales = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NonNullRetOfSales = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NonNullPurchases = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NonNullRetOfPurchases = Utility::StdStrToDouble(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "TurnoversOfSavingsPerDay(nRep=" << nRep << ",DailySales=" << Utility::FloatToStdStr(DailySales,2,'.') << ",DailyRetOfSales=" << Utility::FloatToStdStr(DailyRetOfSales,2,'.') << ",DailyPurchases=" << Utility::FloatToStdStr(DailyPurchases,2,'.') << ",DailyRetOfPurchases=" << Utility::FloatToStdStr(DailyRetOfPurchases,2,'.') << ",NonNullSales=" << Utility::FloatToStdStr(NonNullSales,2,'.') << ",NonNullRetOfSales=" << Utility::FloatToStdStr(NonNullRetOfSales,2,'.') << ",NonNullPurchases=" << Utility::FloatToStdStr(NonNullPurchases,2,'.') << ".NonNullRetOfPurchases=" << Utility::FloatToStdStr(NonNullRetOfPurchases,2,'.') << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Получение статуса принтера
MyError DP25::GetStatusFP(std::string& StatusBytes)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetStatusFP();");

	std::string msg;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetStatusFP,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string rez = Utility::CutBeforeFirst(answer, '\t');
			StatusBytes = "";
			if (rez.length() >= 1)
			{
				StatusBytes += getBitVal(rez[0], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[0], 0) ? '1' : '0';
			}
			if (rez.length() >= 2)
			{
				//Байт 1: Общее предназначение
				StatusBytes += getBitVal(rez[1], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[1], 0) ? '1' : '0';
			}
			if (rez.length() >= 3)
			{
				//Байт 2: Общее предназначение
				StatusBytes += getBitVal(rez[2], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[2], 0) ? '1' : '0';
			}
			if (rez.length() >= 4)
			{
				//Байт 3: Состояние конфигурационных переключателей
				StatusBytes += getBitVal(rez[3], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[3], 0) ? '1' : '0';
			}
			if (rez.length() >= 5)
			{
				//Байт 4: Фискальная память
				StatusBytes += getBitVal(rez[4], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[4], 0) ? '1' : '0';
			}
			if (rez.length() >= 6)
			{
				//Байт 5: Фискальная память
				StatusBytes += getBitVal(rez[5], 7) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 6) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 5) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 4) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 3) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 2) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 1) ? '1' : '0';
				StatusBytes += getBitVal(rez[5], 0) ? '1' : '0';
			}
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetStatusFP(StatusBytes="+StatusBytes+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Статус фискального чека
//IsOpen - Status of current receipt;

//    '0' - Receipt is closed;
//    '1' - Sales receipt is open;
//    '2' - Return of sales receipt is open;
//    '3' - Purchases receipt is open;
//    '4' - Return of purchases receipt is open;
//    '5' - Non fiscal receipt is open;

// Items – Количество продаж в текущем или в последнем фискальном чеке;
// Amount – Сумма текущего или последнего фискального чека;
// Payed – Сумма оплаты текущего или последнего фискального чека;
//SlipNumber - Current slip number (1...99999999);
//SlipNumberFiscal - Current number of the sales receipt or of the refund receipt ( 1...99999999 );
MyError DP25::FiscalTransactionsStatus(char& IsOpen,int& Items,double& Amount,double& Payed,int& SlipNumber,int &SlipNumberFiscal)
{
	IsOpen=0; Items=0; Amount=0; Payed=0; SlipNumber=0; SlipNumberFiscal=0;

	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start FiscalTransactionsStatus();");

	std::string msg;

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFiscalTransactionsStatus,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			IsOpen = num[0];
			num = Utility::CutBeforeFirst(answer, '\t');
			Items = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			Amount = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			Payed = Utility::StdStrToDouble(num);

			num = Utility::CutBeforeFirst(answer, '\t');
			SlipNumber = Utility::StdStrToInt(num, true);
			num = Utility::CutBeforeFirst(answer, '\t');
			SlipNumberFiscal = Utility::StdStrToInt(num, true);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "FiscalTransactionsStatus(IsOpen=" << IsOpen << ",Items="+Utility::IntToStdStr(Items)+",Amount="+Utility::FloatToStdStr(Amount,2,'.')+",Payed="+Utility::FloatToStdStr(Payed,2,'.')+",SlipNumber="+Utility::IntToStdStr(SlipNumber)+",SlipNumberFiscal="+Utility::IntToStdStr(SlipNumberFiscal)+");"; 
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Звуковой сигнал
///\param Hz Частота звука
///\param mSec Милисекунд
MyError DP25::Beep(int Hz,int mSec)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start Beep();");

	std::string msg;
	msg+=Utility::IntToStdStr(Hz)+"\t";
	msg+=Utility::IntToStdStr(mSec)+"\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcBeep,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "Beep(Hz="+Utility::IntToStdStr(Hz)+",mSec="+Utility::IntToStdStr(mSec)+");"; 
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
//Установка даты и времени
// DateTime – Дата и время (формат "DD-MM-YY hh:mm:ss");
// DD - День; MM - Месяц; YY - Год; hh - Час; mm - Минута; ss - Секунда;
MyError DP25::SetDateTime(std::string DateTime)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start SetDateTime();");

	std::string msg;
	msg+=DateTime+"\t";	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcSetDateTime,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){
		}
		else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetDateTime(DateTime="+DateTime+");"; 
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Поолучение даты и времени
///\param date - Дата в формате "DD-MM-YY"
///\param time - врремя в формате "HH:MM:SS"
MyError DP25::GetDateTime(std::string &DateTime)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetDateTime();");

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetDateTime,NULL,0,answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){
			DateTime = Utility::CutBeforeFirst(answer, '\t');
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetDateTime(DateTime="+DateTime+");"; 
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Show current date and time
MyError DP25::ShowDateTime(std::string &DateTime)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start ShowDateTime();");

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcShowDateTime, NULL, 0, answer);

	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0") {
			DateTime = Utility::CutBeforeFirst(answer, '\t');
		}
		else {
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetDateTime(DateTime=" + DateTime + ");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Подитог
//Print – Печать промежуточного итога. '0' – Не печатать; '1' – Печатать сумму промежуточного итога;
//Display – Показ суммы промежуточного итога на дисплее покупателя. '0' – Не показывать; '1' - Показывать сумму промежуточного итога на дисплее;
//DiscountType – тип дисконта. '0' или пусто – без дисконта; '1' – наценка в процентах; '2' – скидка в процентах; '3' – наценка суммой; '4' – скидка суммой;
//DiscountValue – значение дисконта. число от 0.00 до 21474836.47 для операций суммой; o	число от 0.00 до 99.99 для операций в процентах;

//SlipNumber - Текущий номер чека продажи или чека возврата (1...99999999);
//Subtotal – Промежуточный итог чека (0.00...9999999.99);
//TaxX – Оборот чека по НДС группы X (0.00...9999999.99);
MyError DP25::Subtotal(char Print,char Display,char DiscountType,double DiscountValue,int& SlipNumber,double& Subtotal,double& TaxA,double& TaxB,double& TaxC)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start Subtotal();");

	MyError result;
	SlipNumber=0; Subtotal=0; TaxA=0; TaxB=0; TaxC=0;

	std::string msg;
	msg+=Print; msg+="\t";
	msg+=Display; msg+="\t";

	msg+=DiscountType; msg+="\t";
	if(DiscountType!='0')
	{	msg+=Utility::FloatToStdStr(DiscountValue,2,'.');
	}
	msg+="\t";

		
	std::string answer;

	result.ErrorCode =SendPMessage(fcSubtotal,(unsigned char*)msg.c_str(), (int)msg.size(),answer);

	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			SlipNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			Subtotal = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			TaxA = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			TaxB = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			TaxC = Utility::StdStrToDouble(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}




	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "Subtotal(Print=" << Print << ",Display=" << Display << ",DiscountType=" << DiscountType << ",DiscountValue=" << Utility::FloatToStdStr(DiscountValue,2,'.') << ",SlipNumber=" << SlipNumber << ",Subtotal=" << Utility::FloatToStdStr(Subtotal,2,'.') << ",TaxA=" << Utility::FloatToStdStr(TaxA,2,'.') << ",TaxB=" << Utility::FloatToStdStr(TaxB,2,'.') << ",TaxC=" << Utility::FloatToStdStr(TaxC,2,'.') << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
int DP25::GetLineLength() //Получить ширину строки чека в символах. PrinterName = "PORT MP-55L FKZ"
{
	int result;
	if(PrinterName=="FPG-1000") result=46; //ПОРТ FPG-1000 ФKZ
	else if(PrinterName=="FPG-350") result=46; //ПОРТ FPG-350 ФKZ
	else if(PrinterName=="FPG-60") result=40; //ПОРТ FPG-60 ФKZ
	else if(PrinterName=="DPG-150") result=72; //ПОРТ DPG-150 ФKZ
	else if(PrinterName=="DPG-35") result=72; //ПОРТ DPG-35 ФKZ
	else if(PrinterName=="DPG-25") result=72; //ПОРТ DPG-25 ФKZ
	else if(PrinterName=="DP-25") result=72; //ПОРТ MP-55B ФKZ ОФД
	else result=40;

	return result;
}
//---------------------------------------------------------------------------
//Bold - flag 0 or 1, 1 = print bold text; empty field = normal text;
//Italic - flag 0 or 1, 1 = print italic text; empty field = normal text;
//DoubleH - flag 0 or 1, 1 = print double height text; empty field = normal text;
//Underline - flag 0 or 1, 1 = print underlined text; empty field = normal text;
//Alignment - 0, 1 or 2. 0=left alignment, 1=center, 2=right; empty field = left alignment;
MyError DP25::PrintFreeTextInFiscalInv(std::string Text,char Bold,char Italic,char Height,char Underline,char Alignment)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintFreeTextInFiscalInv();");

	std::string msg;
	msg.append(Text, 0, Utility::StdStrToInt(PrintColumns));

	msg+='\t';


	msg+=Bold;
	msg+='\t';
	msg+=Italic;
	msg+='\t';
	msg+= Height;
	msg+='\t';
	msg+=Underline;
	msg+='\t';
	msg+=Alignment;
	msg+='\t';

	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintFreeTextInFiscalInv,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintFreeTextInFiscalInv(Text="+Text+",Bold="<< Bold <<",Italic="<< Italic <<",DoubleH="<< Height <<",Underline="<< Underline <<",Alignment="<<Alignment<< ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Оплата (итог)
// PaidMode – Тип оплаты. По умолчанию: 0; '0' - наличные; '1' - карта; '2' - кредит; '3' - тара;
// Amount – Сумма оплаты (0.00...9999999.99). По умолчанию: остаточная сумма чека;
// ErrorStatus - Указывает на ошибку или ее отсутствие; 'D' – Возвращается если сумма оплаты меньше или равна сумме чека. Оставшаяся для оплаты сумма (может ровняться 0) возвращается в Amount; 'R' - Возвращается если сумма оплаты больше суммы чека. Сумма сдачи возвращается в Amount;
// Amount – Оставшаяся для оплаты сумма (может ровняться 0) или сумма сдачи (0.00...9999999.99);
// SlipNumber - Текущий номер чека продажи или чека возврата (1...99999999);
MyError DP25::Total(int PaidMode,double Amount,int& ErrorStatus,double& NewAmount,int& SlipNumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start Total();");

	ErrorStatus=' '; NewAmount=0; SlipNumber=0;

	std::string msg;
	msg+=PaidMode; msg+='\t';
	msg+=Utility::FloatToStdStr(Amount,2,'.');  msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcTotal,(unsigned char*)msg.c_str(), (int)msg.size(),answer); //answer = "R	88.00	0	"
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		//'D' – Возвращается если сумма оплаты меньше или равна сумме чека. Оставшаяся для оплаты сумма (может ровняться 0) возвращается в Amount;
		//'R' - Возвращается если сумма оплаты больше суммы чека. Сумма сдачи возвращается в Amount;
		if (ErrorCode == "0")
		{
			std::string rs = Utility::CutBeforeFirst(answer, '\t');
			if(rs == "0" || rs == "P" || rs == "D" || rs == "R")
			{
				ErrorStatus = rs[0];
				std::string num;
				num = Utility::CutBeforeFirst(answer, '\t');
				NewAmount = Utility::StdStrToDouble(num);
				num = Utility::CutBeforeFirst(answer, '\t');
				SlipNumber = Utility::StdStrToInt(num);
			}
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "Total(PaidMode=" << (char)PaidMode << ",Amount="+Utility::FloatToStdStr(Amount,2,'.')+",ErrorStatus=" << (char)ErrorStatus << ",NewAmount="+Utility::FloatToStdStr(NewAmount,2,'.')+",SlipNumber="+Utility::IntToStdStr(SlipNumber)+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Служебный приход или расход
// Type – Тип операции; '0' - Внесение; '1' - Выплата;
// Amount - Сумма (0.00...9999999.99);
// CashSum – Сумма положенная в денежный ящик (0.00...9999999.99);
// CashIn – Итоговая сумма операций внесения (0.00...9999999.99);
// CashOut – Итоговая сумма операций выплаты (0.00...9999999.99);
MyError DP25::ParishOrConsumption(char Type,double Amount,double& CashSum,double& CashIn,double& CashOut)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ParishOrConsumption();");

	CashSum=0;CashIn=0;CashOut=0;

	std::string msg;
	msg+=Type; msg+="\t";
	msg+=Utility::FloatToStdStr(Amount,2,'.'); msg+="\t";
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcParishOrConsumption,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			CashSum = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			CashIn = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			CashOut = Utility::StdStrToDouble(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ParishOrConsumption(Type="<< Type <<",Amount="<< Amount <<",CashSum="<< CashSum <<",CashIn="<< CashIn <<",CashOut="<< CashOut <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Количество логических мест для фискальных записей
///\Logical Количество логических мест для фискальных записей
MyError DP25::FreeFieldsByFiscalMemory(int& ReportsLeft)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start FreeFieldsByFiscalMemory();");

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFreeFieldsByFiscalMemory,NULL,0,answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num = Utility::CutBeforeFirst(answer, '\t');
			ReportsLeft = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "FreeFieldsByFiscalMemory(ReportsLeft="<< ReportsLeft << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
//Печатать отчёт
// nRep - Номер Z-отчета (1...3800);
// TotX – Итоговый оборот в чеках продажи по группе НДС X (0.00...9999999.99);
// TotNegX - Итоговый оборот в чеках возврата по группе НДС X (0.00...9999999.99);
MyError DP25::PrintReport(char Type,int& nRep,double& TotA,double& TotB,double& TotC,double& TotNegA,double& TotNegB,double& TotNegC, double& TotPuA, double& TotPuB, double& TotPuC, double& TotPuNegA, double& TotPuNegB, double& TotPuNegC)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintReport();");

	nRep=0; TotA=0; TotB=0; TotC=0; TotNegA=0; TotNegB=0; TotNegC=0;

	std::string msg;
	msg += Type; msg += "\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcDailyFinancialReport, (unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num=Utility::CutBeforeFirst(answer,'\t');
			nRep=Utility::StdStrToInt(num);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotA=Utility::StdStrToDouble(num,0);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotB=Utility::StdStrToDouble(num,0);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotC=Utility::StdStrToDouble(num,0);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotNegA=Utility::StdStrToDouble(num,0);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotNegB=Utility::StdStrToDouble(num,0);
			num=Utility::CutBeforeFirst(answer,'\t');
			TotNegC=Utility::StdStrToDouble(num,0);
			
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuA = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuB = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuC = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuNegA = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuNegB = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotPuNegC = Utility::StdStrToDouble(num, 0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintReport(Type="<< Type<<",nRep="<< nRep <<",TotA="<< TotA <<",TotB="<< TotB <<",TotC="<< TotC <<",TotNegA="<< TotNegA <<",TotNegB="<< TotNegB <<",TotNegC="<< TotNegC <<",TotPuA="<< TotPuA <<",TotPuB="<< TotPuB <<",TotPuC="<< TotPuC <<",TotPuNegA="<< TotPuNegA <<",TotPuNegB="<< TotPuNegB <<",TotPuNegC="<< TotPuNegC <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Печатать дневной отчёт с гашением
MyError DP25::PrintZReport()
{
	int nRep;
	double TotA,TotB,TotC,TotNegA,TotNegB,TotNegC;
	double TotPuA, TotPuB, TotPuC, TotPuNegA, TotPuNegB, TotPuNegC;
	return PrintReport('Z',nRep,TotA,TotB,TotC,TotNegA,TotNegB,TotNegC,TotPuA,TotPuB,TotPuC,TotPuNegA,TotPuNegB,TotPuNegC);
}
//---------------------------------------------------------------------------
//Печатать дневной отчёт без гашения
MyError DP25::PrintXReport()
{
	int nRep;
	double TotA,TotB,TotC,TotNegA,TotNegB,TotNegC;
	double TotPuA, TotPuB, TotPuC, TotPuNegA, TotPuNegB, TotPuNegC;
	return PrintReport('X',nRep,TotA,TotB,TotC,TotNegA,TotNegB,TotNegC, TotPuA, TotPuB, TotPuC, TotPuNegA, TotPuNegB, TotPuNegC);
}
//---------------------------------------------------------------------------
///Печать диагностической информации
// InfoType – Тип печатаемой информации. По умолчанию: 0; o	'0' – Общая диагностическая информация об устройстве; o	'1' – Тест модема;
MyError DP25::PrintDiagnostic(char InfoType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintDiagnostic();");

	std::string msg;
	msg+=InfoType; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintDiagnostic,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintDiagnostic("<< InfoType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::PrintDiagnostic()
{
	return PrintDiagnostic('0');
}
//---------------------------------------------------------------------------
/// Фискализация и пререгистрация
// SerialNumber – Заводской номер (Две цифры (01) и 10 цифр (xxxxxxxxxx=уникальный заводской номер: 01xxxxxxxxxx) );
// TAXnumber1 - РНМ (до 12 цифр); (8 на чеке)
// TAXnumber2 - БИН (до 12 цифр);
// InspPssword – Новый пароль налогового инспектора (до 8 цифр);
MyError DP25::Fiscalization(std::string SerialNumber,std::string REGnumber,std::string TAXnumber,std::string InspPssword)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start Fiscalization();");

	std::string msg;

	msg+= SerialNumber; msg+='\t';
	msg+= REGnumber; msg+='\t'; //РНМ (на чеке 8 чифр)
	msg+= TAXnumber; msg+='\t'; //БИН
	msg+= InspPssword; msg+='\t';

	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFiscalization,(unsigned char*)msg.c_str(), (int)msg.size(),answer);

	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "Fiscalization(SerialNumber="<< SerialNumber <<",REGnumber="<< REGnumber <<",TAXnumber="<< TAXnumber <<",InspPssword="<<InspPssword<<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Программирование ставок НДС
// TaxX – Значение ставки НДС X; 0.00...99.99 - разрешена; 	100.00 – без налога; 100.01 - запрещена;
// RemainingChanges – Количество изменений ставок НДС (1...30);
MyError DP25::SetTaxRates(double TaxA,double TaxB,double TaxC,int& RemainingChanges)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start SetTaxRates();");

	RemainingChanges = 0;

	std::string msg;
	msg+=Utility::FloatToStdStr(TaxA,2,'.'); msg+="\t";
	msg+=Utility::FloatToStdStr(TaxB,2,'.'); msg+="\t";
	msg+=Utility::FloatToStdStr(TaxC,2,'.'); msg+="\t";
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcSetTaxRates,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			RemainingChanges = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetTaxRates(TaxA="<< TaxA <<",TaxB="<< TaxB <<",TaxC="<< TaxC <<",RemainingChanges="<< RemainingChanges <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
//Печать штрих-кода
//'1' - EAN8 barcode. {Data} must contain only 8 digits;
//'2' - EAN13 barcode. {Data} must contain only 13 digits;
//'3' - Code128 barcode. {Data} must contain symbols with ASCII codes between 32 and 127. {Data} length is between 3 and 31 symbols; Data - Data of the barcode;
MyError DP25::PrintBarCode(char Type,std::string Data,int QRcodeSize)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintBarCode();");

	std::string msg;
	msg+=Type; msg+="\t";
	msg+=Data; msg+="\t";
	if(QRcodeSize>0)
	{
		msg+=Utility::IntToStdStr(QRcodeSize); msg+="\t";
	}
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintBarCode,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0"){}
		else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintBarCode(Type="<<Type<<",Data="<<Data<<",QRcodeSize="<< QRcodeSize <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Дата последней фискальной записи
MyError DP25::DateOfLastEntryByFiscalMemory(std::string& DateTime)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start DateOfLastEntryByFiscalMemory();");

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcDateOfLastEntryByFiscalMemory,NULL,0,answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			DateTime = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DateOfLastEntryByFiscalMemory("<< DateTime <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Получение информации по группам товаров
//ItemGroup - Номер группы товаров
// TotSales – Количество продаж по данной группе товаров за день;
// TotSum – Накопленная сумма по данной группе товаров за день;
// Name – Наименование группы товаров;
MyError DP25::GetTradingGroupInfo(int ItemGroup,int& TotSales,double& TotSum,std::string& Name)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetTradingGroupInfo();");

	std::string msg;
	msg+=Utility::IntToStdStr(ItemGroup); msg+="\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetTradingGroupInfo,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			TotSales = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			TotSum = Utility::StdStrToDouble(num, 0);
			Name = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetTradingGroupInfo(ItemGroup="<<ItemGroup<<",TotSales="<< TotSales <<",TotSum="<< TotSum <<",Name="<< Name <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Получение информации по отделу в текущем чеке
// Department – Номер отдела (1...16);
// TaxGr, – группа НДС (буква 'A' или 'Б' или 'В' );
// Price – Максимальная цена для продаж и возвратов в отделе (0.00...9999999.99). Если Price = 0.00, то цена не ограничена;
// RecSales – Количество продаж в данном отделе в текущем фискальном чеке (1...99999999);
// RecQuanSales – Количество проданного товара в данном отделе в текущем фискальном чеке (0.001...99999.999);
// RecSumSales – Сумма продаж в данном отделе в текущем фискальном чеке (0.00...9999999.99);
// RecReturns - Количество возвратов в данном отделе в текущем фискальном чеке (1...99999999);
// RecQuanReturns - Количество возвращенного товара в данном отделе в текущем фискальном чеке;
// RecSumReturns - Сумма возвратов в данном отделе в текущем фискальном чеке (0.00...9999999.99);
// TotSales - Количество продаж в данном департаменте в текущем Z-отчете (1...99999999);
// TotQuanSales - Количество проданного товара в данном отделе в текущем Z-отчете (0.001...99999.999);
// TotSumSales - Сумма продаж в данном отделе в текущем Z-отчете (0.00...9999999.99);
// TotReturns - Количество возвратов в данном отделе в текущем Z-отчете (1...99999999);
// TotQuanReturns - Количество возвращенного товара в данном отделе в текущем Z-отчете (0.001...99999.999);
// TotSumReturns - Сумма возвратов в данном отделе в текущем Z-отчете (0.00...9999999.99);
// Name – Наименование отдела (до 32 символов);
MyError DP25::GetDepInfoInCheck(int Department,char& TaxGr,double& Price,int& RecSales,double& RecQuanSales,double& RecSumSales,int& RecReturns, double& RecQuanReturns,double& RecSumReturns,int& TotSales,double& TotQuanSales,double& TotSumSales,int& TotReturns,double& TotQuanReturns,double& TotSumReturns,std::string& Name)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetDepInfoInCheck();");

	std::string msg;
	msg+=Utility::IntToStdStr(Department); msg+="\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetDepInfoInCheck,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecSales = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecQuanSales = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecSumSales = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecReturns = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecQuanReturns = Utility::StdStrToDouble(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecSumReturns = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotSales = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotQuanSales = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotSumSales = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotReturns = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotQuanReturns = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			TotSumReturns = Utility::StdStrToDouble(num,0);
			Name = Utility::CutBeforeFirst(answer,'\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetDepInfoInCheck(Department="<<Department<<",TaxGr="<<TaxGr<<",Price="<<Price<<",RecSales="<< RecSales <<",RecQuanSales="<< RecQuanSales <<",RecSumSales="<< RecSumSales <<",RecReturns="<< RecReturns<<",RecQuanReturns=" << RecQuanReturns << ",RecSumReturns=" << RecSumReturns << ",TotSales=" << TotSales << ",TotQuanSales=" << TotQuanSales << ",TotSumSales=" << TotSumSales << ",TotReturns=" << TotReturns << ",TotQuanReturns=" << TotQuanReturns << ",TotSumReturns=" << TotSumReturns << ",Name=" << Name << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::TestOfFiscalMemory(bool Mode,int& Records)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start TestOfFiscalMemory();");

	std::string msg;
	if(Mode)
		msg += "1\t";
	else
		msg += "0\t";

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcTestOfFiscalMemory, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			Records = Utility::StdStrToInt(num, 0);
		}else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "TestOfFiscalMemory(Mode="<< Mode <<",Records="<< Records <<");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::SetManufacturersSerialNumber(std::string Serial,std::string& Country)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start SetManufacturersSerialNumber();");

	std::string msg;
	msg+=Serial; msg+="\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcSetManufacturersSerialNumber,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			Country = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetManufacturersSerialNumber(Serial="<< Serial <<",Country="<< Country <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Печать разделительной линии
MyError DP25::PrintDivideLine(char Type)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintDivideLine();");

	std::string msg;
	msg+=Type; msg+="\t";	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintDivideLine,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintDivideLine(Type="<<Type<<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Полный фискальный отчет за период заданный датами
// Type – Тип отчета; '0' - Сокращенный; '1' - Полный;
// Start – Начальная дата (формат "DD-MM-YY"). По умолчанию: Дата фискализации;
// End – Конечная дата (формат "DD-MM-YY"). По умолчанию: Текущая дата;
MyError DP25::FiscalReportByDate(char Type,std::string Start,std::string End,std::string InspPssword)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start FiscalReportByDate();");
	Utility::Trim(InspPssword);

	std::string msg;
	msg+=Type; msg+="\t";
	msg+=Start; msg+="\t";
	msg+=End; msg+="\t";
	msg+=InspPssword; msg+="\t";
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFiscalReportByDate,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "FiscalReportByDate(Type="<< Type <<",Start="<< Start <<",End="<< End <<",InspPssword="<< InspPssword  <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
///Фискальный отчет по номерам Z-отчетов
MyError DP25::FiscalReportByNumber(char Type,int Start,int End,std::string InspPssword)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start FiscalReportByNumber();");

	std::string msg;
	msg+=Type; msg+="\t";
	msg+=Utility::IntToStdStr(Start); msg+="\t";
	msg+=Utility::IntToStdStr(End); msg+="\t";
	msg+=InspPssword; msg+="\t";

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcFiscalReportByNumber,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "FiscalReportByNumber(Type="<< Type <<",Start="<< Start <<",End="<< End <<",InspPssword="<< InspPssword <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::SetSoftwarePassword(std::string Pwd)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start SetOperatorPassword();");

	std::string msg;
	msg += Pwd; msg += "\t";

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcSetOperatorPassword, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetOperatorPassword(Pwd="<< Pwd <<");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
// Установка пароля оператора
// OpCode – Номер оператора (1...30);
// NewPwd – Пароль оператора (Строка цифр в кодировке Ascii, длиной 1...8);
// OldPwd – Старый пароль оператора или пароль администратора (операторы 29 и 30). Может быть пустым если установлена сервисная перемычка;
MyError DP25::SetOperatorPassword(std::string OpCode,std::string OldPwd,std::string NewPwd)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start SetOperatorPassword();");

	std::string msg;
	msg+=OpCode; msg+="\t";
	msg+=OldPwd; msg+="\t";
	msg+=NewPwd; msg+="\t";
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcSetOperatorPassword,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetOperatorPassword(OpCode="<< OpCode <<",OldPwd="<< OldPwd <<",NewPwd="<< NewPwd <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
// Информация о текущем чеке
MyError DP25::InfoByCurrentInv(int& Type,double& SumVATA,double& SumVATB,double& SumVATC)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start InfoByCurrentInv();");

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcInfoByCurrentInv,NULL,0,answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			Type = Utility::StdStrToInt(num, 0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumVATA = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumVATB = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SumVATC = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "InfoByCurrentInv(SumVATA="<< SumVATA <<",SumVATB="<< SumVATB <<",SumVATC="<< SumVATC <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Отчет по операторам
// FirstOper – Первый оператор в отчете (1...30). По умолчанию: 1;
// LastOper – Последний оператор в отчете (1...30). По умолчанию: 30;
// Clear – Тип отчета. По умолчанию: 0; '0' – Отчет по операторам без гашения; '1' – Отчет по операторам с гашением;
MyError DP25::OperatorReport(int FirstOper,int LastOper,char Clear)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start OperatorReport();");

	std::string msg;
	msg+=Utility::IntToStdStr(FirstOper); msg+='\t';
	msg+=Utility::IntToStdStr(LastOper); msg+='\t';
	msg+=Clear; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcOperatorReport,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "OperatorReport(FirstOper="<< FirstOper <<",LastOper="<< LastOper <<",Clear="<< Clear <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Открытие денежного ящика
MyError DP25::OpenCashDrawer(int MSec)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start OpenCashDrawer();");

	MyError result;
	if(PrinterName=="FPG-350")
	{
		result.ErrorCode=0;
		if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","OpenCashDrawer() ErrorCode: 0 ErrorDescription: Для этого принтера нет ящика");
	}else
	{
		std::string msg;
		if(MSec>0) msg+=Utility::IntToStdStr(MSec);
		msg+='\t';
		

		std::string answer;
		
		result.ErrorCode =SendPMessage(fcOpenCashDrawer,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
		if(result.ErrorCode==0)
		{
			std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
			if (ErrorCode == "0")
			{
			}
			else
			{
				result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
			}
		}

		m_LastErrorCode=result.ErrorCode;
		m_LastErrorDescription=result.ErrorMessage;
		if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
		{
			std::string rErrorMessage;
			int rECode;
			ReadingError(result.ErrorCode, rECode, rErrorMessage);
			m_LastErrorDescription = rErrorMessage;
			result.ErrorMessage = rErrorMessage;
			m_LastErrorCode = result.ErrorCode;
		}

		if(m_SaveLog)
		{
			std::stringstream ss;
			ss << "OpenCashDrawer(MSec="<< MSec <<");";
			if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
			Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
		}
	}
	return result;
}
//---------------------------------------------------------------------------
//Дневной отчет по типам оплаты
// Type – Тип информации. По умолчанию: 0; '0' – Способы оплаты в чеках продажи; '1' – Способы оплаты в чеках возврата;
// PayX - Сумма (0.00...9999999.99) оплаченная/возвращенная способом оплаты X; '0' - наличные; '1' - карта; '2' - кредит; '3' - тара;
MyError DP25::DailyReportByTypesOfPayment(char Type,double& Pay0,double& Pay1,double& Pay2,double& Pay3)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start DailyReportByTypesOfPayment();");

	std::string msg;
	msg+=Type; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcDailyReportByTypesOfPayment,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			Pay0 = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Pay1 = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Pay2 = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Pay3 = Utility::StdStrToDouble(num, 0);
		}else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "DailyReportByTypesOfPayment(Type="<<Type<<",Pay0="<< Pay0 <<",Pay1="<< Pay1 <<",Pay2="<< Pay2 <<",Pay3="<< Pay3 <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Отчет по артикулам
// Type – Тип отчета; '0' – по оборотам PLU без гашения; '1' – по оборотам PLU с гашением; '2' – по параметрам PLU; '3' – по остаткам PLU;
// FirstPLU - Первый PLU в отчете (1...100000). По умолчанию: 1;
// LastPLU - Последний PLU в отчете (1...100000). По умолчанию: 100000;
MyError DP25::ReportByArticle(char Type,int FirstPLU,int LastPLU)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByArticle();");

	std::string msg;
	msg+=Type; msg+='\t';
	msg+=Utility::IntToStdStr(FirstPLU); msg+='\t';
	msg+=Utility::IntToStdStr(LastPLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByArticle(Type="<< Type <<",FirstPLU="<< FirstPLU <<",LastPLU="<< LastPLU <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
//Программирование и считывание параметров товаров
// 'I' – Информация о товаре;
// Total - Общее количество программируемых товаров (3000);
// Prog - Общее количество запрограммированных товаров (0...3000);
// NameLen – Максимальная длина наименования товара (32);
MyError DP25::PrgAndReadArticleI(int& Total,int& Prog,int& NameLen)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleI();");

	std::string msg;
	msg+='I'; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			Total = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Prog = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NameLen = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleI(Total="<<Total<<",Prog="<< Prog <<",NameLen="<< NameLen <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///Программирование и считывание параметров товаров
// Обязательные параметры:
// PLU – Код товара (1...100000);
// TaxGr – Группа НДС (буквы 'A' или 'Б' или 'В');
// Dep - Отдел (1...16);
// Group – Группа товаров (1...99);
// PriceType – Тип цены ('0' – фиксированная цена, '1' – свободная цена, '2' – максимальная цена; более подробное описание смотрите в инструкции оператора);
// Price - Цена (0.00...9999999.99);
// Quantity - Количество (0.001...99999.999);
// Name – Наименование товара (до 32 символов);
//Опциональные параметры:
// AddQty – Байт со значением 'A',
// BarX – Штрих-код X (до 13 цифр);
MyError DP25::PrgAndReadArticleP(int PLU,char TaxGr,int Dep,int Group,char PriceType,double Price,char AddQty,double Quantity,std::string Bar1,std::string Bar2,std::string Bar3,std::string Bar4,std::string Name,int UnitCode,int MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleP();");

	//{Option}<SEP>{PLU}<SEP>{TaxGr}<SEP>{Dep}<SEP>{Group}<SEP>{PriceType}<SEP>{Price}<SEP>{AddQty}<SEP>{Quantity}<SEP>{Bar1}<SEP>{Bar2}<SEP>{Bar3}<SEP>{Bar4}<SEP>{Name}<SEP>
	std::string msg;
	msg+='P'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	msg+=TaxGr; msg+='\t';
	msg+=Utility::IntToStdStr(Dep); msg+='\t';
	msg+=Utility::IntToStdStr(Group); msg+='\t';
	msg+=PriceType; msg+='\t';
	msg+=Utility::FloatToStdStr(Price,2,'.'); msg+='\t';
	msg+=AddQty; msg+='\t';
	msg+=Utility::FloatToStdStr(Quantity,3,'.'); msg+='\t';
	msg+= Utility::trim(Bar1); msg+='\t';
	msg+= Utility::trim(Bar2); msg+='\t';
	msg+= Utility::trim(Bar3); msg+='\t';
	msg+= Utility::trim(Bar4); msg+='\t';
	msg.append(Name,0,128); msg+='\t';
	msg += Utility::IntToStdStr(UnitCode); msg += '\t';
	msg += Utility::IntToStdStr(MarkType); msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleP(PLU="<< PLU <<",char TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",AddQty=" << AddQty << ",Quantity=" << Quantity << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType=" << MarkType << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Изменение доступного количества товара
// PLU – Код товара (1...3000);
// Quantity - Количество (0.001...99999.999);
//Error DP25::PrgAndReadArticleP(int PLU,char TaxGr,int Dep,int Group,char PriceType,double Price,char AddQty,double Quantity,std::string Bar1,std::string Bar2,std::string Bar3,std::string Bar4,std::string Name)
MyError DP25::PrgAndReadArticleA(int PLU,double Quantity) ///<Программирование и считывание параметров товаров
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleA();");

	//{Option}<SEP>{PLU}<SEP>{Quantity}<SEP>
	std::string msg;
	msg+='A'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	msg+=Utility::FloatToStdStr(Quantity,3,'.'); msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleA(PLU="<<PLU<<",Quantity="<< Quantity <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Удаление товара;
// firstPLU – Код первого товара из диапазона удаляемых товаров (1...3000). Если значение этого параметра 'A', то все товары будут удалены (lastPLU может быть пустым);
// lastPLU - Код последнего товара из диапазона удаляемых товаров (1...3000). По умолчанию: {firstPLU} ;
MyError DP25::PrgAndReadArticleD(int FirstPLU,int LastPLU) ///<Программирование и считывание параметров товаров
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleD();");

	//{Option}<SEP>{firstPLU}<SEP>{lastPLU}<SEP>
	std::string msg;
	msg+='D'; msg+='\t';
	msg+=Utility::IntToStdStr(FirstPLU); msg+='\t';
	if(FirstPLU!=LastPLU)
	{	msg+=Utility::IntToStdStr(LastPLU);
		msg+='\t';
	}
	
	//107,D[\t]1[\t]2[\t]
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleD(FirstPLU="<< FirstPLU <<",LastPLU="<< LastPLU <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Считывание данных товара
// PLU – Код товара (1...100000);
// TaxGr – Группа НДС (буква 'A' или 'Б' или 'В' );
// Dep - Отдел (1...16);
// Group – Группа товаров (1...99);
// PriceType – Тип цены ( '0' – фиксированная цена, '1' – свободная цена, '2' – максимальная цена; более подробное описание смотрите в инструкции оператора);
// Price - Цена (0.00...9999999.99);
// Turnover – Накопленная сумма по товару (0.00...9999999.99);
// SoldQty – Количество проданного товара (0.001...99999.999);
// StockQty – Текущее количество (0.001...99999.999);
// BarX – Штрих-код X (до 13 цифр);
// Name – Наименование товара (до 32 символов);
MyError DP25::PrgAndReadArticleR(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name,int& UnitCode,int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleR();");

	std::string msg;
	msg+='R'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleR(PLU="<< PLU <<",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType=" << MarkType << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Возврат данных первого найденного запрограммированного товара
MyError DP25::PrgAndReadArticleF(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleF();");

	std::string msg;
	msg+='F'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleF(PLU=" << PLU << ",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType="<< MarkType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Возврат данных последнего найденного запрограммированного товара
MyError DP25::PrgAndReadArticleL(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleL();");

	std::string msg;
	msg+='L'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleL(PLU="<< PLU <<",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType=" << MarkType << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Возврат данных последнего найденного товара имеющего обороты продаж
MyError DP25::PrgAndReadArticleLL(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleLL();");

	std::string msg;
	msg+='l'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleLL(PLU=" << PLU << ",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType="<< MarkType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Возврат данных последнего найденного запрограммированного товара
MyError DP25::PrgAndReadArticleN(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleN();");

	std::string msg;
	msg+='N'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleN(PLU=" << PLU << ",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType="<< MarkType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
//Возврат данных следующего найденного товара имеющего обороты продаж
MyError DP25::PrgAndReadArticleNN(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleNN();");

	std::string msg;
	msg+='n'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleNN(PLU=" << PLU << ",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType="<< MarkType <<");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Возврат данных первого найденного товара имеющего обороты продаж
MyError DP25::PrgAndReadArticleFF(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleFF();");

	std::string msg;
	msg+='f'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			PLU =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			TaxGr = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Dep =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Group =  Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			PriceType = num[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Price = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Turnover = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			SoldQty = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			StockQty = Utility::StdStrToDouble(num,0);
			Bar1 = Utility::CutBeforeFirst(answer,'\t');
			Bar2 = Utility::CutBeforeFirst(answer,'\t');
			Bar3 = Utility::CutBeforeFirst(answer,'\t');
			Bar4 = Utility::CutBeforeFirst(answer,'\t');
			Name = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleFF(PLU=" << PLU << ",TaxGr=" << TaxGr << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType="<< MarkType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Поиск первого незапрограммированного товара
//PLU - Код товара (1...3000). По умолчанию: 0
MyError DP25::PrgAndReadArticleX(int PLU,int& FirstPLU)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleX();");

	std::string msg;
	msg+='X'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			FirstPLU = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription =result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleX(PLU=" << PLU << ",FirstPLU="<< FirstPLU <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Поиск последнего незапрограммированного товара
//PLU - Код товара (1...3000). По умолчанию: 3000
MyError DP25::PrgAndReadArticleXX(int PLU,int& LastPLU)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrgAndReadArticleXX();");

	std::string msg;
	msg+='x'; msg+='\t';
	msg+=Utility::IntToStdStr(PLU); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrgAndReadArticle,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			LastPLU =  Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrgAndReadArticleXX(PLU="<< PLU <<",LastPLU="<< LastPLU << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Отчет по операторам
// Operator – Номер оператора (1...30);
// Receipts – Количество чеков продажи;
// Total – Сумма в чеках продажи;
// nDiscount – Количество скидок в чеках продажи;
// Discount – Сумма скидок в чеках продажи;
// nSurcharge - Количество наценок в чеках продажи;
// Surcharge - Сумма наценок в чеках продажи;
// nVoid – Количество коррекций в чеках продаж;
// Void – Сумма коррекций в чеках продаж;
// nAllVoided – Количество аннулированных чеков продаж;
// AllVoided – Сумма аннулированных чеков продаж;
// nCancelled – Количество отмененных чеков продаж;
// Cancelled – Сумма отмененных чеков продаж;
// RetReceipts – Количество чеков возврата;
// RetTotal – Сумма чеков возврата;
// RetnDiscount - Количество скидок в чеках возврата;
// RetDiscount - Сумма скидок в чеках возврата;
// RetnSurcharge - Количество наценок в чеках возврата;
// RetSurcharge - Сумма наценок в чеках возврата;
// RetnVoid - Количество коррекций в чеках возврата;
// RetVoid - Сумма коррекций в чеках возврата;
// RetnAllVoided - Количество аннулированных чеков возврата;
// RetAllVoided - Сумма аннулированных чеков возврата;
// RetnCancelled - Количество отмененных чеков возврата;
// RetCancelled - Сумма отмененных чеков возврата;
// nCashIn – Количество внесений;
// CashIn – Сумма внесений;
// nCashOut – Количество выплат;
// CashOut – Сумма выплат;
MyError DP25::ReportByOperators(int Operator,int& Receipts,double& Total,int& nDiscount,double& Discount,int& nSurcharge,double& Surcharge,int& nVoid,double& Void,int& nAllVoided,double& AllVoided,int& nCancelled,double& Cancelled,int& RetReceipts,double& RetTotal,int& RetnDiscount,double& RetDiscount,int& RetnSurcharge,double& RetSurcharge,int& RetnVoid,double& RetVoid,int& RetnAllVoided,double& RetAllVoided,int& RetnCancelled,double& RetCancelled,int& nCashIn,double& CashIn,int& nCashOut,double& CashOut)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			Receipts = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Total = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nDiscount = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Discount = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nSurcharge = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Surcharge = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nVoid = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Void = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nAllVoided = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			AllVoided = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nCancelled = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Cancelled = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetReceipts = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetTotal = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetnDiscount = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetDiscount = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetnSurcharge = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetSurcharge = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetnVoid = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetVoid = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetnAllVoided = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetAllVoided = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetnCancelled = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RetCancelled = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nCashIn = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			CashIn = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			nCashOut = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			CashOut = Utility::StdStrToDouble(num,0);

		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators(Operator=" << Operator << ",Receipts=" << Receipts << ",Total=" << Total << ",nDiscount=" << nDiscount << ",Discount=" << Discount << ",nSurcharge=" << nSurcharge << ",Surcharge=" << Surcharge << ",nVoid=" << nVoid << ",Void=" << Void << ",nAllVoided=" << nAllVoided << ",AllVoided=" << AllVoided << ",nCancelled=" << nCancelled << ",Cancelled=" << Cancelled << ",RetReceipts=" << RetReceipts << ",RetTotal=" << RetTotal << ",RetnDiscount=" << RetnDiscount << ",RetDiscount=" << RetDiscount << ",RetnSurcharge=" << RetnSurcharge << ",RetSurcharge=" << RetSurcharge << ",RetnVoid=" << RetnVoid << ",RetVoid=" << RetVoid << ",RetnAllVoided=" << RetnAllVoided << ",RetAllVoided=" << RetAllVoided << ",RetnCancelled=" << RetnCancelled << ",RetCancelled=" << RetCancelled << ",nCashIn=" << nCashIn << ",CashIn=" << CashIn << ",nCashOut=" << nCashOut << ",CashOut="<< CashOut <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Payments in sales receipts
MyError DP25::ReportByOperators0(long Operator,double& Pay0,double& Pay1,double& Pay2,double& Pay3)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators0();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='0'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');		
			Pay0 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay1 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay2 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay3 = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators0(Operator="<< Operator << ",Pay0=" << Pay0 << ",Pay1=" << Pay1 << ",Pay2=" << Pay2 << ",Pay3=" << Pay3 << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Payments in refund receipts
MyError DP25::ReportByOperators1(long Operator,double& Pay0,double& Pay1,double& Pay2,double& Pay3)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators1();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='1'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');		
			Pay0 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay1 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay2 = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			Pay3 = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators1(Operator="<< Operator << ",Pay0=" << Pay0 << ",Pay1=" << Pay1 << ",Pay2=" << Pay2 << ",Pay3=" << Pay3 << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of sells
MyError DP25::ReportByOperators2(long Operator,long& Num,double& Sum)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators2();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='2'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			Num = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Sum = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators2(Operator="<< Operator << ",Num=" << Num << ",Sum=" << Sum << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of refund
MyError DP25::ReportByOperators3(long Operator,long& Num,double& Sum)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators3();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='3'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			Num = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			Sum = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators2(Operator="<< Operator << ",Num=" << Num << ",Sum=" << Sum << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of discounts and surcharges from sales
MyError DP25::ReportByOperators4(long Operator,long& qSur,double& sSur,long& qDis,double& sDis)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators4();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='4'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			qSur = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sSur = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qDis = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sDis = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators4(Operator="<< Operator << ",qSur=" << qSur << ",sSur=" << sSur << ",qDis=" << qDis << ",sDis=" << sDis << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of discounts and surcharges from refund
MyError DP25::ReportByOperators5(long Operator,long& qSur,double& sSur,long& qDis,double& sDis)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators5();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='5'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			qSur = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sSur = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qDis = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sDis = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators5(Operator="<< Operator << ",qSur=" << qSur << ",sSur=" << sSur << ",qDis=" << qDis << ",sDis=" << sDis << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of corrections and annulled receipts from sales
MyError DP25::ReportByOperators6(long Operator,long& qVoid,double& sVoid,long& qAnul,double& sAnul,long& qCancel,double& sCancel)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators6();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='6'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			qVoid = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sVoid = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qAnul = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sAnul = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qCancel = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sCancel = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators6(Operator="<< Operator << ",qVoid=" << qVoid << ",sVoid=" << sVoid << ",qAnul=" << qAnul << ",sAnul=" << sAnul << ",qCancel=" << qCancel << ",sCancel=" << sCancel << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of corrections and annulled receipts from refund
MyError DP25::ReportByOperators7(long Operator,long& qVoid,double& sVoid,long& qAnul,double& sAnul,long& qCancel,double& sCancel)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators7();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='7'; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			qVoid = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sVoid = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qAnul = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sAnul = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qCancel = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sCancel = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators7(Operator="<< Operator << ",qVoid=" << qVoid << ",sVoid=" << sVoid << ",qAnul=" << qAnul << ",sAnul=" << sAnul << ",qCancel=" << qCancel << ",sCancel=" << sCancel << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///<Number and sum of cash in and cash out operations
MyError DP25::ReportByOperators8(long Operator,long& qCashIn,double& sCashIn,long& qCashOut,double& sCashOut)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReportByOperators8();");

	std::string msg;
	msg+=Utility::IntToStdStr(Operator); msg+='\t';
	msg+='8'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			qCashIn = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sCashIn = Utility::StdStrToDouble(num,0);
			num = Utility::CutBeforeFirst(answer,'\t');
			qCashOut = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			sCashOut = Utility::StdStrToDouble(num,0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}
	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReportByOperators8(Operator="<< Operator << ",qCashIn=" << qCashIn << ",sCashIn=" << sCashIn << ",qCashOut=" << qCashOut << ",sCashOut=" << sCashOut << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/*MyError DP25::GetPLUTurnoversByZReport(char Option, int Parameters, int& PLU, std::string& Name, double& SoldQty, double& Turnover)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start GetPLUTurnoversByZReport();");

	std::string msg;
	msg += Option; msg += '\t';
	msg += Utility::IntToStdStr(Parameters); msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcGetPLUTurnoversByZReport, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			PLU = Utility::StdStrToInt(num);
			Name = Utility::CutBeforeFirst(answer, '\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			SoldQty = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Turnover = Utility::StdStrToDouble(num, 0);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetPLUTurnoversByZReport(PLU=" << PLU << ",Name=" << Name << ",SoldQty=" << SoldQty << ",Turnover=" << Turnover << ");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}*/
//---------------------------------------------------------------------------
MyError DP25::GetSales(int Znumber)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start GetSales();");

	std::string msg;
	msg += 'O'; msg += '\t';
	msg += Utility::IntToStdStr(Znumber); msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcGetPLUTurnoversByZReport, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetSales(Znumber="<< Znumber <<");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::GetSalesPLU(int PLU, char& TaxCode, int& Dep, int& Group, char& PriceType, double& Price, double& Turnover, double& SoldQty, double& StockQty, std::string& Bar1, std::string& Bar2, std::string& Bar3, std::string& Bar4, std::string& Name, int& UnitCode, int& MarkType)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start GetPLUTurnoversByZReport();");

	std::string msg;
	msg += 'F'; msg += '\t';
	msg += Utility::IntToStdStr(PLU); msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcGetPLUTurnoversByZReport, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			PLU = Utility::StdStrToInt(num);
			TaxCode = Utility::CutBeforeFirst(answer, '\t')[0];
			num = Utility::CutBeforeFirst(answer, '\t');
			Dep = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			Group = Utility::StdStrToInt(num);
			PriceType = Utility::CutBeforeFirst(answer, '\t')[0];
			num = Utility::CutBeforeFirst(answer, '\t');
			Price = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Turnover = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			SoldQty = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			StockQty = Utility::StdStrToDouble(num, 0);
			Bar1 = Utility::CutBeforeFirst(answer, '\t');
			Bar2 = Utility::CutBeforeFirst(answer, '\t');
			Bar3 = Utility::CutBeforeFirst(answer, '\t');
			Bar4 = Utility::CutBeforeFirst(answer, '\t');
			Name = Utility::CutBeforeFirst(answer, '\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetSalesPLU(PLU=" << PLU << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType=" << MarkType << ");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::GetSalesNextPLU(int& PLU, char& TaxCode, int& Dep, int& Group, char& PriceType, double& Price, double& Turnover, double& SoldQty, double& StockQty, std::string& Bar1, std::string& Bar2, std::string& Bar3, std::string& Bar4, std::string& Name, int& UnitCode, int& MarkType)
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start GetPLUTurnoversByZReport();");

	std::string msg;
	msg += 'N'; msg += '\t';


	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fcGetPLUTurnoversByZReport, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			PLU = Utility::StdStrToInt(num);
			TaxCode = Utility::CutBeforeFirst(answer, '\t')[0];
			num = Utility::CutBeforeFirst(answer, '\t');
			Dep = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			Group = Utility::StdStrToInt(num);
			PriceType = Utility::CutBeforeFirst(answer, '\t')[0];
			num = Utility::CutBeforeFirst(answer, '\t');
			Price = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			Turnover = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			SoldQty = Utility::StdStrToDouble(num, 0);
			num = Utility::CutBeforeFirst(answer, '\t');
			StockQty = Utility::StdStrToDouble(num, 0);
			Bar1 = Utility::CutBeforeFirst(answer, '\t');
			Bar2 = Utility::CutBeforeFirst(answer, '\t');
			Bar3 = Utility::CutBeforeFirst(answer, '\t');
			Bar4 = Utility::CutBeforeFirst(answer, '\t');
			Name = Utility::CutBeforeFirst(answer, '\t');
			num = Utility::CutBeforeFirst(answer, '\t');
			UnitCode = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer, '\t');
			MarkType = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetSalesPLU(PLU=" << PLU << ",Dep=" << Dep << ",Group=" << Group << ",PriceType=" << PriceType << ",Price=" << Price << ",Turnover=" << Turnover << ",SoldQty=" << SoldQty << ",StockQty=" << StockQty << ",Bar1=" << Bar1 << ",Bar2=" << Bar2 << ",Bar3=" << Bar3 << ",Bar4=" << Bar4 << ",Name=" << Name << ",UnitCode=" << UnitCode << ",MarkType=" << MarkType << ");";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Считывание ФП
// Address – Начальный адрес;
// nBytes – Количество байт;
// Data – Считанные данные. Количество байт равно запрошенному в nBytes;
MyError DP25::ReadFiscalMemoryBlock(int Address,int nBytes,std::string& Data)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReadFiscalMemoryBlock();");

	std::string msg;
	msg+='0'; msg+='\t';
	msg+=Utility::IntToStdStr(Address); msg+='\t';
	msg += Utility::IntToStdStr(nBytes); msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReportByOperators,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			Data = Utility::CutBeforeFirst(answer,'\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReadFiscalMemoryBlock(Address="<< Address <<",nBytes=" << nBytes << ",Data=" << Data << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
/// Информация об устройстве
// SerialNumber – Заводской номер (Две цифры (01) и десять цифр (xxxxxxxxxx=уникальный заводской номер: 01xxxxxxxxxx) );
// Header line 1 - Предположительно, содержит наименование компании (до 42 символов);
// Header line 2 - Предположительно, содержит адрес компании (до 42 символов);
// TAXnumber1 - РНМ (до 12 цифр);
// TAXnumber2 - БИН (до 12 цифр);
MyError DP25::ReadDeviceInfo1(std::string& SerialNumber,std::string& REGnumber, std::string&  TAXnumber, std::string& HeaderLine1, std::string& HeaderLine2,std::string& HeaderLine3,std::string& HeaderLine4)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReadDeviceInfo1();");

	std::string msg;
	msg+='1'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReadDeviceInfo,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			SerialNumber = Utility::CutBeforeFirst(answer,'\t');
			REGnumber = Utility::CutBeforeFirst(answer, '\t');
			TAXnumber = Utility::CutBeforeFirst(answer, '\t');
			HeaderLine1 = Utility::CutBeforeFirst(answer,'\t');
			HeaderLine2 = Utility::CutBeforeFirst(answer,'\t');
			HeaderLine3 = Utility::CutBeforeFirst(answer, '\t');
			HeaderLine4 = Utility::CutBeforeFirst(answer, '\t');
		}else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReadDeviceInfo1(SerialNumber=" << SerialNumber << ",REGnumber=" << REGnumber << ", TAXnumber = " << TAXnumber << ",HeaderLine1=" << HeaderLine1 << ",HeaderLine2=" << HeaderLine2 << ",HeaderLine3=" << HeaderLine3 << ",HeaderLine4=" << HeaderLine4 << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Информация об устройстве
MyError DP25::ReadDeviceInfo2(std::string& APN,std::string& APNUserName,std::string& APNPassword,std::string& ServerAddress,std::string& ServerPort,std::string&  ServerVersion)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReadDeviceInfo2();");

	std::string msg;
	msg+='2'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReadDeviceInfo,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			APN = Utility::CutBeforeFirst(answer,'\t');
			APNUserName = Utility::CutBeforeFirst(answer,'\t');
			APNPassword = Utility::CutBeforeFirst(answer,'\t');
			ServerAddress = Utility::CutBeforeFirst(answer,'\t');
			ServerPort = Utility::CutBeforeFirst(answer,'\t');
			ServerVersion = Utility::CutBeforeFirst(answer, '\t');
		}else{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReadDeviceInfo2(APN=" << APN << ",APNUserName=" << APNUserName << ",APNPassword=" << APNPassword << ",ServerAddress=" << ServerAddress << ",ServerPort=" << ServerPort << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
/// Информация об устройстве
// RecSales – Номер последнего чека продажи (1...99999999);
// DateSales – Дата и время последнего чека продажи (формат "DD-MM-YYYY hh:mm:ss");
// RecReturns – Номер последнего чека возврата (1...99999999);
// DateReturns - Дата и время последнего чека возврата (формат "DD-MM-YYYY hh:mm:ss");
// Znumber – Номер последнего Z-отчета (1..3800);
// Zdate – Дата и время последнего Z-отчета (формат "DD-MM-YYYY hh:mm:ss");
MyError DP25::ReadDeviceInfo3(int& RecSales,std::string& DateSales,int& RecReturns,std::string& DateReturns,int& Znumber,std::string& Zdate)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start ReadDeviceInfo3();");

	std::string msg;
	msg+='3'; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcReadDeviceInfo,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer,'\t');
			RecSales = Utility::StdStrToInt(num);
			DateSales = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer,'\t');
			RecReturns = Utility::StdStrToInt(num);
			DateReturns = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer,'\t');
			Znumber = Utility::StdStrToInt(num);
			Zdate = Utility::CutBeforeFirst(answer,'\t');
		}else{result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "ReadDeviceInfo3(RecSales=" << RecSales << ",DateSales=" << DateSales << ",RecReturns=" << RecReturns << ",DateReturns=" << DateReturns << ",Znumber=" << Znumber << ",Zdate="<< Zdate <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Поиск документа в ЭЖ по дате
// StartDate – Начальная дата для поиска (формат "DD-MM-YY"). По умолчанию: Дата первого документа;
// EndDate – Конечная дата для поиска (формат "DD-MM-YY"). По умолчанию: Дата последнего документа;
// DocType – Тип документа; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
// DateFirst – Дата первого документа типа Type в периоде (формат "DD-MM-YY hh:mm:ss");
// DateLast - Дата последнего документа типа Type в периоде (формат "DD-MM-YY hh:mm:ss");
// NumFirst - Номер первого документа типа Type в периоде (1...99999999);
// NumLast - Номер последнего документа типа Type в периоде (1...99999999);
MyError DP25::GetDocInEJByDate(std::string StartDate,std::string EndDate,char DocType,std::string& DateFirst,std::string& DateLast,int& NumFirst,int& NumLast)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetDocInEJByDate();");

	std::string msg;
	msg+=StartDate; msg+='\t';
	msg+=EndDate; msg+='\t';
	msg+=DocType; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetDocInEJByDate,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			DateFirst = Utility::CutBeforeFirst(answer,'\t');
			DateLast = Utility::CutBeforeFirst(answer,'\t');
			num = Utility::CutBeforeFirst(answer,'\t');
			NumFirst = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			NumLast = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetDocInEJByDate(StartDate=" << StartDate << ",EndDate=" << EndDate << ",DocType=" << DocType << ",DateFirst=" << DateFirst << ",DateLast=" << DateLast << ",NumFirst=" << NumFirst << ",NumLast=" << NumLast << ");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Информация из ЭЖ. Установка документа для чтения
// DocNum – Номер документа (1...99999999). Необходимо установить Option = 0;
// DocType – Тип документа. Необходимо установить Option = 0; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
// DocNumber – Номер документа - общий (1...99999999);
// RecNumber – Номер документа - по Type (1...99999999);
// Date – Дата документа (формат "DD-MM-YY hh:mm:ss");
// DocType – Тип документа; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
//Znumber - Номер Z-отчета (1..3800);
MyError DP25::GetInfoFromEJ0(int DocNum,char DocType,int& GlobalNum,int& DocNumber,int& RecNumber,std::string& Date,char& DocTypeRez,int& Znumber)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetInfoFromEJ0();");

	std::string msg;
	msg+='0'; msg+='\t';
	msg+=Utility::IntToStdStr(DocNum); msg+='\t';
	msg+=DocType; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetInfoFromEJ,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			std::string num;
			num = Utility::CutBeforeFirst(answer, '\t');
			GlobalNum = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			DocNumber = Utility::StdStrToInt(num);
			num = Utility::CutBeforeFirst(answer,'\t');
			RecNumber = Utility::StdStrToInt(num);
			Date = Utility::CutBeforeFirst(answer,'\t');
			DocTypeRez = Utility::CutBeforeFirst(answer,'\t')[0];
			num = Utility::CutBeforeFirst(answer,'\t');
			Znumber = Utility::StdStrToInt(num);
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetInfoFromEJ0(DocNum="<< DocNum <<",DocType="<< DocType <<",DocNumber="<< DocNumber <<",RecNumber="<< RecNumber <<",Date="<< Date <<",DocTypeRez=" << DocTypeRez << ",Znumber="<< Znumber <<");";

		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
// Информация из ЭЖ. Чтение одной строки текста. Для считывания всего документа необходимо выполнить команду несколько раз
// DocNum – Номер документа (1...99999999). Необходимо установить Option = 0;
// DocType – Тип документа. Необходимо установить Option = 0; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
//TextData – Текст документа;
MyError DP25::GetInfoFromEJ1(std::string& TextData)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetInfoFromEJ1();");

	std::string msg;
	msg+='1'; msg+='\t';
	//msg+=Utility::IntToStdStr(DocNum); msg+='\t';
	//msg+=DocType; msg+='\t';
	
	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetInfoFromEJ,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			TextData = Utility::CutBeforeFirst(answer,'\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetInfoFromEJ1(TextData="<< TextData <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Информация из ЭЖ. Чтение данных. Для считывания всего документа необходимо выполнить команду несколько раз
// DocNum – Номер документа (1...99999999). Необходимо установить Option = 0;
// DocType – Тип документа. Необходимо установить Option = 0; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
//Data – Данные документа
MyError DP25::GetInfoFromEJ2(std::string& Data)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetInfoFromEJ2();");

	std::string msg;
	msg+='2'; msg+='\t';
	//msg+=Utility::IntToStdStr(DocNum); msg+='\t';
	//msg+=DocType; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetInfoFromEJ,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			Data = Utility::CutBeforeFirst(answer,'\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetInfoFromEJ2(Data="<< Data <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
/// Информация из ЭЖ. Печать документа
// DocNum – Номер документа (1...99999999). Необходимо установить Option = 0;
// DocType – Тип документа. Необходимо установить Option = 0; '0' – все документы; '1' – чек продажи; '2' – чек возврата; '3' - Z-отчет;
MyError DP25::GetInfoFromEJ3(int DocNum,char DocType)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start GetInfoFromEJ3();");

	std::string msg;
	msg+='3'; msg+='\t';
	msg+=Utility::IntToStdStr(DocNum); msg+='\t';
	msg+=DocType; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcGetInfoFromEJ,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "GetInfoFromEJ3(DocNum="<< DocNum <<",DocType="<< DocType <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
// Установка сервисных параметров
//Type – Тип устанавливаемого параметра; '0' – Пароль режима Сервис (Пароль сервисного специалиста);
// Value – Значение вводимого параметра; Пароль режима Сервис (Пароль сервисного специалиста). Текст до 8 символов. Пароль по умолчанию пустой (0 символов) или "70";
MyError DP25::SetServiceParam(std::string Type,std::string Value, std::string& IsUnblocked)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start SetServiceParam();");

	std::string msg;
	msg+=Type; msg+='\t';
	msg+=Value; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fnSetServiceParam,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			IsUnblocked = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "SetServiceParam(Type="<< Type <<", Value="<< Value <<", IsUnblocked="<< IsUnblocked <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
///< Программирование
MyError DP25::Programming(std::string Name,std::string Index,std::string& Value)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start Programming();");

	if(PrinterName=="DPG-150" || PrinterName=="DPG-35" || PrinterName=="DPG-25" || PrinterName=="DP-25")
	{
		if(Value=="1200") Value="0"; else
		if(Value=="2400") Value="1"; else
		if(Value=="4800") Value="2"; else
		if(Value=="9600") Value="3"; else
		if(Value=="14400") Value="4"; else
		if(Value=="19200") Value="5"; else
		if(Value=="38400") Value="6"; else
		if(Value=="56000") Value="7"; else
		if(Value=="57600") Value="8"; else
		if(Value=="115200") Value="9";
	}

	//Trim(Value); не ставить а то пустые строки в заголовке по получится поставить //Константин сказал что пароль с пробелами поэтому добавил сюда
	bool re = Value.length() == 0;

	//Для заголовка и подвала чека
	/*std::wstring fromKAZASCII(const std::string str);
	std::string toKAZASCII(const std::wstring str);
	Header*/

	std::string msg;
	msg+=Name; msg+='\t';
	if(Index.size()>0)
		msg+=Index;
	msg+='\t';
	msg+=Value; msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fnProgramming,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			if(Value.size()==0) Value = Utility::CutBeforeFirst(answer,'\t');
			if(Name=="FpComBaudRate")
			{
				if(Value=="1200") Value="0"; else
				if(Value=="2400") Value="1"; else
				if(Value=="4800") Value="2"; else
				if(Value=="9600") Value="3"; else
				if(Value=="14400") Value="4"; else
				if(Value=="19200") Value="5"; else
				if(Value=="38400") Value="6"; else
				if(Value=="56000") Value="7"; else
				if(Value=="57600") Value="8"; else
				if(Value=="115200") Value="9";
			}
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "Programming(Name="+Name+",Index="+Index+"," + (re ? "read" : "write") + " Value="+Value+");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}


	return result;
}
//---------------------------------------------------------------------------
MyError DP25::UploadImage(std::string Data,std::string& crc) //Загрузка фотографии в принтер
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start UploadImage();");

	std::string msg;
	msg+=Data; 
	msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fnUploadImage,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			crc = Utility::CutBeforeFirst(answer, '\t');
		}else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "UploadImage(Data="<< Data <<",crc="<< crc <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
MyError DP25::PowerOff()
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start PowerOff();");

	std::string msg;
	msg += "POWEROFF"; msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fnUploadImage, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{

		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "PowerOff();";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
MyError DP25::Restart()
{
	if (m_SaveLog) Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", "Start PowerOff();");

	std::string msg;
	msg += "RESTART"; msg += '\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fnUploadImage, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{

		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode = result.ErrorCode;
	m_LastErrorDescription = result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if (m_SaveLog)
	{
		std::stringstream ss;
		ss << "PowerOff();";
		if (m_LastErrorCode != 0) ss << " ErrorCode: " << m_LastErrorCode;
		Utility::logrotate(m_LogFilePath + sp3()+"log.txt","main","info", ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
//Загрузить изображение для штампа
MyError DP25::UploadStamp(std::string Data,std::string& crc)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start UploadStamp();");

	std::string msg;
	msg+=Data; 
	msg+='\t';

	std::string answer;
	MyError result;
	result.ErrorCode = SendPMessage(fnUploadStamp, (unsigned char*)msg.c_str(), (int)msg.size(), answer);
	if (result.ErrorCode == 0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{
			crc = Utility::CutBeforeFirst(answer, '\t');
		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "UploadStamp(Data="<< Data <<",crc="<< crc <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}
	return result;
}
//---------------------------------------------------------------------------
MyError DP25::CheckUpdate()
{
	std::string IsUnblocked;
	return SetServiceParam("7", "", IsUnblocked);
}
//---------------------------------------------------------------------------
MyError DP25::PrintStamp(char Type,std::string Name)
{
	if(m_SaveLog) Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info","Start PrintStamp();");

	std::string msg;
	msg+=Type; msg+='\t';
	msg+=Name; msg+='\t';
	

	std::string answer;
	MyError result;
	result.ErrorCode =SendPMessage(fcPrintStamp,(unsigned char*)msg.c_str(), (int)msg.size(),answer);
	if(result.ErrorCode==0)
	{
		std::string ErrorCode = Utility::CutBeforeFirst(answer, '\t');
		if (ErrorCode == "0")
		{

		}
		else
		{
			result.ErrorCode = std::abs(Utility::StdStrToInt(ErrorCode));
		}
	}

	m_LastErrorCode=result.ErrorCode;
	m_LastErrorDescription=result.ErrorMessage;
	if (result.ErrorCode != 0) //Если ошибка то получаю описание ошибки
	{
		std::string rErrorMessage;
		int rECode;
		ReadingError(result.ErrorCode, rECode, rErrorMessage);
		m_LastErrorDescription = rErrorMessage;
		result.ErrorMessage = rErrorMessage;
		m_LastErrorCode = result.ErrorCode;
	}

	if(m_SaveLog)
	{
		std::stringstream ss;
		ss << "PrintStamp(Type="<< Type <<",Name="<< Name <<");";
		if(m_LastErrorCode!=0) ss << " ErrorCode: " << m_LastErrorCode << " ErrorDescription: " << m_LastErrorDescription;
		Utility::logrotate(m_LogFilePath+sp3()+"log.txt","main","info",ss.str());
	}

	return result;
}
//---------------------------------------------------------------------------
