//--------------------------------------------------------------------------- #pragma hdrstop #include "PrinterOPOS.h" //#include "OposFiscalPrinter_1_7_Lib_OCX.h" //#include "ud_Module.h" //#include #include #include #include //#include //#include #include "inifile.h" #include "stdTools.h" //--------------------------------------------------------------------------- //#pragma package(smart_init) //--------------------------------------------------------------------------- //FiscalPrinter* g_printer; //--------------------------------------------------------------------------- wchar_t * kkm_err_msg_ru[] = { L"OK", //0 L"ФП ID ошибка", //1 FM ID Error L"Ошибка записи в ФП ", //2 FM Rec Error L"Flash Chip не может быть очищен", //3 Flash Chip cant clear L"ФП не пуста", //4 FM not empty L"Данные в ФП разрушенны", //5 FM Data destroyed L"Реж принтер игнорир кмд", //6 Cmd ignor prn mode L"Нет кода оператора", //7 Oper code is absent L"Нет типа документа", //8 Doc type is absent L"Сер. номер ККМ", //9 Ser num CR L"Ошибка пароля", //10 Password error L"Ошибка дата/время", //11 Data/Time error L"Завод. рег. ранее", //12 Factory registration has already pass L"Сер ном ККМ разрушен", //13 Ser num CR destroyed L"Фискализация ранее", //14 Fiscalize has already pass L"ККМ не фиск режим", //15 Not fisc mode CR L"Фискал ККМ разрушен", //16 Fiscalize Data destroyed L"Перерег ККМ исчерпан", //17 Rewrite is conclude L"Перерег ККМ разрушен", //18 Rewrite is destroyed L"Смена открыта", //19 Shift already open L"См не была открыта", //20 Shift not opened L"Много товара в чеке", //21 Many goods in receipt L"СМ в ФП разрушенна", //22 EOD data in FM destroyed L"Формат документа", //23 Document format error L"Перезапись текста", //24 Text rewrite L"Много пар-ров док", //25 Many parameters in document L"Ош параметр док-та", //26 Document parameters error L"Ош значения пар-ра", //27 Parameters value error L"Несуществующ объект", //28 Object non-existent L"Док не был завершен", //29 Document is not finished L"Товар/опер не полно", //30 goods/operation description not enough L"Контрол сумма пакета", //31 Check sum packet L"Принтер не готов", //32 Prn not ready L"Вложенные прерывания", //33 Nested interrupts L"Байт подтв прием данных", //34 Check Sum Error L"Переполненние в ФП", //35 Overflow if FM L"Неизвестная комманда", //36 Unknown command L"CRC ОЗУ", //37 CRC RAM L"CRC ФП", //38 CRC FM L"Порт данных неисправ", //39 Data port defective L"Порядок рекв чека", //40 Receipts parameters sequence L"0xy для обязат рекв", //41 0xy for required properties L"Длинна запроса", //42 Length request L"Разрядность числа", //43 number capacity L"Переполнение", //44 Overflow L"Нет числа", //45 Number is absent L"Нет ответа", //46 Not response L"Ошибка передачи", //47 Transmission error L"Мат. переполнение", //48 Math overflow L"Нет бумаги...", //49 Paper out... L"ККМ не готова!!!", //50 CR not ready!!! L"Сбой памяти!!", //51 Memory error!! L"Принтер выключен", //52 Printer off L"Недостаточно памяти", //53 Insufficient memory L"Длинна номера меньше", //54 Lenght number less L"Нулевая длинна номера", //55 Zero lenght number L"Длинна пароля меньше допустимой", //56 Password lenght less permissible L"Нулевая длинна пароля", //57 Zero lenght password L"Недопустимая величина", //58 Impossible value L"Превышен тайм-аут", //59 Time-out overdraw L"", L"Ош.ЭКЛЗ", L"Недопустимое состояние ЭКЛЗ", L"Данные учтены", L"",L"",L"",L"",L"",L"",//69 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//79 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//89 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//99 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//109 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//119 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//129 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//139 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//149 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//159 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//169 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//179 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//189 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//199 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//209 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//219 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//229 L"",L"",L"",L"",L"",L"",L"",L"",L"",L"",//239 L"Команды нет",//240 Cmd not init L"Ош. посылки команды",//241 Cmd write err L"Команда не отослана ККМ-неготов(DSR=0)",//242 Prn not ready (DSR=0) L"Команда отослана, но ответ что ККМ-неготов",//243 Cmd ok L"Превышено время ожидания ответа",//244 Cmd resp timeout L"Ошибка",//245 Prn error L"Пришло больше данных, чем ожидали",//246 Cmd resp large L"Пришло меньше данных, чем ожидали",//247 Cmd resp small L"Пришли некие данные",//248 L"Порт закрыт",//249 L"Порт закрыт во время выполнения",//250 Cmd break L"ККМ выключен или сломан",//251 L"ККМ неготов",//252 L"Ошибка в параметрах команды",//253 L"Несуществующий номер команды",//254 L"ККМ занят(предыдущая команда)!"//255 Previous cmd run }; //------------------------------------------------------------------------------ bool FiscalPrinter::getNextCheckId(int &id) { CheckId++; //Номер чека SaveSetup(); //сохраняем номер чека id=CheckId; return true; } //--------------------------------------------------------------------------- bool FiscalPrinter::SaveCheck(int CheckId) //Сохранение чека для последующей распечатки (суммы) { /*if(dModule->UserType) //true - Юредическое лицо; false - физическое лицо dModule->SaveCheck(CheckId,dModule->UserId,0,getGoodsPrice()); else dModule->SaveCheck(CheckId,0,dModule->UserId,getGoodsPrice());*/ return true; } //--------------------------------------------------------------------------- bool FiscalPrinter::deleteCheck(int CheckId) //Удаление чека { //dModule->UpdateChek(CheckId); return true; } //--------------------------------------------------------------------------- int FiscalPrinter::getCOMPort() { HKEY keyHandle; char rgValue[1024]; char fnlRes[1024]; DWORD size1; DWORD Type; std::string str = "-1"; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"\\SOFTWARE\\OLEforRetail\\ServiceOPOS\\FiscalPrinter\\MbsFiscalPrinter", 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) { size1 = 1023; RegQueryValueEx(keyHandle, L"COM Num", NULL, &Type, (LPBYTE)rgValue, &size1); str = rgValue; RegCloseKey(keyHandle); } return Utility::StdStrToInt(str); } //--------------------------------------------------------------------------- bool FiscalPrinter::setBaudRate(std::wstring data) { HKEY keyHandle; bool result; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\OLEforRetail\\ServiceOPOS\\FiscalPrinter\\MbsFiscalPrinter", 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) { LONG nError = RegSetValueEx(keyHandle, L"COM Speed", NULL, REG_DWORD, (LPBYTE)data.c_str(), sizeof(DWORD)); RegCloseKey(keyHandle); result = true; } else result = false; return result; } //--------------------------------------------------------------------------- int FiscalPrinter::getBaudRate() { HKEY keyHandle; char rgValue[1024]; char fnlRes[1024]; DWORD size1; DWORD Type; std::string str = "-1"; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\OLEforRetail\\ServiceOPOS\\FiscalPrinter\\MbsFiscalPrinter", 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) { size1 = 1023; RegQueryValueEx(keyHandle, L"COM Speed", NULL, &Type, (LPBYTE)rgValue, &size1); str = rgValue; RegCloseKey(keyHandle); } return Utility::StdStrToInt(str); } //--------------------------------------------------------------------------- bool PrinterOPOS::setCOMPort(std::wstring data) { HKEY keyHandle; bool result; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\OLEforRetail\\ServiceOPOS\\FiscalPrinter\\MbsFiscalPrinter", 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) { LONG nError = RegSetValueEx(keyHandle, L"COM Num", NULL, REG_DWORD, (LPBYTE)data.c_str(), sizeof(DWORD)); RegCloseKey(keyHandle); result = true; } else result = false; return result; } //--------------------------------------------------------------------------- void FiscalPrinter::LoadSetup() { TIniFile* ini = new TIniFile(); ini->Load("settings.ini"); //TIniFile* ini=new TIniFile(ExtractFilePath(ParamStr(0))+"\\Setup.ini"); // cPort->port=ini->ReadString("Printer","Port",""); // cPort->BaudRate=ini->ReadInteger("Printer","BaudRate",0); CheckId=ini->ReadLong("Printer","CheckCount","0"); TestMode=ini->ReadBool("Printer","TestMode","1"); HeadLine=ini->ReadString(L"Printer",L"HeadLine",L""); GoodsName=ini->ReadString(L"Printer",L"GoodsName",L""); CasireName=ini->ReadString(L"Printer",L"CasireName",L""); AutoOpenShift=ini->ReadBool("Printer","AutoOpenShift","0"); delete ini; } //--------------------------------------------------------------------------- void FiscalPrinter::SaveSetup() { TIniFile* ini = new TIniFile(); ini->Load("settings.ini"); // ini->WriteString("Printer","Port",cPort->port); //Зачем коментил раньше: // ini->WriteInteger("Printer","BaudRate",cPort->BaudRate); //Зачем коментил раньше: ini->WriteLong("Printer","CheckCount",CheckId); ini->WriteBool("Printer","TestMode",TestMode); ini->WriteString(L"Printer",L"GoodsName",GoodsName); ini->WriteString(L"Printer",L"CasireName",CasireName); ini->WriteBool("Printer","AutoOpenShift",AutoOpenShift); delete ini; } //--------------------------------------------------------------------------- int FiscalPrinter::getGoodsPrice() { int sum=0; for(int i=0;icount();i++) sum+=((Goods*)FListGoods->get(i))->price; return sum; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- PrinterOPOS::PrinterOPOS():FiscalPrinter() { Crashed=false; AutoOpenShift=false; //fp=new TOPOSFiscalPrinter(AOwner); fp.CreateInstance(L"OposFiscalPrinter_1_7.OPOSFiscalPrinter"); fp->DeviceEnabled = 0; /// 0 == FALSE, -1 == TRUE LoadSetup(); } //--------------------------------------------------------------------------- PrinterOPOS::~PrinterOPOS() { delete FListGoods; delete fp; } //--------------------------------------------------------------------------- //Соедениться по COM порту и проинициализировать принтер bool PrinterOPOS::Start() { if(fp->DeviceEnabled) return true; FState = fp->Open(L"MbsFiscalPrinter"); if(FState!=0) { Utility::logrotateW(m_LogFileWPath + std::wstring(L"\\log.txt"), Utility::IntToStdWStr(FState)+std::wstring(L"(PrinterOPOS::Start)")+GetStatusDescription(FState)); return false; } FState = fp->ClaimDevice(1000); if(FState!=0) { Utility::logrotateW(m_LogFileWPath + std::wstring(L"\\log.txt"), Utility::IntToStdWStr(FState)+ std::wstring(L"(PrinterOPOS::Start)")+GetStatusDescription(FState)); return false; } fp->DeviceEnabled = -1; // 0 == FALSE, -1 == TRUE return true; } //--------------------------------------------------------------------------- void PrinterOPOS::setHeader(TSimpleList2* Text) { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); for(int i=0;icount();i++) { std::wstring str=Text->get(i); err=fp->SetHeaderLine(i+1,str.c_str(),VARIANT_FALSE); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } err=fp->ResetPrinter(); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setHeader)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::setHeader)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setHeader) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::setHeader) Нет описания ошибки")); } } //--------------------------------------------------------------------------- void PrinterOPOS::getHeader(TSimpleList2* Text) { TIniFile* ini=new TIniFile(); ini->Load("settings.ini"); Text->add(ini->ReadString(L"Printer",L"HeadLine1",L"")); Text->add(ini->ReadString(L"Printer",L"HeadLine2",L"")); Text->add(ini->ReadString(L"Printer",L"HeadLine3",L"")); Text->add(ini->ReadString(L"Printer",L"HeadLine4",L"")); Text->add(ini->ReadString(L"Printer",L"HeadLine5",L"")); delete ini; //Удаляю первые пустые строки если они есть for(int i=Text->count()-1;i>=0;i--) if(Text->get(i)==L"") Text->del(i); else break; } //--------------------------------------------------------------------------- void PrinterOPOS::setTrailer(TSimpleList2* Text) { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); for(int i=0;icount();i++) { std::wstring str=Text->get(i); err=fp->SetTrailerLine(i+1,str.c_str(),false); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } err=fp->ResetPrinter(); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setTrailer)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::setTrailer)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setTrailer) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::setTrailer) Нет описания ошибки")); } } //--------------------------------------------------------------------------- void PrinterOPOS::getTrailer(TSimpleList2* Text) { TIniFile* ini=new TIniFile(); ini->Load("settings.ini"); Text->add(ini->ReadString(L"Printer",L"TailLine1",L"")); Text->add(ini->ReadString(L"Printer",L"TailLine2",L"")); Text->add(ini->ReadString(L"Printer",L"TailLine3",L"")); Text->add(ini->ReadString(L"Printer",L"TailLine4",L"")); Text->add(ini->ReadString(L"Printer",L"TailLine5",L"")); delete ini; for(int i=Text->count()-1;i>=0;i--) if(Text->get(i)==L"") Text->del(i); else break; } //--------------------------------------------------------------------------- bool PrinterOPOS::PrintLine(std::wstring line) { //Не фискальная печать long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); std::wstring str = L""; str += WCHAR(0x1B); str += WCHAR(0x7C); str += line; str += L"\n"; BSTR bstr = SysAllocString(str.c_str()); err = fp->PrintNormal(2, bstr); SysFreeString(bstr); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintLine)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::PrintLine)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintLine) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::PrintLine) Нет описания ошибки")); } return err==0; } //--------------------------------------------------------------------------- //sales - true продажа, false - возврат //check - номер чека если не задан =0 то генериться //TODO Фича это фиксировать не распечатанные чеки потом печатать их bool PrinterOPOS::PrintCheck(bool sales, int check, std::wstring headLine) //Тестовая печать { long err=0; double cur=0; double cAllPrice=0; bool bOk=true; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); //Считаем сумму в чеке (заранее на случай ошибки) cAllPrice=getGoodsPrice(); if(check==0) //если не задан номер чека то генерим сдесь { CheckId++; //Номер чека check=CheckId; SaveSetup(); //сохраняем номер чека } if(fp->RecEmpty) throw std::runtime_error("Нет бумаги!"); if(!DayOpened()) throw std::runtime_error("Смена не открыта"); double UnitPrice,AllPriceDrb,AllPrice; long Qnt,vat; BSTR* bstr; std::wstring sStr; BSTR sTmp=new OLECHAR[255]; sTmp=L""; long MbsResponceCode; CURRENCY Amount1,Amount2; //Установка номера отдела //vat=11; sTmp=L"отдел"; //err = fp->DirectIO(4, &vat, &sTmp); //if (err) goto ErrHandler; //Желателььно сделать в нутри чека TODO!!! if(headLine.size()>0) PrintLine(headLine); if(sales) fp->FiscalReceiptType = FPTR_RT_SALES; //Чек продажи else fp->FiscalReceiptType=FPTR_RT_SERVICE; //Чек возврата //setTrainingMode(true); //Фискальная печать (с заголовком или без) err = fp->BeginFiscalReceipt(true); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); //251 } //Товары из списка в драйвер (TODO При печати чека не печатается услуга) for(int i=0;icount();i++) { Goods* goods=(Goods*)FListGoods->get(i); VarCyFromR8(goods->price*100,&Amount1); Amount2.int64=0; std::wstring tmp=goods->name1+L"-/--/-0"; err=fp->PrintRecItem(tmp.c_str(), Amount1, goods->count, goods->VatInfo, Amount2, L"Шт"); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } ClearGoods(); //установка номера чека (Перед PrintRecTotal) err = fp->DirectIO(3, &CheckId, &sTmp); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //Установка значений массива налоговых ставок //setNalog(1,12); //Формирования итога в чеке Amount2.int64=0; VarCyFromR8(cAllPrice*100,&Amount1); err=fp->PrintRecTotal(Amount1, Amount1, L"na"); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } err = fp->EndFiscalReceipt(VARIANT_TRUE); //Окончания печати, в нем происходит печать дополнительного трейлера (AdditionalTrailer) и обрезка бумаги if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } catch(std::exception &exception) { ClearGoods(); if(err==251) Crashed=true; //Кабздец //Utility::logrotate(m_LogFilePath + "\\log.txt", "Ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+CurrToStr(cAllPrice)+" Чек: "+ std::string(CheckId)+". "+exception); //dModule->SendError(err,"Ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+IntToStr(cAllPrice)+" Чек: "+ std::string(CheckId)+". "+exception); bOk=false; } catch(...) { ClearGoods(); if(err==251) Crashed=true; //Кабздец //Utility::logrotate(m_LogFilePath + "\\log.txt", "Не опознанная ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+IntToStr(cAllPrice)+" Чек: "+ std::string(CheckId)); //dModule->SendError(1,"Не опознанная ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+IntToStr(cAllPrice)+" Чек: "+ std::string(CheckId)); bOk=false; } //сброс чека if(!bOk) { fp->PrintRecVoid(L""); } return bOk; } //--------------------------------------------------------------------------- bool PrinterOPOS::Cut() //Отрезать бумагу { long err=0; try { if (Crashed) { throw std::runtime_error("Драйвер принтера разрушен!"); } std::wstring wstr = L""; wstr += WCHAR(0x1B); wstr += WCHAR(0x7C); wstr += L"75P"; err=fp->PrintNormal(2, wstr.c_str()); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::Cut)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::Cut)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::Cut) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::Cut) Нет описания ошибки")); } } //--------------------------------------------------------------------------- //Получить текущее состояние принтера (чтоб проверить готовность печати) /*int PrinterOPOS::GetState() { if(!fp->DeviceEnabled)FState=245; //if(FState!=0) return FState; //проверяем //Надо добавить лог // fp->ResultCodeExtended return 0; } */ //--------------------------------------------------------------------------- //Проверка роботоспособности принтера bool PrinterOPOS::isOk() { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); if(fp->RecEmpty) throw "Нет бумаги!"; err=fp->ResetPrinter(); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); //Очищает очередь с событиями } std::wstring str; //if(!dModule->getDayShift())throw std::runtime_error("Смена в базе не открыта!"); //Проверяем в базе открыта ли смен bool dOpen=DayOpened(); if(!dOpen && AutoOpenShift && OpenShift()) dOpen=true; if(!dOpen) throw std::runtime_error("Смена не открыта!"); if(DayOpened()) { //Проверка на длину смены std::wstring dt=getDateOpenShift(); str=getLastError(&err); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //dModule->getDate(); //if(HoursBetween(dt,dModule->date)>24) //Разница не более 24 часов // throw std::runtime_error("[1]Смена не закрыта"); } else throw std::runtime_error("Принтер не работает!"); BSTR bstr=new OLECHAR[50]; err=fp->GetDate(&bstr); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::isOk)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::isOk)")+exception); return false; } catch (...) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::isOk)Неопознанная ошибка")); //dModule->SendError(1,std::string("(PrinterOPOS::isOk)Неопознанная ошибка")); return false; } return true; } //--------------------------------------------------------------------------- //Получить дату открытия смены std::wstring PrinterOPOS::getDateOpenShift() { long err=0; std::wstring date=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); long iTmp; BSTR sTmp=new OLECHAR[50]; err=fp->DirectIO(13, &iTmp, &sTmp); //ММ/ДД/ГГ ЧЧ:ММ:СС if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } date=sTmp; }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getDateOpenShift)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::getDateOpenShift)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getDateOpenShift) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::getDateOpenShift) Нет описания ошибки")); } return date; } //--------------------------------------------------------------------------- //Описание статуса std::wstring PrinterOPOS::GetStatusDescription(long err) { std::wstring str; try { if(err<256) str=kkm_err_msg_ru[err]; if(str==L"") str=L"Нет описания ошибки"; }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::GetStatusDescription) Нет описания ошибки")); return L"Нет описания ошибки"; } return str; } //--------------------------------------------------------------------------- //Получить код последней ошибки std::wstring PrinterOPOS::getLastError(long* err) { BSTR str=new OLECHAR[255]; str=L"Нет описания ошибки!"; try { fp->DirectIO(1, err, &str); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getLastError) Нет описания ошибки")); } if(str==L"") return GetStatusDescription(*err); return std::wstring(str); } //--------------------------------------------------------------------------- std::wstring PrinterOPOS::getLastError() { long err; return getLastError(&err); } //--------------------------------------------------------------------------- //Печать отчёта и закрытие смены bool PrinterOPOS::PrintZReport() { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); int sum=getDaySum(); err=fp->PrintZReport(); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //dModule->addZReport(sum);//Послать на сервер время снятия Z отчёта //dModule->addPaper(-142*2);//Для подсчёта конца бумаги }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintZReport)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::PrintZReport)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintZReport) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::PrintZReport) Нет описания ошибки")); } return err==0; } //--------------------------------------------------------------------------- //Печать суточного отчёта без закрытия смены void PrinterOPOS::PrintXReport() { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); err=fp->PrintXReport(); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintXReport)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::PrintXReport)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::PrintXReport) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::PrintXReport) Нет описания ошибки")); } } //--------------------------------------------------------------------------- //Открытие смены bool PrinterOPOS::OpenShift() { long err; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); long n=1; //if(CasireName==NULL) CasireName=L" "; BSTR str= SysAllocString(CasireName.c_str()); err=fp->DirectIO (6,&n,&str); SysFreeString(str); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); //Передал номер и название кассира } err=fp->SetVatValue(1,L"120"); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::OpenShift)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::OpenShift)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::OpenShift) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::OpenShift) Нет описания ошибки")); } return err==0; } //--------------------------------------------------------------------------- bool PrinterOPOS::DayOpened() { return fp->DayOpened; } //--------------------------------------------------------------------------- bool PrinterOPOS::setTrainingMode(bool val) { long err; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); if(getTrainingMode()==val) return true; if(val) err=fp->BeginTraining(); else err=fp->EndTraining(); if (err) { throw std::runtime_error(Utility::WStringToString(getLastError(&err), std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setTrainingMode)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::setTrainingMode)")+exception); }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setTrainingMode) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::setTrainingMode) Нет описания ошибки")); } return err==0; } //--------------------------------------------------------------------------- bool PrinterOPOS::getTrainingMode() { return fp->TrainingModeActive; } //--------------------------------------------------------------------------- //Заполнение массива с суммами по налоговым ставкам bool PrinterOPOS::setNalog(long n,float stavka) { long err; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); long s=stavka*10; std::wstring str= Utility::IntToStdWStr(s); BSTR bstr = SysAllocString(str.c_str()); err = fp->DirectIO(2, &n, &bstr); SysFreeString(bstr); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setNalog)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::setNalog)")+exception); return true; }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::setNalog) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::setNalog) Нет описания ошибки")); return true; } return err==0; } //--------------------------------------------------------------------------- //Дневной итог int PrinterOPOS::getDaySum() { long err; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); long n=1; BSTR str=new OLECHAR[20]; err=fp->DirectIO (300,&n,&str); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } return Utility::StdWStrToInt(str)/100.0; }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getDaySum)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::getDaySum)")+exception); return 0; }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getDaySum) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::getDaySum) Нет описания ошибки")); return 0; } } //--------------------------------------------------------------------------- //Сумма в кассе int PrinterOPOS::getAllSum() { long err=0; try { if(Crashed) throw std::runtime_error("Драйвер принтера разрушен!"); long n=2; BSTR str=new OLECHAR[20]; err=fp->DirectIO (300,&n,&str); if (err) { std::wstring estr = getLastError(&err); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } std::wstring wstr = str; return Utility::StdWStrToInt(wstr)/100.0; }catch(std::exception &exception) { if(err==251) Crashed=true; //Кабздец Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getAllSum)")+exception.what()); //dModule->SendError(err,std::string("(PrinterOPOS::getAllSum)")+exception); return 0; }catch(...) { Utility::logrotate(m_LogFilePath + "\\log.txt", std::string("(PrinterOPOS::getAllSum) Нет описания ошибки")); //dModule->SendError(1,std::string("(PrinterOPOS::getAllSum) Нет описания ошибки")); return 0; } } //--------------------------------------------------------------------------- //sales - true продажа, false - возврат //check - номер чека если не задан =0 то генериться //Фича: фиксировать не распечатанные чеки потом печатать их bool FiscalPrinterPort::PrintCheck(bool sales, int check, std::wstring headLine ) { //bool err=0; double cur=0; double cAllPrice=0; bool bOk=true; try { //Считаем сумму в чеке (заранее на случай ошибки) cAllPrice=getGoodsPrice(); double UnitPrice,AllPriceDrb,AllPrice; long Qnt,vat; BSTR* bstr; std::wstring sStr; BSTR sTmp=new OLECHAR[255]; sTmp=L""; long MbsResponceCode; double Amount1,Amount2; //Фискальный чек продажи или возврата if(sales) bOk = fp->OpenFiscalInv(1,"0000",1).ErrorCode==0; else bOk = fp->OpenBackInv(1,"0000",1).ErrorCode==0; if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } if(headLine.size()>0) PrintLine(headLine); //Товары из списка в драйвер for(int i=0;icount();i++) { Goods* goods=(Goods*)FListGoods->get(i); bOk=fp->RegisterSale(goods->name1.c_str(),goods->name2.c_str(),0,"А",goods->price,goods->count,0,0).ErrorCode==0; //Регистрация продажи (либо возврата) if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } ClearGoods(); //Формирования итога в чеке (оплата) double Change; bOk=fp->Total("","","P",cAllPrice,Change).ErrorCode==0; if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //Закрываем чек bOk = fp->CloseFiscalInv().ErrorCode==0; if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } } catch(std::exception &exception) { ClearGoods(); //Utility::logrotate(m_LogFilePath + "\\log.txt", "Ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+CurrToStr(cAllPrice)+" Чек: "+ std::string(CheckId)+". "+exception); //dModule->SendError(bOk,"Ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+FloatToStr(cAllPrice)+" Чек: "+ std::string(CheckId)+". "+exception); bOk=false; } catch(...) { ClearGoods(); //Utility::logrotate(m_LogFilePath + "\\log.txt", "Не опознанная ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+FloatToStr(cAllPrice)+" Чек: "+ std::string(CheckId)); //dModule->SendError(1,"Не опознанная ошибка при печати чека: N: "+IntToStr(dModule->UserId)+" сумма: "+FloatToStr(cAllPrice)+" Чек: "+ std::string(CheckId)); bOk=false; } //сброс чека if(!bOk) { fp->CancelFiscalInv(); } return bOk; } //--------------------------------------------------------------------------- bool FiscalPrinterPort::PrintZReport() { bool bOk; try { double Amount=0,CashSum=0,ServIn=0,ServOut=0; std::string Oper,Password,ExitCode=""; std::wstring strH,strF; bOk=fp->ParishOrConsumption(Oper,Password,Amount,strH,strF,ExitCode,CashSum,ServIn,ServOut).ErrorCode==0; if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } bOk=fp->PrintZReport().ErrorCode==0; if (!bOk) { std::wstring estr = getLastError(); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //dModule->addZReport(CashSum);//Послать на сервер время снятия Z отчёта } catch(std::exception &exception) { ClearGoods(); Utility::logrotate(m_LogFilePath + std::string("\\log.txt"), std::string("Ошибка при печати Z отчёта ")+exception.what()); //dModule->SendError(bOk,"Ошибка при печати Z отчёта "+exception); bOk=false; } catch(...) { ClearGoods(); Utility::logrotate(m_LogFilePath + std::string("\\log.txt"), std::string("Не опознанная ошибка при печати Z отчёта.")); //dModule->SendError(1,"Не опознанная ошибка при печати Z отчёта."); bOk=false; } return bOk; }; //--------------------------------------------------------------------------- bool FiscalPrinterPort::isOk() { try { MyError err = fp->DiagnosticInfo(); if (err.ErrorCode!=0) { std::wstring estr = Utility::convUTF8ToUTF16(err.ErrorMessage); throw std::runtime_error(Utility::WStringToString(estr, std::locale(""))); } //if(!dModule->getDayShift())throw std::runtime_error("Смена в базе не открыта!"); //Проверяем в базе открыта ли смен } catch(std::exception &exception) { Utility::logrotate(m_LogFilePath + std::string("\\log.txt"), std::string("(PrinterOPOS::isOk)")+exception.what()); //dModule->SendError(1,std::string("(PrinterOPOS::isOk)")+exception); return false; } catch (...) { Utility::logrotate(m_LogFilePath + std::string("\\log.txt"), std::string("(PrinterOPOS::isOk)Неопознанная ошибка")); //dModule->SendError(1,std::string("(PrinterOPOS::isOk)Неопознанная ошибка")); return false; } return true; }; //---------------------------------------------------------------------------