diff --git a/src/ATBAPP/ATBDeviceControllerPlugin.cpp b/src/ATBAPP/ATBDeviceControllerPlugin.cpp index 3a843d3..308dcec 100644 --- a/src/ATBAPP/ATBDeviceControllerPlugin.cpp +++ b/src/ATBAPP/ATBDeviceControllerPlugin.cpp @@ -45,6 +45,7 @@ PLUGIN_STATE ATBDeviceControllerPlugin::initDCPlugin(QObject *eventReceiver, con QString printerLocaleString = settings.value("ATBDeviceControllerPlugin/printerLocale", "de_DE").toString().toLatin1(); this->printerLocale = QLocale(printerLocaleString); + this->initTicketTemplateList(&settings); this->init_sc_dbus(); @@ -140,6 +141,58 @@ PLUGIN_STATE ATBDeviceControllerPlugin::initDCPlugin(QObject *eventReceiver, con } +void ATBDeviceControllerPlugin::initTicketTemplateList(const QSettings * settings) +{ + QList templateList; + QString templateListString; + + + QMetaEnum metaTicketVariants = QMetaEnum::fromType(); + for (int i = 0; i < metaTicketVariants.keyCount(); i++) { + const char* ticketVariant_char = metaTicketVariants.key(i); + quint8 intValue = metaTicketVariants.value(i); + + // DEBUG + //qCritical() << " processing TICKET_VARIANT::" << ticketVariant_char; + + QString configKey = QString("TICKET_TEMPLATES/") + ticketVariant_char; + QVariant raw_templateList = settings->value(configKey, ""); + if (raw_templateList.type() == QVariant::StringList) { + templateListString = raw_templateList.toStringList().join(","); + } else { + templateListString = raw_templateList.toString(); + } + + // DEBUG + //qCritical() << " configKey: " << configKey; + //qCritical() << " templateListString: " << templateListString; + + QStringList templateListStringList = templateListString.split(",", QString::SplitBehavior::SkipEmptyParts); + + quint8 templateEntry; + bool ok; + for (const auto & ListEntry : templateListStringList) { + templateEntry = ListEntry.toInt(&ok); + if (ok) { + templateList.append(templateEntry); + } + } + + // DEBUG + /* + QStringList elements; + for (const auto &item : templateList) { + elements << QString::number(item); + } + qCritical() << " template list: " << elements.join(','); + */ + + this->ticketTemplateList.insert(static_cast(intValue), templateList); + templateList.clear(); + } +} + + void ATBDeviceControllerPlugin::sendDeviceParameter(const QJsonObject &jsonObject) { @@ -678,17 +731,32 @@ void ATBDeviceControllerPlugin::onNewVoltage(uint32_t voltage) */ void ATBDeviceControllerPlugin::requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash & printingData) { - QList templateList; - - // TODO: read template list from .ini + QList templateList = this->ticketTemplateList[ticketVariant]; + if (templateList.isEmpty()) { + qCritical() << "ATBDeviceControllerPlugin::requestPrintTicket()"; + qCritical() << " TICKET_VARIANT: " << ticketVariant; + qCritical() << " -> templateList is empty!"; + qCritical() << " -> switching to legacy interface"; + this->requestPrintTicket(printingData); + return; + } // DEBUG qCritical() << "------------------------------------------------------------------------"; qCritical() << "ATBDeviceControllerPlugin::requestPrintTicket()"; qCritical() << " TICKET_VARIANT: " << ticketVariant; + if (ticketVariant == nsDeviceControllerInterface::TICKET_VARIANT::FOOD_STAMP) { qCritical() << " dyn1_list: " << printingData["dyn1_list"].toStringList(); qCritical() << " dyn2_list: " << printingData["dyn2_list"].toStringList(); + } + QStringList listElements; + for (const auto &item : templateList) { + listElements << QString::number(item); + } + qCritical() << " template list: " << listElements.join(','); + + qCritical() << "------------------------------------------------------------------------"; @@ -1110,10 +1178,13 @@ void ATBDeviceControllerPlugin::prepareDynTemplateData() private_setupDynTemplatData_FINE_PAYMENT(dynTicketData, this->currentTicket); break; case nsDeviceControllerInterface::TICKET_VARIANT::RECEIPT: + private_setupDynTemplateData_DEFAULT(dynTicketData, this->currentTicket); break; case nsDeviceControllerInterface::TICKET_VARIANT::ERROR_RECEIPT: + private_setupDynTemplateData_DEFAULT(dynTicketData, this->currentTicket); break; case nsDeviceControllerInterface::TICKET_VARIANT::PARKING_TICKET: + private_setupDynTemplateData_DEFAULT(dynTicketData, this->currentTicket); break; case nsDeviceControllerInterface::TICKET_VARIANT::FREE_TICKET: private_setupDynTemplatData_FREE_TICKET(dynTicketData, this->currentTicket); @@ -1121,6 +1192,9 @@ void ATBDeviceControllerPlugin::prepareDynTemplateData() case nsDeviceControllerInterface::TICKET_VARIANT::FOOD_STAMP: private_setupDynTemplatData_FOOD_STAMP(dynTicketData, this->currentTicket); break; + default: + private_setupDynTemplateData_DEFAULT(dynTicketData, this->currentTicket); + break; } // C-Programmierung: wird hier nur 'licensePlate' gedruckt? @@ -1276,6 +1350,41 @@ void ATBDeviceControllerPlugin::private_setupDynTemplatData_FREE_TICKET(struct T // ! and yes... 'ParkingEndDate' is 'currentTime' } +void ATBDeviceControllerPlugin::private_setupDynTemplateData_DEFAULT(struct T_dynDat *dynTicketData, Ticket *ticket) +{ + QDateTime parkingEndDateTime = QDateTime::fromString(ticket->getPrintingData()["parkingEnd"].toString(), Qt::ISODate); + QDateTime currentDateTime = QDateTime::fromString(ticket->getPrintingData()["currentDateTime"].toString(), Qt::ISODate); + + QString parkingEndDateString = TicketUtils::getLocaleDateString(this->printerLocale, parkingEndDateTime.date()); + QString currentDateString = TicketUtils::getLocaleDateString(this->printerLocale, currentDateTime.date()); + + + // set dynamic printer data: + QByteArray ba_licenseplate = codec->fromUnicode(ticket->getPrintingData()["licenseplate"].toString()); + memcpy((char*)dynTicketData->licensePlate, ba_licenseplate.data(), std::min(ba_licenseplate.size(),8)); + + QByteArray ba_amount = codec->fromUnicode(ticket->getPrintingData()["amount"].toString()); + memcpy((char*)dynTicketData->vendingPrice, ba_amount.data(), std::min(ba_amount.size(),8)); // Szeged + memcpy((char*)dynTicketData->dynDat6, ba_amount.data(), std::min(ba_amount.size(),8)); // Schoenau + + QByteArray ba_parkingEndTime = codec->fromUnicode(parkingEndDateTime.toString("hh:mm")); + memcpy((char*)dynTicketData->parkingEnd, ba_parkingEndTime.data(), std::min(ba_parkingEndTime.size(),8)); + + QByteArray ba_parkingEndDate = codec->fromUnicode(parkingEndDateString); + memcpy((char*)dynTicketData->currentTime, ba_parkingEndDate.data(), std::min(ba_parkingEndDate.size(),8)); + // ! and yes... 'ParkingEndDate' is 'currentTime' + + QByteArray ba_currentDate = codec->fromUnicode(currentDateString); + memcpy((char*)dynTicketData->currentDate, ba_currentDate.data(), std::min(ba_currentDate.size(),8)); + + // Product-Text + QByteArray ba_productText = codec->fromUnicode(ticket->getPrintingData()["productText"].toString()); + memcpy((char*)dynTicketData->dynDat5, ba_productText.data(), std::min(ba_productText.size(),8)); + + // Ticket-Number + QByteArray ba_ticketNumber = codec->fromUnicode(ticket->getPrintingData()["ticketNumber"].toString()); + memcpy((char*)dynTicketData->dynDat7, ba_ticketNumber.data(), std::min(ba_ticketNumber.size(),8)); +} /************************************************************************************************ * cash payment diff --git a/src/ATBAPP/ATBDeviceControllerPlugin.h b/src/ATBAPP/ATBDeviceControllerPlugin.h index 53f562b..e8378aa 100644 --- a/src/ATBAPP/ATBDeviceControllerPlugin.h +++ b/src/ATBAPP/ATBDeviceControllerPlugin.h @@ -140,8 +140,12 @@ private: Ticket * currentTicket; QLocale printerLocale; + QHash> ticketTemplateList; + + void initTicketTemplateList(const QSettings * settings); void prepareDynTemplateData(); + void private_setupDynTemplateData_DEFAULT(struct T_dynDat *dynTicketData, Ticket *ticket); void private_setupDynTemplateData_START_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket); void private_setupDynTemplatData_STOP_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket); void private_setupDynTemplatData_FOOD_STAMP(struct T_dynDat *dynTicketData, Ticket *ticket); diff --git a/src/ATBAPP/DeviceControllerInterface.h b/src/ATBAPP/DeviceControllerInterface.h index 8ad9581..7217a9f 100644 --- a/src/ATBAPP/DeviceControllerInterface.h +++ b/src/ATBAPP/DeviceControllerInterface.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "ATBAPPplugin.h" @@ -212,10 +213,11 @@ signals: Q_DECLARE_INTERFACE(DeviceControllerInterface, - "eu.atb.ptu.plugin.DeviceControllerInterface/1.2.0") + "eu.atb.ptu.plugin.DeviceControllerInterface/1.2.1") namespace nsDeviceControllerInterface { + Q_NAMESPACE enum class PLUGIN_STATE : quint8 { NOT_INITIALIZED = 0, @@ -240,15 +242,43 @@ namespace nsDeviceControllerInterface { enum class TICKET_VARIANT : quint8 { + INVALID, + NO_TICKET, PARKING_TICKET, + PARKING_TICKET_CAR, + PARKING_TICKET_VAN, + PARKING_TICKET_CAMPER, + DAY_TICKET, + DAY_TICKET_ADULT, + DAY_TICKET_TEEN, + DAY_TICKET_CHILD, + DAY_TICKET_CAR, + DAY_TICKET_VAN, + DAY_TICKET_CAMPER, RECEIPT, ERROR_RECEIPT, START_RECEIPT, // e.g. Szeged Start STOP_RECEIPT, // e.g. Szeged Stop FINE_PAYMENT, // e.g. Klaipeda FOOD_STAMP, + FIXED_PRICE_1, + FIXED_PRICE_2, + FIXED_PRICE_3, + FIXED_PRICE_4, + FIXED_PRICE_5, + FIXED_PRICE_6, + FIXED_PRICE_7, + FIXED_PRICE_8, + FIXED_PRICE_9, + FIXED_PRICE_10, FREE_TICKET }; + Q_ENUM_NS(TICKET_VARIANT) + + inline uint qHash(const nsDeviceControllerInterface::TICKET_VARIANT &key, uint seed = 0) + { + return ::qHash(static_cast(key), seed); + } enum class COIN_PROCESSOR : quint8 { CHANGER, @@ -270,4 +300,6 @@ namespace nsDeviceControllerInterface { }; } + + #endif // DEVICECONTROLLERINTERFACE_H diff --git a/src/ATBAPP/support/Ticket.cpp b/src/ATBAPP/support/Ticket.cpp index fdab619..8dff45e 100644 --- a/src/ATBAPP/support/Ticket.cpp +++ b/src/ATBAPP/support/Ticket.cpp @@ -50,25 +50,42 @@ bool Ticket::initNew(TICKET_VARIANT ticketVariant, const QList & templat qCritical() << " -> " << ticketVariant; int multiplicatorInt = 1; // default + quint8 headerTemplate; + quint8 multiTemplate; + quint8 footerTemplate; switch (this->ticketVariant) { - case TICKET_VARIANT::PARKING_TICKET: - break; - case TICKET_VARIANT::RECEIPT: - break; - case TICKET_VARIANT::ERROR_RECEIPT: - break; case TICKET_VARIANT::START_RECEIPT: - this->_templateList << 21 << 22 << 23; + if (templateList.isEmpty()) { + this->_templateList << 21 << 22 << 23; + } + else { + this->_templateList = templateList; + } break; case TICKET_VARIANT::STOP_RECEIPT: - this->_templateList << 24 << 25 << 26; + if (templateList.isEmpty()) { + this->_templateList << 24 << 25 << 26; + } + else { + this->_templateList = templateList; + } break; case TICKET_VARIANT::FINE_PAYMENT: - this->_templateList << 24 << 25 << 26; + if (templateList.isEmpty()) { + this->_templateList << 24 << 25 << 26; + } + else { + this->_templateList = templateList; + } break; case TICKET_VARIANT::FREE_TICKET: - this->_templateList << 24 << 25 << 26; + if (templateList.isEmpty()) { + this->_templateList << 24 << 25 << 26; + } + else { + this->_templateList = templateList; + } break; case TICKET_VARIANT::FOOD_STAMP: if (printingData.contains("dyn1_list")) { @@ -78,19 +95,52 @@ bool Ticket::initNew(TICKET_VARIANT ticketVariant, const QList & templat this->dyn2List = printingData["dyn2_list"].toStringList(); } + if (templateList.isEmpty()) { + headerTemplate = 0; + multiTemplate = 1; + footerTemplate = 2; + } + else + if (templateList.size() == 2) { + headerTemplate = 0; + multiTemplate = templateList.at(0); + footerTemplate = templateList.at(1); + } + else + if (templateList.size() == 3) { + headerTemplate = templateList.at(0); + multiTemplate = templateList.at(1); + footerTemplate = templateList.at(2); + } + else { + headerTemplate = 0; + multiTemplate = 1; + footerTemplate = 2; + } + + // header is optional: + if (headerTemplate != 0) { + this->_templateList << headerTemplate; + } + if (printingData.contains("multiplicator")) { multiplicatorInt = printingData["multiplicator"].toInt(); for (int i = 1; i < multiplicatorInt; i++) { - this->_templateList << 1; + this->_templateList << multiTemplate; } // last template: - this->_templateList << 2; + this->_templateList << footerTemplate; + } + else { + this->_templateList = templateList; } // DEBUG FOOD_STAMP: qCritical() << " --> printingData[\"multiplicator\"]" << multiplicatorInt; break; + default: + this->_templateList = templateList; }