//! FP300KZ /*! Класс принтера FP300KZ \author Иванов Игорь М. \file FP300KZ.cpp */ //--------------------------------------------------------------------------- #pragma hdrstop #include "stdafx.h" #include "FP300KZ.h" #include #include #include #include #include #include //#include #include #include #include //mkdir //#include //#include //#include #if defined( __WXMSW__ ) //Если кроссплатформкннное приложение #include #endif // __WXMSW__ //--------------------------------------------------------------------------- //#pragma package(smart_init) //--------------------------------------------------------------------------- //Добавил когда делал кросплатформеного кассирра //typedef unsigned long DWORD; //--------------------------------------------------------------------------- //Сохранить лог в текстовый файл bool saveLog(std::string FileName, std::string Text) { try { for(uint4 i=0;is[0][0]) return 4; //0x04 Некорректные параметры в команде обращения к ФП /*5 5 Нет запрошенных данных 6 6 ФП в режиме вывода данных 7 7 Некорректные параметры в команде для данной реализации ФП 8 8 Команда не поддерживается в данной реализации ФП 9 9 Некорректная длина команды 0A 10 Формат данных не BCD 0B 11 Неисправна ячейка памяти ФП при записи итога 11 17 Не введена лицензия 12 18 Заводской номер уже введен 13 19 Текущая дата меньше даты последней записи в ФП 14 20 Область сменных итогов ФП переполнена 15 21 Смена уже открыта 16 22 Смена не открыта 17 23 Номер первой смены больше номера последней смены 18 24 Дата первой смены больше даты последней смены 19 25 Нет данных в ФП 1A 26 Область перерегистраций в ФП переполнена 1B 27 Заводской номер не введен 1C 28 В заданном диапазоне есть поврежденная запись 1D 29 Повреждена последняя запись сменных итогов 1F 31 Отсутствует память регистров 20 32 Переполнение денежного регистра при добавлении 21 33 Вычитаемая сумма больше содержимого денежного регистра 22 34 Неверная дата 23 35 Нет записи активизации 24 36 Область активизаций переполнена 25 37 Нет активизации с запрашиваемым номером 33 51 Некорректные параметры в команде 35 53 Некорректный параметр при данных настройках 36 54 Некорректные параметры в команде для данной реализации ФР 37 55 Команда не поддерживается в данной реализации ФР 38 56 Ошибка в ПЗУ + 39 57 Внутренняя ошибка ПО ФР 3A 58 Переполнение накопления по надбавкам в смене 3C 60 ЭКЛЗ: неверный регистрационный номер 3E 62 Переполнение накопления по секциям в смене 3F 63 Переполнение накопления по скидкам в смене 40 64 Переполнение диапазона скидок 41 65 Переполнение диапазона оплаты наличными 42 66 Переполнение диапазона оплаты типом 2 43 67 Переполнение диапазона оплаты типом 3 44 68 Переполнение диапазона оплаты типом 4 45 69 Cумма всех типов оплаты меньше итога чека 46 70 Не хватает наличности в кассе 47 71 Переполнение накопления по налогам в смене 48 72 Переполнение итога чека 4A 74 Открыт чек - операция невозможна 4B 75 Буфер чека переполнен 4C 76 Переполнение накопления по обороту налогов в смене 4D 77 Вносимая безналичной оплатой сумма больше суммы чека 4E 78 Смена превысила 24 часа */ //if(CommandName==fcOpenFiscalInv && Password=="") return 79; //4F 79 Неверный пароль /*50 80 Идет печать предыдущей команды 51 81 Переполнение накоплений наличными в смене 52 82 Переполнение накоплений по типу оплаты 2 в смене 53 83 Переполнение накоплений по типу оплаты 3 в смене 54 84 Переполнение накоплений по типу оплаты 4 в смене 56 86 Нет документа для повтора 57 87 ЭКЛЗ: количество закрытых смен не совпадает с ФП 58 88 Ожидание команды продолжения печати 59 89 Документ открыт другим оператором 5B 91 Переполнение диапазона надбавок 5C 92 Понижено напряжение 24В 5D 93 Таблица не определена 5E 94 Некорректная операция 5F 95 Отрицательный итог чека 60 96 Переполнение при умножении 61 97 Переполнение диапазона цены 62 98 Переполнение диапазона количества 63 99 Переполнение диапазона отдела 64 100 ФП отсутствует + 65 101 Не хватает денег в секции 66 102 Переполнение денег в секции*/ if(!cPort->bOpen) return 103; //0x67 Ошибка связи с ФП + /*68 104 Не хватает денег по обороту налогов 69 105 Переполнение денег по обороту налогов 6A 106 Ошибка питания в момент ответа по I2C 6B 107 Нет чековой ленты 6C 108 Нет контрольной ленты 6D 109 Не хватает денег по налогу 6E 110 Переполнение денег по налогу 6F 111 Переполнение по выплате в смене 70 112 Переполнение ФП 71 113 Ошибка отрезчика + 72 114 Команда не поддерживается в данном подрежиме 73 115 Команда не поддерживается в данном режиме 74 116 Ошибка ОЗУ 75 117 Ошибка питания + 76 118 Ошибка принтера: нет импульсов с тахогенератора + 77 119 Ошибка принтера: нет сигнала с датчиков + 78 120 Замена ПО 79 121 Замена ФП 7A 122 Поле не редактируется 7B 123 Ошибка оборудования 7C 124 Не совпадает дата 7D 125 Неверный формат даты 7E 126 Неверное значение в поле длины 7F 127 Переполнение диапазона итога чека 80 128 Ошибка связи с ФП + 81 129 Ошибка связи с ФП + 82 130 Ошибка связи с ФП + 83 131 Ошибка связи с ФП + 84 132 Переполнение наличности 85 133 Переполнение по продажам в смене 86 134 Переполнение по покупкам в смене 87 135 Переполнение по возвратам продаж в смене 88 136 Переполнение по возвратам покупок в смене 89 137 Переполнение по внесению в смене 8A 138 Переполнение по надбавкам в чеке 8B 139 Переполнение по скидкам в чеке 8C 140 Отрицательный итог надбавки в чеке 8D 141 Отрицательный итог скидки в чеке 8E 142 Нулевой итог чека 8F 143 Касса не фискализирована 90 144 Поле превышает размер, установленный в настройках 91 145 Выход за границу поля печати при данных настройках шрифта 92 146 Наложение полей 93 147 Восстановление ОЗУ прошло успешно 94 148 Исчерпан лимит операций в чеке A0 160 Ошибка связи с ЭКЛЗ + A1 161 ЭКЛЗ отсутствует + A2 162 ЭКЛЗ: Некорректный формат или параметр команды A3 163 Некорректное состояние ЭКЛЗ A4 164 Авария ЭКЛЗ A5 165 Авария КС в составе ЭКЛЗ A6 166 Исчерпан временной ресурс ЭКЛЗ A7 167 ЭКЛЗ переполнена A8 168 ЗКЛЗ: Неверные дата и время A9 169 ЭКЛЗ: Нет запрошенных данных AA 170 Переполнение ЭКЛЗ (отрицательный итог документа) B0 176 ЭКЛЗ: Переполнение в параметре количество B1 177 ЭКЛЗ: Переполнение в параметре сумма B2 178 ЭКЛЗ: Уже активизирована*/ if(Status->s[0][2]) return 192; //0xC0 Контроль даты и времени (подтвердите дату и время) /*C1 193 ЭКЛЗ: суточный отчёт с гашением прервать нельзя C2 194 Превышение напряжения в блоке питания C3 195 Несовпадение итогов чека и ЭКЛЗ C4 196 Несовпадение номеров смен С5 197 Буфер подкладного документа пуст C6 198 Подкладной докуемнт отсутствует C7 199 Поле не редактируется в данном режиме*/ //Свои коды ошибок потому что немогу найти в списке выше этого значения if(Status->s[0][4]) return 500; //Печатающее устройство неисправно. if(Status->s[0][1]) return 501; //Неправильный код полученной команды. if(Status->s[1][4]) return 502; //После включения принтера обнаружены нарушения данных в ОЗУ. if(Status->s[1][3]) return 503; //Батарея разряжена (Таймер реального времени в состоянии RESET). if(Status->s[1][2]) return 504; //ОЗУ обнулено. if(Status->s[1][1]) { if(CommandName==fcOpenFiscalInv && Status->s[2][3]) return 509; else //Уже открыт фискальный чек или чек возврата. if(CommandName==fcCloseFiscalInv) { bool Open; int Items; double Amount=0,Tender=0; FiscalTransactionsStatus(Open,Items,Amount,Tender); CommandName=fcCloseFiscalInv; //Чтоб при следующем вызове не обнолилось Status->s[1][1]=true; //Чтоб по прежнему была ошибка if(Open && Amount-(Tender+0.002)>0) return 511; //"Не возможно закрыть чек доплатите денег!" }else if(CommandName==fcOpenFiscalInv) { //Проверяем сколько времени прошло с начала смены m_SaveLog=false; int sec; if(SessionSec(sec) && sec>24*60*60) { Status->s[1][1]=true; CommandName=fcOpenFiscalInv; //Чтоб не изменилось return 78; } m_SaveLog=true; } return 505; //Команда не может быть выполнена в данном фискальном режиме. } if(Status->s[4][0]) return 506; //Ошибка записи в фискальную память. if(Status->s[4][4]) return 507; //Фискальная память заполнена. if(Status->s[2][0]) return 508; //Закончилась лента. //509 занят "Уже открыт фискальный чек или чек возврата." if(Status->s[1][5]) return 510; //Крышка принтера открыта! //511 занят "Не возможно закрыть чек доплатите денег!" //512 Не используется //513 Проведено максимальное количество перерегистраций. //514 Не установлен заводской номер (фискализация) или не верный пароль налогового инспектора (перерегистрация). //515 Некорректный заводской номер. //516 Открыт фискальный или нефискальный чек. //517 Отпечатаны фискальные чеки после Z-отчета. Необходимо снять Z-отчет. //518 Не установлены ставки НДС. //519 Не включена ни одна группа НДС. //520 Не установлены дата и время или фискальная память в режиме "ТОЛЬКО ДЛЯ ЧТЕНИЯ". return m_ErrorCode; } //--------------------------------------------------------------------------- FP300KZ::FP300KZ() { cPort=new ComPort(); Status=new MyStatus(); CheckCount=0; for(int i=0;ibOpen) { m_ErrorCode=103; return false; } CommandName=msg[3]; //Сохраняем номер последней команды for(int i=0;ibOpen) { for(int i=0;i<5;i++) //Если после 5 попыток нет ответа то принтер неисправен... { //Отправляю запрос на принтер msg[1]=0x20+size-1; //Размер msg[2]=FrameSeqNumber; unsigned int crc=MakeCRC(msg,1,size); cPort->Write(msg,size); //Отправляем данные cPort->Write(&crc,4); //Контрольная сумма cPort->WriteChar(0x03); //Признак конца сообщения //Пытаюсь принять ответ от принтера bool isOk=true; int j=0; while(j<9) //9*60=540 в цикле чтоб ждать ответа не более 500ms по документации { uint1 start=0; unsigned long BytesRead=cPort->Read(&start,sizeof(start)); //читаемм байт (ответ должен прити в течении 60 ms хост должен ждать 500 ms) if(BytesRead==0) //Ничего не прочитал { #ifdef __WXMSW__ wxThread::Sleep(60); #endif // __WXMSW__ #ifdef _BORLAND Sleep(60); #endif isOk=false; m_ErrorCode=103; //Код ошибки break; }else if(start==0x15) //NACK ошибка в контрольной сумме запрос заново отправить { #ifdef __WXMSW__ wxThread::Sleep(60); #endif // __WXMSW__ #ifdef _BORLAND Sleep(60); #endif isOk=false; break; }else if(start==0x16) //SYN комманда подождать данные посылается каждые 60ms { #ifdef __WXMSW__ wxThread::Sleep(60); #endif // __WXMSW__ #ifdef _BORLAND Sleep(60); #endif j=0; //Начинаем ждать по новой (может зациклится) }else if(start==0x01) //Дочитываем { ReadAr[0]=start; //Для подсчёта CRC uint1 size=0; cPort->Read(&size,1); //Рзамер данных в байтах ReadAr[1]=size; size=ReadAr[1]-0x20 + 6; //Размер всего сообщения (+5 это 1 байт начало и CRC 4 байта и 1 байт конец) BytesRead=2; //Так как признак начала и размер уже прочитали for(int j=0;j<100;j++) { BytesRead+=cPort->Read(&ReadAr[BytesRead],size-BytesRead); if(BytesRead>=size) break; } //Проверяем ответ на CRC unsigned int crc0=MakeCRC(ReadAr,1,size-5); unsigned int crc1=*((unsigned int*)&ReadAr[size-5]); if(crc0!=crc1) isOk=false; //Ошибка в контрольной сумме ответа else { Status->SetStatus(&ReadAr[size-12]); //читаем статус answer.assign((char*)&ReadAr[4],size-17); //Добавляем ответ в результат result=true; } if(result) break; } j++; } if(!isOk) continue; //Ошибка повторяем запрос break; //всё в порядке } } if(!result) m_ErrorCode=5; return result; } //--------------------------------------------------------------------------- bool FP300KZ::OpenCOMPort(int ComNumber,int BaudRate) { if(ComNumber>=0) cPort->ComNumber=ComNumber; if(BaudRate>=0) cPort->BaudRate=BaudRate; cPort->Close(); if(cPort->Open(cPort->ComNumber)) { if(!cPort->Setup(0)) return false; }else return false; return true; } //--------------------------------------------------------------------------- void FP300KZ::LoadSetup() { /* std::wstring path=getCommonAppPathW()+L"\\NewTon\\Setup.ini"; TIniFile* ini=new TIniFile(ExtractFilePath(ParamStr(0))+"\\Setup.ini"); cPort->port=ini->ReadString("Printer","Port",""); cPort->BaudRate=ini->ReadInteger("Printer","BaudRate",0); CheckCount=ini->ReadInteger("Printer","CheckCount",0); delete ini; */ } //--------------------------------------------------------------------------- void FP300KZ::SaveSetup() { /* std::wstring path=getCommonAppPathW()+L"\\NewTon\\Setup.ini"; TIniFile* ini=new TIniFile(ExtractFilePath(ParamStr(0))+"\\Setup.ini"); ini->WriteString("Printer","Port",cPort->port); ini->WriteInteger("Printer","BaudRate",cPort->BaudRate); ini->WriteInteger("Printer","CheckCount",CheckCount); delete ini; */ } //--------------------------------------------------------------------------- bool FP300KZ::Print() { return false; } //--------------------------------------------------------------------------- void FP300KZ::NewLine() { } //--------------------------------------------------------------------------- /*public byte[] ReturnBCC(byte[] bytePacketData) { // Контролна сума (0000H-FFFFH) // дължина: 4 байта // стойност: 30H - 3FH // Сумата включва от <01> без него до <05> вкл. // Всяка цифра от двата байта се предава като и се прибави 30H. // Например сумата 1AE3H се представя като 31H,3AH,3EH,33H. // IN HEX // 01 25 50 4C 54 05 30 // In decimal // 1 37 80 76 84 5 48 Int64 triset_HEX = 0x30; byte[] bRes = new byte[4]; int i = 48; int iRes = 0; // int i = 0; int iCountB = 0; string hexval1 = String.Empty; string hexval2 = String.Empty; StringBuilder sb = new StringBuilder(); foreach (byte n in bytePacketData) { if (n != (byte)01) { if (iCountB == 0) { sb.Append(n.ToString("X2")); string hexString = sb.ToString(); triset_HEX = triset_HEX + Convert.ToInt64(hexString, 16); } iCountB++; if (iCountB > 1) iCountB = 0; } if (n == (byte)05) break; } return this.ConvertHexToByteArr(Convert.ToString( triset_HEX )); } */ //--------------------------------------------------------------------------- ///Постройка CRC специального для этого принтера //BufStart - С какого байта начинать подсчёт //BufEnd - По какой байт считать (не длина) unsigned int MakeCRC(unsigned char* Buf, unsigned int BufStart,unsigned int BufEnd) { unsigned int cs=0; for(unsigned int i=BufStart;i> 0x0C) & 0x0F) + 0x30; mas[1]=((cs >> 0x08) & 0x0F) + 0x30; mas[2]=((cs >> 0x04) & 0x0F) + 0x30; mas[3]=((cs >> 0x00) & 0x0F) + 0x30; return result; } //--------------------------------------------------------------------------- //Инициализация переменных PrinterName PrinterVersion PrinterNumber PrinterDecimal //Без которых принтер не может работать... bool FP300KZ::PrinterInit() { bool b=DiagnosticInfo(); if(b) { bool bA,bB,bC,bD; std::string Decimal,r,TaxA,TaxB,TaxC,TaxD; b=b && GetTaxRates(Decimal,r,bA,bB,bC,bD,TaxA,TaxB,TaxC,TaxD); // if(b) b=b && fp->GetStatusFP(); } return b; } //--------------------------------------------------------------------------- ///Получение байтов статуса принтера 4A bool FP300KZ::GetStatusFP() { unsigned char msg[5] = {0x01,0x24,0x00,fcGetStatusFP,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("GetStatusFP(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Аннуляция (сторно) фискального чека bool FP300KZ::CancelFiscalInv() { unsigned char msg[5] = {0x01,0x24,0x00,fcCancelFiscalInv,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("CancelFiscalInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Открытие фискального (клиентского) чека ///OpCode - Номер оператора 1..16 ///OpPwd - Пароль оператора 4 - 6 цифр ///TillNmb - Номер кассового места целое число 1..99999 bool FP300KZ::OpenFiscalInv(int OpCode,std::string OpPwd,int TillNmb) { std::string msg; msg+=(char)0x01; msg+=(char)0x00; msg+=(char)0x00; msg+=(char)fcOpenFiscalInv; msg+=IntToStdStr(OpCode)+","+OpPwd+","+IntToStdStr(TillNmb); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки //if(b) //{ Password=OpPwd; //Сохраняем пароль //} saveLog(PrinterName+"_"+PrinterNumber,std::string("OpenFiscalInv(OpCode="+IntToStdStr(OpCode)+",OpPwd=****,TillNmb="+IntToStdStr(TillNmb)+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Закрытие фискального чека bool FP300KZ::CloseFiscalInv() { unsigned char msg[5] = {0x01,0x24,0x00,fcCloseFiscalInv,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("CloseFiscalInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Открытие нефискального чека bool FP300KZ::OpenServiceInv() { unsigned char msg[5] = {0x01,0x24,0x00,fcOpenServiceInv,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("OpenServiceInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Закрытие нефискального чека ///TODO ответ: Количество всех напечатанных чеков (фискальных и служебных) с момента последнего закрытия смены до текущего момента /4 байта/. bool FP300KZ::CloseServiceInv(int& count) { count=0; unsigned char msg[5] = {0x01,0x24,0x00,fcCloseServiceInv,0x05}; std::string str; bool b=SendPMessage(msg,sizeof(msg),str); b=b && !Status->s[0][5]; //Признак ошибки if(b) count=fromString(str); saveLog(PrinterName+"_"+PrinterNumber,std::string("CloseServiceInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Открытие чека возврата /**OpCode - Номер оператора 1..16 * OpPwd - 4 - 6 цифр * TillNmb - Номер кассового места /целое число 1..99999/ */ bool FP300KZ::OpenBackInv(int OpCode,std::string OpPwd,int TillNmb) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcOpenBackInv; msg+=IntToStdStr(OpCode)+','+OpPwd+','+IntToStdStr(TillNmb); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("OpenBackInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Печать дубликата чека bool FP300KZ::PrintDuplicateInv() { unsigned char msg[6] = {0x01,0x25,0x00,fcPrintDuplicateInv,0x31,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintDuplicateInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- /** Установка наименований дополнительных типов оплаты Option - 1..4 номер типа оплаты Name - Наименование типа оплаты (если name = '' то вернёт текущее) */ bool FP300KZ::SetAddTypesOfPayment(char Option, std::wstring& Text) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetAddTypesOfPayment; switch(Option) { case 1: msg+='I'; break; case 2: msg+='J'; break; case 3: msg+='K'; break; case 4: msg+='L'; break; } if(Text.length()!=0) { msg+=','; msg.append(ws2s(Text),0,31); //В документации макс 31 байт } msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b && Text.length()!=0 && answer!="P") b=b && false; if(b && Text.length()==0) Text=s2ws(answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("SetAddTypesOfPayment(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Печатать дневной отчёт с гашением bool FP300KZ::PrintZReport() { bool b=PrintEJ(); //печатаем контрольную ленту if(b) b=b && EJ("E"); //Отчищяяем контрольную ленту if(b) b=b && DailyFinancialReport('1'); //Сам Z отчёт return b; } //--------------------------------------------------------------------------- //Печатать дневной отчёт без гашения bool FP300KZ::PrintXReport() { return DailyFinancialReport('3'); } //--------------------------------------------------------------------------- //Печатает строку текста (на служебном и на фискальном) bool FP300KZ::PrintLine(std::wstring line) { bool b=PrintFreeTextInFiscalInv(ws2s(line)); //TODO подправить на ru-ru.1251 роверить в интернете if(!b) b=PrintFreeTextInServiceInv(ws2s(line)); //Печать свободного текста в нефискальном чеке return b; // bool b=PrintFreeTextInFiscalInv(WStringToString(line, std::locale(""),'?')); //TODO подправить на ru-ru.1251 роверить в интернете // if(!b) b=PrintFreeTextInServiceInv(WStringToString(line, std::locale(""),'?')); //Печать свободного текста в нефискальном чеке // return b; } //--------------------------------------------------------------------------- ///Дневной финансовый отчет ///'0' - Z отчёт без регистров ///'1' - Z отчёт с регистрами ///'2' - X отчёт без регистров ///'3' - X отчёт с содержанием регистров bool FP300KZ::DailyFinancialReport(uint1 Option) { //N на конце не сделал смотри документацию unsigned char msg[6] = {0x01,0x25,0x00,fcDailyFinancialReport,Option,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("DailyFinancialReport(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Отчет по налоговым ставкам и положению десятичной точки за период ///Start - Дата начала периода – DDMMYY /6 байт/ ///End - Дата окончания периода – DDMMYY /6 байт/ bool FP300KZ::ReportOnTaxRates(std::string Start,std::string End) //Отчет по налоговым ставкам и положению десятичной точки за период { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcReportOnTaxRates; msg+=Start+','+End; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); if(answer=="f") b=false; //Если не заданно налоговых ставок за период. b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("ReportOnTaxRates(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Полный фискальный отчет за период заданный датами ///Password - Пароль налогового инспектора от 4 до 6 цифр. ///Receipts - Не обязательный параметр: один байт со значением 'X'. Если он присутствует, то в отчете печатается количество фискальных чеков за день. ///Start - Начальная дата периода. 6 байт DDMMYY. ///End - Конечная дата периода. 6 байт DDMMYY. ///Если второй параметр отсутствует, команда генерирует месячный или годовой отчет. Синтаксис в этом случае: ///Start Месяц - 4 байта (MMYY) для месячного отчета. ///Start Год - 2 байта (YY) для годового отчета. bool FP300KZ::FullFiscalReportByDate(std::string Password,std::string Receipts,std::string Start,std::string End) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFullFiscalReportByDate; msg+=Password+','; msg+=Receipts; msg+=Start+','+End; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("FullFiscalReportByDate(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Сокращёный фискальный отчет за период заданный датами ///Password - Пароль налогового инспектора от 4 до 6 цифр. ///Receipts - Не обязательный параметр: один байт со значением 'X'. Если он присутствует, то в отчете печатается количество фискальных чеков за день. ///Start - Начальная дата периода. 6 байт DDMMYY. ///End - Конечная дата периода. 6 байт DDMMYY. ///Если второй параметр отсутствует, команда генерирует месячный или годовой отчет. Синтаксис в этом случае: ///Start Месяц - 4 байта (MMYY) для месячного отчета. ///Start Год - 2 байта (YY) для годового отчета. bool FP300KZ::ReduceFiscalReportByDate(std::string Password,std::string Receipts,std::string Start,std::string End) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcReduceFiscalReportByDate; msg+=Password+','; msg+=Receipts; msg+=Start+','+End; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("ReduceFiscalReportByDate(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Полный фискальный отчет за период заданный номерами смен ///Область данных: , [[],] ///Password - Пароль налогового инспектора – от 4 до 6 цифр. ///Receipts - Не обязательный параметр: один байт со значением ‘X’. Если он присутствует, то в отчете печатается количество фискальных чеков за день. ///Start - Номер первой смены отчетного периода. 4 байта. ///End - Номер последней смены отчетного периода. 4 байта. bool FP300KZ::FullFiscalReportByNumber(std::string Password,std::string Receipts,int Start,int End) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFullFiscalReportByNumber; msg+=Password+','; msg+=Receipts; msg+=IntToStdStr(Start)+','+IntToStdStr(End); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("FullFiscalReportByNumber(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Сокращёный фискальный отчет за период заданный номерами смен ///Область данных: , [[],] ///Password - Пароль налогового инспектора – от 4 до 6 цифр. ///Receipts - Не обязательный параметр: один байт со значением ‘X’. Если он присутствует, то в отчете печатается количество фискальных чеков за день. ///Start - Номер первой смены отчетного периода. 4 байта. ///End - Номер последней смены отчетного периода. 4 байта. bool FP300KZ::ReduceFiscalReportByNumber(std::string Password,std::string Receipts,int Start,int End) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcReduceFiscalReportByNumber; msg+=Password+','; msg+=Receipts; msg+=IntToStdStr(Start)+','+IntToStdStr(End); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("ReduceFiscalReportByNumber(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Дневной отчет по типам оплаты bool FP300KZ::DailyReportByTypesOfPayment(std::string& Cash,std::string& Credit,std::string& Debit,std::string& Cheque,std::string& Pay1,std::string& Pay2,std::string& Pay3,std::string& Pay4,std::string& Closure,std::string& Receipt) { // unsigned char msg[5] = {0x01,0x24,0x00,fcDailyReportByTypesOfPayment,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { Cash=CutBeforeFirst(answer,','); Credit=CutBeforeFirst(answer,','); Debit=CutBeforeFirst(answer,','); Cheque=CutBeforeFirst(answer,','); Pay1=CutBeforeFirst(answer,','); Pay2=CutBeforeFirst(answer,','); Pay3=CutBeforeFirst(answer,','); Pay4=CutBeforeFirst(answer,','); Closure=CutBeforeFirst(answer,','); Receipt=CutBeforeFirst(answer,','); } saveLog(PrinterName+"_"+PrinterNumber,std::string("DailyReportByTypesOfPayment(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Отчет по артикулам ///'S' - Печатаются только данные артикулов по которым были продажи. ///'P' - Печатаются данные всех запрограммированных артикулов. bool FP300KZ::ReportByArticle(std::string Option) //#define fcReportByArticle 0x6F //(111)Отчет по артикулам { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcReportByArticle; msg+=Option; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("ReportByArticle(Option="+Option+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Отчет по операторам bool FP300KZ::OperatorReport() { unsigned char msg[5] = {0x01,0x24,0x00,fcOperatorReport,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("OperatorReport(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Протяжка ленты ///\param cnt Количество строк bool FP300KZ::FeedPaper(int cnt) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFeedPaper; msg+=IntToStdStr(cnt); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("FeedPaper(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Открытие денежного ящика bool FP300KZ::OpenCashDrawer(int mSec) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcOpenCashDrawer; if(mSec>0) msg+=IntToStdStr(mSec); msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("OpenCashDrawer(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //,[] ///Задать наименование департамента (Секции) bool FP300KZ::SetDepartmentName(int dept,std::wstring line1,std::wstring line2) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetDepartmentName; msg+=IntToStdStr(dept); msg+=','; msg.append(ws2s(line1),0,36); //В документации макс 36 байт if(line2.length()>0) { msg+=(char)10; msg.append(ws2s(line2),0,46); //В документации макс 46 байт } msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("SetDepartmentName(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Получить информацию по секциям bool FP300KZ::GetDepartmentInfo(int dept,int &RecSales,float &RecSum,int &TotSales,float &TotSum,std::wstring &Line1,std::wstring &Line2) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcGetDepartmentInfo; msg+=IntToStdStr(dept); msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); if(b) { if(CutBeforeFirst(str,',')=="P") //Секция запрограммированна { std::string nstr; nstr=CutBeforeFirst(str,','); RecSales=StdStrToInt(nstr); RecSum=fromString(CutBeforeFirst(str,',')); //Натуральное число в текстовом виде с 2 десятичными знаками nstr=CutBeforeFirst(str,','); TotSales=StdStrToInt(nstr); TotSum=fromString(CutBeforeFirst(str,',')); //Натуральное число в текстовом виде с 2 десятичными знаками Line1=s2ws(CutBeforeFirst(str,(char)10)); Line2=s2ws(str); }else { RecSales=0; RecSum=0; TotSales=0; TotSum=0; Line1=L' '; Line2=L' '; } } saveLog(PrinterName+"_"+PrinterNumber,std::string("GetDepartmentInfo(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Обрезка ленты bool FP300KZ::CutPaper() { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcCutPaper; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("CutPaper(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Печать диагностической информации bool FP300KZ::PrintDiagnostic() { unsigned char msg[5] = {0x01,0x20,0x20,fcPrintDiagnostic,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintDiagnostic(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- bool FP300KZ::SetManufacturersSerialNumber(std::string Serial) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetManufacturersSerialNumber; msg+=Serial; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { b=b && BeforeFirst(answer,',')=="P"; //Вторая часть ддолжна быть "KAZAKHSTAN" } saveLog(PrinterName+"_"+PrinterNumber,std::string("SetManufacturersSerialNumber(Serial="+Serial+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- std::string FP300KZ::GetStatusDescription(BYTE StatusCode) { if (StatusCode == 0x00) { return "OK"; } if (StatusCode == 0xFF) { return "Принтер недоступен!"; } BYTE code = (BYTE)StatusCode & (BYTE)0x04; if (code > 0) { return "Бумага кончилась "; } code = (BYTE)StatusCode & (BYTE)0x01; if (code > 0) { return "Бумага скоро кончится "; } return ""; } //--------------------------------------------------------------------------- ///Чтение РНН и РНМ bool FP300KZ::GetRNNAndRNM(std::string &RNN,std::string &RNM) { unsigned char msg[5] = {0x01,0x24,0x00,fcGetRNNAndRNM,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); RNN=BeforeFirst(answer,','); RNM=AfterFirst(answer,','); saveLog(PrinterName+"_"+PrinterNumber,std::string("GetRNNAndRNM("+RNN+","+RNM+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Установка РНН и РНМ bool FP300KZ::SetRNNAndRNM(std::string RNN,std::string RNM) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetRNNAndRNM; msg+=RNN+','+RNM; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("SetRNNAndRNM(RNN="+RNN+",RNM="+RNM+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Установка пароля оператора ///\param OpCode Номер оператора ///\param OldPwd Старый пароль ///\param NewPwd Новый пароль ///\return Успех либо провал bool FP300KZ::SetOperatorPassword(std::string OpCode,std::string OldPwd,std::string NewPwd) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetOperatorPassword; msg+=OpCode+','+OldPwd+','+NewPwd; msg+=(char)0x05; std::string answer; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("SetOperatorPassword(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Установка наименования оператора ///\param OpCode Номер оператора. От 1 до 16 строка. ///\param Pwd Пароль (4 до 8 цифр). ///\param OpName Наименование оператора (до 30 символов). ///\return Успех либо провал bool FP300KZ::SetOperatorName(std::string OpCode,std::string Pwd,std::string OpName) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetOperatorName; msg+=OpCode+','+Pwd+','+OpName; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("SetOperatorName(OpCode="+OpCode+",OpName="+OpName+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Установка даты и времени ///\param date - Дата в формате "DD-MM-YY" ///\param time - врремя в формате "HH:MM[:SS]" bool FP300KZ::SetDateTime(std::string date, std::string time) //#define fcSetDateTime 0x3D //(61)Установка даты и времени { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetDateTime; msg+=trim(date)+' '+trim(time); msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("SetDateTime(\"")+date+std::string("\", \"")+time+std::string("\"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Поолучение даты и времени ///\param date - Дата в формате "DD-MM-YY" ///\param time - врремя в формате "HH:MM:SS" bool FP300KZ::GetDateTime(unsigned short& De,unsigned short& Me,unsigned short& Ye,unsigned short& Ho,unsigned short& Mi,unsigned short& Se) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcGetDateTime; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); if(b) { De=fromString(CutBeforeFirst(str,'-')); Me=fromString(CutBeforeFirst(str,'-')); Ye=fromString(CutBeforeFirst(str,' '));//+2000; закоментил чтоб было одинаково с тем что при установки времени Ho=fromString(CutBeforeFirst(str,':')); Mi=fromString(CutBeforeFirst(str,':')); Se=fromString(str); } saveLog(PrinterName+"_"+PrinterNumber,std::string("GetDateTime(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Установка HEADER и FOOTER и опций печати bool FP300KZ::PrintSetup(std::string Item, std::string Text, std::string& Answer) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrintSetup; msg+=Item+Text; msg+=(char)0x05; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),Answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintSetup(Item="+Item+",Text="+Text+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- bool FP300KZ::PrintFreeTextInServiceInv(std::string Text) //Печать свободного текста в нефискальном чеке { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrintFreeTextInServiceInv; msg+=Text; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintFreeTextInServiceInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Печать свободного текста в фискальном чеке bool FP300KZ::PrintFreeTextInFiscalInv(std::string Text) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrintFreeTextInFiscalInv; msg+=Text; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintFreeTextInFiscalInv(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Регистрация продажи ///[][]<[Sign]Price>[*][,Perc|;Abs] ///L1 - Первая строка описания продажи, до 36 байт текста ///L2 - Вторая строка описания продажи, до 36 байт текста ///dep - Департамент отдел (1..10) ///TaxCd - Один байт содержащий букву соответствующую налоговой группе (А, Б, В, Г, Д). ///Price - Цена единицы (до 8 значащих цифр). ///Qwan - Количество товара (Длина до 8 значащих цифр не более 3-х знаков после десятичной точки). ///Abs - абсолюбное ли значение в Perc иначе проценты ///Perc - Надбавка или скидка (в зависимости от знака) в процентах bool FP300KZ::RegisterSale(std::wstring L1,std::wstring L2,int dep, std::string TaxCd,double Price,double Qwan,bool Abs,double Perc) { L1=replaceStrings(L1,L"\n",L" "); //Избавляемся от переходов на новую строку L2=replaceStrings(L2,L"\n",L" "); //Избавляемся от переходов на новую строку std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcRegisterSale; msg.append(ws2s(L1),0,36); //В документации макс 36 байт if(L2.length()>0) { msg+=(char)0x0A; msg.append(ws2s(L2),0,36); //В документации макс 36 байт } msg+=(char)0x09; if(dep>0) { msg+=IntToStdStr(dep); //Параметр департамент отдел в документации в строке команды пропущен!!!! msg+=(char)0x09; } msg+=TaxCd; //налоговой группа 1 байт msg+=FloatToStdStr(Price,m_Dots); //Учитываем знаки после запятой msg+='*'+FloatToStdStr(Qwan,3); if(Perc!=0) if(Abs) msg+=';'+FloatToStdStr(Perc,m_Dots); //В абсолютном значении else msg+=','+FloatToStdStr(Perc,2); //Скидка или надбавка msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("RegisterSale(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Регистрация продажи с выводом на дисплей /// [Line]]<[Sign]Price>[*Qwan][,Perc|;Abs] ///Line - Строка до 20 байта содержащая текст описывающий продажу. ///TaxCd - Один байт содержащий букву соответствующую налоговой группе (А, Б, В, Г, Д). ///Price - Цена единицы (до 8 значащих цифр). bool FP300KZ::RegisterSaleDisp(std::string L1,int dep,std::string TaxCd,std::string Price) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcRegisterSaleDisp; msg+=L1; msg+=(char)0x09; if(dep>0) { msg+=IntToStdStr(dep); //Параметр департамент отдел в документации в строке команды пропущен!!!! msg+=(char)0x09; } msg+=TaxCd; //налоговой группа 1 байт msg+=Price; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("RegisterSaleDisp(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Подитог //Print - Если ‘1’ – подитог печатается. //Display - Если ‘1’ – сумма подитога выводится на дисплей. //Abs - Абсолютное ли значчение false то Perc в процентах //Perc - Скидка или надбавка в процентах (+-99.9) в зависимости от знака //Sum - Сумма подитога в текущем фискальном чеке /до 10 байта/ bool FP300KZ::Subtotal(std::string Print,std::string Display, bool Abs, double Perc,double& Sum) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSubtotal; msg+=Print+Display; if(Perc!=0) //Скидка либо наценка { if(Abs) msg+=';'+FloatToStdStr(Perc,2); else msg+=','+FloatToStdStr(Perc,2); } msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки if(b) { Sum=fromString(CutBeforeFirst(str,','))/M(); } saveLog(PrinterName+"_"+PrinterNumber,std::string("Subtotal(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Оплата (итог) //Line1 - Первая строка текста до 36 байт //Line2 - Вторая строка текста до 36 байт //PaidMode - Тип оплаты: 'P' – Оплата наличными; 'N' – Оплата в кредит; 'C' – Оплата чеком; 'D' – Оплата дебитной картой 'I' - Программируемый тип оплаты 1 'J' - Программируемый тип оплаты 2 'K' - Программируемый тип оплаты 3 'L' - Программируемый тип оплаты 4 //Один байт со значением ‘+’, указывающий знак Amount (суммы оплаты). //Amount - Сумма оплаты /до 10 значащих цифр/. //Change - Сдача bool FP300KZ::Total(std::string Line1,std::string Line2,std::string PaidMode,double Amount, double& Change) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcTotal; msg+=Line1; msg+=(char)0x0A; msg+=Line2; msg+=(char)0x09; // msg+=PaidMode; //Тип оплаты if(Amount>0) msg+='+'; msg+=FloatToStdStr(Amount,m_Dots); msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки if(b) { if(str[0]=='F') b=false; std::string s=""; s.append(str,1,str.length()-1); Change=fromString(s)/M(); if(str[0]=='D') Change=-fabs(Change); } saveLog(PrinterName+"_"+PrinterNumber,std::string("Total(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Служебный приход или расход //Amount Сумма (до 10 значащих цифр). В зависимости от знака интерпретируется как приход или расход. //strH - Заголовок strF - последняя строка //ExitCode ‘P’ Заявка исполнена. Если заявленная сумма ненулевая, принтер печатает служебный чек регистрирующий операцию. ‘F’ Заявка отклонена в случае если: Сумма наличности в кассе меньше суммы заявленного служебного расхода. Открыт фискальный или нефискальный чек. //CashSum Сумма наличности в кассе. Сумма нарастающая после служебного прихода и после каждой оплаты наличными. //ServIn Сумма всех команд “Служебный приход”. //ServOut Сумма всех команд “Служебный расход”. bool FP300KZ::ParishOrConsumption(std::string Oper,std::string Password,double Amount,std::wstring strH,std::wstring strF,std::string& ExitCode,double& CashSum,double& ServIn,double& ServOut) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcParishOrConsumption; /* 46h (70) Служебный приход или расход. Область данных: [,,] Ответ: ExitCode,CashSum,ServIn,ServOut Oper Код оператора. Целое число от 1 до 24. Password Пароль оператора от 4 до 8 знаков Amount Сумма (до 11 значащих цифр). В зависимости от знака интерпретируется как приход или расход. ExitCode ‘P’ - Заявка исполнена. Если заявленная сумма ненулевая, ФР печатает служебный чек регистрирующий операцию. ‘F’ - Заявка отклонена в случае если: • Сумма наличности в кассе меньше суммы заявленного служебного расхода. • Открыт фискальный или нефискальный документ. CashSum Сумма наличности в кассе. Сумма нарастающая после служебного прихода и после каждой оплаты наличными. ServIn Сумма всех команд “Служебный приход”. ServOut Сумма всех команд “Служебный расход”. */ if(PrinterName.find("FP600")!=std::string::npos) { if(Amount!=0) { msg+=Oper+","; //Для Беларусов msg+=Password+","; //Для Беларусов msg+=FloatToStdStr(Amount,2); } }else { if(Amount!=0) { msg+=FloatToStdStr(Amount,2); while(strH.length()>0) { std::wstring str = CutBeforeWFirst(strH,L'\n'); msg+='\t'; msg+='h'; msg.append(ws2s(str),0,48); } while(strF.length()>0) { std::wstring str = CutBeforeWFirst(strF,L'\n'); msg+='\t'; msg+='f'; msg.append(ws2s(str),0,48); } } } msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки if(b) { ExitCode=CutBeforeFirst(str,','); CashSum=fromString(CutBeforeFirst(str,','))/M(); ServIn=fromString(CutBeforeFirst(str,','))/M(); ServOut=fromString(str)/M(); } saveLog(PrinterName+"_"+PrinterNumber,std::string("ParishOrConsumption(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Печать штрих-кода ///Type - Тип штрих кода от 1 до 5 (1-EAN8, 2-EAN13, 3-Code 128, 4-ITF, 5-ITF) bool FP300KZ::PrintBarCode(int Type,std::string Data) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrintBarCode; msg+=IntToStdStr(Type); msg+=','; msg+=Data; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("PrintBarCode(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Звуковой сигнал ///\param Hz Частота звука ///\param mSec Милисекунд bool FP300KZ::Beep(int Hz,int mSec) { if(Hz==0) Hz=294; if(mSec==0) mSec=1000/8; std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcBeep; msg+=IntToStdStr(Hz); msg+=','; msg+=IntToStdStr(mSec); msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("Beep(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Количество логических мест для фискальных записей ///\Logical Количество логических мест для фискальных записей bool FP300KZ::FreeFieldsByFiscalMemory(long& Logical) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFreeFieldsByFiscalMemory; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); if(b) {// Logical=fromString(CutBeforeFirst(str,',')); Logical=fromString(CutBeforeFirst(str,',')); // } b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("FreeFieldsByFiscalMemory(Logical); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Программирование конфигурационных ключей ///Если update=false то команда записывает из ОЗУ во флэш-память графический логотип, высоту печати штрих-кода, плотность печати и длину импульса открывания денежного ящика. После обнуления ОЗУ значения этих параметров восстанавливаются из флэш-памяти. ///\param update Если false то значения конфигуразионных ключей не изменяются, а данные настроек принтера записываются во флэш-память bool FP300KZ::SwitchPrg(bool update) { std::string msg,key=""; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSwitchPrg; if(update) { if(Sw8) key+='1'; else key+='0'; //Срокость if(Sw7) key+='1'; else key+='0'; //Срокость if(Sw6) key+='1'; else key+='0'; //Срокость if(Sw5) key+='1'; else key+='0'; //Не используется if(Sw4) key+='1'; else key+='0'; //Работа дисплея с кодовой таблицей Windows 1251 if(Sw3) key+='1'; else key+='0'; //Режим прозрачного дисплея if(Sw2) key+='1'; else key+='0'; //Не используется if(Sw1) key+='1'; else key+='0'; //запись частичной информации на контрольную ленту(старое: Автоматическая обрезка ленты) msg+=key; } msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("SwitchPrg("+key+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Для сохранение сокращённой информации в ЭКЛ bool FP300KZ::getSmallEJ(bool& val) { //val=Sw1; val=Sw2; return true;//Всегда true потому что значение берётся не здесь. } //--------------------------------------------------------------------------- //Для сохранение сокращённой информации в ЭКЛ bool FP300KZ::setSmallEJ(bool val) { //Sw1=val; Sw2=val; return SwitchPrg(true); //Сохраним переключатели } //--------------------------------------------------------------------------- //Режим прозрачного дисплея bool FP300KZ::getDisplayTransparent(bool& val) { val=Sw3; return true;//Всегда true потому что значение берётся не здесь. } //--------------------------------------------------------------------------- //Режим прозрачного дисплея bool FP300KZ::setDisplayTransparent(bool val) { Sw3=val; return SwitchPrg(true); } //--------------------------------------------------------------------------- ///<Работа дисплея с кодовой таблицей Windows 1251 bool FP300KZ::getDisplayWin1251(bool& val) { val=Sw4; return true;//Всегда true потому что значение берётся не здесь. } //--------------------------------------------------------------------------- ///<Работа дисплея с кодовой таблицей Windows 1251 bool FP300KZ::setDisplayWin1251(bool val) { Sw4=val; return SwitchPrg(true); } //--------------------------------------------------------------------------- //Получить скорость порта из конфига "bps" int FP300KZ::getComSpeed() { int speed=0; if(!Sw6 && !Sw7 && !Sw8) speed=1200; if(!Sw6 && !Sw7 && Sw8) speed=2400; if(!Sw6 && Sw7 && !Sw8) speed=4800; if(!Sw6 && Sw7 && Sw8) speed=9600; if( Sw6 && !Sw7 && !Sw8) speed=19200; if( Sw6 && !Sw7 && Sw8) speed=38400; if( Sw6 && Sw7 && !Sw8) speed=57600; if( Sw6 && Sw7 && Sw8) speed=115200; return speed; } //--------------------------------------------------------------------------- //Установить скорость порта bool FP300KZ::setComSpeed(int Speed) { bool b=false; if(Speed==1200) {Sw6=0; Sw7=0; Sw8=0; b=true;} if(Speed==2400) {Sw6=0; Sw7=0; Sw8=1; b=true;} if(Speed==4800) {Sw6=0; Sw7=1; Sw8=0; b=true;} if(Speed==9600) {Sw6=0; Sw7=1; Sw8=1; b=true;} if(Speed==19200) {Sw6=1; Sw7=0; Sw8=0; b=true;} if(Speed==38400) {Sw6=1; Sw7=0; Sw8=1; b=true;} if(Speed==57600) {Sw6=1; Sw7=1; Sw8=0; b=true;} if(Speed==115200) {Sw6=1; Sw7=1; Sw8=1; b=true;} if(b) b=SwitchPrg(true); //Запишем return b; } //--------------------------------------------------------------------------- ///Команда очищает дисплей. ///Если открыт фискальный чек и Sw3 в положении OFF, очищается только нижняя строка. bool FP300KZ::DisplayClear() { unsigned char msg[5] = {0x01,0x24,0x00,fcDisplayClear,0x05}; std::string answer; bool b=SendPMessage(msg,sizeof(msg),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("DisplayClear(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Вывод текста в нижнюю строку дисплея //Text - До 20 символов текста bool FP300KZ::DispalyLower(std::string Text) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcDispalyLower; msg+=Text; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("DispalyLower(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Вывод текста в верхнюю строку дисплея ///Text - До 20 символов текста bool FP300KZ::DispalyUpper(std::string Text) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcDispalyUpper; msg+=Text; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("DispalyUpper(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Вывод на дисплей свободного текста ///Текст (до 40 символов), который выводится на дисплей. Если необходимо вывести символ ASCII меньше чем 20h (управляющие символы) то они увеличиваются на 40h и предваряются 10h. bool FP300KZ::DispalyFree(std::string Text) { //Text=TransformCode(Text); std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcDispalyFree; msg+=Text; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); saveLog(PrinterName+"_"+PrinterNumber,std::string("DispalyFree(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Чтение запрограммированных налоговых ставок ///\param Decimals Точек после запятой 0,1 или 2 ///\param bA,bB,bC,bD Означает разрешение налоговой группы ///\param TaxA Налоговая ставка А ///\param TaxB Налоговая ставка Б ///\param TaxC Налоговая ставка В ///\param TaxD Налоговая ставка Г bool FP300KZ::GetTaxRates(std::string &Decimals,std::string &Rounding,bool& bA,bool& bB,bool& bC,bool& bD, std::string &TaxA, std::string &TaxB, std::string &TaxC, std::string &TaxD) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetTaxRates; msg+=(char)0x05; std::string str=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),str); if(b) { Decimals=CutBeforeFirst(str,','); m_Dots=fromString(Decimals); //Заполняем глобальную переменную if(PrinterName.find("FP600")!=std::string::npos) { Rounding=CutBeforeFirst(str,','); //Для Беларусов округление } bA=str[0]=='1'; bB=str[1]=='1'; bC=str[2]=='1'; bD=str[3]=='1'; CutBeforeFirst(str,','); TaxA=CutBeforeFirst(str,','); TaxB=CutBeforeFirst(str,','); TaxC=CutBeforeFirst(str,','); TaxD=str; } saveLog(PrinterName+"_"+PrinterNumber,std::string("GetTaxRates(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Установка положения десятичной точки и налоговых ставок ///\param Decimal 0,1 или 2 знака после запятой bool FP300KZ::SetTaxRates(int Decimal,std::string Rounding,std::string TaxA, std::string TaxB, std::string TaxC, std::string TaxD) { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcSetTaxRates; str+=IntToStdStr(Decimal)+","; //0,1,2 знака после запятой str+=Rounding+','; if(TaxA!="") str+='1'; else str+='0'; //Разрешена или нет if(TaxB!="") str+='1'; else str+='0'; //Разрешена или нет if(TaxC!="") str+='1'; else str+='0'; //Разрешена или нет if(TaxD!="") str+='1'; else str+='0'; //Разрешена или нет str+=","; str+=TaxA+','; str+=TaxB+','; str+=TaxC+','; str+=TaxD; msg+=str; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("SetTaxRates("+answer+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Статус фискальной транзакции ///\param Open Открыт фискальный или служебный чек ///\param Items Количество зарегистрированных продаж в текущем или последнем фискальном чеке. ///\param Amount Сумма последнего фискального чека ///\param Tender Сумма оплаты текущего или последнего чека. bool FP300KZ::FiscalTransactionsStatus(bool& Open,int& Items,double& Amount,double& Tender) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFiscalTransactionsStatus; msg+='T'; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); Open=CutBeforeFirst(answer,',')=="1"; Items=fromString(CutBeforeFirst(answer,',')); Amount=fromString(CutBeforeFirst(answer,','))/M(); Tender=fromString(answer)/M(); saveLog(PrinterName+"_"+PrinterNumber,std::string("FiscalTransactionsStatus(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Получить количество секунд с начала открытия смены bool FP300KZ::SessionSec(int& sec) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)93; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); if(b) sec=fromString(answer); if(m_SaveLog) saveLog(PrinterName+"_"+PrinterNumber,std::string("SessionSec(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Диагностическая информация bool FP300KZ::DiagnosticInfo() { unsigned char msg[5] = {0x01,0x20,0x20,fcDiagnosticInfo,0x05}; std::string answer=""; bool b=SendPMessage(msg,sizeof(msg),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { //,,, PrinterName=CutBeforeFirst(answer,','); PrinterVersion=CutBeforeFirst(answer,','); //Версия дата время CutBeforeFirst(answer,','); //Контрольная сумма std::string Sw18 = CutBeforeFirst(answer,',');//Положение конфигурационных переключателей Sw1 до Sw8. Строка 4 байта состоящая из‘0’ и‘1’ Sw8=Sw18[0]=='1'; Sw7=Sw18[1]=='1'; Sw6=Sw18[2]=='1'; Sw5=Sw18[3]=='1'; Sw4=Sw18[4]=='1'; Sw3=Sw18[5]=='1'; Sw2=Sw18[6]=='1'; Sw1=Sw18[7]=='1'; PrinterNumber=answer; //Заводской номер - 12 байт. } saveLog(PrinterName+"_"+PrinterNumber,std::string("DiagnosticInfo(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Работа с электронной контрольной лентой bool FP300KZ::EJ(std::string Cmd) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcEJ; msg+=Cmd; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("EJ("+Cmd+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Печать электронной контрольной ленты с начала (первая строка) нормальным шрифтом. Не Не печатаются служебные чеки, чеки служебного прихода и расхода и Х-отчет. Поле Data пустое. bool FP300KZ::PrintEJ() { return EJ("PL"); } //--------------------------------------------------------------------------- ///Сервисная очистка контрольной ленты bool FP300KZ::ServiceClearEJ() { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcServiceClearEJ; msg+='F'; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); if(b) { if(answer!="P") b=false; //'P' (успешно) или 'F' (грешка) } saveLog(PrinterName+"_"+PrinterNumber,std::string("ServiceClearEJ(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- ///Сервисное обнуление ОЗУ bool FP300KZ::ServiceClearRAM() { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcServiceClearRAM; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("ServiceClearRAM(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Печатается ли графический логотип ///\param Enable Разрешено либо запрещено печатать графический логотип. ///\param Height Высота графического логотипа bool FP300KZ::getPrintLogo(bool& Enable,int& Height) { std::string str; if(PrintSetup("I","L",str)) { Enable = CutBeforeFirst(str,',')=="1"; Height =fromString(str); return true; } return false; } //--------------------------------------------------------------------------- //Печатать ли графический логотип ///\param Enable Разрешено либо запрещено печатать графический логотип. ///\param Height Высота графического логотипа bool FP300KZ::setPrintLogo(bool Enable,int Height) { std::string str=""; if(Enable) str+="1,"; else str+="0,"; str+=IntToStdStr(Height); std::string Answer=""; return PrintSetup("L",str,Answer); } //--------------------------------------------------------------------------- //Программирование графического логотипа 576x96 точеек //RowNum - номер линии //Data - шестадцатеричная строка bool FP300KZ::PrgGraphicLogo(int RowNum, std::string Data) { std::string msg; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrgGraphicLogo; msg+=IntToStdStr(RowNum); msg+=','; msg+=Data; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); saveLog(PrinterName+"_"+PrinterNumber,std::string("PrgGraphicLogo("+IntToStdStr(RowNum)+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Программирование графического логотипа ///\param RowNum - Номер строки ///\param Data - Результат "01010101110" bool FP300KZ::getGraphicLogo(int RowNum, std::string &Data) { std::string msg,res; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcPrgGraphicLogo; msg+='R'+IntToStdStr(RowNum); msg+=(char)0x05; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),res); if(b) { Data=""; for(uint4 i=0;i, bool FP300KZ::Fiscalization(std::string Password,std::string Serial,std::string& ErrCode) { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFiscalization; msg+=Password+","+Serial; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); ErrCode=answer; //Код ошибки m_ErrCode=answer; b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("Fiscalization("+Password+","+Serial+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Перерегистрация //,,, bool FP300KZ::reFiscalization(std::string OldPwd,std::string Password,std::string RNN,std::string RNM,std::string& ErrCode) { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcFiscalization; msg+=Password+","+OldPwd+","+RNN+","+RNM; //Была ошибка в документации (старый и новый пароль поменял местами) msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); ErrCode=answer; m_ErrCode=answer; b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("reFiscalization("+OldPwd+","+Password+","+RNN+","+RNM+"); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Информация о сумме накоплений за день bool FP300KZ::AmountOfSavingsPerDay(double& TaxA,double& TaxB,double& TaxC,double& TaxD,double& TaxE) { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcAmountOfSavingsPerDay; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { TaxA=fromString(CutBeforeFirst(answer,','))/M();//TaxA TaxB=fromString(CutBeforeFirst(answer,','))/M();//TaxB TaxC=fromString(CutBeforeFirst(answer,','))/M();//TaxC TaxD=fromString(CutBeforeFirst(answer,','))/M();//TaxD TaxE=fromString(CutBeforeFirst(answer,','))/M();//TaxE } saveLog(PrinterName+"_"+PrinterNumber,std::string("AmountOfSavingsPerDay(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- bool FP300KZ::DepartmentReport() { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcDepartmentReport; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки saveLog(PrinterName+"_"+PrinterNumber,std::string("DepartmentReport(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- bool FP300KZ::GetLastPrintedDocNumber(int& num) { std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcGetLastPrintedDocNumber; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { num=fromString(answer); }else num=0; saveLog(PrinterName+"_"+PrinterNumber,std::string("GetLastPrintedDocNumber(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //--------------------------------------------------------------------------- //Информация о последней фискальной записи ///\param Clos Номер последней фискальной записи - 4 байта. ///\param Rec Количество фискальных чеков за день - 4 байта. ///\param Total Общая сумма продаж за день - 12 байт со знаком. ///\param VAT Общая сумма налогов за день - 12 байт со знаком. ///\param Date Дата последней фискальной записи - 6 байт /DDMMYY/. bool FP300KZ::LatestFiscalRecord(std::string& Clos,int& Rec, float& Total,float& VAT,std::string& Date) { /* Область данных: Нет данных Ответ: Clos,Rec,Total,VAT,Date Clos Номер последней фискальной записи - 4 байта. Rec Количество фискальных чеков за день - 4 байта. Total Общая сумма продаж за день - 14 байт со знаком. VAT Общая сумма налогов за день - 14 байт со знаком. Date Дата последней фискальной записи - 6 байт /DDMMYY/. Команда передает компьютеру информацию о последней записи в фискальную память. */ std::string msg,str; msg+=(char)0x01; msg+=(char)0x20; msg+=(char)0x20; msg+=(char)fcLatestFiscalRecord; msg+=(char)0x05; std::string answer=""; bool b=SendPMessage((uint1*)msg.c_str(),msg.size(),answer); b=b && !Status->s[0][5]; //Признак ошибки if(b) { Clos=CutBeforeFirst(answer,','); Rec=fromString(CutBeforeFirst(answer,',')); Total=fromString(CutBeforeFirst(answer,',')); VAT=fromString(CutBeforeFirst(answer,',')); Date=answer; } saveLog(PrinterName+"_"+PrinterNumber,std::string("GetLastPrintedDocNumber(); //")+(b ? "OK=" : "ERROR=")+IntToStdStr(ResultCode())+" "+getErrorDesc(ResultCode())); return b; } //---------------------------------------------------------------------------