diff --git a/.swp b/.swp new file mode 100644 index 0000000..24c2401 Binary files /dev/null and b/.swp differ diff --git "a/\\" "b/\\" new file mode 100644 index 0000000..ba5817e --- /dev/null +++ "b/\\" @@ -0,0 +1 @@ + return std::make_pair(CalcState(CalcState::State::OVERPAID), dt); diff --git a/library/include/mobilisis/atb_time.h b/library/include/mobilisis/atb_time.h new file mode 100644 index 0000000..bc6f0cf --- /dev/null +++ b/library/include/mobilisis/atb_time.h @@ -0,0 +1,83 @@ +#ifndef ATB_TIME_H_INCLUDED +#define ATB_TIME_H_INCLUDED + +#include + +class ATBTime { + static QDateTime const m_end; + mutable QDateTime m_time; + +public: + explicit ATBTime(); + explicit ATBTime(int h, int m, int s = 0, int ms = 0); + explicit ATBTime(QString const &time); + explicit ATBTime(QTime const &time); + + explicit ATBTime(ATBTime const &atbTime) { + m_time = atbTime.m_time; + } + + ATBTime &operator=(ATBTime && atbTime) { + m_time = std::move(atbTime.m_time); + return *this; + } + + ATBTime &operator=(ATBTime const &atbTime) { + m_time = atbTime.m_time; + return *this; + } + + + int hour() const { return m_time.time().hour(); } + int minute() const { return m_time.time().minute(); } + int second() const { return m_time.time().second(); } + int msec() const { return m_time.time().msec(); } + + int secsTo(QString const &t) const { + if (t == "24:00:00") { + return m_time.secsTo(m_end); + } + return m_time.time().secsTo(QTime::fromString(t, Qt::ISODate)); + } + + int msecsTo(QTime t) const { return m_time.time().msecsTo(t); } + + bool setHMS(int h, int m, int s, int ms = 0); + + bool isNull() const { return m_time.time().isNull(); } + bool isValid() const { return m_time.time().isValid(); } + + + QTime addMSecs(int ms) const; + QTime addMSecs(int ms); + + QTime addSecs(int s) const; + QTime addSecs(int s); + + int msecsSinceStartOfDay() const; + QString toString(Qt::DateFormat format = Qt::TextDate) const; + + + static bool isValid(int h, int m, int s, int ms = 0); + + static QTime currentTime() { return QDateTime::currentDateTime().time(); } + + static constexpr QTime fromMSecsSinceStartOfDay(int msecs); + + static QTime fromString(QString const &string, Qt::DateFormat format = Qt::TextDate); + static QTime fromString(QString const &string, const QString &format); + + friend bool operator!=(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator<=(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator>=(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator>(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept; + friend QDataStream &operator<<(QDataStream &out, ATBTime const &time); + friend QDebug &operator<<(QDebug &out, ATBTime const &time); + friend QDataStream &operator>>(QDataStream &in, ATBTime &time); +}; + + +#endif // ATB_TIME_H_INCLUDED diff --git a/library/include/mobilisis/calculate_price.h b/library/include/mobilisis/calculate_price.h index 66638f5..83484b1 100644 --- a/library/include/mobilisis/calculate_price.h +++ b/library/include/mobilisis/calculate_price.h @@ -3,6 +3,7 @@ #include #include +#include "tariff_time_range.h" #include #include @@ -17,6 +18,8 @@ #define CALCULATE_LIBRARY_API #endif +#include "tariff_permit_type.h" + class Configuration; typedef Configuration parking_tariff_t; @@ -31,77 +34,242 @@ struct CALCULATE_LIBRARY_API price_t { double brutto; double vat_percentage; double vat; + + explicit price_t() { + units = 0; + netto = brutto = vat_percentage = vat = 0.0; + } }; struct CALCULATE_LIBRARY_API CalcState { + static QString const SUCCESS; + static QString const ERROR_PARSING_ZONE_NR; + static QString const ERROR_LOADING_TARIFF; + static QString const ERROR_PARSING_TARIFF; + static QString const NEGATIVE_PARKING_TIME; + static QString const INVALID_START_DATE; + static QString const WRONG_PARAM_VALUES; + static QString const WRONG_ISO_TIME_FORMAT; + static QString const ABOVE_MAX_PARKING_TIME; + static QString const BELOW_MIN_PARKING_TIME; + static QString const BELOW_MIN_PARKING_PRICE; + static QString const ABOVE_MAX_PARKING_PRICE; + static QString const OVERPAID; + static QString const OUTSIDE_ALLOWED_PARKING_TIME; + static QString const SUCCESS_MAXPRICE; + enum class State : uint8_t { SUCCESS, ERROR_PARSING_ZONE_NR, ERROR_LOADING_TARIFF, ERROR_PARSING_TARIFF, - NEGATIVE_PARING_TIME, + NEGATIVE_PARKING_TIME, INVALID_START_DATE, WRONG_PARAM_VALUES, WRONG_ISO_TIME_FORMAT, ABOVE_MAX_PARKING_TIME, BELOW_MIN_PARKING_TIME, BELOW_MIN_PARKING_PRICE, - OVERPAID + ABOVE_MAX_PARKING_PRICE, + OVERPAID, + OUTSIDE_ALLOWED_PARKING_TIME, + SUCCESS_MAXPRICE }; State m_status; QString m_desc; + TariffTimeRange m_allowedTimeRange; - explicit CalcState() : m_status(State::SUCCESS), m_desc("") {} + explicit CalcState() + : m_status(State::SUCCESS) + , m_desc("") { + } + + explicit CalcState(State state, QString desc = "") + : m_status(state) + , m_desc(desc) { + } + + explicit CalcState(State state, QString desc, + QTime const &from, + QTime const &until) + : m_status(state) + , m_desc(desc) + , m_allowedTimeRange(from, until) { + } explicit operator bool() const noexcept { return (m_status == State::SUCCESS); } + QString toString() { + QString s; + switch (m_status) { + case State::SUCCESS: + s = CalcState::SUCCESS; + break; + case State::SUCCESS_MAXPRICE: + s = CalcState::SUCCESS_MAXPRICE; + break; + case State::ERROR_PARSING_ZONE_NR: + s = CalcState::ERROR_PARSING_ZONE_NR; + break; + case State::ERROR_LOADING_TARIFF: + s = CalcState::ERROR_LOADING_TARIFF; + break; + case State::ERROR_PARSING_TARIFF: + s = CalcState::ERROR_PARSING_TARIFF; + break; + case State::NEGATIVE_PARKING_TIME: + s = CalcState::NEGATIVE_PARKING_TIME; + break; + case State::ABOVE_MAX_PARKING_TIME: + s = CalcState::ABOVE_MAX_PARKING_TIME; + break; + case State::WRONG_PARAM_VALUES: + s = CalcState::WRONG_PARAM_VALUES; + break; + case State::BELOW_MIN_PARKING_TIME: + s = CalcState::BELOW_MIN_PARKING_TIME; + break; + case State::BELOW_MIN_PARKING_PRICE: + s = CalcState::BELOW_MIN_PARKING_PRICE; + break; + case State::OVERPAID: + s = CalcState::OVERPAID; + break; + case State::INVALID_START_DATE: + s = CalcState::INVALID_START_DATE; + break; + case State::WRONG_ISO_TIME_FORMAT: + s = CalcState::WRONG_ISO_TIME_FORMAT; + break; + case State::OUTSIDE_ALLOWED_PARKING_TIME: + s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME; + break; + case State::ABOVE_MAX_PARKING_PRICE: + s = CalcState::ABOVE_MAX_PARKING_TIME; + break; + } + if (m_desc.size() > 0) { + return s + ":" + m_desc; + } + return s; + } + explicit operator QString () const noexcept { QString s; switch (m_status) { case State::SUCCESS: - s = "SUCCESS"; + s = CalcState::SUCCESS; + break; + case State::SUCCESS_MAXPRICE: + s = CalcState::SUCCESS_MAXPRICE; break; case State::ERROR_PARSING_ZONE_NR: - s = "ERROR_PARSING_ZONE_NR"; + s = CalcState::ERROR_PARSING_ZONE_NR; break; case State::ERROR_LOADING_TARIFF: - s = "ERROR_LOADING_TARIFF"; + s = CalcState::ERROR_LOADING_TARIFF; break; case State::ERROR_PARSING_TARIFF: - s = "ERROR_PARSING_TARIFF"; - break; - case State::NEGATIVE_PARING_TIME: - s = "NEGATIVE_PARKING_TIME"; + s = CalcState::ERROR_PARSING_TARIFF; break; + case State::NEGATIVE_PARKING_TIME: + s = CalcState::NEGATIVE_PARKING_TIME; + break; case State::ABOVE_MAX_PARKING_TIME: - s = "ABOVE_MAX_PARKING_TIME"; + s = CalcState::ABOVE_MAX_PARKING_TIME; break; case State::WRONG_PARAM_VALUES: - s = "WRONG_PARAM_VALUES"; + s = CalcState::WRONG_PARAM_VALUES; break; case State::BELOW_MIN_PARKING_TIME: - s = "BELOW_MIN_PARKING_TIME"; + s = CalcState::BELOW_MIN_PARKING_TIME; break; case State::BELOW_MIN_PARKING_PRICE: - s = "BELOW_MIN_PARKING_PRICE"; + s = CalcState::BELOW_MIN_PARKING_PRICE; break; case State::OVERPAID: - s = "OVERPAID"; + s = CalcState::OVERPAID; break; case State::INVALID_START_DATE: - s = "INVALID_START_DATE"; + s = CalcState::INVALID_START_DATE; break; case State::WRONG_ISO_TIME_FORMAT: - s = "WRONG_ISO_TIME_FORMAT"; + s = CalcState::WRONG_ISO_TIME_FORMAT; + break; + case State::OUTSIDE_ALLOWED_PARKING_TIME: + s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME; + break; + case State::ABOVE_MAX_PARKING_PRICE: + s = CalcState::ABOVE_MAX_PARKING_TIME; + break; } return s + ":" + m_desc; } CalcState &set(State s) { m_status = s; return *this; } - CalcState &setDesc(QString s) { m_desc = s; return *this; } + CalcState &setStatus(State s) { return set(s); } + CalcState &setStatus(QString const &desc) { + if (desc == SUCCESS) { + m_status = State::SUCCESS; + } else + if (desc == SUCCESS_MAXPRICE) { + m_status = State::SUCCESS_MAXPRICE; + } + if (desc == ERROR_PARSING_ZONE_NR) { + m_status = State::ERROR_PARSING_ZONE_NR; + } else + if (desc == ERROR_LOADING_TARIFF) { + m_status = State::SUCCESS; + } else + if (desc == ERROR_PARSING_TARIFF) { + m_status = State::ERROR_LOADING_TARIFF; + } else + if (desc == NEGATIVE_PARKING_TIME) { + m_status = State::NEGATIVE_PARKING_TIME; + } else + if (desc == INVALID_START_DATE) { + m_status = State::INVALID_START_DATE; + } else + if (desc == WRONG_PARAM_VALUES) { + m_status = State::WRONG_PARAM_VALUES; + } else + if (desc == WRONG_ISO_TIME_FORMAT) { + m_status = State::WRONG_ISO_TIME_FORMAT; + } else + if (desc == ABOVE_MAX_PARKING_TIME) { + m_status = State::ABOVE_MAX_PARKING_TIME; + } else + if (desc == BELOW_MIN_PARKING_TIME) { + m_status = State::BELOW_MIN_PARKING_TIME; + } else + if (desc == BELOW_MIN_PARKING_PRICE) { + m_status = State::BELOW_MIN_PARKING_PRICE; + } else + if (desc == OVERPAID) { + m_status = State::OVERPAID; + } else + if (desc == OUTSIDE_ALLOWED_PARKING_TIME) { + m_status = State::OUTSIDE_ALLOWED_PARKING_TIME; + } else + if (desc == ABOVE_MAX_PARKING_PRICE) { + m_status = State::ABOVE_MAX_PARKING_PRICE; + } + + return *this; + } + State getStatus() const { return m_status; } + CalcState &setDesc(QString const &s) { m_desc = s; return *this; } + + void setAllowedTimeRange(QTime const &from, QTime const &until) { + m_allowedTimeRange.setTimeRange(from, until); + } + + TariffTimeRange getAllowedTimeRange() { + return m_allowedTimeRange; + } }; CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, @@ -109,35 +277,76 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff); int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1); +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, + int UpDown, PermitType const &permitType); + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg); + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING, + int paymentOptionIndex=0); + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING, + int paymentOptionIndex=0); + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING, + int paymentOptionIndex = 0, + QDateTime const &start = QDateTime::currentDateTime()); + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING, + int paymentOptionIndex=0); + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING, + QDateTime const &start = QDateTime::currentDateTime(), + QDateTime *productStart = nullptr, + QDateTime *productEnd = nullptr); + CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated parking_tariff_t *tariff, time_t start_parking_time, time_t end_parking_time, - struct price_t *price); + struct price_t *price, + PermitType permitType); CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( parking_tariff_t *tariff, - QDateTime const &start_parking_time, + QDateTime &start_parking_time, int netto_parking_time, QDateTime &end_parking_time, // return value - struct price_t *price); // return value + struct price_t *price, // return value + PermitType permitType, + bool prepaid = true); CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( // deprecated parking_tariff_t *tariff, time_t start_parking_time, double cost, - QString &duration); + QString &duration, + PermitType permitType); CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( parking_tariff_t *tariff, QDateTime const &start_parking_time, double cost, - QDateTime &ticketEndTime); // return value + QDateTime &ticketEndTime, + PermitType permitType); // return value CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket( parking_tariff_t *tariff, QDateTime const &start_parking_time, - QDateTime &ticketEndTime); + QDateTime &ticketEndTime, + PermitType permitType); + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &start_parking_time, + QDateTime &ticketEndTime, + PERMIT_TYPE permitType, + struct price_t *price); //#ifdef __cplusplus //} // extern "C" //#endif diff --git a/library/include/mobilisis/calculator_functions.h b/library/include/mobilisis/calculator_functions.h index 413429b..0aa26cf 100644 --- a/library/include/mobilisis/calculator_functions.h +++ b/library/include/mobilisis/calculator_functions.h @@ -1,13 +1,81 @@ -#pragma once +#ifndef CALCULATOR_FUNCTIONS_H_INCLUDED +#define CALCULATOR_FUNCTIONS_H_INCLUDED + #include +#include +#include + #include "configuration.h" +#include "calculate_price.h" #include "payment_method.h" +#include "ticket.h" +#include "tariff_time_range.h" + #include using namespace std; -class Calculator -{ +class Calculator { + mutable QVector> m_timeSteps; + mutable QList m_priceSteps; + + CalcState isParkingAllowedForWeekDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex); + + CalcState isParkingAllowedForSpecialDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex); + struct State { + bool m_timeLimitReached; + uint32_t m_costAtTimeLimit; + } m_state; + +protected: + explicit Calculator() { + m_state.m_timeLimitReached = false; + m_state.m_costAtTimeLimit = ~0; + } + public: + Calculator(Calculator const &other) = delete; + void operator=(Calculator const &) = delete; + + static Calculator &GetInstance() { + static Calculator c; + return c; + } + + bool timeLimitReached() const { return m_state.m_timeLimitReached; } + void setTimeLimitReached(bool timeLimitReached) { m_state.m_timeLimitReached = timeLimitReached; } + bool costAtTimeLimit() const { return m_state.m_costAtTimeLimit; } + void setCostAtTimeLimit(uint32_t cost) { if (m_state.m_costAtTimeLimit > cost) m_state.m_costAtTimeLimit = cost; } + void resetCostAtTimeLimit() { m_state.m_costAtTimeLimit = ~0; } + + void ResetTimeSteps(int paymentOptionIndex) { + if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) { + m_timeSteps[paymentOptionIndex].clear(); + } + } + QList timeSteps(int paymentOptionIndex=0) const { + if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) { + return m_timeSteps[paymentOptionIndex]; + } + return QList(); + } + + void ResetPriceSteps() { m_priceSteps.clear(); } + QList priceSteps() const { return m_priceSteps; } + + CalcState isParkingAllowed(Configuration const *cfg, + QDateTime const &start); + + CalcState isParkingAllowed(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex); + /// /// Gets duration in seconds from cost /// @@ -16,7 +84,9 @@ public: /// Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) /// /// Returns duration in seconds (data type: double) - std::string GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price, bool nextDay = false, bool prepaid = false); + std::pair + GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price, + PermitType permitType, bool nextDay = false, bool prepaid = false); /// /// Gets cost from duration in seconds @@ -27,25 +97,75 @@ public: /// Date/time of park end to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) /// Duration of parking in minutes /// Returns cost (data type: double) - double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, const QDateTime start_datetime, QDateTime & end_datetime, double durationMin, bool nextDay = false, bool prepaid = false); + double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin, + PermitType permitType, bool nextDay = false, bool prepaid = false); + + std::pair ComputeDurationFromCost(Configuration *cfg, QDateTime const &startDatetimePassed, int cost); + std::pair> ComputeCostFromDuration(Configuration *cfg, QDateTime const &startDatetime, QDateTime &endDatetime, int nettoParkingTime); // Daily ticket QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over); + std::optional GetDailyTicketPrice(Configuration* cfg, QDateTime const &startDatetime, QDateTime &endTime, PERMIT_TYPE permitType); // // helper function to find time steps for a tariff with PaymentMethod::Steps // (e.g. Schoenau/Koenigsee) // - QList GetTimeSteps(Configuration *cfg) const; + QList &GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const; + QList GetSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const { + return GetTimeSteps(cfg, paymentOptionIndex, start); + } -private: + QList GetPriceSteps(Configuration *cfg) const; + + // additional helper functions + bool noSpecialDays(Configuration const *cfg) const { + return (cfg->SpecialDays.size() == 0) && (cfg->SpecialDaysWorktime.size() == 0); + } + bool specialDays(Configuration const *cfg) const { + return !noSpecialDays(cfg); + } + bool tariffIs24_7(Configuration const *cfg) const { + return (cfg->YearPeriod.size() == 0 && + cfg->SpecialDays.size() == 0 && + cfg->SpecialDaysWorktime.size() == 0); + } + +// testing public: // Introduced for PaymentMethod::Steps (e.g. Schoenau) // For tariff of following structure: only steps, no special days, nonstop. - uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, quint64 durationMinutes) const; - uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, QDateTime const &end) const; + uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, quint64 durationMinutes, int paymentOptionIndex=0) const; + uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, QDateTime const &end, int paymentOptionIndex=0) const; +private: + Ticket private_GetCostFromDuration(Configuration const* cfg, + QDateTime const &start, + int durationMinutes, + bool prepaid = false); + Ticket private_GetDurationFromCost(Configuration *cfg, + QDateTime const &start, + uint32_t price, + bool prepaid = false); + + bool checkDurationMinutes(int minParkingTime, int maxParkingTime, + int durationMinutes); // - uint32_t GetPriceForTimeStep(Configuration *cfg, int timeStep) const; + uint32_t GetPriceForTimeStep(Configuration *cfg, int timeStep, int paymentOptionIndex) const; + //uint32_t GetPriceForStep(Configuration *cfg, int step) const { + // return GetPriceForTimeStep(cfg, step, 0); + //} uint32_t GetDurationForPrice(Configuration *cfg, int price) const; + uint32_t GetStepForPrice(Configuration *cfg, int price) const { + return GetDurationForPrice(cfg, price); + } + + int findWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size); + int findNextWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size); }; + +#endif // CALCULATOR_FUNCTIONS_H_INCLUDED diff --git a/library/include/mobilisis/configuration.h b/library/include/mobilisis/configuration.h index 65bce06..5428c24 100644 --- a/library/include/mobilisis/configuration.h +++ b/library/include/mobilisis/configuration.h @@ -21,26 +21,68 @@ #include "period_year.h" #include "payment_rate.h" #include "atb_project.h" +#include "tariff_daily_ticket.h" +#include "time_range_header.h" +#include "tariff_timestep_config.h" +#include "tariff_product.h" +#include "tariff_interpolation.h" +#include "tariff_prepaid.h" +#include "tariff_carryover.h" +#include "tariff_permit_type.h" +#include "tariff_service.h" +#include "tariff_out_of_service.h" + +#include +#include using namespace std; using namespace rapidjson; + +class Calculator; class Configuration { public: + using SpecialDaysType = std::multimap; + using SpecialDaysWorktimeType = std::multimap; + using TimeRangeType = std::multimap; + using TariffProductType = std::multimap; + using ATBPaymentOptionType = std::multimap; + using TariffInterpolationType = std::multimap; + using TariffPrepaidType = std::multimap; + using TariffCarryOverType = std::multimap; + using TariffDurationType = std::multimap; + using TariffServiceType = std::multimap; + using TariffOutOfServiceType = std::multimap; + using ATBTariffPrepaidType = std::multimap; + using ATBTariffCarryOverType = std::multimap; + ATBProject project; ATBCurrency Currency; - ATBDuration duration; + ATBDuration duration; - multimap Duration; + TariffDurationType Duration; multimap PaymentMethod; multimap PaymentRate; - multimap SpecialDaysWorktime; - multimap SpecialDays; - multimap WeekDays; + SpecialDaysWorktimeType SpecialDaysWorktime; + SpecialDaysType SpecialDays; + multimap WeekDays; multimap YearPeriod; multimap WeekDaysWorktime; - multimap PaymentOption; + ATBPaymentOptionType PaymentOption; + multimap DailyTicket; + TimeRangeType TimeRange; + multimap TimeStepConfig; + multimap TimeBase; + multimap Customer; + TariffProductType TariffProduct; + TariffInterpolationType TariffInterpolations; + TariffPrepaidType TariffPrepaidOptions; + TariffCarryOverType TariffCarryOverOptions; + TariffServiceType TariffServices; + TariffOutOfServiceType TariffOutOfServices; + ATBTariffPrepaidType TariffPrepaids; + ATBTariffCarryOverType TariffCarryOvers; /// /// Parse JSON string @@ -49,7 +91,41 @@ public: /// Returns operation status bool (OK | FAIL) bool ParseJson(Configuration* cfg, const char* json); - ATBPaymentOption const & getPaymentOptions(); + ATBPaymentOption &getPaymentOptions(int paymentOptionsIndex=0); + ATBPaymentOption const &getPaymentOptions(int paymentOptionsIndex=0) const; + QVector &getAllPaymentOptions(); + QVector const &getAllPaymentOptions() const; + int getPaymentOptionIndex(QDateTime const &dt) const; + int getPaymentOptionIndexIfSpecialDay(QDateTime const &dt) const; + bool isSpecialDay(QDateTime const &dt) const; + int specialDayId(QDateTime const &dt) const; + ATBSpecialDays specialDay(QDateTime const &dt) const; + bool isDayIncluded(uint64_t businessHours, QDateTime const &dt) const; + bool isDayIncludedAsSpecialDay(uint64_t businessHours, QDateTime const &dt) const; + bool isDayIncludedAsSpecialDay(uint64_t businessHours, int specialDayId) const; + std::optional> getPaymentRateForAllKeys() const; + std::optional> getPaymentOptionsForAllKeys() const; + std::optional getPaymentOptionForId(int key) const; + std::optional> getPaymentRateForKey(int key) const; + std::optional getPaymentOptionForKey(PERMIT_TYPE permitType) const; + std::optional getPaymentOptionForKey(int permitType) const; + std::optional getPaymentOptionForKey(QString const &permitType) const; + std::optional> getDailyTicketsForAllKeys() const; + std::optional> getDailyTicketsForKey(int key) const; + std::optional getInterpolationType(int type) const; + std::optional getInterpolationEnd(QDateTime const &start, int paymentOptionIndex) const; + std::optional getPrepaidType(int type) const; + std::optional> getTariffProductForAllKeys() const; + std::optional> getTariffProductForProductId(int id) const; + std::optional> getTariffProductForProductId(PermitType permitType) const; + std::optional> getTariffProductForProductTypeName(QString const &permitTypeName) const; + std::optional getCustomerForType(ATBCustomer::CustomerType customerType); + std::optional getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek); + std::optional> getAllWeekDayWorkTimes(); + + std::optional prepaidStart(QDateTime const &start, int prepaid_option_id); + int getPaymentOptionIndex(PERMIT_TYPE permitType); + int getPaymentOptionIndex(PERMIT_TYPE permitType) const; private: /// @@ -59,5 +135,17 @@ private: /// MemberType IdentifyJsonMember(const char* member_name); - ATBPaymentOption currentPaymentOptions; + QVector currentPaymentOptions; }; + +bool previousDayHoliday(Configuration const &cfg, QDateTime const &t); +bool isHoliday(Configuration const &cfg, QDateTime const &t); +int getPaymentOptionIndex(Configuration const &cfg, QDateTime const& dt = QDateTime::currentDateTime()); + +ATBWeekDay parseWeekDay(Configuration &cfg, + rapidjson::GenericMemberIterator, + rapidjson::MemoryPoolAllocator> k, + QString const &innerObjName, + Qt::DayOfWeek weekDay, + QString const &weekDayName); diff --git a/library/include/mobilisis/duration.h b/library/include/mobilisis/duration.h index 9c6ca65..5dd1503 100644 --- a/library/include/mobilisis/duration.h +++ b/library/include/mobilisis/duration.h @@ -1,10 +1,40 @@ -#pragma once #include +#include + class ATBDuration { public: + explicit ATBDuration() + : pun_id(0) + , pun_label("") + , pun_duration(0) + , pun_duration_saved(0) + , pun_duration_min(0) + , pun_duration_max(0) + , pun_interpolation_id(-1) { + } + + friend QDebug operator<<(QDebug debug, ATBDuration const &td) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " pun_id: " << td.pun_id << "\n" + << " pun_label: " << QString::fromStdString(td.pun_label) << "\n" + << " pun_duration: " << td.pun_duration << "\n" + << " pun_duration_saved: " << td.pun_duration_saved << "\n" + << " pun_duration_min: " << td.pun_duration_min << "\n" + << " pun_duration_max: " << td.pun_duration_max << "\n" + << "pun_interpolation_id: " << td.pun_interpolation_id << "\n"; + + return debug; + } + int pun_id; std::string pun_label; int pun_duration; -}; \ No newline at end of file + int pun_duration_saved; + int pun_duration_min; + int pun_duration_max; + int pun_interpolation_id; +}; diff --git a/library/include/mobilisis/member_type.h b/library/include/mobilisis/member_type.h index 6a66214..dcfd012 100644 --- a/library/include/mobilisis/member_type.h +++ b/library/include/mobilisis/member_type.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef MEMBER_TYPE_H_INCLUDED +#define MEMBER_TYPE_H_INCLUDED enum MemberType { @@ -12,5 +13,16 @@ enum MemberType WeekDaysWorkTimeType = 0x06, SpecialDaysWorktimeType = 0x07, SpecialDaysType = 0x08, - PeriodYearType = 0x09 -}; \ No newline at end of file + PeriodYearType = 0x09, + DailyTicketType = 0x0A, + CustomerType = 0x0B, + TimeBaseType = 0x0C, + TimeRangeType = 0x0D, + TimeStepConfigType = 0x0E, + ProductType = 0x0F, + InterpolationType = 0x10, + PrepaidType = 0x11, + CarryOverType = 0x12 +}; + +#endif // MEMBER_TYPE_H_INCLUDED diff --git a/library/include/mobilisis/payment_method.h b/library/include/mobilisis/payment_method.h index d6d1921..9c55cb3 100644 --- a/library/include/mobilisis/payment_method.h +++ b/library/include/mobilisis/payment_method.h @@ -1,10 +1,13 @@ -#pragma once - -enum PaymentMethod -{ - Undefined = 0xFF, - Progressive = 0x01, - Degressive = 0x02, - Linear = 0x03, - Steps = 0x04 -}; \ No newline at end of file +#ifndef PAYMENT_METHOD_H_INCLUDED +#define PAYMENT_METHOD_H_INCLUDED + +enum PaymentMethod { + Undefined = 0xFF, + Progressive = 0x01, + Degressive = 0x02, + Linear = 0x03, + Steps = 0x04, + Unified = 0x05 +}; + +#endif // PAYMENT_METHOD_H_INCLUDED diff --git a/library/include/mobilisis/payment_opt.h b/library/include/mobilisis/payment_opt.h index 0655755..1f4a89a 100644 --- a/library/include/mobilisis/payment_opt.h +++ b/library/include/mobilisis/payment_opt.h @@ -1,18 +1,94 @@ -#pragma once +#ifndef PAYMENT_OPT_H_INCLUDED +#define PAYMENT_OPT_H_INCLUDED + + #include +#include + +#include class ATBPaymentOption { public: - int pop_id; - std::string pop_label; - int pop_payment_method_id; - std::string pop_day_end_time; - std::string pop_day_night_end_time; - double pop_price_night; - double pop_min_time; - double pop_max_time; - double pop_min_price; - int pop_carry_over; + ATBPaymentOption() = default; + + void reset() { + pop_id = 0; + pop_label = ""; + pop_product_id = -1; + pop_product_name = ""; + pop_payment_method_id = 0; + pop_day_end_time = ""; + pop_day_night_end_time = ""; + pop_price_night = 0; + pop_min_time = 0; + pop_max_time = 0; + pop_min_price = 0; + pop_max_price = 0; + pop_max_price_save = 0; + pop_carry_over = -1; + pop_carry_over_option_id = -1; + pop_prepaid_option_id = -1; + pop_truncate_last_interpolation_step = false; + pop_accumulate_prices = false; + pop_accumulate_durations = false; + pop_carry_over_target = false; + pop_carry_over_time_range_id = -1; + pop_carry_over_start_time_range = -1; + pop_carry_over_end_time_range = -1; + pop_daily_card_price = -1; + pop_business_hours = -1; + pop_time_step_config = -1; + pop_use_only_upto_datetime = ""; // deprecated + pop_use_only_for_duration = 0; // deprecated + pop_plus_steps = 1; // +: jump steps forward + pop_plus_steps_saved = 1; + pop_minus_steps = 1; // -: jump steps backward + pop_allow_overpay = false; + pop_apply_carry_over_to_ticket_endtime = false; + } + + int pop_id; + std::string pop_label; + int pop_product_id; + QString pop_product_name; + int pop_payment_method_id; + QString pop_use_only_upto_datetime; + int pop_use_only_for_duration; + std::string pop_day_end_time; + std::string pop_day_night_end_time; + double pop_price_night; + double pop_min_time; + double pop_max_time; + double pop_min_price; + double pop_max_price; + double pop_max_price_save; + int pop_carry_over; + int pop_carry_over_option_id; + bool pop_truncate_last_interpolation_step; + int pop_prepaid_option_id; + bool pop_carry_over_target; + int pop_carry_over_time_range_id; + int pop_carry_over_start_time_range; + int pop_carry_over_end_time_range; int pop_daily_card_price; + uint64_t pop_business_hours; + int pop_time_step_config; + bool pop_accumulate_prices; + bool pop_accumulate_durations; + int pop_plus_steps; + int pop_plus_steps_saved; + int pop_minus_steps; + bool pop_allow_overpay; + bool pop_apply_carry_over_to_ticket_endtime; + + struct ATBMaxDateTime { + int direction; + uint8_t week; + uint8_t day; + QTime time; + } pop_min_date_time, + pop_max_date_time; }; + +#endif // PAYMENT_OPT_H_INCLUDED diff --git a/library/include/mobilisis/payment_rate.h b/library/include/mobilisis/payment_rate.h index b9c6c94..6f111a8 100644 --- a/library/include/mobilisis/payment_rate.h +++ b/library/include/mobilisis/payment_rate.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef PAYMENT_RATE_INCLUDED_H +#define PAYMENT_RATE_INCLUDED_H class ATBPaymentRate { @@ -6,4 +7,6 @@ public: int pra_payment_option_id; int pra_payment_unit_id; double pra_price; -}; \ No newline at end of file +}; + +#endif // PAYMENT_RATE_INCLUDED_H diff --git a/library/include/mobilisis/spec_days.h b/library/include/mobilisis/spec_days.h index 65ebadf..fb5036e 100644 --- a/library/include/mobilisis/spec_days.h +++ b/library/include/mobilisis/spec_days.h @@ -4,10 +4,12 @@ class ATBSpecialDays { public: + explicit ATBSpecialDays() = default; int ped_id; std::string ped_label; std::string ped_date_start; std::string ped_date_end; - int ped_period_special_day_id; + int ped_period_special_day_id; + int ped_payment_option_id; int ped_year; -}; \ No newline at end of file +}; diff --git a/library/include/mobilisis/spec_days_worktime.h b/library/include/mobilisis/spec_days_worktime.h index 95c7ade..83baf4f 100644 --- a/library/include/mobilisis/spec_days_worktime.h +++ b/library/include/mobilisis/spec_days_worktime.h @@ -8,5 +8,9 @@ public: int pedwt_period_exc_day_id; std::string pedwt_time_from; std::string pedwt_time_to; - double pedwt_price; -}; \ No newline at end of file + double pedwt_price; + int pedwt_paid; // 00: not paid (i.e. free) + // 01: not paid in winter term, piad in summer term + // 10: paid in winter term, not paid in summer term + // 11: paid in winter and in summer term +}; diff --git a/library/include/mobilisis/tariff_business_hours.h b/library/include/mobilisis/tariff_business_hours.h new file mode 100644 index 0000000..3b8a48a --- /dev/null +++ b/library/include/mobilisis/tariff_business_hours.h @@ -0,0 +1,92 @@ +#ifndef TARIFF_BUSINESS_HOURS_H_INCLUDED +#define TARIFF_BUSINESS_HOURS_H_INCLUDED + +/// +/// Business hours (byte represents payment option id) +/// +/// + +#include + +#define _NO_RESTRICTION_24_7_ (uint64_t)(0ULL) +#define _MON_ (uint64_t)(1ULL << 8) +#define _TUE_ (uint64_t)(1ULL << 9) +#define _WED_ (uint64_t)(1ULL << 10) +#define _THU_ (uint64_t)(1ULL << 11) +#define _FRI_ (uint64_t)(1ULL << 12) +#define _SAT_ (uint64_t)(1ULL << 13) +#define _SUN_ (uint64_t)(1ULL << 14) +#define _WEEK_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_)) +#define _WORKING_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_)) +#define _ALL_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_|_SUN_)) +#define _OFFICIAL_HOLIDAY_ (uint64_t)(1ULL << 15) +#define _ONLY_WEEKEND_ ((_SAT_|_SUN_)) +#define _ONLY_OPEN_FOR_BUSINESS_DAYS_ (uint64_t)(1ULL << 16) /* verkaufsoffen */ +#define _WITH_RESTRICTED_HOURS_ (uint64_t)(1ULL << 17) +#define _ALL_DAYS_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_ALL_DAYS_)) +#define _WEEKEND_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_|_SAT_|_SUN_)) +#define _WORKING_DAYS_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_WORKING_DAYS_)) +#define _FRI_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_)) +#define _SAT_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SAT_)) +#define _SUN_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SUN_)) +#define _NOT_DEFINED_ (uint64_t)(~0ULL) + +enum BusinessHours : std::uint64_t +{ + NoRestriction_24_7 = 0, + OnlyWorkingDays = 1, // [Monday-Friday] + OnlyWeekDays = 2, // [Monday-Saturday] + OnlyWeekEnd = 4, // [Saturday+Sunday] + OnlyOfficialHolidays = 8, + OnlySundaysAndHolidays = 12, // [Sun+Holiday] + OnlySpecialDays = 16, + OnlySchoolHolidays = 32, + SpecialAndSchoolHolidays = 48, + OnlyOpenForBusinessDays = 64, // verkaufsoffen + AllDaysWithRestrictedHours = 128, // every day, restricted to some time range + NoBusinessHoursDefined = 255, + + // new 12.04.2024 + NO_RESTRICTION_24_7 = _NO_RESTRICTION_24_7_, + MON = _MON_, + TUE = _TUE_, + WED = _WED_, + THU = _THU_, + FRI = _FRI_, + SAT = _SAT_, + SUN = _SUN_, + WEEK_DAYS = _WEEK_DAYS_, + WORKING_DAYS = _WORKING_DAYS_, + ALL_DAYS = _ALL_DAYS_, + OFFICIAL_HOLIDAY = _OFFICIAL_HOLIDAY_, + ONLY_WEEKEND = _ONLY_WEEKEND_, + ONLY_OPEN_FOR_BUSINESS_DAYS = _ONLY_OPEN_FOR_BUSINESS_DAYS_, + ALL_DAYS_WITH_RESTRICTED_HOURS = _ALL_DAYS_WITH_RESTRICTED_HOURS_, + WEEKEND_WITH_RESTRICTED_HOURS = _WEEKEND_WITH_RESTRICTED_HOURS_, + WORKING_DAYS_WITH_RESTRICTED_HOURS = _WORKING_DAYS_WITH_RESTRICTED_HOURS_, + FRI_WITH_RESTRICTED_HOURS = _FRI_WITH_RESTRICTED_HOURS_, + SAT_WITH_RESTRICTED_HOURS = _SAT_WITH_RESTRICTED_HOURS_, + SUN_WITH_RESTRICTED_HOURS = _SUN_WITH_RESTRICTED_HOURS_, + NOT_DEFINED = _NOT_DEFINED_ +}; + +#if 0 +static bool business(uint64_t businessHours, QDateTime &const dt) { + switch (dayOfWeek) { + case Qt::Monday: + (businessHours & _MON_) == _MON_; + case Qt::Tuesday: + case Qt::Wednesday: + case Qt::Thursday: + case Qt::Saturday: + case Qt::Sunday: + } + +} +#endif + +struct BusinessHours_struct { + BusinessHours bh; +}; + +#endif // TARIFF_BUSINESS_HOURS_H_INCLUDED diff --git a/library/include/mobilisis/tariff_carryover.h b/library/include/mobilisis/tariff_carryover.h new file mode 100644 index 0000000..7f5085c --- /dev/null +++ b/library/include/mobilisis/tariff_carryover.h @@ -0,0 +1,194 @@ +#ifndef TARIFF_CARRYOVER_H_INCLUDED +#define TARIFF_CARRYOVER_H_INCLUDED + +#include + +#include "time_range.h" + +enum class ApplyCarryOver { + NEVER = 0, + MATCH_PREV_DAY = 1, + MATCH_NEXT_DAY = 2, + ALWAYS = 3 +}; + +struct ATBTariffCarryOver { + int m_id; + QString m_weekDay; + TimeRange m_range; + QDate m_date; + ApplyCarryOver m_carryOverIf; + + explicit ATBTariffCarryOver() + : m_id(-1) + , m_carryOverIf(ApplyCarryOver::NEVER) { + } + + void setCarryOverIf(QString const &coif) { + if (coif == "never") { + m_carryOverIf = ApplyCarryOver::NEVER; + } else + if (coif == "match_prev_day") { + m_carryOverIf = ApplyCarryOver::MATCH_PREV_DAY; + } else + if (coif == "match_next_day") { + m_carryOverIf = ApplyCarryOver::MATCH_NEXT_DAY; + } else + if (coif == "always") { + m_carryOverIf = ApplyCarryOver::ALWAYS; + } else { + qCritical() << "ERROR unknown carry over application" << coif; + } + } + + ApplyCarryOver carryOverIf() const { + return m_carryOverIf; + } + + QString carryOverIfStr() const { + if (m_carryOverIf == ApplyCarryOver::NEVER) { + return "never"; + } + if (m_carryOverIf == ApplyCarryOver::ALWAYS) { + return "always"; + } + if (m_carryOverIf == ApplyCarryOver::MATCH_PREV_DAY) { + return "match prev day"; + } + if (m_carryOverIf == ApplyCarryOver::MATCH_NEXT_DAY) { + return "match next day"; + } + return QString("ERROR unknown carry over application: %1").arg(static_cast(m_carryOverIf)); + } + + int computeMinutesUntilCarryOverEnd(QDateTime const &dt) { + int minutes = 0; + QString end = m_range.m_end.toString(Qt::ISODate); + if (end == "24:00:00") { + // note: this did not work + // QDateTime t(dt.addDays(1)); + // t.setTime(QTime(0,0,0)); + // dt: 2024-10-27T00:00:00 EEST, but t: 2024-10-28T00:00:00 EET (!) + // so the difference is 1500 instead of 1440 + // reason: change from summer to winter time + + // compute minutes directly + if (dt.time().isValid()) { + minutes = 1440 - (dt.time().hour() * 60 + dt.time().minute()); + } + } else { + QTime t(QTime::fromString(end, Qt::ISODate)); + if (t.isValid() && dt.time().isValid()) { + minutes = (t.hour() * 60 + t.minute()) - (dt.time().hour() * 60 + dt.time().minute()); + } + } + + if (minutes < 0 || minutes > m_range.m_duration) { + minutes = 0; + } + + // qCritical() << __func__ << ":" << __LINE__ << "minutes" << minutes; + + return minutes; + } + + friend QDebug operator<<(QDebug debug, ATBTariffCarryOver const &co) { + QDebugStateSaver saver(debug); + + debug.nospace() + << "\nTariffCarryOver:\n" + << " week day: " << co.m_weekDay << "\n" + << " date: " << co.m_date.toString(Qt::ISODate) << "\n" + << " id: " << co.m_id << "\n" + << " start: " << co.m_range.m_start << "\n" + << " end: " << co.m_range.m_end << "\n" + << " duration: " << co.m_range.m_duration << "\n" + << " carry over if: " << co.carryOverIfStr() << endl; + return debug; + } +}; + +struct ATBCarryOver { + struct week { + int day; + bool seemless; + bool never; + QTime static_start; + QTime static_end; + int duration; + } carryover[8]; + + int id; + + explicit ATBCarryOver() + : id(-1) { + + for (int i = 0 ; i < 8; ++i) { + carryover[i].day = -1; + carryover[i].seemless = false; + carryover[i].never = false; + carryover[i].static_start = QTime(23, 59, 59); + carryover[i].static_end = QTime(0, 0, 0); + carryover[i].duration = -1; + } + } + + friend QDebug operator<<(QDebug debug, ATBCarryOver const &co) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " id:" << co.id << "\n" + << " **** Monday **** \n" + << " day: " << co.carryover[(int)Qt::Monday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Monday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Monday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Monday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Monday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Monday].never << "\n" + << " **** Tuesday **** \n" + << " day: " << co.carryover[(int)Qt::Tuesday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Tuesday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Tuesday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Tuesday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Tuesday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Tuesday].never << "\n" + << " **** Wednesday **** \n" + << " day: " << co.carryover[(int)Qt::Wednesday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Wednesday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Wednesday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Wednesday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Wednesday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Wednesday].never << "\n" + << " **** Thursday **** \n" + << " day: " << co.carryover[(int)Qt::Thursday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Thursday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Thursday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Thursday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Thursday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Thursday].never << "\n" + << " **** Friday **** \n" + << " day: " << co.carryover[(int)Qt::Friday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Friday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Friday].static_end.toString(Qt::ISODate) << "\n" + << " anytime: " << co.carryover[(int)Qt::Friday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Friday].never << "\n" + << " **** Saturday **** \n" + << " day: " << co.carryover[(int)Qt::Saturday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Saturday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Saturday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Saturday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Saturday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Saturday].never << "\n" + << " **** Sunday **** \n" + << " day: " << co.carryover[(int)Qt::Sunday].day << "\n" + << " static_start: " << co.carryover[(int)Qt::Sunday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << co.carryover[(int)Qt::Sunday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << co.carryover[(int)Qt::Sunday].duration << "\n" + << " anytime: " << co.carryover[(int)Qt::Sunday].seemless << "\n" + << " never: " << co.carryover[(int)Qt::Sunday].never << "\n"; + + return debug; + } +}; + +#endif // TARIFF_CARRYOVER_H_INCLUDED diff --git a/library/include/mobilisis/tariff_carryover_settings.h b/library/include/mobilisis/tariff_carryover_settings.h new file mode 100644 index 0000000..3177976 --- /dev/null +++ b/library/include/mobilisis/tariff_carryover_settings.h @@ -0,0 +1,69 @@ +#ifndef ATB_TARIFF_CARRYOVER_SETTINGS_H_INCLUDED +#define ATB_TARIFF_CARRYOVER_SETTINGS_H_INCLUDED + +#include +#include + +#include + +struct ATBTariffCarryOverSettings { + + // parking time limit not violated: return false, otherwise: return true. + using ParkingTimeLimitChecker = std::function; + + int m_duration; + QTime m_start; + QTime m_end; + ParkingTimeLimitChecker m_parkingTimeLimitChecker; + + QTime m_parking_time_limit; + QTime m_about_to_exceed_parking_time_limit; + + explicit ATBTariffCarryOverSettings() + : m_duration(0) + , m_start(QTime()) + , m_end(QTime()) + , m_parkingTimeLimitChecker([](ATBTariffCarryOverSettings const&, + QDateTime const&, QDateTime const&, int) { return false; }) + , m_parking_time_limit(QTime()) + , m_about_to_exceed_parking_time_limit(QTime()) {} + + explicit ATBTariffCarryOverSettings(int duration, QTime const &start, + QTime const &end, + QTime const &parking_time_limit, + QTime const &about_to_exceed_parking_time_limit, + ParkingTimeLimitChecker parkingTimeLimitChecker) + : m_duration(duration) + , m_start(start) + , m_end(end) + , m_parkingTimeLimitChecker(std::move(parkingTimeLimitChecker)) + , m_parking_time_limit(parking_time_limit) + , m_about_to_exceed_parking_time_limit(about_to_exceed_parking_time_limit) { + } + + bool parkingTimeLimitExceeded(QDateTime const &startTime, + QDateTime const &endTime, + int paymentOptionIndex) const { + return m_parkingTimeLimitChecker(*this, startTime, endTime, paymentOptionIndex); + } + + QTime const &parkingTimeLimit() const { return m_parking_time_limit; } + QTime &parkingTimeLimit() { return m_parking_time_limit; } + + friend QDebug operator<<(QDebug debug, ATBTariffCarryOverSettings const &co) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " duration: " << co.m_duration << "\n" + << " start: " << co.m_start.toString(Qt::ISODate) << "\n" + << " end: " << co.m_end.toString(Qt::ISODate) << "\n" + << " parking_time_limit: " << co.m_parking_time_limit.toString(Qt::ISODate) << endl; + + return debug; + } +}; + +#endif // ATB_TARIFF_CARRYOVER_SETTINGS_H_INCLUDED diff --git a/library/include/mobilisis/tariff_cfg.h b/library/include/mobilisis/tariff_cfg.h index 40b99d6..8f11198 100644 --- a/library/include/mobilisis/tariff_cfg.h +++ b/library/include/mobilisis/tariff_cfg.h @@ -1,4 +1,3 @@ -#pragma once #include #include #include diff --git a/library/include/mobilisis/tariff_customer.h b/library/include/mobilisis/tariff_customer.h new file mode 100644 index 0000000..f25ffaa --- /dev/null +++ b/library/include/mobilisis/tariff_customer.h @@ -0,0 +1,47 @@ +#ifndef TARIFF_CUSTOMER_H_INCLUDED +#define TARIFF_CUSTOMER_H_INCLUDED + +#include +#include +#include + +struct ATBCustomer { + enum class CustomerType {ADULT=1000, CHILD, TEEN}; + + ATBCustomer() = default; + + int cust_id; + CustomerType cust_type; + QString cust_label; + + friend QDebug operator<<(QDebug debug, ATBCustomer const &customer) { + QDebugStateSaver saver(debug); + + debug.nospace() << "CUSTOMER" << "\n"; + + switch(customer.cust_type) { + case ATBCustomer::CustomerType::ADULT: + debug.nospace() + << " cust_id: " << customer.cust_id << "\n" + << " cust_type: " << "CustomerType::ADULT" << "\n" + << "cust_label: " << customer.cust_label << "\n"; + break; + case ATBCustomer::CustomerType::CHILD: + debug.nospace() + << " cust_id: " << customer.cust_id << "\n" + << " cust_type: " << "CustomerType::CHILD" << "\n" + << "cust_label: " << customer.cust_label << "\n"; + break; + case ATBCustomer::CustomerType::TEEN: + debug.nospace() + << " cust_id: " << customer.cust_id << "\n" + << " cust_type: " << "CustomerType::TEEN" << "\n" + << "cust_label: " << customer.cust_label << "\n"; + break; + } + + return debug; + } +}; + +#endif // TARIFF_CUSTOMER_H_INCLUDED diff --git a/library/include/mobilisis/tariff_daily_ticket.h b/library/include/mobilisis/tariff_daily_ticket.h new file mode 100644 index 0000000..b40b6ad --- /dev/null +++ b/library/include/mobilisis/tariff_daily_ticket.h @@ -0,0 +1,67 @@ +#ifndef TARIFF_DAILY_TICKET_H_INCLUDED +#define TARIFF_DAILY_TICKET_H_INCLUDED + +#include +#include +#include +#include +#include + + +#include "tariff_customer.h" +#include "tariff_time_range.h" +#include "tariff_timebase.h" + +struct ATBDailyTicket { + ATBDailyTicket() = default; + + int daily_ticket_payment_option_id; + int daily_ticket_id; + int daily_ticket_price_id; + + int daily_ticket_tb_id; + // time base setting for ticket: + // absolute: using time stamps + // relative: use offsets from + // some reference time point, + // typically "start time". + + QVector daily_ticket_clearance_customer_ids; + // who is allowed to buy the ticket: + // list of customer types + + QTime daily_ticket_from_min; // absolute time base + QTime daily_ticket_to_max; + int daily_ticket_from_offset_min; // relative time base + int daily_ticket_to_offset_max; + + void reset() { + daily_ticket_payment_option_id = 0; + daily_ticket_id = 0; + daily_ticket_price_id = 0; + daily_ticket_tb_id = 0; + daily_ticket_clearance_customer_ids.clear(); + daily_ticket_from_min = QTime(); + daily_ticket_to_max = QTime(); + daily_ticket_from_offset_min = 0; + daily_ticket_to_offset_max = 0; + } + + friend QDebug operator<<(QDebug debug, ATBDailyTicket const &ticket) { + QDebugStateSaver saver(debug); + + debug.nospace() + << "DAILY TICKET " << "\n" + << " daily_ticket_id: " << ticket.daily_ticket_id << "\n" + << " daily_ticket_payment_option_id: " << ticket.daily_ticket_payment_option_id << "\n" + << " daily_ticket_tbase_id: " << ticket.daily_ticket_tb_id << "\n" + << " daily_ticket_price_id: " << ticket.daily_ticket_price_id << "\n" + << "daily_ticket_clearance_customer_ids: " << ticket.daily_ticket_clearance_customer_ids << "\n" + << " daily_ticket_from_min: " << ticket.daily_ticket_from_min.toString(Qt::ISODate) << "\n" + << " daily_ticket_to_min: " << ticket.daily_ticket_to_max.toString(Qt::ISODate) << "\n"; + + return debug; + } +}; + +#endif // TARIFF_DAILY_TICKET_H_INCLUDED diff --git a/library/include/mobilisis/tariff_duration.h b/library/include/mobilisis/tariff_duration.h index ba599d1..ac912d6 100644 --- a/library/include/mobilisis/tariff_duration.h +++ b/library/include/mobilisis/tariff_duration.h @@ -1,4 +1,3 @@ -// #pragma once /// /// Duration data @@ -6,7 +5,9 @@ class TariffDuration { public: - int pun_id; - std::string pun_label; - int pun_duration; + int pun_id; + std::string pun_label; + int pun_duration; + int pun_duration_min; + int pun_duration_max; }; diff --git a/library/include/mobilisis/tariff_global_defines.h b/library/include/mobilisis/tariff_global_defines.h new file mode 100644 index 0000000..cdc3509 --- /dev/null +++ b/library/include/mobilisis/tariff_global_defines.h @@ -0,0 +1,20 @@ +#ifndef TARIFF_GLOBAL_DEFINES_H_INCLUDED +#define TARIFF_GLOBAL_DEFINES_H_INCLUDED + +#define DBG_HEADER "(" << __func__ << ":" << __LINE__ << ")" + +#define DBG_EMERGENCY (0) // System is unusable +#define DBG_ALERT (1) // Action must be taken immediately +#define DBG_CRITICAL (2) // Critical conditions +#define DBG_ERROR (3) // Error conditions +#define DBG_WARNING (4) // Warning conditions +#define DBG_NOTICE (5) // Normal but significant conditions + // Conditions that are not error conditions, but that may require special handling +#define DBG_INFORMATION (6) // Informational messages + // Confirmation that the program is working as expected +#define DBG_DEBUG (7) // Debug-level messages + // Messages that contain information normally of use only when debugging a program + +extern int DBG_LEVEL; + +#endif // TARIFF_GLOBAL_DEFINES_H_INCLUDED diff --git a/library/include/mobilisis/tariff_interpolation.h b/library/include/mobilisis/tariff_interpolation.h new file mode 100644 index 0000000..76968de --- /dev/null +++ b/library/include/mobilisis/tariff_interpolation.h @@ -0,0 +1,95 @@ +#ifndef TARIFF_INTERPOLATION_H_INCLUDED +#define TARIFF_INTERPOLATION_H_INCLUDED + +#include +#include + +struct ATBInterpolation { + + enum Type { + NO_INTERPOLATION = 1, + STATIC_WALLCLOCK_TIME_VALUES = 2, + STATIC_TIMEPOINT_AND_DURATION = 3, + DYNAMIC_TIMEPOINT_AND_STATIC_DURATION = 4, + DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_DURATION = 5, + DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_PRICE = 6, + DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_END_TIME = 7 + }; + + static QString name(int i) { + switch(i) { + case (int)(NO_INTERPOLATION): + return QString("%1: NO_INTERPOLATION").arg(i); + case (int)(STATIC_WALLCLOCK_TIME_VALUES): + return QString("%1: STATIC_WALLCLOCK_TIME_VALUES").arg(i); + case (int)(STATIC_TIMEPOINT_AND_DURATION): + return QString("%1: STATIC_TIMEPOINT_AND_DURATION").arg(i); + case (int)(DYNAMIC_TIMEPOINT_AND_STATIC_DURATION): + return QString("%1: DYNAMIC_TIMEPOINT_AND_STATIC_DURATION").arg(i); + case (int)(DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_DURATION): + return QString("%1: DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_DURATION").arg(i); + case (int)(DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_PRICE): + return QString("%1: DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_PRICE").arg(i); + case (int)(DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_END_TIME): + return QString("%1: DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_END_TIME").arg(i); + default:; + } + return "ERROR"; + } + + explicit ATBInterpolation() + : id(0) + , static_start(QTime()) + , static_end(QTime()) + , static_start_str(QString()) + , static_end_str(QString()) + , static_duration(0) + , dynamic_start(QTime()) + , dynamic_end(QTime()) + , dynamic_start_str(QString()) + , dynamic_end_str(QString()) + , dynamic_duration(0) + , dynamic_until_price(0) + , seemless(false) + , never(false) { + } + + int id; + QTime static_start; + QTime static_end; + QString static_start_str; + QString static_end_str; + int static_duration; + QTime dynamic_start; + QTime dynamic_end; + QString dynamic_start_str; + QString dynamic_end_str; + int dynamic_duration; + int dynamic_until_price; + bool seemless; + bool never; + + friend QDebug operator<<(QDebug debug, ATBInterpolation const &i) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " id: " << name(i.id) << "\n" + << " static_start: " << i.static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << i.static_end.toString(Qt::ISODate) << "\n" + << " static_start_str: " << i.static_start_str << "\n" + << " static_end_str: " << i.static_end_str << "\n" + << " static_duration: " << i.static_duration << "\n" + << " dynamic_start: " << i.dynamic_start.toString(Qt::ISODate) << "\n" + << " dynamic_end: " << i.dynamic_end.toString(Qt::ISODate) << "\n" + << " dynamic_start_str: " << i.dynamic_start_str << "\n" + << " dynamic_end_str: " << i.dynamic_end_str << "\n" + << " dynamic_duration: " << i.dynamic_duration << "\n" + << "dynamic_until_price: " << i.dynamic_until_price << "\n" + << " seemless: " << i.seemless << "\n" + << " never: " << i.never << "\n"; + + return debug; + } +}; + +#endif // TARIFF_INTERPOLATION_H_INCLUDED diff --git a/library/include/mobilisis/tariff_log.h b/library/include/mobilisis/tariff_log.h index ecdc677..788c65f 100644 --- a/library/include/mobilisis/tariff_log.h +++ b/library/include/mobilisis/tariff_log.h @@ -14,6 +14,8 @@ void setDebugLevel(int level); int getDebugLevel(); +#if 0 + static void print() { std::cerr << "\n"; if (getDebugLevel() == DBG_LEVEL_FATAL) { @@ -75,4 +77,6 @@ static void LOG_FATAL(const Arg1& arg1, const Args&&... args) { } } +#endif + #endif // TARIFF_LOG_INCLUDED_H diff --git a/library/include/mobilisis/tariff_out_of_service.h b/library/include/mobilisis/tariff_out_of_service.h new file mode 100644 index 0000000..f3ebe1e --- /dev/null +++ b/library/include/mobilisis/tariff_out_of_service.h @@ -0,0 +1,79 @@ +#ifndef TARIFF_OUT_OF_SERVICE_H_INCLUDED +#define TARIFF_OUT_OF_SERVICE_H_INCLUDED + +#include +#include + +#include "time_range.h" + +enum class ApplyOutOfService { + NEVER = 0, + MATCH_PREV_DAY = 1, + MATCH_NEXT_DAY = 2, + ALWAYS = 3 +}; + +struct ATBTariffOutOfService { + int m_id; + QString m_weekDay; + QDate m_date; + TimeRange m_range; + ApplyOutOfService m_outOfServiceIf; + + explicit ATBTariffOutOfService() + : m_id(-1) + , m_outOfServiceIf(ApplyOutOfService::NEVER) { + } + + void setOutOfServiceIf(QString const &oosif) { + if (oosif == "never") { + m_outOfServiceIf = ApplyOutOfService::NEVER; + } else + if (oosif == "match_prev_day") { + m_outOfServiceIf = ApplyOutOfService::MATCH_PREV_DAY; + } else + if (oosif == "match_next_day") { + m_outOfServiceIf = ApplyOutOfService::MATCH_NEXT_DAY; + } else + if (oosif == "always") { + m_outOfServiceIf = ApplyOutOfService::ALWAYS; + } else { + qCritical() << "ERROR unknown servcie application" << oosif; + } + } + + ApplyOutOfService outOfServiceIf() const { + return m_outOfServiceIf; + } + + QString outOfServiceIfStr() const { + if (m_outOfServiceIf == ApplyOutOfService::NEVER) { + return "never"; + } + if (m_outOfServiceIf == ApplyOutOfService::ALWAYS) { + return "always"; + } + if (m_outOfServiceIf == ApplyOutOfService::MATCH_PREV_DAY) { + return "match prev day"; + } + if (m_outOfServiceIf == ApplyOutOfService::MATCH_NEXT_DAY) { + return "match next day"; + } + return QString("ERROR unknown out of service application: %1").arg(static_cast(m_outOfServiceIf)); + } + friend QDebug operator<<(QDebug debug, ATBTariffOutOfService const &oos) { + QDebugStateSaver saver(debug); + + debug.nospace() + << "\nTariffOutOfService:\n" + << " week day: " << oos.m_weekDay << "\n" + << " date: " << oos.m_date.toString(Qt::ISODate) << "\n" + << " id: " << oos.m_id << "\n" + << " start: " << oos.m_range.m_start << "\n" + << " end: " << oos.m_range.m_end << "\n" + << " duration: " << oos.m_range.m_duration << endl; + return debug; + } +}; + +#endif // TARIFF_SERVICE_H_INCLUDED diff --git a/library/include/mobilisis/tariff_permit_type.h b/library/include/mobilisis/tariff_permit_type.h new file mode 100644 index 0000000..4ccc675 --- /dev/null +++ b/library/include/mobilisis/tariff_permit_type.h @@ -0,0 +1,263 @@ +#ifndef TARIFF_PERMIT_TYPE_H_INCLUDED +#define TARIFF_PERMIT_TYPE_H_INCLUDED + +#include + +enum class PERMIT_TYPE : quint8 { + SHORT_TERM_PARKING=0, + DAY_TICKET=1, + SZEGED_START=2, + SZEGED_STOP=3, + DAY_TICKET_ADULT=4, + DAY_TICKET_TEEN=5, + DAY_TICKET_CHILD=6, + INVALID=7, + FOOD_STAMP=8, + TWENTY_FOUR_HOURS_TICKET=9, + SHORT_TERM_PARKING_PKW=10, + SHORT_TERM_PARKING_BUS=11, + SHORT_TERM_PARKING_CAMPER=12, + DAY_TICKET_PKW=13, + DAY_TICKET_BUS=14, + DAY_TICKET_CAMPER=15 +}; + +struct PermitType { + PERMIT_TYPE m_permitType; + + PermitType() { m_permitType = PERMIT_TYPE::INVALID; } + PermitType(int permitType) { + switch(permitType) { + case 0: + m_permitType = PERMIT_TYPE::SHORT_TERM_PARKING; + break; + case 1: + m_permitType = PERMIT_TYPE::DAY_TICKET; + break; + case 2: + m_permitType = PERMIT_TYPE::SZEGED_START; + break; + case 3: + m_permitType = PERMIT_TYPE::SZEGED_STOP; + break; + case 4: + m_permitType = PERMIT_TYPE::DAY_TICKET_ADULT; + break; + case 5: + m_permitType = PERMIT_TYPE::DAY_TICKET_TEEN; + break; + case 6: + m_permitType = PERMIT_TYPE::DAY_TICKET_CHILD; + break; + case 8: + m_permitType = PERMIT_TYPE::FOOD_STAMP; + break; + case 9: + m_permitType = PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET; + break; + case 10: + m_permitType = PERMIT_TYPE::SHORT_TERM_PARKING_PKW; + break; + case 11: + m_permitType = PERMIT_TYPE::SHORT_TERM_PARKING_BUS; + break; + case 12: + m_permitType = PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER; + break; + case 13: + m_permitType = PERMIT_TYPE::DAY_TICKET_PKW; + break; + case 14: + m_permitType = PERMIT_TYPE::DAY_TICKET_BUS; + break; + case 15: + m_permitType = PERMIT_TYPE::DAY_TICKET_CAMPER; + break; + default: + m_permitType = PERMIT_TYPE::INVALID; + } + } + PermitType(PERMIT_TYPE permitType) : m_permitType(permitType) {} + + void set(PERMIT_TYPE p) { m_permitType = p; } + PERMIT_TYPE get() const { return m_permitType; } + + operator PERMIT_TYPE() const { return m_permitType; } + + operator int () const { + switch(m_permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: + return 0; + case PERMIT_TYPE::DAY_TICKET: + return 1; + case PERMIT_TYPE::SZEGED_START: + return 2; + case PERMIT_TYPE::SZEGED_STOP: + return 3; + case PERMIT_TYPE::DAY_TICKET_ADULT: + return 4; + case PERMIT_TYPE::DAY_TICKET_CHILD: + return 5; + case PERMIT_TYPE::DAY_TICKET_TEEN: + return 6; + case PERMIT_TYPE::FOOD_STAMP: + return 8; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: + return 9; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: + return 10; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: + return 11; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + return 12; + case PERMIT_TYPE::DAY_TICKET_PKW: + return 13; + case PERMIT_TYPE::DAY_TICKET_BUS: + return 14; + case PERMIT_TYPE::DAY_TICKET_CAMPER: + return 15; + default: + break; + } + return 7; + } + + static PERMIT_TYPE toPermitType(QString const permitTypeStr) { + if (permitTypeStr == "DAY_TICKET") { + return PERMIT_TYPE::DAY_TICKET; + } else + if (permitTypeStr == "DAY_TICKET_ADULT") { + return PERMIT_TYPE::DAY_TICKET_ADULT; + } else + if (permitTypeStr == "DAY_TICKET_CHILD") { + return PERMIT_TYPE::DAY_TICKET_CHILD; + } else + if (permitTypeStr == "DAY_TICKET_ADULT") { + return PERMIT_TYPE::DAY_TICKET_ADULT; + } else + if (permitTypeStr == "DAY_TICKET_TEEN") { + return PERMIT_TYPE::DAY_TICKET_TEEN; + } else + if (permitTypeStr == "SHORT_TERM_PARKING") { + return PERMIT_TYPE::SHORT_TERM_PARKING; + } else + if (permitTypeStr == "SZEGED_START") { + return PERMIT_TYPE::SZEGED_START; + } else + if (permitTypeStr == "SZEGED_STOP") { + return PERMIT_TYPE::SZEGED_STOP; + } else + if (permitTypeStr == "FOOD_STAMP") { + return PERMIT_TYPE::FOOD_STAMP; + } else + if (permitTypeStr == "TWENTY_FOUR_HOURS_TICKET") { + return PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET; + } else + if (permitTypeStr == "SHORT_TERM_PARKING_PKW") { + return PERMIT_TYPE::SHORT_TERM_PARKING_PKW; + } else + if (permitTypeStr == "SHORT_TERM_PARKING_BUS") { + return PERMIT_TYPE::SHORT_TERM_PARKING_BUS; + } else + if (permitTypeStr == "SHORT_TERM_PARKING_CAMPER") { + return PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER; + } else + if (permitTypeStr == "DAY_TICKET_PKW") { + return PERMIT_TYPE::DAY_TICKET_PKW; + } else + if (permitTypeStr == "DAY_TICKET_BUS") { + return PERMIT_TYPE::DAY_TICKET_BUS; + } else + if (permitTypeStr == "DAY_TICKET_CAMPER") { + return PERMIT_TYPE::DAY_TICKET_CAMPER; + } + + return PERMIT_TYPE::INVALID; + } + + QString toString() { + switch(m_permitType) { + case PERMIT_TYPE::DAY_TICKET: + return QString("DAY_TICKET"); + case PERMIT_TYPE::DAY_TICKET_ADULT: + return QString("DAY_TICKET_ADULT"); + case PERMIT_TYPE::DAY_TICKET_CHILD: + return QString("DAY_TICKET_CHILD"); + case PERMIT_TYPE::DAY_TICKET_TEEN: + return QString("DAY_TICKET_TEEN"); + case PERMIT_TYPE::SHORT_TERM_PARKING: + return QString("SHORT_TERM_PARKING"); + case PERMIT_TYPE::SZEGED_START: + return QString("SZEGED_START"); + case PERMIT_TYPE::SZEGED_STOP: + return QString("SZEGED_STOP"); + case PERMIT_TYPE::FOOD_STAMP: + return QString("FOOD_STAMP"); + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: + return QString("TWENTY_FOUR_HOURS_TICKET"); + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: + return QString("SHORT_TERM_PARKING_PKW"); + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: + return QString("SHORT_TERM_PARKING_BUS"); + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + return QString("SHORT_TERM_PARKING_CAMPER"); + case PERMIT_TYPE::DAY_TICKET_PKW: + return QString("DAY_TICKET_PKW"); + case PERMIT_TYPE::DAY_TICKET_BUS: + return QString("DAY_TICKET_BUS"); + case PERMIT_TYPE::DAY_TICKET_CAMPER: + return QString("DAY_TICKET_CAMPER"); + default: + break; + } + return QString("INVALID"); + } + + QString toString() const { + switch(m_permitType) { + case PERMIT_TYPE::DAY_TICKET: + return QString("DAY_TICKET"); + case PERMIT_TYPE::DAY_TICKET_ADULT: + return QString("DAY_TICKET_ADULT"); + case PERMIT_TYPE::DAY_TICKET_CHILD: + return QString("DAY_TICKET_CHILD"); + case PERMIT_TYPE::DAY_TICKET_TEEN: + return QString("DAY_TICKET_TEEN"); + case PERMIT_TYPE::SHORT_TERM_PARKING: + return QString("SHORT_TERM_PARKING"); + case PERMIT_TYPE::SZEGED_START: + return QString("SZEGED_START"); + case PERMIT_TYPE::SZEGED_STOP: + return QString("SZEGED_STOP"); + case PERMIT_TYPE::FOOD_STAMP: + return QString("FOOD_STAMP"); + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: + return QString("TWENTY_FOUR_HOURS_TICKET"); + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: + return QString("SHORT_TERM_PARKING_PKW"); + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: + return QString("SHORT_TERM_PARKING_BUS"); + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + return QString("SHORT_TERM_PARKING_CAMPER"); + case PERMIT_TYPE::DAY_TICKET_PKW: + return QString("DAY_TICKET_PKW"); + case PERMIT_TYPE::DAY_TICKET_BUS: + return QString("DAY_TICKET_BUS"); + case PERMIT_TYPE::DAY_TICKET_CAMPER: + return QString("DAY_TICKET_CAMPER"); + default: + break; + } + return QString("INVALID"); + } + + operator QString () { + return toString(); + } + + operator QString () const { + return toString(); + } +}; + +#endif // TARIFF_PERMIT_TYPE_H_INCLUDED diff --git a/library/include/mobilisis/tariff_prepaid.h b/library/include/mobilisis/tariff_prepaid.h new file mode 100644 index 0000000..db3eaaa --- /dev/null +++ b/library/include/mobilisis/tariff_prepaid.h @@ -0,0 +1,160 @@ +#ifndef TARIFF_PREPAID_H_INCLUDED +#define TARIFF_PREPAID_H_INCLUDED + +#include +#include + +#include "time_range.h" + +enum class ApplyPrepaid { + NEVER = 0, + MATCH_PREV_DAY = 1, + MATCH_NEXT_DAY = 2, + ALWAYS = 3 +}; + +struct ATBTariffPrepaid { + int m_id; + QString m_weekDay; + QDate m_date; + TimeRange m_range; + ApplyPrepaid m_prepaidIf; + + explicit ATBTariffPrepaid() + : m_id(-1) + , m_prepaidIf(ApplyPrepaid::NEVER) { + } + + void setPrepaidIf(QString const &ppif) { + if (ppif == "never") { + m_prepaidIf = ApplyPrepaid::NEVER; + } else + if (ppif == "match_prev_day") { + m_prepaidIf = ApplyPrepaid::MATCH_PREV_DAY; + } else + if (ppif == "match_next_day") { + m_prepaidIf = ApplyPrepaid::MATCH_NEXT_DAY; + } else + if (ppif == "always") { + m_prepaidIf = ApplyPrepaid::ALWAYS; + } else { + qCritical() << "ERROR unknown carry over application" << ppif; + } + } + + ApplyPrepaid prepaidIf() const { + return m_prepaidIf; + } + + QString prepaidIfStr() const { + if (m_prepaidIf == ApplyPrepaid::NEVER) { + return "never"; + } + if (m_prepaidIf == ApplyPrepaid::ALWAYS) { + return "always"; + } + if (m_prepaidIf == ApplyPrepaid::MATCH_PREV_DAY) { + return "match prev day"; + } + if (m_prepaidIf == ApplyPrepaid::MATCH_NEXT_DAY) { + return "match next day"; + } + return QString("ERROR unknown prepaid application: %1").arg(static_cast(m_prepaidIf)); + } + + friend QDebug operator<<(QDebug debug, ATBTariffPrepaid const &pp) { + QDebugStateSaver saver(debug); + + debug.nospace() + << "\nTariffPrepaid:\n" + << " week day: " << pp.m_weekDay << "\n" + << " date: " << pp.m_date.toString(Qt::ISODate) << "\n" + << " id: " << pp.m_id << "\n" + << " start: " << pp.m_range.m_start << "\n" + << " end: " << pp.m_range.m_end << "\n" + << " duration: " << pp.m_range.m_duration << "\n" + << " prepaid if: " << pp.prepaidIfStr() << endl; + return debug; + } +}; + +// deprecated + +struct ATBPrepaid { + int id; + bool anytime; + bool never; + QTime static_start; + QTime static_end; + + struct week { + int day; + QTime static_start; + QTime static_end; + int duration; + } prepaid[8]; + + explicit ATBPrepaid() + : id(-1) + , anytime(false) + , never(false) + , static_start(QTime(23, 59, 59)) + , static_end(QTime(0, 0, 0)) { + + for (int i = 0 ; i < 8; ++i) { + prepaid[i].day = -1; + prepaid[i].static_start = QTime(23, 59, 59); + prepaid[i].static_end = QTime(0, 0, 0); + prepaid[i].duration = -1; + } + } + + friend QDebug operator<<(QDebug debug, ATBPrepaid const &pp) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " id: " << pp.id << "\n" + << " static_start: " << pp.static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.static_end.toString(Qt::ISODate) << "\n" + << " anytime: " << pp.anytime << "\n" + << " never: " << pp.never << "\n" + << " **** Monday **** \n" + << " day: " << pp.prepaid[(int)Qt::Monday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Monday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Monday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Monday].duration << "\n" + << " **** Tuesday **** \n" + << " day: " << pp.prepaid[(int)Qt::Tuesday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Tuesday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Tuesday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Tuesday].duration << "\n" + << " **** Wednesday **** \n" + << " day: " << pp.prepaid[(int)Qt::Wednesday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Wednesday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Wednesday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Wednesday].duration << "\n" + << " **** Thursday **** \n" + << " day: " << pp.prepaid[(int)Qt::Thursday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Thursday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Thursday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Thursday].duration << "\n" + << " **** Friday **** \n" + << " day: " << pp.prepaid[(int)Qt::Friday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Friday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Friday].static_end.toString(Qt::ISODate) << "\n" + << " **** Saturday **** \n" + << " day: " << pp.prepaid[(int)Qt::Saturday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Saturday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Saturday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Saturday].duration << "\n" + << " **** Sunday **** \n" + << " day: " << pp.prepaid[(int)Qt::Sunday].day << "\n" + << " static_start: " << pp.prepaid[(int)Qt::Sunday].static_start.toString(Qt::ISODate) << "\n" + << " static_end: " << pp.prepaid[(int)Qt::Sunday].static_end.toString(Qt::ISODate) << "\n" + << " duration: " << pp.prepaid[(int)Qt::Sunday].duration << "\n"; + + return debug; + } +}; + +#endif // TARIFF_PREPAID_H_INCLUDED diff --git a/library/include/mobilisis/tariff_product.h b/library/include/mobilisis/tariff_product.h new file mode 100644 index 0000000..56b61cd --- /dev/null +++ b/library/include/mobilisis/tariff_product.h @@ -0,0 +1,66 @@ +#ifndef TARIFF_PRODUCT_H_INCLUDED +#define TARIFF_PRODUCT_H_INCLUDED + +#include +#include +#include +#include + +#include "tariff_permit_type.h" + +struct ATBTariffProduct { + PermitType m_tariff_product_id; + uint32_t m_tariff_product_price; + QString m_tariff_product_name; + QTime m_tariff_product_start; + QTime m_tariff_product_end; + int m_tariff_product_from_in_minutes_from_start; + int m_tariff_product_to_in_minutes_from_start; + + explicit ATBTariffProduct() = default; + + QTime const &getTimeStart() const { return m_tariff_product_start; } + QTime const &getTimeEnd() const { return m_tariff_product_end; } + + bool computeQTimeStart(QTime const &t) { + if (m_tariff_product_from_in_minutes_from_start != -1) { + m_tariff_product_start = t.addSecs(m_tariff_product_from_in_minutes_from_start * 60); + return m_tariff_product_start.isValid(); + } + return false; + } + + bool computeQTimeEnd(QTime const &t) { + if (m_tariff_product_to_in_minutes_from_start != -1) { + m_tariff_product_end = t.addSecs(m_tariff_product_from_in_minutes_from_start * 60); + return m_tariff_product_end.isValid(); + } + return false; + } + + bool computeQTimes(QTime const &t) { + if (!t.isNull() && t.isValid()) { + return computeQTimeStart(t) && computeQTimeEnd(t); + } + return false; + } + + uint32_t getProductPrice() const { return m_tariff_product_price; } + + friend QDebug operator<<(QDebug debug, ATBTariffProduct const &product) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " m_tariff_product_id: " << QString(product.m_tariff_product_id) << "\n" + << " m_tariff_product_name: " << product.m_tariff_product_name << "\n" + << " m_tariff_product_price: " << product.m_tariff_product_price << "\n" + << " m_tariff_product_start: " << product.m_tariff_product_start << "\n" + << " m_tariff_product_end: " << product.m_tariff_product_end << "\n" + << "m_tariff_product_from_in_minutes_from_start: " << product.m_tariff_product_from_in_minutes_from_start << "\n" + << " m_tariff_product_to_in_minutes_from_start: " << product.m_tariff_product_to_in_minutes_from_start << "\n"; + + return debug; + } +}; + +#endif // TARIFF_PRODUCT_H_INCLUDED diff --git a/library/include/mobilisis/tariff_service.h b/library/include/mobilisis/tariff_service.h new file mode 100644 index 0000000..601fbe2 --- /dev/null +++ b/library/include/mobilisis/tariff_service.h @@ -0,0 +1,81 @@ +#ifndef TARIFF_SERVICE_H_INCLUDED +#define TARIFF_SERVICE_H_INCLUDED + +#include +#include + +#include "time_range.h" + +enum class ApplyService { + NEVER = 0, + MATCH_PREV_DAY = 1, + MATCH_NEXT_DAY = 2, + ALWAYS = 3 +}; + +struct ATBTariffService { + int m_id; + QString m_weekDay; + QDate m_date; + TimeRange m_range; + ApplyService m_serviceIf; + + explicit ATBTariffService() + : m_id(-1) + , m_serviceIf(ApplyService::NEVER) { + } + + void setServiceIf(QString const &sif) { + if (sif == "never") { + m_serviceIf = ApplyService::NEVER; + } else + if (sif == "match_prev_day") { + m_serviceIf = ApplyService::MATCH_PREV_DAY; + } else + if (sif == "match_next_day") { + m_serviceIf = ApplyService::MATCH_NEXT_DAY; + } else + if (sif == "always") { + m_serviceIf = ApplyService::ALWAYS; + } else { + qCritical() << "ERROR unknown servcie application" << sif; + } + } + + ApplyService serviceIf() const { + return m_serviceIf; + } + + QString serviceIfStr() const { + if (m_serviceIf == ApplyService::NEVER) { + return "never"; + } + if (m_serviceIf == ApplyService::ALWAYS) { + return "always"; + } + if (m_serviceIf == ApplyService::MATCH_PREV_DAY) { + return "match prev day"; + } + if (m_serviceIf == ApplyService::MATCH_NEXT_DAY) { + return "match next day"; + } + return QString("ERROR unknown service application: %1").arg(static_cast(m_serviceIf)); + } + + friend QDebug operator<<(QDebug debug, ATBTariffService const &ts) { + QDebugStateSaver saver(debug); + + debug.nospace() + << "\nTariffService:\n" + << " week day: " << ts.m_weekDay << "\n" + << " date: " << ts.m_date.toString(Qt::ISODate) << "\n" + << " id: " << ts.m_id << "\n" + << " start: " << ts.m_range.m_start << "\n" + << " end: " << ts.m_range.m_end << "\n" + << " duration: " << ts.m_range.m_duration << "\n" + << " prepaid if: " << ts.serviceIfStr() << endl; + return debug; + } +}; + +#endif // TARIFF_SERVICE_H_INCLUDED diff --git a/library/include/mobilisis/tariff_settings.h b/library/include/mobilisis/tariff_settings.h new file mode 100644 index 0000000..03afd4b --- /dev/null +++ b/library/include/mobilisis/tariff_settings.h @@ -0,0 +1,40 @@ +#ifndef ATB_TARIFF_SETTINGS_H_INCLUDED +#define ATB_TARIFF_SETTINGS_H_INCLUDED + +#include + +struct ATBTariffSettings { + int m_max_price; + int m_min_price; + int m_max_time; + int m_min_time; + + explicit ATBTariffSettings() + : m_max_price(0) + , m_min_price(0) + , m_max_time(0) + , m_min_time(0) { + } + + explicit ATBTariffSettings(int max_price, int min_price, int max_time, int min_time) + : m_max_price(max_price) + , m_min_price(min_price) + , m_max_time(max_time) + , m_min_time(min_time) { + } + + friend QDebug operator<<(QDebug debug, ATBTariffSettings const &ts) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " max_price: " << ts.m_max_price << "\n" + << " min_price: " << ts.m_min_price << "\n" + << " max_time: " << ts.m_max_time << "\n" + << " min_time: " << ts.m_min_time << endl; + + return debug; + } +}; + + +#endif // ATB_TARIFF_SETTINGS_H_INCLUDED diff --git a/library/include/mobilisis/tariff_time_range.h b/library/include/mobilisis/tariff_time_range.h index 55243e2..6201778 100644 --- a/library/include/mobilisis/tariff_time_range.h +++ b/library/include/mobilisis/tariff_time_range.h @@ -1,17 +1,34 @@ -// #pragma once #ifndef TARIFF_TIME_RANGE_H_INCLUDED #define TARIFF_TIME_RANGE_H_INCLUDED -#include +#include /// /// Time range definition /// class TariffTimeRange { + QTime m_time_from; // if m_time_from == m_time_until, then the time range + QTime m_time_until; // actually is the time point m_time_from + public: - time_t time_from; - time_t time_to; - TariffTimeRange() : time_from(0), time_to(0) {} + + TariffTimeRange() + : m_time_from(QTime()) + , m_time_until(QTime()) {} + + TariffTimeRange(QTime const& from, QTime const &until) + : m_time_from(from) + , m_time_until(until) { + + } + + void setTimeRange(QTime const& from, QTime const &until) { + m_time_from = from; + m_time_until = until; + } + + QTime const &getTimeFrom() const { return m_time_from; } + QTime const &getTimeUntil() const { return m_time_until; } }; #endif // TARIFF_TIME_RANGE_H_INCLUDED diff --git a/library/include/mobilisis/tariff_timebase.h b/library/include/mobilisis/tariff_timebase.h new file mode 100644 index 0000000..8c075de --- /dev/null +++ b/library/include/mobilisis/tariff_timebase.h @@ -0,0 +1,44 @@ +#ifndef TARIFF_TIME_BASE_H_INCLUDED +#define TARIFF_TIME_BASE_H_INCLUDED + +#include +#include +#include + +struct ATBTimeBase { + enum class TimeBaseType {ABSOLUTE=0, RELATIVE=1}; + + ATBTimeBase() = default; + int tbase_id; + TimeBaseType tbase_type; + QString tbase_label; + + friend QDebug operator<<(QDebug debug, ATBTimeBase const &timeBase) { + QDebugStateSaver saver(debug); + + debug.nospace() << "TIMEBASE" << "\n"; + + switch(timeBase.tbase_type) { + case ATBTimeBase::TimeBaseType::ABSOLUTE: + debug.nospace() + << " tbase_id: " << timeBase.tbase_id << "\n" + << " tbase_type: " << "TimeBaseType::ABSOLUTE" << "\n" + << "tbase_label: " << timeBase.tbase_label << "\n"; + break; + case ATBTimeBase::TimeBaseType::RELATIVE: + debug.nospace() + << " tbase_type: " << "TimeBaseType::RELATIVE" << "\n" + << "tbase_label: " << timeBase.tbase_label << "\n"; + break; + default: + debug.nospace() + << " tbase_type: " << "TimeBaseType::???" << "\n"; + break; + } + + return debug; + } + +}; + +#endif // TARIFF_TIME_BASE_H_INCLUDED diff --git a/library/include/mobilisis/tariff_timestep_config.h b/library/include/mobilisis/tariff_timestep_config.h new file mode 100644 index 0000000..861c9e1 --- /dev/null +++ b/library/include/mobilisis/tariff_timestep_config.h @@ -0,0 +1,26 @@ +#ifndef TARIFF_TIMESTEP_CONFIG_H_INCLUDED +#define TARIFF_TIMESTEP_CONFIG_H_INCLUDED + +#include +#include +#include + +struct ATBTimeStepConfig { + enum class TimeStepConfig {STATIC=1, DYNAMIC=2}; + + ATBTimeStepConfig() = default; + int tsconfig_id; + QString tsconfig_label; + + friend QDebug operator<<(QDebug debug, ATBTimeStepConfig const &tsConfig) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " tsconfig_id: " << tsConfig.tsconfig_id << "\n" + << "tsconfig_label: " << tsConfig.tsconfig_label << "\n"; + + return debug; + } +}; + +#endif // TARIFF_TIMESTEP_CONFIG_H_INCLUDED diff --git a/library/include/mobilisis/ticket.h b/library/include/mobilisis/ticket.h new file mode 100644 index 0000000..228a752 --- /dev/null +++ b/library/include/mobilisis/ticket.h @@ -0,0 +1,66 @@ +#ifndef TICKET_H_INCLUDED +#define TICKET_H_INCLUDED + +#include +#include + +#include +#include +#include +#include + +#define NOT_INITIALIZED (0) +#define VALID (1) +#define INVALID_FROM_DATETIME (2) +#define INVALID_UNTIL_DATETIME (3) +#define INVALID_PRICE (4) +#define STATUS_END (5) + +class Ticket { + enum {CODE=0, CODE_STR=1, CODE_DESC=3}; +public: + using Status = std::tuple; + + explicit Ticket(); + explicit Ticket(QDateTime const &s, QDateTime const &e, + int durationMinutesNetto, int durationMinutesBrutto, + uint32_t price, Status status); + + explicit operator bool() { return std::get(m_status) == VALID; } + operator QString(); + + Status getStatus() const; + QDateTime getValidFrom() const; + QDateTime getValidUntil() const; + uint32_t getPrice() const; + + Status setStatus(Status status); + void setValidFrom(QDateTime const &validFrom); + void setValidUntil(QDateTime const &validUnil); + void setPrice(uint32_t price); + + bool isValid() { return operator bool(); } + + static constexpr const Status s[STATUS_END] = { + {NOT_INITIALIZED , "NOT_INITIALIZED" , "Ticket not initialized" }, + {VALID , "VALID" , "Ticket is valid" }, + {INVALID_FROM_DATETIME , "INVALID_FROM_DATETIME" , "Ticket has invalid start datetime"}, + {INVALID_UNTIL_DATETIME, "INVALID_UNTIL_DATETIME", "Ticket has invalid end datetime" }, + {INVALID_PRICE , "INVALID_PRICE" , "PARKING NOT ALLOWED: Ticket has invalid price" } + }; + +private: + Status m_status; + + QDateTime m_validFrom; + QDateTime m_validUntil; + + int m_durationMinutesNetto; + int m_durationMinutesBrutto; + + uint32_t m_price; +}; + +QDebug operator<<(QDebug debug, Ticket::Status const &status); + +#endif // TICKET_H_INCLUDED diff --git a/library/include/mobilisis/time_range.h b/library/include/mobilisis/time_range.h index 54272ad..c95f387 100644 --- a/library/include/mobilisis/time_range.h +++ b/library/include/mobilisis/time_range.h @@ -1,8 +1,46 @@ -#pragma once -#include "time_range_header.h" - -struct TimeRange { -public: - bool IsActive; - ATBTimeRange TimeRangeStructure; -}; \ No newline at end of file +#ifndef TIME_RANGE_H_INCLUDED +#define TIME_RANGE_H_INCLUDED + +#include "atb_time.h" + +#include + +struct TimeRange { + ATBTime m_start; + ATBTime m_end; + int m_duration; + + explicit TimeRange() = default; + explicit TimeRange(QString const &start, QString const &end, int duration) + : m_start(start) + , m_end(end) + , m_duration(duration) { + } + explicit TimeRange(ATBTime const &start, ATBTime const &end, int duration) + : m_start(start) + , m_end(end) + , m_duration(duration) { + } + + explicit TimeRange(TimeRange const &timeRange) { + m_start = timeRange.m_start; + m_end = timeRange.m_end; + m_duration = timeRange.m_duration; + } + + TimeRange &operator=(TimeRange && timeRange) { + m_start = std::move(timeRange.m_start); + m_end = std::move(timeRange.m_end); + m_duration = timeRange.m_duration; + return *this; + } + + TimeRange &operator=(TimeRange const &timeRange) { + m_start = timeRange.m_start; + m_end = timeRange.m_end; + m_duration = timeRange.m_duration; + return *this; + } +}; + +#endif // TIME_RANGE_H_INCLUDED diff --git a/library/include/mobilisis/time_range_header.h b/library/include/mobilisis/time_range_header.h index feb5d5c..4b82784 100644 --- a/library/include/mobilisis/time_range_header.h +++ b/library/include/mobilisis/time_range_header.h @@ -1,8 +1,70 @@ -#pragma once -#include +#ifndef TIME_RANGE_HEADER_H_INCLUDED +#define TIME_RANGE_HEADER_H_INCLUDED -class ATBTimeRange { -public: - time_t time_from; - time_t time_to; -}; \ No newline at end of file +#include +#include +#include +#include + +struct ATBTimeRange { + int time_range_id; + QTime time_range_from; + QTime time_range_to; + int time_range_from_in_minutes_from_start; + int time_range_to_in_minutes_from_start; + int time_range_tbase_id; + int time_range_payment_type_id; + + explicit ATBTimeRange() + : time_range_id(-1) + , time_range_from(QTime()) + , time_range_to(QTime()) + , time_range_from_in_minutes_from_start(-1) + , time_range_to_in_minutes_from_start(-1) + , time_range_tbase_id(-1) + , time_range_payment_type_id(-1) { + } + + QTime const &getTimeFrom() const { return time_range_from; } + QTime const &getTimeUntil() const { return time_range_to; } + + bool computeQTimeFrom(QTime const &t) { + if (time_range_from_in_minutes_from_start != -1) { + time_range_from = t.addSecs(time_range_from_in_minutes_from_start * 60); + return time_range_from.isValid(); + } + return false; + } + + bool computeQTimeTo(QTime const &t) { + if (time_range_to_in_minutes_from_start != -1) { + time_range_to = t.addSecs(time_range_to_in_minutes_from_start * 60); + return time_range_to.isValid(); + } + return false; + } + + bool computeQTimes(QTime const &t) { + if (!t.isNull() && t.isValid()) { + return computeQTimeFrom(t) && computeQTimeTo(t); + } + return false; + } + + friend QDebug operator<<(QDebug debug, ATBTimeRange const &timeRange) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " time_range_id: " << timeRange.time_range_id << "\n" + << " time_range_from: " << timeRange.time_range_from.toString(Qt::ISODate) << "\n" + << " time_range_to: " << timeRange.time_range_to.toString(Qt::ISODate) << "\n" + << " time_range_from_in_minutes_from_start: " << timeRange.time_range_from_in_minutes_from_start << "\n" + << " time_range_to_in_minutes_from_start: " << timeRange.time_range_to_in_minutes_from_start << "\n" + << " time_range_tbase_id: " << timeRange.time_range_tbase_id << "\n" + << " time_range_payment_type_id: " << timeRange.time_range_payment_type_id << "\n"; + + return debug; + } +}; + +#endif // TIME_RANGE_HEADER_H_INCLUDED diff --git a/library/include/mobilisis/utilities.h b/library/include/mobilisis/utilities.h index 09de817..9c9a46a 100644 --- a/library/include/mobilisis/utilities.h +++ b/library/include/mobilisis/utilities.h @@ -1,73 +1,106 @@ -#pragma once -#include -#include -#include -#include -#include - -#include "day_of_week.h" -#include "configuration.h" -#include "time_range.h" - -using namespace std; - -class Utilities { -public: - - /// - /// Get day of week from current date (Zeller's Algorithm), starting day is Sunday - /// - /// - /// - static DayOfWeek GetDayOfWeek(struct tm* tm); - - /// - /// Date and time parse helper function - /// - /// Returns time (tm) structure - static struct tm DateTimeToStructTm(const char* dateTimeStr); - - /// - /// Date parse helper function - /// - /// Returns time (tm) structure - static struct tm DateToStructTm(const char* dateStr); - - /// - /// Time parse helper function - /// - /// Returns time (tm) structure - static struct tm TimeToStructTm(const char* timeStr, int year, int mon, int mday, int wday); - - /// - /// Get current local time - /// - /// Returns time_t structure - static time_t GetCurrentLocalTime(); - - /// - /// Zeller's algorithm for determining day of week - /// - static int ZellersAlgorithm(int day, int month, int year); - - /// - /// Checks if current datetime is in range between start and end month of parking worktime - /// - /// - /// - /// - static bool IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTime); - - /// - /// Check permissions - /// - static bool CheckSpecialDay(Configuration* cfg, const char* currentDateTimeStr, int* specialDayId, double* specialDayPrice); - - /// - /// Calculates price per unit - /// - /// - /// - static double CalculatePricePerUnit(double pra_price, double durationUnit = -1); - -}; +#pragma once +#include +#include +#include +#include +#include + +#include "day_of_week.h" +#include "configuration.h" +#include "time_range.h" +#include "payment_method.h" +#include "tariff_business_hours.h" + +#include + +using namespace std; + +namespace Utilities { + + bool isDayIncluded(uint64_t businessHours, QDateTime const &dt); + + /// + /// Get day of week from current date (Zeller's Algorithm), starting day is Sunday + /// + /// + /// + DayOfWeek GetDayOfWeek(struct tm* tm); + + /// + /// Date and time parse helper function + /// + /// Returns time (tm) structure + struct tm DateTimeToStructTm(const char* dateTimeStr); + + /// + /// Date parse helper function + /// + /// Returns time (tm) structure + struct tm DateToStructTm(const char* dateStr); + + /// + /// Time parse helper function + /// + /// Returns time (tm) structure + struct tm TimeToStructTm(const char* timeStr, int year, int mon, int mday, int wday); + + /// + /// Get current local time + /// + /// Returns time_t structure + time_t GetCurrentLocalTime(); + + /// + /// Zeller's algorithm for determining day of week + /// + int ZellersAlgorithm(int day, int month, int year); + + /// + /// Checks if current datetime is in range between start and end month of parking worktime + /// + /// + /// + /// + bool IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTime); + bool IsYearPeriodActive(Configuration const *cfg, QDateTime const ¤tDateTime); + std::optional GetYearPeriodActive(Configuration const *cfg, QDateTime const ¤tDateTime); + + /// + /// Check permissions + /// + bool CheckSpecialDay(Configuration* cfg, const char* currentDateTimeStr, int* specialDayId, double* specialDayPrice); + bool CheckSpecialDay(Configuration const *cfg, + QDateTime const ¤tDateTimeS, + int* specialDayId, uint32_t *specialDayPrice); + + /// + /// Calculates price per unit + /// + /// + /// + double CalculatePricePerUnit(double pra_price, double durationUnit = -1); + + QTime SpecialDaysWorkTimeFrom(Configuration const *cfg, int specialDayId); + QTime SpecialDaysWorkTimeFrom(Configuration::SpecialDaysWorktimeType::const_iterator const &it); + QTime SpecialDaysWorkTimeUntil(Configuration const *cfg, int specialDayId); + QTime SpecialDaysWorkTimeUntil(Configuration::SpecialDaysWorktimeType::const_iterator const &it); + QTime WeekDaysWorkTimeFrom(std::multimap::const_iterator const &itr); + QTime WeekDaysWorkTimeUntil(std::multimap::const_iterator const &itr); + int WeekDayId(std::multimap::const_iterator const &itr); + // PaymentRate GetPaymentRate(Configuration const *cfg, ); + bool isCarryOverSet(Configuration const *cfg, PaymentMethod paymentMethodId); + bool isCarryOverNotSet(Configuration const *cfg, PaymentMethod paymentMethodId); + PaymentMethod getPaymentMethodId(Configuration const *cfg); + + int getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId); + int getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId); + uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId); + uint32_t getMaximalParkingPrice(Configuration const *cfg, PaymentMethod methodId); + uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId); + uint32_t getTimeRangeStep(Configuration const *cfg, int step, PaymentMethod methodId); + BusinessHours getBusinessHours(Configuration const *cfg, PaymentMethod methodId); + uint32_t computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id); + double computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id); + QStringList dumpBusinessHours(uint64_t businessHours); + uint32_t getDailyTicketCardPrice(Configuration const *cfg, PaymentMethod methodId); +} diff --git a/library/include/mobilisis/weekdays.h b/library/include/mobilisis/weekdays.h index 3911cf5..e5187e9 100644 --- a/library/include/mobilisis/weekdays.h +++ b/library/include/mobilisis/weekdays.h @@ -1,10 +1,57 @@ -#pragma once -#include +#include "tariff_settings.h" +#include "tariff_carryover_settings.h" -class ATBWeekDays -{ -public: - int pdiw_id; - std::string pdiw_label; - int pdiw_index; -}; \ No newline at end of file +#include +#include +#include + +struct ATBWeekDay { + enum WeekDayType {USUAL_WEEKDAY=0, HOLIDAY=1}; + + Qt::DayOfWeek m_id; + QString m_name; + QDate m_date; + WeekDayType m_type; + ATBTariffSettings m_tariffSettings; + ATBTariffCarryOverSettings m_tariffCarryOverSettings; + + explicit ATBWeekDay() + : m_id(Qt::Monday) + , m_name("") + , m_date(QDate()) + , m_type(USUAL_WEEKDAY) + , m_tariffSettings() + , m_tariffCarryOverSettings() {} + + explicit ATBWeekDay(Qt::DayOfWeek id, QString const &name, WeekDayType type, + QDate const &date, + ATBTariffSettings const &tariffSettings, + ATBTariffCarryOverSettings const &tariffCarryOverSettings) + : m_id(id) + , m_name(name) + , m_date(date) + , m_type(type) + , m_tariffSettings(tariffSettings) + , m_tariffCarryOverSettings(tariffCarryOverSettings) {} + + ATBTariffCarryOverSettings &getTariffCarryOverSettings() { return m_tariffCarryOverSettings; } + ATBTariffCarryOverSettings const &getTariffCarryOverSettings() const { return m_tariffCarryOverSettings; } + + ATBTariffSettings &getTariffSettings() { return m_tariffSettings; } + ATBTariffSettings const &getTariffSettings() const { return m_tariffSettings; } + + friend QDebug operator<<(QDebug debug, ATBWeekDay const &wd) { + QDebugStateSaver saver(debug); + + debug.nospace() + << " id: " << (int)wd.m_id << "\n" + << " name: " << wd.m_name << "\n" + << " type: " << (int)wd.m_type << "\n\n" + << " tariff settings: " << "\n" + << wd.m_tariffSettings << "\n" + << "tariff carryover settings: " << "\n" + << wd.m_tariffCarryOverSettings << endl; + + return debug; + } +}; diff --git a/library/include/mobilisis/weekdays_worktime.h b/library/include/mobilisis/weekdays_worktime.h index ceaf61c..3a21797 100644 --- a/library/include/mobilisis/weekdays_worktime.h +++ b/library/include/mobilisis/weekdays_worktime.h @@ -4,8 +4,10 @@ class ATBWeekDaysWorktime { public: - int pwd_id; - int pwd_period_week_day_id; + int pwd_id; + int pwd_pop_id; + int pwd_next_id; + int pwd_period_week_day_id; int pwd_period_day_in_week_id; std::string pwd_time_from; std::string pwd_time_to; diff --git a/library/kleipeda/calculate_price.cpp b/library/kleipeda/calculate_price.cpp new file mode 100644 index 0000000..ad569fd --- /dev/null +++ b/library/kleipeda/calculate_price.cpp @@ -0,0 +1,1255 @@ +#include "calculate_price.h" +#include "configuration.h" +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" +#include "tariff_global_defines.h" +#include "period_year.h" + +#include +#include +#include +#include +#include + +QString const CalcState::SUCCESS = "SUCCESS"; +QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR"; +QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF"; +QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF"; +QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME"; +QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE"; +QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES"; +QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT"; +QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE"; +QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE"; +QString const CalcState::OVERPAID = "OVERPAID"; +QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { + return Calculator::GetInstance().GetTimeSteps(cfg); +} + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int minTime = 0; + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + qCritical() << __func__ << __LINE__ << "permit" << PermitType(permitType).toString(); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + qCritical() << __func__ << __LINE__ << minTime; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: + // for each new sell-procedure, recomute the timesteps. implicitly, set + // the minimal parking time. + Calculator::GetInstance().ResetTimeSteps(paymentOptionIndex); + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = qRound(cfg->getPaymentOptions(paymentOptionIndex).pop_min_time); + } + + qCritical() << "minTime" << minTime; + return minTime; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + int maxTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: ; + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } + + return maxTime; +} + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex, + QDateTime const &start) { + int minPrice = -1; + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg, start)) == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + int payment_method_id = cfg->getPaymentOptions(paymentOptionIndex).pop_payment_method_id; + + if (payment_method_id == PaymentMethod::Degressive) { + // Degressive: new for Fuchs Technik (500), ValserAlm (Fane): + // the minimal price has to be calculated, in cannot be hard coded into + // the tariff file. + // The working times have a reference into the payment rates. Two special + // entries (with the numbers 1000/1001) point to the respective prices. + switch(permitType) { + default: { + // find the correct work time range + int weekDay = start.date().dayOfWeek(); + std::optional> const &wd = cfg->getAllWeekDayWorkTimes(); + if (wd.has_value()) { + QVector const &vec = wd.value(); + for (int i = 0; i < vec.size(); ++i) { + ATBWeekDaysWorktime const &wt = vec[i]; + if (wt.pwd_period_day_in_week_id == weekDay) { + if (start.time() >= QTime::fromString(QString::fromStdString(wt.pwd_time_from), Qt::ISODate) + && start.time() <= QTime::fromString(QString::fromStdString(wt.pwd_time_to), Qt::ISODate)) { + // found worktime range + int pop_id = wt.pwd_pop_id; // 1000 or 1001 + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + i = vec.size(); // to leave outer loop + minPrice = itr->second.pra_price; // this is now the minimal price + break; + } + } + } + } + } + } + } + } else { + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + case PERMIT_TYPE::DAY_TICKET: { + minPrice = compute_product_price(cfg, permitType, start); + } break; + default: + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } + } + + return minPrice; +} + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType, + QDateTime const &start, + QDateTime *productStart, + QDateTime *productEnd) { + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_TEEN: + // [[fallthrough]]; + case PERMIT_TYPE::FOOD_STAMP: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + if (product.size() > 0) { + ATBTariffProduct const &p = product[0]; + return p.m_tariff_product_price; +#if 0 + // in case we do not have prepaid-option + QTime const ¤tTime = QDateTime::currentDateTime().time(); + + if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) { + return p.m_tariff_product_price; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "ERROR currentTime" + << currentTime.toString(Qt::ISODate) + << "INVALID (" + << p.m_tariff_product_start.toString(Qt::ISODate) + << p.m_tariff_product_end.toString(Qt::ISODate) << ")"; + } +#endif + } + } + } break; + case PERMIT_TYPE::INVALID: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + int product_price = 0; + + if (productStart && productEnd) { + *productStart = start; + *productEnd = start; + if (product.size() > 0) { + productStart->setTime(product[0].getTimeStart()); + productEnd->setTime(product[0].getTimeEnd()); + } + } + + for (QVector::size_type i=0; i= startTime && start.time() < endTime) { + product_price = p.getProductPrice(); + if (productStart && productEnd) { + productStart->setTime(startTime); + productEnd->setTime(endTime); + } + } + } + + return product_price; + } else { + // SZEGED + int const pop_daily_card_price = cfg->getPaymentOptions().pop_daily_card_price; + + qDebug() << QString("(%1:%2) no products defined in tariff-file").arg(__func__).arg(__LINE__); + qDebug() << QString("(%1:%2) pop_daily_card_price=%3").arg(__func__).arg(__LINE__).arg(pop_daily_card_price); + + // static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + // return Utilities::getDailyTicketCardPrice(cfg, paymentMethodId); + + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + int product_price = 0; + QVector product = products.value(); + + if (product.size() > 0) { + if (productStart && productEnd) { + int pop_min_time = get_minimal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + int pop_max_time = get_maximal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + if (pop_max_time >= pop_min_time) { + *productStart = start; + *productEnd = start.addSecs(pop_max_time*60); + product_price = product[0].getProductPrice(); + } + } + } + + return product_price; + } + + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "SHORT_TERM_PARKING_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + qCritical() << "TODO: SHORT_TERM_PARKING_BUS"; + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: { + qCritical() << "TODO: SHORT_TERM_PARKING_CAMPER"; + } break; + case PERMIT_TYPE::DAY_TICKET_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_BUS: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_BUS: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_CAMPER: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + default: + break; + } + + return 0; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxPrice = -1; + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg)) == -1) { + qCritical() << "paymentOptionIndex" << paymentOptionIndex; + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + qCritical() << "YYYYYY paymentOptionIndex" << paymentOptionIndex; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + if (paymentMethodId == PaymentMethod::Progressive || paymentMethodId == PaymentMethod::Steps) { + //maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + maxPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price; // maxTime is given in minutes + qCritical() << "YYYYYY maxPrice" << maxPrice; + } else { // PaymentMethod::Linear -> e.g. szeged + int const key = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; // maxTime is given in minutes + std::optional> const &pv = cfg->getPaymentRateForKey(key); + if (pv) { + QVector const &paymentRate = pv.value(); + if (paymentRate.size() > 0) { + int const price = paymentRate.last().pra_price; // price is given per hour + maxPrice = qRound((maxTime * price) / 60.0f); + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: + break; + case PERMIT_TYPE::DAY_TICKET_TEEN: + break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + break; + case PERMIT_TYPE::DAY_TICKET_BUS: + break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: + break; + case PERMIT_TYPE::DAY_TICKET_PKW: + break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + break; + default: ; + } + + return maxPrice; +} + +int CALCULATE_LIBRARY_API get_zone_nr(int zone) +{ + if(zone > -1) return zone; + else + { + QFile zone("/etc/zone_nr"); + if (zone.exists()) { + QFileInfo finfo(zone); + if (finfo.size() <= 4) { // decimal 000\n + if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&zone); + return in.readLine(100).toInt(); + } + } + } + return -1; + } +} + +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { + *tariff = new Configuration(); + + CalcState calcState; +#if __linux__ + + int const zone = get_zone_nr(); + + // DEBUG + qCritical() << "init_tariff:"; + qCritical() << " ... zone = " << zone; + + if (zone <= 0) { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_PARSING_ZONE_NR); + } + + QString confFile(config_file); + if (!confFile.endsWith(QChar('/'))) { + confFile += "/"; + } + + char buffer[32]; + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone); + confFile += buffer; +#else // windows + QString confFile(config_file); +#endif + + // DEBUG + qCritical() << " ... confFile = " << confFile; + + QFile fname(confFile); + if (fname.exists() && + fname.open(QIODevice::ReadOnly | QIODevice::Text)) { + // DEBUG + qCritical() << " ... confFile is open"; + + QString json = fname.readAll(); + if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error parsing tariff"; + return calcState.set(CalcState::State::ERROR_PARSING_TARIFF); + } + } else { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error loading tariff"; + return calcState.set(CalcState::State::ERROR_LOADING_TARIFF); + } + + qCritical() << "init_tariff: Parsing tariff config (" << confFile << ")"; + + return calcState; +} + +void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { + if (tariff != nullptr) { + delete tariff; + } +} + +// +// UpDown 1 -> up; 0 -> down +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, + int UpDown, PermitType const &permitType) +{ + + qCritical() << __LINE__ << "compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() up/down (1=up, 0=down): " << UpDown; + + // FIXME + //std::optional paymentOption = tariff->getPaymentOptionForKey(permitType.get()); + //if (!paymentOption.has_value()) { + // qCritical() << " compute_next_timestep() ERROR"; + // return currentTimeMinutes; + //} + + int paymentOptionIndex = getPaymentOptionIndex(*tariff); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int const &pop_plus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_plus_steps; + int const &pop_minus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_minus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() payment option index: " << paymentOptionIndex; + qCritical() << __LINE__ << "compute_next_timestep() plus steps: " << pop_plus_steps; + qCritical() << __LINE__ << "compute_next_timestep() minus steps: " << pop_minus_steps; + + Configuration const *cfg = tariff; + + // compute payment method id (e.g. Linear=3, Steps=4) + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + switch (paymentMethodId) { + case PaymentMethod::Progressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Progressive"; + break; + case PaymentMethod::Degressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Degressive"; + break; + case PaymentMethod::Linear: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Linear"; + break; + case PaymentMethod::Steps: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps"; + break; + case PaymentMethod::Undefined: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined"; + break; + } + + // use tariff with structure as for instance Schnau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + if ((paymentMethodId == PaymentMethod::Steps) || + // progressive tariff: e.g. Neuhauser, Kirchdorf (743) + (paymentMethodId == PaymentMethod::Progressive) || + // degressive tariff: e.g. Fuchs Technik (500) + (paymentMethodId == PaymentMethod::Degressive)) + { + QList &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex); + + int const size = stepList.size(); + if (size == 0) { + qCritical() << "compute_next_timestep() *ERROR empty step-list*"; + return currentTimeMinutes; + } + + qCritical() << __LINE__ << "compute_next_timestep() first time step:" << stepList[0]; + qCritical() << __LINE__ << "compute_next_timestep() timeSteps:" << stepList; + qCritical() << __LINE__ << "compute_next_timestep() currentTimeInMinutes:" << currentTimeMinutes; + + // consider time shift: the step-list might have been computed at a + // slightly different time point + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); + if (currentStepIndex == -1) { + unsigned minimalDistance = ~0; + int j = -1; + for (int i = 0; i < stepList.size(); ++i) { + unsigned distance = std::abs(stepList[i] - currentTimeMinutes); + if (distance < minimalDistance) { + minimalDistance = distance; + j = i; + } + } + // max. tolerance set to 3 minutes + // unsigned const tolerance = std::min(minimalDistance, (unsigned)(3)); + if (j != -1) { + stepList[j] = currentTimeMinutes; + } + } + +#if 0 + int maxStep = -1; + if (size >= 2) { + maxStep = stepList[1] - stepList[0]; + } + // max. tolerance set to 5 minutes + int const tolerance = (maxStep == -1) ? 5 : std::min(maxStep, 5); + for (int i=0; i < stepList.size(); ++i) { + if (std::abs(stepList[i] - currentTimeMinutes) <= tolerance) { + qCritical().noquote() + << __LINE__ << QString("compute_next_timestep() correction stepList[%1]=%2 -> %3:") + .arg(i).arg(stepList[0]).arg(currentTimeMinutes); + stepList[i] = currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() NEW timeSteps:" << stepList; + } + } + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); +#endif + + currentStepIndex = stepList.indexOf(currentTimeMinutes); + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + if (currentStepIndex == -1) { + qCritical() << __LINE__ << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + + if (UpDown == 1) { // UP + if (stepList[currentStepIndex] == stepList.last()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const rest = currentStepIndex % pop_plus_steps; + + if (rest) { + currentStepIndex -= rest; + } + + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + int const nextStepIndex = currentStepIndex + pop_plus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + if (UpDown == 0) { // DOWN + if (stepList[currentStepIndex] == stepList.first()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const nextStepIndex = currentStepIndex - pop_minus_steps; + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + } else + if (paymentMethodId == PaymentMethod::Linear) { + + // currentTimeMinutes is the number of minutes actually used. This + // value is an offset from the start time and cannot be used as a + // QDateTime. + + qCritical() << "compute_next_timestep() up/down (1=up, 0=down):" << UpDown; + + // get minimal and maximal parking times + int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + + qCritical() << " compute_next_timestep() maxParkingTime:" << maxParkingTime; + qCritical() << " compute_next_timestep() minParkingTime:" << minParkingTime; + + // use the first (i.e. main duration step contained in the tariff json-file) + int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId); + firstDurationStep = ((UpDown == 1) ? firstDurationStep : -firstDurationStep); + + qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep; + + int const nextTimeStep = currentTimeMinutes + firstDurationStep; + + if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) { + qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep; + return nextTimeStep; + } + } + + qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; +} + +// this is currently not used +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, // in minutes + time_t end_parking_time, // netto time in minutes + struct price_t *price, + PermitType permitType) { // permitType maps to product + + CalcState calcState; + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + QDateTime end(start); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType.get()); + } + + double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_max_time; + + if (minMin < 0 || maxMin < 0 || maxMin < minMin) { + calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin)); + return calcState.set(CalcState::State::WRONG_PARAM_VALUES); + } + + int const duration = end_parking_time - start_parking_time; + if (duration < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time, start_parking_time)); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (duration > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (duration < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (duration == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + //QDate const d(1970, 1, 1); + //QTime const t(0, 0, 0); + //QDateTime start(d, t, Qt::UTC); + //start = start.toLocalTime().addSecs(start_parking_time * 60); + //QDateTime end(start); + if (start.isValid()) { + double cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + start, + end, + duration, false, true); + double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + price->units = cost; + price->netto = cost; + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time_, + int netto_parking_time, + QDateTime &end_parking_time, + struct price_t *price, + PermitType permitType, + bool prepaid) +{ + CalcState calcState; + + QDateTime start_parking_time(start_parking_time_); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time; + double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time; + + // DEBUG + qCritical() << "compute_price_for_parking_ticket() " << endl + << " paymentOptionIndex: " << paymentOptionIndex << endl + << " start_parking_time: " << start_parking_time << endl + << " netto_parking_time: " << netto_parking_time << endl + << " start + netto: " << start_parking_time.addSecs(netto_parking_time * 60) << endl + << " minMin: " << minMin << endl + << " maxMin: " << maxMin + << " prepaid: " << prepaid + << " permitType: " << permitType.toString(); + + if (netto_parking_time < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time.toString(Qt::ISODate), + start_parking_time.toString(Qt::ISODate))); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (netto_parking_time > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (netto_parking_time < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (netto_parking_time == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + double cost = -1; + if (start_parking_time.isValid()) { + if (tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Steps || + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Degressive) { + // hier muesste man unterscheiden: uebertrag oder nicht? + calcState = Calculator::GetInstance().isParkingAllowed(tariff, start_parking_time, + netto_parking_time, paymentOptionIndex); + if (calcState.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << calcState.toString(); + return calcState; + } + + QList tlist = Calculator::GetInstance().GetTimeSteps(tariff); + Q_UNUSED(tlist); + + // compute cost (price) + cost = Calculator::GetInstance().GetCostFromDuration(tariff, start_parking_time, netto_parking_time, paymentOptionIndex); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + int pop_prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + qCritical() << __func__ << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + pop_prepaid_option_id = period.pye_id; + qCritical() << __func__ << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + qCritical() << __func__ << __LINE__ << " re-computed prepaid-id" << pop_prepaid_option_id; + } + + QTime carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + int carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + qCritical() << __func__ << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << __LINE__ << "carryOverDuration" << carryOverDuration; + + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << ":" << __LINE__ << "prepaid: no"; + } else { + qCritical() << __func__ << ":" << __LINE__ << " prepaidStart" << p.prepaid[weekDay].static_start.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " prepaidEnd" << p.prepaid[weekDay].static_end.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "prepaid duration" << p.prepaid[weekDay].duration; + + if (start_parking_time.time() < p.prepaid[weekDay].static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_end); + } else + if (start_parking_time.time() > p.prepaid[weekDay].static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_start); + } + } + } + + // handle carry over + int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60; + if (netto_parking_time > minutesUntilCarryOver) { + int const rest = netto_parking_time - minutesUntilCarryOver; + QDateTime s(effectiveStartTime); + s = s.addSecs(minutesUntilCarryOver * 60); + s = s.addSecs(carryOverDuration * 60); + end_parking_time = s.addSecs(rest * 60); + } else { + end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60); + } + + weekDay = end_parking_time.date().dayOfWeek(); + + // musste man in einer schleife machen + carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + if (end_parking_time.time() > carryOverStart) { + end_parking_time = end_parking_time.addSecs(carryOverDuration * 60); + } + + end_parking_time.setTime(QTime(end_parking_time.time().hour(), + end_parking_time.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " week-day:" << weekDay; + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)weekDay); itr != rangeEnd; ++itr) { + ATBWeekDay const &wd = itr->second; + bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(effectiveStartTime, + end_parking_time, + paymentOptionIndex); + if (parkTimeLimitViolated) { + //QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + //end_parking_time.setTime(tlimit); + + calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + .arg(end_parking_time.time().toString(Qt::ISODate))); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + } else { + cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + start_parking_time, // starting time + end_parking_time, // return value: end time + netto_parking_time, // minutes, netto + false, prepaid); + } + // qCritical() << __func__ << __LINE__; + double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + + // DEBUG + //qCritical() << __LINE__ << " end_parking_time: " << end_parking_time; + //qCritical() << __LINE__ << " -> calculated cost (netto): " << cost; + + price->brutto = price->vat = price->vat_percentage = 0; + price->units = cost; + price->netto = cost; + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + if (end_parking_time.time().hour() == 0 && end_parking_time.time().minute() == 0) { + end_parking_time = end_parking_time.addDays(-1); + end_parking_time.setTime(QTime(23, 59, 0)); + } + qCritical() << __func__ << __LINE__ << "end_parking_time" << end_parking_time.toString(Qt::ISODate); + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double price, + QString &duration, + PermitType permitType) { + CalcState calcState; + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + + bool prepaid = true; + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + qCritical() << " payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + if (prepaid_option_id == 2) { // see tariff03.json for 502: 2 means no prepaid-option + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + qCritical() << "compute_duration_for_parking_ticket(1): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " start (cs): " << cs; + qCritical() << " price: " << price; + + duration = Calculator::GetInstance().GetDurationFromCost(tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + QDateTime d = QDateTime::fromString(duration, Qt::ISODate); + if (!d.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime const &start_parking_time, + double price, + QDateTime &ticketEndTime, + PermitType permitType) +{ + CalcState calcState; + + bool prepaid = true; + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + qCritical() << __func__ << ":" << __LINE__ << "payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << ":" << __LINE__ << " payment option index: " << paymentOptionIndex; + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + if (prepaid_option_id == 2) { + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "compute_duration_for_parking_ticket(2): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " price: " << price; + } + + if (start_parking_time.isValid()) { + + int const pop_time_step_config = tariff->getPaymentOptions(paymentOptionIndex).pop_time_step_config; + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << __LINE__ << "prepaid: no"; + } else { + if (start_parking_time.time() < p.static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.static_end); + } else + if (start_parking_time.time() > p.static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.static_start); + } + } + } + } + + QString cs = start_parking_time.toString(Qt::ISODate); + QString endTime = Calculator::GetInstance().GetDurationFromCost( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + + if (endTime == CalcState::SUCCESS) { + calcState.setDesc(QString("SUCCESS")); + calcState.setStatus(endTime); + } else + if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_LOADING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_PARSING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::NEGATIVE_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::INVALID_START_DATE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_PARAM_VALUES) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) { + calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE); + calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE); + return calcState; + } else + if (endTime == CalcState::OVERPAID) { + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } else + if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else { + ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "step-config:" << pop_time_step_config; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle carry over for ticket-end-time + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + qCritical() << __func__ << ":" << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + } + + QTime carryOverStart; + QTime carryOverEnd; + int carryOverDuration = -1; + + // using TariffCarryOverType = std::multimap; + std::multimap::const_iterator it; + if ((it = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)) != + tariff->TariffCarryOverOptions.cend()) { + carryOverStart = it->second.carryover[weekDay].static_start; + carryOverEnd = it->second.carryover[weekDay].static_end; + carryOverDuration = it->second.carryover[weekDay].duration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid()) { + qCritical() << __func__ << ":" << __LINE__ << "carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverEnd" << carryOverEnd.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid() && carryOverDuration != -1) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() > carryOverStart) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } else { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() < carryOverEnd) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING: wrong carry-over-settings"; + } + } + + + ticketEndTime.setTime(QTime(ticketEndTime.time().hour(), + ticketEndTime.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)(ticketEndTime.date().dayOfWeek())); + itr != rangeEnd; + ++itr) { + ATBWeekDay const &wd = itr->second; + bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(start_parking_time, + ticketEndTime, + paymentOptionIndex); + if (parkTimeLimitViolated) { + QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + ticketEndTime.setTime(tlimit); + + + //calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + // .arg(ticketEndTime.time().toString(Qt::ISODate))); + //return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + + if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) { + ticketEndTime = ticketEndTime.addDays(-1); + ticketEndTime.setTime(QTime(23, 59, 0)); + } + + // DEBUG + qCritical() << __func__ << ":" << __LINE__ << " endTime:" << endTime; + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, + QDateTime const &start_parking_time, + QDateTime &ticketEndTime, + PermitType /* PermitType */) +{ + CalcState calcState; + if (start_parking_time.isValid()) { + + ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff, + start_parking_time, + tariff->getPaymentOptions().pop_payment_method_id, + false); // carry over + + // DEBUG + qCritical() << "compute_duration_for_daily_ticket(): "; + qCritical() << " ticketEndTime: " << ticketEndTime; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(ticketEndTime.toString(Qt::ISODate))); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &startDatetime, + QDateTime &endDatetime, + PERMIT_TYPE permitType, + struct price_t *price) {// return value + CalcState calcState; + + + if (startDatetime.isValid()) { + if (std::optional p = + Calculator::GetInstance().GetDailyTicketPrice(tariff, + startDatetime, + endDatetime, + permitType)) { + *price = p.value(); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + return calcState.set(CalcState::State::SUCCESS); +} + diff --git a/library/library.pro b/library/library.pro index 37edc3f..2f7001c 100644 --- a/library/library.pro +++ b/library/library.pro @@ -2,12 +2,20 @@ TEMPLATE = lib TARGET = mobilisis_calc #CONFIG += staticlib -QMAKE_CXXFLAGS += -std=c++17 -g -O0 +QMAKE_CXXFLAGS += -std=c++17 -g -O INCLUDEPATH += $$_PRO_FILE_PWD_/include INCLUDEPATH += $$_PRO_FILE_PWD_/include/mobilisis INCLUDEPATH += $$_PRO_FILE_PWD_/include/rapidjson +#start version with project neuhauser/galtuer +#Version is set in yocto recipe with "EXTRA_QMAKEVARS_PRE" +#VERSION=1.0.0 + +# 04.06.2024: Fix for Szeged: read price for daily ticket directly from entry +# PaymentOptions in tariff-file if it is not given as part of a +# Json-Product-Array in tariff-file. + CONFIG(debug, debug|release) { win32 { QMAKE_CXXFLAGS += -DCALCULATE_LIBRARY_EXPORTS @@ -25,7 +33,10 @@ SOURCES += \ src/utilities.cpp \ src/configuration.cpp \ src/tariff_log.cpp \ - src/calculate_price.cpp + src/calculate_price.cpp \ + src/ticket.cpp \ + src/tariff_global_defines.cpp \ + src/atb_time.cpp HEADERS += \ include/mobilisis/calculator_functions.h \ @@ -66,9 +77,28 @@ HEADERS += \ include/mobilisis/tariff_payment_rate.h \ include/mobilisis/tariff_log.h \ include/mobilisis/calculate_price.h \ - include/mobilisis/atb_project.h + include/mobilisis/atb_project.h \ + include/mobilisis/ticket.h \ + include/mobilisis/tariff_business_hours.h \ + include/mobilisis/tariff_daily_ticket.h \ + include/mobilisis/tariff_customer.h \ + include/mobilisis/tariff_timebase.h \ + include/mobilisis/tariff_timestep_config.h \ + include/mobilisis/tariff_product.h \ + include/mobilisis/tariff_permit_type.h \ + include/mobilisis/tariff_global_defines.h \ + include/mobilisis/tariff_interpolation.h \ + include/mobilisis/tariff_prepaid.h \ + include/mobilisis/tariff_carryover.h \ + include/mobilisis/tariff_global_defines.h \ + include/mobilisis/atb_time.h \ + include/mobilisis/tariff_service.h \ + include/mobilisis/tariff_out_of_service.h -OTHER_FILES += src/main.cpp +OTHER_FILES += src/main.cpp \ + ../tariffs/tariff_korneuburg.json \ + ../tariffs/tariff_linsinger_maschinenbau.json \ + ../tariffs/tariff_naz.json # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/library/src/atb_time.cpp b/library/src/atb_time.cpp new file mode 100644 index 0000000..3340e4d --- /dev/null +++ b/library/src/atb_time.cpp @@ -0,0 +1,151 @@ +#include "atb_time.h" +#include + +QDateTime const ATBTime::m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate)); + +ATBTime::ATBTime() + : m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) { +} + +ATBTime::ATBTime(int h, int m, int /*s*/, int /*ms*/) + : m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) { + + if (h == 24 && m == 0) { + m_time = m_end; + } else { + QTime const t(h, m, 0, 0); + m_time.setTime(t); + } +} + +ATBTime::ATBTime(QString const &t) + : m_time(QDateTime::fromString("1970-01-01T00:00:00")) { + + if (t == "24:00:00") { + m_time = m_end; + } else { + QTime tmp = QTime::fromString(t, Qt::ISODate); + if (tmp.isValid()) { + m_time.setTime(tmp); + } + } +} + +ATBTime::ATBTime(QTime const &t) + : m_time(QDateTime::fromString("1970-01-01T00:00:00")) { + m_time.setTime(t); +} + +QTime ATBTime::addMSecs(int ms) const { + return m_time.time().addMSecs(ms); +} + +QTime ATBTime::addMSecs(int ms) { + QTime t = m_time.time(); + t = t.addMSecs(ms); + m_time.setTime(t); + return t; +} + +QTime ATBTime::addSecs(int s) const { + return m_time.time().addSecs(s); +} + +QTime ATBTime::addSecs(int s) { + QTime t = m_time.time(); + t = t.addSecs(s); + m_time.setTime(t); + return t; +} + +constexpr QTime ATBTime::fromMSecsSinceStartOfDay(int msecs) { + return QTime::fromMSecsSinceStartOfDay(msecs); +} + +QTime ATBTime::fromString(QString const &string, Qt::DateFormat format) { + return QTime::fromString(string, format); +} + +QTime ATBTime::fromString(QString const &string, QString const &format) { + return QTime::fromString(string, format); +} + +bool ATBTime::isValid(int h, int m, int s, int ms) { + return QTime(h, m, s, ms).isValid(); +} + +int ATBTime::msecsSinceStartOfDay() const { + return m_time.time().msecsSinceStartOfDay(); +} + +bool ATBTime::setHMS(int h, int m, int s, int ms) { + if (isValid(h, m, s, ms)) { + QTime t(h, m, s, ms); + m_time.setTime(t); + return true; + } + return false; +} + +QString ATBTime::toString(Qt::DateFormat format) const { + if (m_time == m_end) { + return "24:00:00"; + } + return m_time.time().toString(format); +} + +bool operator!=(const ATBTime &lhs, const ATBTime &rhs) noexcept { + return lhs.m_time.time() != rhs.m_time.time(); +} + +bool operator<=(const ATBTime &lhs, const ATBTime &rhs) noexcept { + if (rhs.m_time == rhs.m_end) { + return true; + } + return lhs.m_time.time() <= rhs.m_time.time(); +} + +bool operator>=(const ATBTime &lhs, const ATBTime &rhs) noexcept { + return lhs.m_time.time() >= rhs.m_time.time(); +} + +bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept { + if (rhs.m_time == rhs.m_end) { + return true; + } + return lhs.m_time.time() < rhs.m_time.time(); +} + +bool operator>(const ATBTime &lhs, const ATBTime &rhs) noexcept { + return lhs.m_time.time() > rhs.m_time.time(); +} + +bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept { + return lhs.m_time.time() == rhs.m_time.time(); +} + +QDebug &operator<<(QDebug &debug, ATBTime const &time) { + QDebugStateSaver saver(debug); + if (time.m_time == time.m_end) { + debug.nospace() << QString("24:00:00"); + } else { + debug.nospace() << time.m_time.time().toString(Qt::ISODate); + } + return debug; +} + +QDataStream &operator<<(QDataStream &out, ATBTime const &time) { + if (time.m_time == time.m_end) { + out << QString("24:00:00"); + } else { + out << time.m_time.time(); + } + return out; +} + +QDataStream &operator>>(QDataStream &in, ATBTime &time) { + QTime t; + in >> t; + time.m_time.setTime(t); + return in; +} diff --git a/library/src/calculate_price.cpp b/library/src/calculate_price.cpp index 405989d..85cdd74 100644 --- a/library/src/calculate_price.cpp +++ b/library/src/calculate_price.cpp @@ -2,27 +2,406 @@ #include "configuration.h" #include "calculator_functions.h" #include "payment_option.h" +#include "utilities.h" +#include "tariff_global_defines.h" +#include "period_year.h" #include #include #include #include +#include -static Calculator calculator; +QString const CalcState::SUCCESS = "SUCCESS"; +QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR"; +QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF"; +QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF"; +QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME"; +QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE"; +QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES"; +QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT"; +QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE"; +QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE"; +QString const CalcState::OVERPAID = "OVERPAID"; +QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; +QString const CalcState::SUCCESS_MAXPRICE = "SUCCESS_MAXPRICE"; + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { + return Calculator::GetInstance().GetTimeSteps(cfg); +} + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int minTime = 0; + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + qCritical() << __func__ << __LINE__ << "permit" << PermitType(permitType).toString(); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + qCritical() << __func__ << __LINE__ << minTime; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: + // for each new sell-procedure, recomute the timesteps. implicitly, set + // the minimal parking time. + Calculator::GetInstance().ResetTimeSteps(paymentOptionIndex); + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = qRound(cfg->getPaymentOptions(paymentOptionIndex).pop_min_time); + } + + qCritical() << "minTime" << minTime; + return minTime; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + int maxTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: ; + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } + + return maxTime; +} + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex, + QDateTime const &start) { + int minPrice = -1; + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg, start)) == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + int payment_method_id = cfg->getPaymentOptions(paymentOptionIndex).pop_payment_method_id; + + if (payment_method_id == PaymentMethod::Degressive) { + // Degressive: new for Fuchs Technik (500), ValserAlm (Fane): + // the minimal price has to be calculated, in cannot be hard coded into + // the tariff file. + // The working times have a reference into the payment rates. Two special + // entries (with the numbers 1000/1001) point to the respective prices. + switch(permitType) { + default: { + // find the correct work time range + int weekDay = start.date().dayOfWeek(); + std::optional> const &wd = cfg->getAllWeekDayWorkTimes(); + if (wd.has_value()) { + QVector const &vec = wd.value(); + for (int i = 0; i < vec.size(); ++i) { + ATBWeekDaysWorktime const &wt = vec[i]; + if (wt.pwd_period_day_in_week_id == weekDay) { + if (start.time() >= QTime::fromString(QString::fromStdString(wt.pwd_time_from), Qt::ISODate) + && start.time() <= QTime::fromString(QString::fromStdString(wt.pwd_time_to), Qt::ISODate)) { + // found worktime range + int pop_id = wt.pwd_pop_id; // 1000 or 1001 + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + i = vec.size(); // to leave outer loop + minPrice = itr->second.pra_price; // this is now the minimal price + break; + } + } + } + } + } + } + } + } else { + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + case PERMIT_TYPE::DAY_TICKET: { + minPrice = compute_product_price(cfg, permitType, start); + } break; + default: + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } + } + + return minPrice; +} + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType, + QDateTime const &start, + QDateTime *productStart, + QDateTime *productEnd) { + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_TEEN: + // [[fallthrough]]; + case PERMIT_TYPE::FOOD_STAMP: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + if (product.size() > 0) { + ATBTariffProduct const &p = product[0]; + return p.m_tariff_product_price; +#if 0 + // in case we do not have prepaid-option + QTime const ¤tTime = QDateTime::currentDateTime().time(); + + if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) { + return p.m_tariff_product_price; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "ERROR currentTime" + << currentTime.toString(Qt::ISODate) + << "INVALID (" + << p.m_tariff_product_start.toString(Qt::ISODate) + << p.m_tariff_product_end.toString(Qt::ISODate) << ")"; + } +#endif + } + } + } break; + case PERMIT_TYPE::INVALID: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + int product_price = 0; + + if (productStart && productEnd) { + *productStart = start; + *productEnd = start; + if (product.size() > 0) { + productStart->setTime(product[0].getTimeStart()); + productEnd->setTime(product[0].getTimeEnd()); + } + } + + for (QVector::size_type i=0; i= startTime && start.time() < endTime) { + product_price = p.getProductPrice(); + if (productStart && productEnd) { + productStart->setTime(startTime); + productEnd->setTime(endTime); + } + } + } + + return product_price; + } else { + // SZEGED + int const pop_daily_card_price = cfg->getPaymentOptions().pop_daily_card_price; + + qDebug() << QString("(%1:%2) no products defined in tariff-file").arg(__func__).arg(__LINE__); + qDebug() << QString("(%1:%2) pop_daily_card_price=%3").arg(__func__).arg(__LINE__).arg(pop_daily_card_price); + + // static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + // return Utilities::getDailyTicketCardPrice(cfg, paymentMethodId); + + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + int product_price = 0; + QVector product = products.value(); + + if (product.size() > 0) { + if (productStart && productEnd) { + int pop_min_time = get_minimal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + int pop_max_time = get_maximal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + if (pop_max_time >= pop_min_time) { + *productStart = start; + *productEnd = start.addSecs(pop_max_time*60); + product_price = product[0].getProductPrice(); + } + } + } + + return product_price; + } + + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "SHORT_TERM_PARKING_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + qCritical() << "TODO: SHORT_TERM_PARKING_BUS"; + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: { + qCritical() << "TODO: SHORT_TERM_PARKING_CAMPER"; + } break; + case PERMIT_TYPE::DAY_TICKET_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_BUS: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_BUS: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_CAMPER: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + default: + break; + } + + return 0; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxPrice = -1; + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg)) == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + if (paymentMethodId == PaymentMethod::Progressive + || paymentMethodId == PaymentMethod::Steps + || paymentMethodId == PaymentMethod::Unified) { + //maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + ATBPaymentOption const &po = cfg->getPaymentOptions(paymentOptionIndex); + maxPrice = po.pop_max_price; // maxTime is given in minutes + } else { // PaymentMethod::Linear -> e.g. szeged + int const key = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; // maxTime is given in minutes + std::optional> const &pv = cfg->getPaymentRateForKey(key); + if (pv) { + QVector const &paymentRate = pv.value(); + if (paymentRate.size() > 0) { + int const price = paymentRate.last().pra_price; // price is given per hour + maxPrice = qRound((maxTime * price) / 60.0f); + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: + break; + case PERMIT_TYPE::DAY_TICKET_TEEN: + break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + break; + case PERMIT_TYPE::DAY_TICKET_BUS: + break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: + break; + case PERMIT_TYPE::DAY_TICKET_PKW: + break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + break; + default: ; + } + + return maxPrice; +} int CALCULATE_LIBRARY_API get_zone_nr(int zone) { if(zone > -1) return zone; else { - QFile zone("/etc/zone_nr"); + QFile zone("/mnt/system_data/zone_nr"); if (zone.exists()) { QFileInfo finfo(zone); - if (finfo.size() <= 4) { // decimal 000\n - if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&zone); - return in.readLine(100).toInt(); - } + if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&zone); + return in.readLine(100).toInt(); } } return -1; @@ -73,11 +452,13 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char cons if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { delete *tariff; *tariff = nullptr; + qCritical() << " ... error parsing tariff"; return calcState.set(CalcState::State::ERROR_PARSING_TARIFF); } } else { delete *tariff; *tariff = nullptr; + qCritical() << " ... error loading tariff"; return calcState.set(CalcState::State::ERROR_LOADING_TARIFF); } @@ -92,16 +473,238 @@ void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { } } +// +// UpDown 1 -> up; 0 -> down +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, + int UpDown, PermitType const &permitType) +{ + + qCritical() << __LINE__ << "compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() up/down (1=up, 0=down): " << UpDown; + + if (UpDown == 1) { + if (Calculator::GetInstance().timeLimitReached()) { + qCritical() << __LINE__ << "compute_next_timestep() time limit reached"; + Calculator::GetInstance().setTimeLimitReached(false); + Calculator::GetInstance().resetCostAtTimeLimit(); + return currentTimeMinutes; + } + } + + // FIXME + //std::optional paymentOption = tariff->getPaymentOptionForKey(permitType.get()); + //if (!paymentOption.has_value()) { + // qCritical() << " compute_next_timestep() ERROR"; + // return currentTimeMinutes; + //} + + int paymentOptionIndex = getPaymentOptionIndex(*tariff); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int const &pop_plus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_plus_steps; + int const &pop_minus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_minus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() payment option index: " << paymentOptionIndex; + qCritical() << __LINE__ << "compute_next_timestep() plus steps: " << pop_plus_steps; + qCritical() << __LINE__ << "compute_next_timestep() minus steps: " << pop_minus_steps; + + Configuration const *cfg = tariff; + + // compute payment method id (e.g. Linear=3, Steps=4) + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + switch (paymentMethodId) { + case PaymentMethod::Progressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Progressive"; + break; + case PaymentMethod::Degressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Degressive"; + break; + case PaymentMethod::Linear: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Linear"; + break; + case PaymentMethod::Steps: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps"; + break; + case PaymentMethod::Unified: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Unified"; + break; + case PaymentMethod::Undefined: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined"; + break; + } + + // use tariff with structure as for instance Schnau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + if ((paymentMethodId == PaymentMethod::Steps) || + // progressive tariff: e.g. Neuhauser, Kirchdorf (743) + (paymentMethodId == PaymentMethod::Progressive) || + // unified tariff: starting with Bad Neuenahr (249), Tariff for Zone5 + (paymentMethodId == PaymentMethod::Unified) || + // degressive tariff: e.g. Fuchs Technik (500) + (paymentMethodId == PaymentMethod::Degressive)) + { + QList &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex); + + int const size = stepList.size(); + if (size == 0) { + qCritical() << "compute_next_timestep() *ERROR empty step-list*"; + return currentTimeMinutes; + } + + qCritical() << __LINE__ << "compute_next_timestep() first time step:" << stepList[0]; + qCritical() << __LINE__ << "compute_next_timestep() timeSteps:" << stepList; + qCritical() << __LINE__ << "compute_next_timestep() currentTimeInMinutes:" << currentTimeMinutes; + + // consider time shift: the step-list might have been computed at a + // slightly different time point + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); + if (currentStepIndex == -1) { + unsigned minimalDistance = ~0; + int j = -1; + for (int i = 0; i < stepList.size(); ++i) { + unsigned distance = std::abs(stepList[i] - currentTimeMinutes); + if (distance < minimalDistance) { + minimalDistance = distance; + j = i; + } + } + // max. tolerance set to 3 minutes + // unsigned const tolerance = std::min(minimalDistance, (unsigned)(3)); + if (j != -1) { + stepList[j] = currentTimeMinutes; + } + } + +#if 0 + int maxStep = -1; + if (size >= 2) { + maxStep = stepList[1] - stepList[0]; + } + // max. tolerance set to 5 minutes + int const tolerance = (maxStep == -1) ? 5 : std::min(maxStep, 5); + for (int i=0; i < stepList.size(); ++i) { + if (std::abs(stepList[i] - currentTimeMinutes) <= tolerance) { + qCritical().noquote() + << __LINE__ << QString("compute_next_timestep() correction stepList[%1]=%2 -> %3:") + .arg(i).arg(stepList[0]).arg(currentTimeMinutes); + stepList[i] = currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() NEW timeSteps:" << stepList; + } + } + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); +#endif + + currentStepIndex = stepList.indexOf(currentTimeMinutes); + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + if (currentStepIndex == -1) { + qCritical() << __LINE__ << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + + if (UpDown == 1) { // UP + if (stepList[currentStepIndex] == stepList.last()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const rest = currentStepIndex % pop_plus_steps; + + if (rest) { + currentStepIndex -= rest; + } + + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + int const nextStepIndex = currentStepIndex + pop_plus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + if (UpDown == 0) { // DOWN + if (stepList[currentStepIndex] == stepList.first()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const nextStepIndex = currentStepIndex - pop_minus_steps; + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + } else + if (paymentMethodId == PaymentMethod::Linear) { + + // currentTimeMinutes is the number of minutes actually used. This + // value is an offset from the start time and cannot be used as a + // QDateTime. + + qCritical() << "compute_next_timestep() up/down (1=up, 0=down):" << UpDown; + + // get minimal and maximal parking times + int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + + qCritical() << " compute_next_timestep() maxParkingTime:" << maxParkingTime; + qCritical() << " compute_next_timestep() minParkingTime:" << minParkingTime; + + // use the first (i.e. main duration step contained in the tariff json-file) + int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId); + firstDurationStep = ((UpDown == 1) ? firstDurationStep : -firstDurationStep); + + qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep; + + int const nextTimeStep = currentTimeMinutes + firstDurationStep; + + if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) { + qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep; + return nextTimeStep; + } + } + + qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; +} // this is currently not used CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( parking_tariff_t *tariff, - time_t start_parking_time, // in minutes - time_t end_parking_time, // netto time in minutes - struct price_t *price) { + time_t start_parking_time, // in minutes + time_t end_parking_time, // netto time in minutes + struct price_t *price, + PermitType permitType) { // permitType maps to product + CalcState calcState; - double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_time; - double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_max_time; + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + QDateTime end(start); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType.get()); + } + + qCritical() << __func__ << ":" << __LINE__ << "pop_max_price" << tariff->getPaymentOptions(paymentOptionIndex).pop_max_price; + + tariff->getPaymentOptions(paymentOptionIndex).pop_max_price + = tariff->getPaymentOptions(paymentOptionIndex).pop_max_price_save; + + double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_max_time; if (minMin < 0 || maxMin < 0 || maxMin < minMin) { calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin)); @@ -112,7 +715,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( if (duration < 0) { calcState.setDesc(QString("end=%1, start=%2") .arg(end_parking_time, start_parking_time)); - return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); } if (duration > maxMin) { calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); @@ -123,25 +726,24 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); } if (duration == 0) { - memset(price, 0x00, sizeof(*price)); return calcState.set(CalcState::State::SUCCESS); } - QDate const d(1970, 1, 1); - QTime const t(0, 0, 0); - QDateTime start(d, t, Qt::UTC); - start = start.toLocalTime().addSecs(start_parking_time * 60); - QDateTime end(start); + //QDate const d(1970, 1, 1); + //QTime const t(0, 0, 0); + //QDateTime start(d, t, Qt::UTC); + //start = start.toLocalTime().addSecs(start_parking_time * 60); + //QDateTime end(start); if (start.isValid()) { - double cost = calculator.GetCostFromDuration( + double cost = Calculator::GetInstance().GetCostFromDuration( tariff, - tariff->getPaymentOptions().pop_payment_method_id, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, start, end, duration, false, true); - double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_price; + double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_price; if (cost < minCost) { - calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost)); + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); } price->units = cost; @@ -155,28 +757,44 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( parking_tariff_t *tariff, - QDateTime const &start_parking_time, + QDateTime &start_parking_time_, int netto_parking_time, QDateTime &end_parking_time, - struct price_t *price) + struct price_t *price, + PermitType permitType, + bool prepaid) { CalcState calcState; - double minMin = tariff->getPaymentOptions().pop_min_time; - double maxMin = tariff->getPaymentOptions().pop_max_time; + + QDateTime start_parking_time(start_parking_time_); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + tariff->getPaymentOptions(paymentOptionIndex).pop_max_price + = tariff->getPaymentOptions(paymentOptionIndex).pop_max_price_save; + + double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time; + double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time; // DEBUG qCritical() << "compute_price_for_parking_ticket() " << endl + << " paymentOptionIndex: " << paymentOptionIndex << endl << " start_parking_time: " << start_parking_time << endl << " netto_parking_time: " << netto_parking_time << endl + << " start + netto: " << start_parking_time.addSecs(netto_parking_time * 60) << endl << " minMin: " << minMin << endl - << " maxMin: " << maxMin; - + << " maxMin: " << maxMin + << " prepaid: " << prepaid + << " permitType: " << permitType.toString(); if (netto_parking_time < 0) { calcState.setDesc(QString("end=%1, start=%2") .arg(end_parking_time.toString(Qt::ISODate), start_parking_time.toString(Qt::ISODate))); - return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); } if (netto_parking_time > maxMin) { calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); @@ -187,33 +805,226 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); } if (netto_parking_time == 0) { - memset(price, 0x00, sizeof(*price)); return calcState.set(CalcState::State::SUCCESS); } + double cost = -1; if (start_parking_time.isValid()) { - double cost = calculator.GetCostFromDuration( + if (tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Steps || + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Degressive) { + // hier muesste man unterscheiden: uebertrag oder nicht? + calcState = Calculator::GetInstance().isParkingAllowed(tariff, start_parking_time, + netto_parking_time, paymentOptionIndex); + if (calcState.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << calcState.toString(); + return calcState; + } + + QList tlist = Calculator::GetInstance().GetTimeSteps(tariff); + Q_UNUSED(tlist); + + // compute cost (price) + cost = Calculator::GetInstance().GetCostFromDuration(tariff, start_parking_time, netto_parking_time, paymentOptionIndex); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + int pop_prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + int period_id = -1; + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + period_id = period.pye_id; + pop_carry_over_option_id = period.pye_id; + pop_prepaid_option_id = period.pye_id; + qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + qCritical() << __func__ << ":" << __LINE__ << " re-computed prepaid-id" << pop_prepaid_option_id; + } + + QTime carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + int carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + + + QDateTime effectiveStartTime(start_parking_time); + + // handle special days + int const specialDayId = tariff->specialDayId(start_parking_time); + if (specialDayId > 0) { // found special day + for (auto[itr, rangeEnd] = tariff->SpecialDaysWorktime.equal_range(specialDayId); itr != rangeEnd; ++itr) { + ATBSpecialDaysWorktime const &wt = itr->second; + switch(period_id) { + case 1: // summer term + if ((wt.pedwt_paid & 1) == 0) { + // does not have to be paid, move to next midnight + + // better: start of next day (falls kein vorkauf besteht) + effectiveStartTime = effectiveStartTime.addDays(1); + effectiveStartTime.setTime(QTime(0, 0, 0)); + } + break; + case 2: // winter term + if ((wt.pedwt_paid & 2) == 0) { + // does not have to be paid, move to next midnight + + // better: start of next day (falls kein vorkauf besteht) + effectiveStartTime = effectiveStartTime.addDays(1); + effectiveStartTime.setTime(QTime(0, 0, 0)); + } + break; + default:; + } + } + } + + // handle prepaid option + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << ":" << __LINE__ << "prepaid: no"; + } else { + qCritical() << __func__ << ":" << __LINE__ << " prepaidStart" << p.prepaid[weekDay].static_start.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " prepaidEnd" << p.prepaid[weekDay].static_end.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "prepaid duration" << p.prepaid[weekDay].duration; + + if (start_parking_time.time() < p.prepaid[weekDay].static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_end); + } else + if (start_parking_time.time() > p.prepaid[weekDay].static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_start); + } + } + } + + effectiveStartTime.setTime(QTime(effectiveStartTime.time().hour(), + effectiveStartTime.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "effectiveStartTime:" << effectiveStartTime.toString(Qt::ISODate); + + int const carryOver = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over; + + qCritical() << __func__ << ":" << __LINE__ << " carryOver flag" << carryOver; + + if (carryOver == 1) { + QTime carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + int carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + + // handle carry over + int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60; + if ((minutesUntilCarryOver > 0) && (netto_parking_time > minutesUntilCarryOver)) { + int const rest = netto_parking_time - minutesUntilCarryOver; + QDateTime s(effectiveStartTime); + s = s.addSecs(minutesUntilCarryOver * 60); + s = s.addSecs(carryOverDuration * 60); + end_parking_time = s.addSecs(rest * 60); + } else { + end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60); + } + + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + + weekDay = end_parking_time.date().dayOfWeek(); + + // musste man in einer schleife machen + carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + if (end_parking_time.time() > carryOverStart) { + end_parking_time = end_parking_time.addSecs(carryOverDuration * 60); + } else + if (end_parking_time.time() == carryOverStart) { + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + ATBPaymentOption const &po = tariff->getPaymentOptions(paymentOptionIndex); + if (po.pop_apply_carry_over_to_ticket_endtime) { + end_parking_time = end_parking_time.addSecs(carryOverDuration * 60); + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + } + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "NO carryOver configured"; + end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60); + } + + end_parking_time.setTime(QTime(end_parking_time.time().hour(), + end_parking_time.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " week-day:" << weekDay; + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)weekDay); itr != rangeEnd; ++itr) { + ATBWeekDay const &wd = itr->second; + bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(effectiveStartTime, + end_parking_time, + paymentOptionIndex); + if (parkTimeLimitViolated) { + //QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + //end_parking_time.setTime(tlimit); + + // max_price neu berechnen + + calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + .arg(end_parking_time.time().toString(Qt::ISODate))); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + } else + if (tariff->getPaymentOptions(0).pop_payment_method_id == PaymentMethod::Unified) { + std::pair> p = + Calculator::GetInstance().ComputeCostFromDuration(tariff, start_parking_time, end_parking_time, netto_parking_time); + CalcState const cs = p.first; + + if ((cs.getStatus() == CalcState::State::SUCCESS || + cs.getStatus() == CalcState::State::SUCCESS_MAXPRICE || + cs.getStatus() == CalcState::State::OVERPAID)) { + if (p.second.has_value()) { + cost = p.second.value(); + } + } else { + return cs; + } + } else { + cost = Calculator::GetInstance().GetCostFromDuration( tariff, tariff->getPaymentOptions().pop_payment_method_id, start_parking_time, // starting time end_parking_time, // return value: end time netto_parking_time, // minutes, netto - false, true); - double minCost = tariff->getPaymentOptions().pop_min_price; + false, prepaid); + } + + double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price; if (cost < minCost) { - calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost)); + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); } // DEBUG - qCritical() << " -> calculated cost (price->netto) = " << cost; + //qCritical() << __LINE__ << " end_parking_time: " << end_parking_time; + //qCritical() << __LINE__ << " -> calculated cost (netto): " << cost; + price->brutto = price->vat = price->vat_percentage = 0; price->units = cost; price->netto = cost; + } else { return calcState.set(CalcState::State::INVALID_START_DATE); } + if (end_parking_time.time().hour() == 0 && end_parking_time.time().minute() == 0) { + end_parking_time = end_parking_time.addDays(-1); + end_parking_time.setTime(QTime(23, 59, 0)); + } + qCritical() << __func__ << __LINE__ << "end_parking_time" << end_parking_time.toString(Qt::ISODate); + return calcState.set(CalcState::State::SUCCESS); } @@ -221,7 +1032,12 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( parking_tariff_t *tariff, time_t start_parking_time, double price, - QString &duration) { + QString &duration, + PermitType permitType) { + + tariff->getPaymentOptions(0).pop_max_price + = tariff->getPaymentOptions(0).pop_max_price_save; + CalcState calcState; QDate const d(1970, 1, 1); QTime const t(0, 0, 0); @@ -230,15 +1046,34 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( if (start.isValid()) { QString cs = start.toString(Qt::ISODate); - // DEBUG - qCritical() << "compute_duration_for_parking_ticket(): "; - qCritical() << " start (cs): " << cs; - qCritical() << " price: " << price; + bool prepaid = true; + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + qCritical() << " payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + if (prepaid_option_id == 2) { // see tariff03.json for 502: 2 means no prepaid-option + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + qCritical() << "compute_duration_for_parking_ticket(1): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " start (cs): " << cs; + qCritical() << " price: " << price; + + std::pair p_duration + = Calculator::GetInstance().GetDurationFromCost(tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid); + duration = p_duration.first.c_str(); + - duration = calculator.GetDurationFromCost(tariff, - tariff->getPaymentOptions().pop_payment_method_id, - cs.toLocal8Bit().constData(), - price, false, true).c_str(); QDateTime d = QDateTime::fromString(duration, Qt::ISODate); if (!d.isValid()) { calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); @@ -255,40 +1090,346 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( parking_tariff_t *tariff, QDateTime const &start_parking_time, double price, - QDateTime &ticketEndTime) + QDateTime &ticketEndTime, + PermitType permitType) { + tariff->getPaymentOptions(0).pop_max_price + = tariff->getPaymentOptions(0).pop_max_price_save; + CalcState calcState; + + bool prepaid = true; + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + qCritical() << __func__ << ":" << __LINE__ << "payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << ":" << __LINE__ << " payment option index: " << paymentOptionIndex; + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + if (prepaid_option_id == 2) { + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "compute_duration_for_parking_ticket(2): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " price: " << price; + } + if (start_parking_time.isValid()) { - QString cs = start_parking_time.toString(Qt::ISODate); - QString endTime = calculator.GetDurationFromCost( + + int const pop_time_step_config = tariff->getPaymentOptions(paymentOptionIndex).pop_time_step_config; + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + + effectiveStartTime.setTime(QTime(effectiveStartTime.time().hour(), + effectiveStartTime.time().minute(), 0)); + + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << __LINE__ << "prepaid: no"; + } else { + if (start_parking_time.time() < p.static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.static_end); + } else + if (start_parking_time.time() > p.static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.static_start); + } + } + } + } + QDateTime start(start_parking_time); + start.setTime(QTime(start.time().hour(), start.time().minute(), 0)); + QString cs = start.toString(Qt::ISODate); + + std::pair p_endTime + = Calculator::GetInstance().GetDurationFromCost( tariff, tariff->getPaymentOptions().pop_payment_method_id, cs.toLocal8Bit().constData(), - price, false, true).c_str(); - ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + price, permitType, nextDay, prepaid); - // DEBUG - qCritical() << "compute_duration_for_parking_ticket(): "; - qCritical() << " endTime: " << endTime; - qCritical() << " ticketEndTime: " << ticketEndTime; + QString endTime = p_endTime.first.c_str(); + ticketEndTime = p_endTime.second; - if (!ticketEndTime.isValid()) { - calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); - return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + qCritical() << __func__ << ":" << __LINE__ << endTime; + qCritical() << __func__ << ":" << __LINE__ << ticketEndTime.toString(Qt::ISODate); + + if (endTime == CalcState::SUCCESS) { + calcState.setDesc(QString("SUCCESS")); + calcState.setStatus(endTime); + qCritical() << __func__ << ":" << __LINE__ << "SUCCESS"; + } else + if (endTime == CalcState::SUCCESS_MAXPRICE) { + calcState.setDesc(QString("SUCCESS_MAXPRICE")); + calcState.setStatus(endTime); + qCritical() << __func__ << ":" << __LINE__ << "SUCCESS_MAXPRICE"; + } else + if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_LOADING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_PARSING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::NEGATIVE_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::INVALID_START_DATE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_PARAM_VALUES) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) { + calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE); + calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE); + return calcState; + } else + if (endTime == CalcState::OVERPAID) { + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } else + if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else { + ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + + ticketEndTime.setTime(QTime(ticketEndTime.time().hour(), + ticketEndTime.time().minute(), 0)); + + int netto_parking_time = start_parking_time.secsTo(ticketEndTime) / 60; + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "step-config:" << pop_time_step_config; + qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + if (tariff->getPaymentOptions().pop_payment_method_id != PaymentMethod::Unified) { + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle carry over for ticket-end-time + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + qCritical() << __func__ << ":" << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + } + + QTime carryOverStart; + QTime carryOverEnd; + int carryOverDuration = -1; + + // using TariffCarryOverType = std::multimap; + std::multimap::const_iterator it; + if ((it = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)) != + tariff->TariffCarryOverOptions.cend()) { + carryOverStart = it->second.carryover[weekDay].static_start; + carryOverEnd = it->second.carryover[weekDay].static_end; + carryOverDuration = it->second.carryover[weekDay].duration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid()) { + qCritical() << __func__ << ":" << __LINE__ << "carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverEnd" << carryOverEnd.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid() && carryOverDuration != -1) { + + // note: in such a case (direct coins) carry-over has been handled + // already in GetDurationFromCost() + netto_parking_time -= carryOverDuration; + qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time; + + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() > carryOverStart) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } else + if (ticketEndTime.time() == carryOverStart) { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + ATBPaymentOption const &po = tariff->getPaymentOptions(paymentOptionIndex); + if (po.pop_apply_carry_over_to_ticket_endtime) { + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + } + } else { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() < carryOverEnd) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING: wrong carry-over-settings"; + } + } + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)(ticketEndTime.date().dayOfWeek())); + itr != rangeEnd; + ++itr) { + ATBWeekDay const &wd = itr->second; + bool parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(start_parking_time, + ticketEndTime, + paymentOptionIndex); + if (parkTimeLimitViolated) { + //QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + //ticketEndTime.setTime(tlimit); + + QList const &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex); + + QDateTime newTicketEndTime = ticketEndTime; + + qCritical() << __func__ << ":" << __LINE__ << "PARK-TIME VIOLATED"; + + for (int i = stepList.size() - 1; i > 0; --i) { + // qCritical() << __func__ << ":" << __LINE__ << "step[" << i << "]" << stepList.at(i); + + if (netto_parking_time > 0 && stepList.at(i) <= netto_parking_time) { + int const diff = stepList.at(i-1) - stepList.at(i); + newTicketEndTime = newTicketEndTime.addSecs(diff * 60); + + // qCritical() << __func__ << ":" << __LINE__ << "new-ticket-end-time" << newTicketEndTime.toString(Qt::ISODate); + + parkTimeLimitViolated + = wd.getTariffCarryOverSettings() + .parkingTimeLimitExceeded(start_parking_time, newTicketEndTime, paymentOptionIndex); + + if (!parkTimeLimitViolated) { + + qCritical() << __func__ << ":" << __LINE__ + << "PARK-TIME NOT VIOLATED FOR" << newTicketEndTime.toString(Qt::ISODate); + + int duration = stepList.at(i-1); + + // qCritical() << __func__ << ":" << __LINE__ << "duration" << duration; + + std::multimap::const_iterator it; + for (it = tariff->Duration.cbegin(); + it != tariff->Duration.cend(); + ++it) { + if (duration == it->second.pun_duration) { + + // qCritical() << __func__ << ":" << __LINE__ << "duration" << duration; + + ATBPaymentOption &po = tariff->getPaymentOptions(paymentOptionIndex); + int const pop_id = po.pop_id; + for (auto[itr, rangeEnd] = tariff->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + + // qCritical() << __func__ << ":" << __LINE__ << "durationId" << durationId << it->second.pun_id; + + // note: for this to work, Duration and PaymentRate must have + // exactly the same structure + if (durationId == it->second.pun_id) { + int const pra_price = itr->second.pra_price; + po.pop_max_price = pra_price; + + qCritical() << __func__ << ":" << __LINE__ << "new max-price" << po.pop_max_price; + + // note: ABOVE_MAX_PARKING_TIME would also be possible + // but here max-parking-time is dynamic. And for + // this dynamic value, opverpaid is actually correct + + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } + } + } + } + } + } + } + + calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + .arg(ticketEndTime.time().toString(Qt::ISODate))); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + } + + if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) { + ticketEndTime = ticketEndTime.addDays(-1); + ticketEndTime.setTime(QTime(23, 59, 0)); + } + + // DEBUG + qCritical() << __func__ << ":" << __LINE__ << " endTime:" << endTime; + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); } } else { return calcState.set(CalcState::State::INVALID_START_DATE); } - return calcState.set(CalcState::State::SUCCESS); + //return calcState.set(CalcState::State::SUCCESS); + qCritical() << __func__ << ":" << __LINE__ << " calcState" << calcState.toString(); + return calcState; } -CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, QDateTime const &start_parking_time, QDateTime &ticketEndTime) +CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, + QDateTime const &start_parking_time, + QDateTime &ticketEndTime, + PermitType /* PermitType */) { + tariff->getPaymentOptions(0).pop_max_price + = tariff->getPaymentOptions(0).pop_max_price_save; + CalcState calcState; if (start_parking_time.isValid()) { - ticketEndTime = calculator.GetDailyTicketDuration(tariff, + ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff, start_parking_time, tariff->getPaymentOptions().pop_payment_method_id, false); // carry over @@ -309,3 +1450,30 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff return calcState.set(CalcState::State::SUCCESS); } + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &startDatetime, + QDateTime &endDatetime, + PERMIT_TYPE permitType, + struct price_t *price) {// return value + + tariff->getPaymentOptions(0).pop_max_price + = tariff->getPaymentOptions(0).pop_max_price_save; + + CalcState calcState; + + if (startDatetime.isValid()) { + if (std::optional p = + Calculator::GetInstance().GetDailyTicketPrice(tariff, + startDatetime, + endDatetime, + permitType)) { + *price = p.value(); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + return calcState.set(CalcState::State::SUCCESS); +} + diff --git a/library/src/calculate_price.cpp.new b/library/src/calculate_price.cpp.new new file mode 100644 index 0000000..60484f9 --- /dev/null +++ b/library/src/calculate_price.cpp.new @@ -0,0 +1,1146 @@ +#include "calculate_price.h" +#include "configuration.h" +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" +#include "tariff_global_defines.h" +#include "period_year.h" + +#include +#include +#include +#include +#include + +QString const CalcState::SUCCESS = "SUCCESS"; +QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR"; +QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF"; +QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF"; +QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME"; +QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE"; +QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES"; +QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT"; +QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE"; +QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE"; +QString const CalcState::OVERPAID = "OVERPAID"; +QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { + return Calculator::GetInstance().GetTimeSteps(cfg); +} + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int minTime = 0; + + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + + qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + qCritical() << __func__ << __LINE__ << "permit" << PermitType(permitType).toString(); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + qCritical() << __func__ << __LINE__ << minTime; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: + // for each new sell-procedure, recomute the timesteps. implicitly, set + // the minimal parking time. + Calculator::GetInstance().ResetTimeSteps(paymentOptionIndex); + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = qRound(cfg->getPaymentOptions(paymentOptionIndex).pop_min_time); + } + + qCritical() << "minTime" << minTime; + return minTime; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + int maxTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: ; + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } + + return maxTime; +} + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex, + QDateTime const &start) { + int minPrice = -1; + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + + int payment_method_id = cfg->getPaymentOptions(paymentOptionIndex).pop_payment_method_id; + + if (payment_method_id == PaymentMethod::Degressive) { + // Degressive: new for Fuchs Technik (500), ValserAlm (Fane): + // the minimal price has to be calculated, in cannot be hard coded into + // the tariff file. + // The working times have a reference into the payment rates. Two special + // entries (with the numbers 1000/1001) point to the respective prices. + switch(permitType) { + default: { + // find the correct work time range + int weekDay = start.date().dayOfWeek(); + std::optional> const &wd = cfg->getAllWeekDayWorkTimes(); + if (wd.has_value()) { + QVector const &vec = wd.value(); + for (int i = 0; i < vec.size(); ++i) { + ATBWeekDaysWorktime const &wt = vec[i]; + if (wt.pwd_period_day_in_week_id == weekDay) { + if (start.time() >= QTime::fromString(QString::fromStdString(wt.pwd_time_from), Qt::ISODate) + && start.time() <= QTime::fromString(QString::fromStdString(wt.pwd_time_to), Qt::ISODate)) { + // found worktime range + int pop_id = wt.pwd_pop_id; // 1000 or 1001 + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + i = vec.size(); // to leave outer loop + minPrice = itr->second.pra_price; // this is now the minimal price + break; + } + } + } + } + } + } + } + } else { + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + case PERMIT_TYPE::DAY_TICKET: { + minPrice = compute_product_price(cfg, permitType, start); + } break; + default: + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } + } + + return minPrice; +} + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType, + QDateTime const &start, + QDateTime *productStart, + QDateTime *productEnd) { + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_TEEN: + // [[fallthrough]]; + case PERMIT_TYPE::FOOD_STAMP: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + if (product.size() > 0) { + ATBTariffProduct const &p = product[0]; + return p.m_tariff_product_price; +#if 0 + // in case we do not have prepaid-option + QTime const ¤tTime = QDateTime::currentDateTime().time(); + + if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) { + return p.m_tariff_product_price; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "ERROR currentTime" + << currentTime.toString(Qt::ISODate) + << "INVALID (" + << p.m_tariff_product_start.toString(Qt::ISODate) + << p.m_tariff_product_end.toString(Qt::ISODate) << ")"; + } +#endif + } + } + } break; + case PERMIT_TYPE::INVALID: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + int product_price = 0; + + if (productStart && productEnd) { + *productStart = start; + *productEnd = start; + if (product.size() > 0) { + productStart->setTime(product[0].getTimeStart()); + productEnd->setTime(product[0].getTimeEnd()); + } + } + + for (QVector::size_type i=0; i= startTime && start.time() < endTime) { + product_price = p.getProductPrice(); + if (productStart && productEnd) { + productStart->setTime(startTime); + productEnd->setTime(endTime); + } + } + } + + return product_price; + } else { + // SZEGED + int const pop_daily_card_price = cfg->getPaymentOptions().pop_daily_card_price; + + qDebug() << QString("(%1:%2) no products defined in tariff-file").arg(__func__).arg(__LINE__); + qDebug() << QString("(%1:%2) pop_daily_card_price=%3").arg(__func__).arg(__LINE__).arg(pop_daily_card_price); + + // static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + // return Utilities::getDailyTicketCardPrice(cfg, paymentMethodId); + + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + int product_price = 0; + QVector product = products.value(); + + if (product.size() > 0) { + if (productStart && productEnd) { + int pop_min_time = get_minimal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + int pop_max_time = get_maximal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + if (pop_max_time >= pop_min_time) { + *productStart = start; + *productEnd = start.addSecs(pop_max_time*60); + product_price = product[0].getProductPrice(); + } + } + } + + return product_price; + } + + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "SHORT_TERM_PARKING_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + qCritical() << "TODO: SHORT_TERM_PARKING_BUS"; + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: { + qCritical() << "TODO: SHORT_TERM_PARKING_CAMPER"; + } break; + case PERMIT_TYPE::DAY_TICKET_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_BUS: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_BUS: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_CAMPER: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + default: + break; + } + + return 0; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxPrice = -1; + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + if (paymentMethodId == PaymentMethod::Progressive || paymentMethodId == PaymentMethod::Steps) { + maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + } else { // PaymentMethod::Linear -> e.g. szeged + int const key = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; // maxTime is given in minutes + std::optional> const &pv = cfg->getPaymentRateForKey(key); + if (pv) { + QVector const &paymentRate = pv.value(); + if (paymentRate.size() > 0) { + int const price = paymentRate.last().pra_price; // price is given per hour + maxPrice = qRound((maxTime * price) / 60.0f); + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: + break; + case PERMIT_TYPE::DAY_TICKET_TEEN: + break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + break; + case PERMIT_TYPE::DAY_TICKET_BUS: + break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: + break; + case PERMIT_TYPE::DAY_TICKET_PKW: + break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + break; + default: ; + } + + return maxPrice; +} + +int CALCULATE_LIBRARY_API get_zone_nr(int zone) +{ + if(zone > -1) return zone; + else + { + QFile zone("/etc/zone_nr"); + if (zone.exists()) { + QFileInfo finfo(zone); + if (finfo.size() <= 4) { // decimal 000\n + if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&zone); + return in.readLine(100).toInt(); + } + } + } + return -1; + } +} + +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { + *tariff = new Configuration(); + + CalcState calcState; +#if __linux__ + + int const zone = get_zone_nr(); + + // DEBUG + qCritical() << "init_tariff:"; + qCritical() << " ... zone = " << zone; + + if (zone <= 0) { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_PARSING_ZONE_NR); + } + + QString confFile(config_file); + if (!confFile.endsWith(QChar('/'))) { + confFile += "/"; + } + + char buffer[32]; + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone); + confFile += buffer; +#else // windows + QString confFile(config_file); +#endif + + // DEBUG + qCritical() << " ... confFile = " << confFile; + + QFile fname(confFile); + if (fname.exists() && + fname.open(QIODevice::ReadOnly | QIODevice::Text)) { + // DEBUG + qCritical() << " ... confFile is open"; + + QString json = fname.readAll(); + if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error parsing tariff"; + return calcState.set(CalcState::State::ERROR_PARSING_TARIFF); + } + } else { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error loading tariff"; + return calcState.set(CalcState::State::ERROR_LOADING_TARIFF); + } + + qCritical() << "init_tariff: Parsing tariff config (" << confFile << ")"; + + return calcState; +} + +void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { + if (tariff != nullptr) { + delete tariff; + } +} + +// +// UpDown 1 -> up; 0 -> down +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, + int UpDown, PermitType const &permitType) +{ + + qCritical() << __LINE__ << "compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() up/down (1=up, 0=down): " << UpDown; + + // FIXME + //std::optional paymentOption = tariff->getPaymentOptionForKey(permitType.get()); + //if (!paymentOption.has_value()) { + // qCritical() << " compute_next_timestep() ERROR"; + // return currentTimeMinutes; + //} + + int const paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + int const &pop_plus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_plus_steps; + int const &pop_minus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_minus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() payment option index: " << paymentOptionIndex; + qCritical() << __LINE__ << "compute_next_timestep() plus steps: " << pop_plus_steps; + qCritical() << __LINE__ << "compute_next_timestep() minus steps: " << pop_minus_steps; + + Configuration const *cfg = tariff; + + // compute payment method id (e.g. Linear=3, Steps=4) + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + switch (paymentMethodId) { + case PaymentMethod::Progressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Progressive"; + break; + case PaymentMethod::Degressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Degressive"; + break; + case PaymentMethod::Linear: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Linear"; + break; + case PaymentMethod::Steps: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps"; + break; + case PaymentMethod::Undefined: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined"; + break; + } + + // use tariff with structure as for instance Schnau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + if ((paymentMethodId == PaymentMethod::Steps) || + // progressive tariff: e.g. Neuhauser, Kirchdorf (743) + (paymentMethodId == PaymentMethod::Progressive) || + // degressive tariff: e.g. Fuchs Technik (500) + (paymentMethodId == PaymentMethod::Degressive)) + { + QList &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex); + + int const size = stepList.size(); + if (size == 0) { + qCritical() << "compute_next_timestep() *ERROR empty step-list*"; + return currentTimeMinutes; + } + + qCritical() << __LINE__ << "compute_next_timestep() first time step:" << stepList[0]; + qCritical() << __LINE__ << "compute_next_timestep() timeSteps:" << stepList; + qCritical() << __LINE__ << "compute_next_timestep() currentTimeInMinutes:" << currentTimeMinutes; + + // consider time shift: the step-list might have been computed at a + // slightly different time point + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); + if (currentStepIndex == -1) { + unsigned minimalDistance = ~0; + int j = -1; + for (int i = 0; i < stepList.size(); ++i) { + unsigned distance = std::abs(stepList[i] - currentTimeMinutes); + if (distance < minimalDistance) { + minimalDistance = distance; + j = i; + } + } + // max. tolerance set to 3 minutes + unsigned const tolerance = std::min(minimalDistance, (unsigned)(3)); + if (j != -1) { + stepList[j] = currentTimeMinutes; + } + } + +#if 0 + int maxStep = -1; + if (size >= 2) { + maxStep = stepList[1] - stepList[0]; + } + // max. tolerance set to 5 minutes + int const tolerance = (maxStep == -1) ? 5 : std::min(maxStep, 5); + for (int i=0; i < stepList.size(); ++i) { + if (std::abs(stepList[i] - currentTimeMinutes) <= tolerance) { + qCritical().noquote() + << __LINE__ << QString("compute_next_timestep() correction stepList[%1]=%2 -> %3:") + .arg(i).arg(stepList[0]).arg(currentTimeMinutes); + stepList[i] = currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() NEW timeSteps:" << stepList; + } + } + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); +#endif + + currentStepIndex = stepList.indexOf(currentTimeMinutes); + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + if (currentStepIndex == -1) { + qCritical() << __LINE__ << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + + if (UpDown == 1) { // UP + if (stepList[currentStepIndex] == stepList.last()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const rest = currentStepIndex % pop_plus_steps; + + if (rest) { + currentStepIndex -= rest; + } + + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + int const nextStepIndex = currentStepIndex + pop_plus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + if (UpDown == 0) { // DOWN + if (stepList[currentStepIndex] == stepList.first()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const nextStepIndex = currentStepIndex - pop_minus_steps; + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + } else + if (paymentMethodId == PaymentMethod::Linear) { + + // currentTimeMinutes is the number of minutes actually used. This + // value is an offset from the start time and cannot be used as a + // QDateTime. + + qCritical() << "compute_next_timestep() up/down (1=up, 0=down):" << UpDown; + + // get minimal and maximal parking times + int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + + qCritical() << " compute_next_timestep() maxParkingTime:" << maxParkingTime; + qCritical() << " compute_next_timestep() minParkingTime:" << minParkingTime; + + // use the first (i.e. main duration step contained in the tariff json-file) + int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId); + firstDurationStep = ((UpDown == 1) ? firstDurationStep : -firstDurationStep); + + qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep; + + int const nextTimeStep = currentTimeMinutes + firstDurationStep; + + if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) { + qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep; + return nextTimeStep; + } + } + + qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; +} + +// this is currently not used +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, // in minutes + time_t end_parking_time, // netto time in minutes + struct price_t *price, + PermitType permitType) { // permitType maps to product + + CalcState calcState; + + int const paymentOptionIndex = tariff->getPaymentOptionIndex(permitType.get()); + + double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_max_time; + + if (minMin < 0 || maxMin < 0 || maxMin < minMin) { + calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin)); + return calcState.set(CalcState::State::WRONG_PARAM_VALUES); + } + + int const duration = end_parking_time - start_parking_time; + if (duration < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time, start_parking_time)); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (duration > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (duration < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (duration == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + QDateTime end(start); + if (start.isValid()) { + double cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + start, + end, + duration, false, true); + double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + price->units = cost; + price->netto = cost; + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time_, + int netto_parking_time, + QDateTime &end_parking_time, + struct price_t *price, + PermitType permitType, + bool prepaid) +{ + CalcState calcState; + + QDateTime start_parking_time(start_parking_time_); + + int paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + + double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time; + double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time; + + // DEBUG + qCritical() << "compute_price_for_parking_ticket() " << endl + << " paymentOptionIndex: " << paymentOptionIndex << endl + << " start_parking_time: " << start_parking_time << endl + << " netto_parking_time: " << netto_parking_time << endl + << " start + netto: " << start_parking_time.addSecs(netto_parking_time * 60) << endl + << " minMin: " << minMin << endl + << " maxMin: " << maxMin + << " prepaid: " << prepaid + << " permitType: " << permitType.toString(); + + if (netto_parking_time < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time.toString(Qt::ISODate), + start_parking_time.toString(Qt::ISODate))); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (netto_parking_time > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (netto_parking_time < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (netto_parking_time == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + double cost = -1; + if (start_parking_time.isValid()) { + if (tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Steps || + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Degressive) { + // hier muesste man unterscheiden: uebertrag oder nicht? + calcState = Calculator::GetInstance().isParkingAllowed(tariff, start_parking_time, + netto_parking_time, paymentOptionIndex); + if (calcState.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << calcState.toString(); + return calcState; + } + + QList tlist = Calculator::GetInstance().GetTimeSteps(tariff); + Q_UNUSED(tlist); + + // compute cost (price) + cost = Calculator::GetInstance().GetCostFromDuration(tariff, start_parking_time, netto_parking_time, paymentOptionIndex); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + qCritical() << __func__ << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + qCritical() << __func__ << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + } + + QTime const carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + int const carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + qCritical() << __func__ << __LINE__ << "carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << __LINE__ << "carryOverDuration" << carryOverDuration; + + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << __LINE__ << "prepaid: no"; + } else { + if (start_parking_time.time() < p.static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.static_end); + } else + if (start_parking_time.time() > p.static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.static_start); + } + } + } + + // handle carry over + int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60; + if (netto_parking_time > minutesUntilCarryOver) { + int const rest = netto_parking_time - minutesUntilCarryOver; + QDateTime s(effectiveStartTime); + s = s.addSecs(minutesUntilCarryOver * 60); + s = s.addSecs(carryOverDuration * 60); + end_parking_time = s.addSecs(rest * 60); + } else { + end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60); + } + + } else { + cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + start_parking_time, // starting time + end_parking_time, // return value: end time + netto_parking_time, // minutes, netto + false, prepaid); + } + // qCritical() << __func__ << __LINE__; + double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + + // DEBUG + //qCritical() << __LINE__ << " end_parking_time: " << end_parking_time; + //qCritical() << __LINE__ << " -> calculated cost (netto): " << cost; + + price->brutto = price->vat = price->vat_percentage = 0; + price->units = cost; + price->netto = cost; + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + if (end_parking_time.time().hour() == 0 && end_parking_time.time().minute() == 0) { + end_parking_time = end_parking_time.addDays(-1); + end_parking_time.setTime(QTime(23, 59, 0)); + } + qCritical() << __func__ << __LINE__ << "end_parking_time" << end_parking_time.toString(Qt::ISODate); + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double price, + QString &duration, + PermitType permitType) { + CalcState calcState; + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + + bool prepaid = true; + int paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + if (prepaid_option_id == 2) { // see tariff03.json for 502: 2 means no prepaid-option + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + qCritical() << "compute_duration_for_parking_ticket(1): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " start (cs): " << cs; + qCritical() << " price: " << price; + + duration = Calculator::GetInstance().GetDurationFromCost(tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + QDateTime d = QDateTime::fromString(duration, Qt::ISODate); + if (!d.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime const &start_parking_time, + double price, + QDateTime &ticketEndTime, + PermitType permitType) +{ + CalcState calcState; + + bool prepaid = true; + int paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + if (prepaid_option_id == 2) { + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "compute_duration_for_parking_ticket(2): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " price: " << price; + } + + if (start_parking_time.isValid()) { + + int const pop_time_step_config = tariff->getPaymentOptions(paymentOptionIndex).pop_time_step_config; + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << __LINE__ << "prepaid: no"; + } else { + if (start_parking_time.time() < p.static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.static_end); + } else + if (start_parking_time.time() > p.static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.static_start); + } + } + } + } + + QString cs = start_parking_time.toString(Qt::ISODate); + QString endTime = Calculator::GetInstance().GetDurationFromCost( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + + if (endTime == CalcState::SUCCESS) { + calcState.setDesc(QString("SUCCESS")); + calcState.setStatus(endTime); + } else + if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_LOADING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_PARSING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::NEGATIVE_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::INVALID_START_DATE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_PARAM_VALUES) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) { + calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE); + calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE); + return calcState; + } else + if (endTime == CalcState::OVERPAID) { + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } else + if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else { + ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle carry over for ticket-end-time + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + qCritical() << __func__ << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + qCritical() << __func__ << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + } + + QTime carryOverStart; + QTime carryOverEnd; + int carryOverDuration = -1; + + // using TariffCarryOverType = std::multimap; + std::multimap::const_iterator it; + if ((it = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)) != + tariff->TariffCarryOverOptions.cend()) { + carryOverStart = it->second.carryover[weekDay].static_start; + carryOverEnd = it->second.carryover[weekDay].static_end; + carryOverDuration = it->second.carryover[weekDay].duration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid()) { + qCritical() << __func__ << __LINE__ << "carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << __LINE__ << "carryOverEnd" << carryOverEnd.toString(Qt::ISODate); + qCritical() << __func__ << __LINE__ << "carryOverDuration" << carryOverDuration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid() && carryOverDuration != -1) { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() > carryOverStart) { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } else { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() < carryOverEnd) { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } + } + } else { + qCritical() << __func__ << __LINE__ << "WARNING: wrong carry-over-settings"; + } + } + + if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) { + ticketEndTime = ticketEndTime.addDays(-1); + ticketEndTime.setTime(QTime(23, 59, 0)); + } + + // DEBUG + qCritical() << __func__ << __LINE__ << " endTime:" << endTime; + qCritical() << __func__ << __LINE__ << "ticketEndTime:" << ticketEndTime; + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, + QDateTime const &start_parking_time, + QDateTime &ticketEndTime, + PermitType PermitType) +{ + CalcState calcState; + if (start_parking_time.isValid()) { + + ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff, + start_parking_time, + tariff->getPaymentOptions().pop_payment_method_id, + false); // carry over + + // DEBUG + qCritical() << "compute_duration_for_daily_ticket(): "; + qCritical() << " ticketEndTime: " << ticketEndTime; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(ticketEndTime.toString(Qt::ISODate))); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &startDatetime, + QDateTime &endDatetime, + PERMIT_TYPE permitType, + struct price_t *price) {// return value + CalcState calcState; + + + if (startDatetime.isValid()) { + if (std::optional p = + Calculator::GetInstance().GetDailyTicketPrice(tariff, + startDatetime, + endDatetime, + permitType)) { + *price = p.value(); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + return calcState.set(CalcState::State::SUCCESS); +} + diff --git a/library/src/calculate_price.cpp.new.2 b/library/src/calculate_price.cpp.new.2 new file mode 100644 index 0000000..1505d8b --- /dev/null +++ b/library/src/calculate_price.cpp.new.2 @@ -0,0 +1,1280 @@ +#include "calculate_price.h" +#include "configuration.h" +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" +#include "tariff_global_defines.h" +#include "period_year.h" + +#include +#include +#include +#include +#include + +QString const CalcState::SUCCESS = "SUCCESS"; +QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR"; +QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF"; +QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF"; +QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME"; +QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE"; +QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES"; +QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT"; +QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE"; +QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE"; +QString const CalcState::OVERPAID = "OVERPAID"; +QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { + return Calculator::GetInstance().GetTimeSteps(cfg); +} + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int minTime = 0; + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + qCritical() << __func__ << __LINE__ << "permit" << PermitType(permitType).toString(); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + qCritical() << __func__ << __LINE__ << minTime; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: + // for each new sell-procedure, recomute the timesteps. implicitly, set + // the minimal parking time. + Calculator::GetInstance().ResetTimeSteps(paymentOptionIndex); + qCritical() << __LINE__ << Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = qRound(cfg->getPaymentOptions(paymentOptionIndex).pop_min_time); + } + + qCritical() << "minTime" << minTime; + return minTime; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + + paymentOptionIndex = getPaymentOptionIndex(*cfg); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + int maxTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: ; + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } + + return maxTime; +} + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex, + QDateTime const &start) { + int minPrice = -1; + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg, start)) == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + int payment_method_id = cfg->getPaymentOptions(paymentOptionIndex).pop_payment_method_id; + + if (payment_method_id == PaymentMethod::Degressive) { + // Degressive: new for Fuchs Technik (500), ValserAlm (Fane): + // the minimal price has to be calculated, in cannot be hard coded into + // the tariff file. + // The working times have a reference into the payment rates. Two special + // entries (with the numbers 1000/1001) point to the respective prices. + switch(permitType) { + default: { + // find the correct work time range + int weekDay = start.date().dayOfWeek(); + std::optional> const &wd = cfg->getAllWeekDayWorkTimes(); + if (wd.has_value()) { + QVector const &vec = wd.value(); + for (int i = 0; i < vec.size(); ++i) { + ATBWeekDaysWorktime const &wt = vec[i]; + if (wt.pwd_period_day_in_week_id == weekDay) { + if (start.time() >= QTime::fromString(QString::fromStdString(wt.pwd_time_from), Qt::ISODate) + && start.time() <= QTime::fromString(QString::fromStdString(wt.pwd_time_to), Qt::ISODate)) { + // found worktime range + int pop_id = wt.pwd_pop_id; // 1000 or 1001 + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + i = vec.size(); // to leave outer loop + minPrice = itr->second.pra_price; // this is now the minimal price + break; + } + } + } + } + } + } + } + } else { + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + case PERMIT_TYPE::DAY_TICKET: { + minPrice = compute_product_price(cfg, permitType, start); + } break; + default: + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } + } + + return minPrice; +} + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType, + QDateTime const &start, + QDateTime *productStart, + QDateTime *productEnd) { + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_TEEN: + // [[fallthrough]]; + case PERMIT_TYPE::FOOD_STAMP: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + if (product.size() > 0) { + ATBTariffProduct const &p = product[0]; + return p.m_tariff_product_price; +#if 0 + // in case we do not have prepaid-option + QTime const ¤tTime = QDateTime::currentDateTime().time(); + + if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) { + return p.m_tariff_product_price; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "ERROR currentTime" + << currentTime.toString(Qt::ISODate) + << "INVALID (" + << p.m_tariff_product_start.toString(Qt::ISODate) + << p.m_tariff_product_end.toString(Qt::ISODate) << ")"; + } +#endif + } + } + } break; + case PERMIT_TYPE::INVALID: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + int product_price = 0; + + if (productStart && productEnd) { + *productStart = start; + *productEnd = start; + if (product.size() > 0) { + productStart->setTime(product[0].getTimeStart()); + productEnd->setTime(product[0].getTimeEnd()); + } + } + + for (QVector::size_type i=0; i= startTime && start.time() < endTime) { + product_price = p.getProductPrice(); + if (productStart && productEnd) { + productStart->setTime(startTime); + productEnd->setTime(endTime); + } + } + } + + return product_price; + } else { + // SZEGED + int const pop_daily_card_price = cfg->getPaymentOptions().pop_daily_card_price; + + qDebug() << QString("(%1:%2) no products defined in tariff-file").arg(__func__).arg(__LINE__); + qDebug() << QString("(%1:%2) pop_daily_card_price=%3").arg(__func__).arg(__LINE__).arg(pop_daily_card_price); + + // static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + // return Utilities::getDailyTicketCardPrice(cfg, paymentMethodId); + + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + int product_price = 0; + QVector product = products.value(); + + if (product.size() > 0) { + if (productStart && productEnd) { + int pop_min_time = get_minimal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + int pop_max_time = get_maximal_parkingtime(cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET); // in minutes + if (pop_max_time >= pop_min_time) { + *productStart = start; + *productEnd = start.addSecs(pop_max_time*60); + product_price = product[0].getProductPrice(); + } + } + } + + return product_price; + } + + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "SHORT_TERM_PARKING_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + qCritical() << "TODO: SHORT_TERM_PARKING_BUS"; + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: { + qCritical() << "TODO: SHORT_TERM_PARKING_CAMPER"; + } break; + case PERMIT_TYPE::DAY_TICKET_PKW: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_PKW: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_BUS: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_BUS: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: { + PermitType p(permitType); + std::optional const paymentOption = cfg->getPaymentOptionForKey(p.get()); + if (paymentOption.has_value()) { + ATBPaymentOption option = paymentOption.value(); + int const pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "DAY_TICKET_CAMPER: daily ticket price" << pop_daily_card_price; + return pop_daily_card_price; + } + } break; + default: + break; + } + + return 0; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxPrice = -1; + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if ((paymentOptionIndex = getPaymentOptionIndex(*cfg)) == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType); + } + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + if (paymentMethodId == PaymentMethod::Progressive || paymentMethodId == PaymentMethod::Steps) { + //maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + ATBPaymentOption const &po = cfg->getPaymentOptions(paymentOptionIndex); + maxPrice = po.pop_max_price; // maxTime is given in minutes + } else { // PaymentMethod::Linear -> e.g. szeged + int const key = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; // maxTime is given in minutes + std::optional> const &pv = cfg->getPaymentRateForKey(key); + if (pv) { + QVector const &paymentRate = pv.value(); + if (paymentRate.size() > 0) { + int const price = paymentRate.last().pra_price; // price is given per hour + maxPrice = qRound((maxTime * price) / 60.0f); + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: + break; + case PERMIT_TYPE::DAY_TICKET_TEEN: + break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + break; + case PERMIT_TYPE::DAY_TICKET_BUS: + break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: + break; + case PERMIT_TYPE::DAY_TICKET_PKW: + break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + std::optional po = cfg->getPaymentOptionForKey(permitType); + if (po.has_value()) { + ATBPaymentOption option = po.value(); + return option.pop_max_price; + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: + break; + default: ; + } + + return maxPrice; +} + +int CALCULATE_LIBRARY_API get_zone_nr(int zone) +{ + if(zone > -1) return zone; + else + { + QFile zone("/etc/zone_nr"); + if (zone.exists()) { + QFileInfo finfo(zone); + if (finfo.size() <= 4) { // decimal 000\n + if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&zone); + return in.readLine(100).toInt(); + } + } + } + return -1; + } +} + +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { + *tariff = new Configuration(); + + CalcState calcState; +#if __linux__ + + int const zone = get_zone_nr(); + + // DEBUG + qCritical() << "init_tariff:"; + qCritical() << " ... zone = " << zone; + + if (zone <= 0) { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_PARSING_ZONE_NR); + } + + QString confFile(config_file); + if (!confFile.endsWith(QChar('/'))) { + confFile += "/"; + } + + char buffer[32]; + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone); + confFile += buffer; +#else // windows + QString confFile(config_file); +#endif + + // DEBUG + qCritical() << " ... confFile = " << confFile; + + QFile fname(confFile); + if (fname.exists() && + fname.open(QIODevice::ReadOnly | QIODevice::Text)) { + // DEBUG + qCritical() << " ... confFile is open"; + + QString json = fname.readAll(); + if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error parsing tariff"; + return calcState.set(CalcState::State::ERROR_PARSING_TARIFF); + } + } else { + delete *tariff; + *tariff = nullptr; + qCritical() << " ... error loading tariff"; + return calcState.set(CalcState::State::ERROR_LOADING_TARIFF); + } + + qCritical() << "init_tariff: Parsing tariff config (" << confFile << ")"; + + return calcState; +} + +void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { + if (tariff != nullptr) { + delete tariff; + } +} + +// +// UpDown 1 -> up; 0 -> down +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, + int UpDown, PermitType const &permitType) +{ + + qCritical() << __LINE__ << "compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() up/down (1=up, 0=down): " << UpDown; + + // FIXME + //std::optional paymentOption = tariff->getPaymentOptionForKey(permitType.get()); + //if (!paymentOption.has_value()) { + // qCritical() << " compute_next_timestep() ERROR"; + // return currentTimeMinutes; + //} + + int paymentOptionIndex = getPaymentOptionIndex(*tariff); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int const &pop_plus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_plus_steps; + int const &pop_minus_steps = tariff->getPaymentOptions(paymentOptionIndex).pop_minus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() payment option index: " << paymentOptionIndex; + qCritical() << __LINE__ << "compute_next_timestep() plus steps: " << pop_plus_steps; + qCritical() << __LINE__ << "compute_next_timestep() minus steps: " << pop_minus_steps; + + Configuration const *cfg = tariff; + + // compute payment method id (e.g. Linear=3, Steps=4) + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + switch (paymentMethodId) { + case PaymentMethod::Progressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Progressive"; + break; + case PaymentMethod::Degressive: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Degressive"; + break; + case PaymentMethod::Linear: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Linear"; + break; + case PaymentMethod::Steps: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps"; + break; + case PaymentMethod::Undefined: + qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined"; + break; + } + + // use tariff with structure as for instance Schnau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + if ((paymentMethodId == PaymentMethod::Steps) || + // progressive tariff: e.g. Neuhauser, Kirchdorf (743) + (paymentMethodId == PaymentMethod::Progressive) || + // degressive tariff: e.g. Fuchs Technik (500) + (paymentMethodId == PaymentMethod::Degressive)) + { + QList &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex); + + int const size = stepList.size(); + if (size == 0) { + qCritical() << "compute_next_timestep() *ERROR empty step-list*"; + return currentTimeMinutes; + } + + qCritical() << __LINE__ << "compute_next_timestep() first time step:" << stepList[0]; + qCritical() << __LINE__ << "compute_next_timestep() timeSteps:" << stepList; + qCritical() << __LINE__ << "compute_next_timestep() currentTimeInMinutes:" << currentTimeMinutes; + + // consider time shift: the step-list might have been computed at a + // slightly different time point + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); + if (currentStepIndex == -1) { + unsigned minimalDistance = ~0; + int j = -1; + for (int i = 0; i < stepList.size(); ++i) { + unsigned distance = std::abs(stepList[i] - currentTimeMinutes); + if (distance < minimalDistance) { + minimalDistance = distance; + j = i; + } + } + // max. tolerance set to 3 minutes + // unsigned const tolerance = std::min(minimalDistance, (unsigned)(3)); + if (j != -1) { + stepList[j] = currentTimeMinutes; + } + } + +#if 0 + int maxStep = -1; + if (size >= 2) { + maxStep = stepList[1] - stepList[0]; + } + // max. tolerance set to 5 minutes + int const tolerance = (maxStep == -1) ? 5 : std::min(maxStep, 5); + for (int i=0; i < stepList.size(); ++i) { + if (std::abs(stepList[i] - currentTimeMinutes) <= tolerance) { + qCritical().noquote() + << __LINE__ << QString("compute_next_timestep() correction stepList[%1]=%2 -> %3:") + .arg(i).arg(stepList[0]).arg(currentTimeMinutes); + stepList[i] = currentTimeMinutes; + qCritical() << __LINE__ << "compute_next_timestep() NEW timeSteps:" << stepList; + } + } + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); +#endif + + currentStepIndex = stepList.indexOf(currentTimeMinutes); + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + if (currentStepIndex == -1) { + qCritical() << __LINE__ << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + + if (UpDown == 1) { // UP + if (stepList[currentStepIndex] == stepList.last()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const rest = currentStepIndex % pop_plus_steps; + + if (rest) { + currentStepIndex -= rest; + } + + qCritical() << __LINE__ << "compute_next_timestep() currentStepIndex (" << currentStepIndex << ")"; + + int const nextStepIndex = currentStepIndex + pop_plus_steps; + + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + if (UpDown == 0) { // DOWN + if (stepList[currentStepIndex] == stepList.first()) { + qCritical() << __LINE__ << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + int const nextStepIndex = currentStepIndex - pop_minus_steps; + qCritical() << __LINE__ << "compute_next_timestep() next step index:" << nextStepIndex; + if (nextStepIndex >= 0 && nextStepIndex < stepList.size()) { + qCritical() << __LINE__ << "compute_next_timestep() return next time step:" << stepList[nextStepIndex]; + return stepList[nextStepIndex]; + } + } + } + } else + if (paymentMethodId == PaymentMethod::Linear) { + + // currentTimeMinutes is the number of minutes actually used. This + // value is an offset from the start time and cannot be used as a + // QDateTime. + + qCritical() << "compute_next_timestep() up/down (1=up, 0=down):" << UpDown; + + // get minimal and maximal parking times + int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + + qCritical() << " compute_next_timestep() maxParkingTime:" << maxParkingTime; + qCritical() << " compute_next_timestep() minParkingTime:" << minParkingTime; + + // use the first (i.e. main duration step contained in the tariff json-file) + int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId); + firstDurationStep = ((UpDown == 1) ? firstDurationStep : -firstDurationStep); + + qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep; + + int const nextTimeStep = currentTimeMinutes + firstDurationStep; + + if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) { + qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep; + return nextTimeStep; + } + } + + qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; +} + +// this is currently not used +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, // in minutes + time_t end_parking_time, // netto time in minutes + struct price_t *price, + PermitType permitType) { // permitType maps to product + + CalcState calcState; + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + QDateTime end(start); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType.get()); + } + + double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_max_time; + + if (minMin < 0 || maxMin < 0 || maxMin < minMin) { + calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin)); + return calcState.set(CalcState::State::WRONG_PARAM_VALUES); + } + + int const duration = end_parking_time - start_parking_time; + if (duration < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time, start_parking_time)); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (duration > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (duration < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (duration == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + //QDate const d(1970, 1, 1); + //QTime const t(0, 0, 0); + //QDateTime start(d, t, Qt::UTC); + //start = start.toLocalTime().addSecs(start_parking_time * 60); + //QDateTime end(start); + if (start.isValid()) { + double cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + start, + end, + duration, false, true); + double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + price->units = cost; + price->netto = cost; + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time_, + int netto_parking_time, + QDateTime &end_parking_time, + struct price_t *price, + PermitType permitType, + bool prepaid) +{ + CalcState calcState; + + QDateTime start_parking_time(start_parking_time_); + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time; + double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time; + + // DEBUG + qCritical() << "compute_price_for_parking_ticket() " << endl + << " paymentOptionIndex: " << paymentOptionIndex << endl + << " start_parking_time: " << start_parking_time << endl + << " netto_parking_time: " << netto_parking_time << endl + << " start + netto: " << start_parking_time.addSecs(netto_parking_time * 60) << endl + << " minMin: " << minMin << endl + << " maxMin: " << maxMin + << " prepaid: " << prepaid + << " permitType: " << permitType.toString(); + + if (netto_parking_time < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time.toString(Qt::ISODate), + start_parking_time.toString(Qt::ISODate))); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (netto_parking_time > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (netto_parking_time < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (netto_parking_time == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + double cost = -1; + if (start_parking_time.isValid()) { + if (tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Steps || + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Degressive) { + // hier muesste man unterscheiden: uebertrag oder nicht? + calcState = Calculator::GetInstance().isParkingAllowed(tariff, start_parking_time, + netto_parking_time, paymentOptionIndex); + if (calcState.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << calcState.toString(); + return calcState; + } + + QList tlist = Calculator::GetInstance().GetTimeSteps(tariff); + Q_UNUSED(tlist); + + // compute cost (price) + cost = Calculator::GetInstance().GetCostFromDuration(tariff, start_parking_time, netto_parking_time, paymentOptionIndex); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + int pop_prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + pop_prepaid_option_id = period.pye_id; + qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + qCritical() << __func__ << ":" << __LINE__ << " re-computed prepaid-id" << pop_prepaid_option_id; + } + + QTime carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + int carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << ":" << __LINE__ << "prepaid: no"; + } else { + qCritical() << __func__ << ":" << __LINE__ << " prepaidStart" << p.prepaid[weekDay].static_start.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " prepaidEnd" << p.prepaid[weekDay].static_end.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "prepaid duration" << p.prepaid[weekDay].duration; + + if (start_parking_time.time() < p.prepaid[weekDay].static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_end); + } else + if (start_parking_time.time() > p.prepaid[weekDay].static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.prepaid[weekDay].static_start); + } + } + } + + qCritical() << __func__ << ":" << __LINE__ << "effectiveStartTime:" << effectiveStartTime.toString(Qt::ISODate); + + // handle carry over + int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60; + if ((minutesUntilCarryOver > 0) && (netto_parking_time > minutesUntilCarryOver)) { + + qCritical() << __func__ << ":" << __LINE__ << ":" << netto_parking_time << minutesUntilCarryOver; + + int const rest = netto_parking_time - minutesUntilCarryOver; + QDateTime s(effectiveStartTime); + s = s.addSecs(minutesUntilCarryOver * 60); + s = s.addSecs(carryOverDuration * 60); + end_parking_time = s.addSecs(rest * 60); + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + } else { + end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60); + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + } + + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + + weekDay = end_parking_time.date().dayOfWeek(); + + // musste man in einer schleife machen + carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + if (end_parking_time.time() > carryOverStart) { + end_parking_time = end_parking_time.addSecs(carryOverDuration * 60); + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + } else + if (end_parking_time.time() == carryOverStart) { + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + ATBPaymentOption const &po = tariff->getPaymentOptions(paymentOptionIndex); + if (po.pop_apply_carry_over_to_ticket_endtime) { + end_parking_time = end_parking_time.addSecs(carryOverDuration * 60); + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + } + } + + end_parking_time.setTime(QTime(end_parking_time.time().hour(), + end_parking_time.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " week-day:" << weekDay; + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)weekDay); itr != rangeEnd; ++itr) { + ATBWeekDay const &wd = itr->second; + bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(effectiveStartTime, + end_parking_time, + paymentOptionIndex); + if (parkTimeLimitViolated) { + //QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + //end_parking_time.setTime(tlimit); + + calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + .arg(end_parking_time.time().toString(Qt::ISODate))); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + } else { + cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + start_parking_time, // starting time + end_parking_time, // return value: end time + netto_parking_time, // minutes, netto + false, prepaid); + } + // qCritical() << __func__ << __LINE__; + double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + + // DEBUG + //qCritical() << __LINE__ << " end_parking_time: " << end_parking_time; + //qCritical() << __LINE__ << " -> calculated cost (netto): " << cost; + + price->brutto = price->vat = price->vat_percentage = 0; + price->units = cost; + price->netto = cost; + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + if (end_parking_time.time().hour() == 0 && end_parking_time.time().minute() == 0) { + end_parking_time = end_parking_time.addDays(-1); + end_parking_time.setTime(QTime(23, 59, 0)); + } + qCritical() << __func__ << __LINE__ << "end_parking_time" << end_parking_time.toString(Qt::ISODate); + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double price, + QString &duration, + PermitType permitType) { + CalcState calcState; + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + + bool prepaid = true; + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start); + qCritical() << " payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + if (prepaid_option_id == 2) { // see tariff03.json for 502: 2 means no prepaid-option + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + qCritical() << "compute_duration_for_parking_ticket(1): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " start (cs): " << cs; + qCritical() << " price: " << price; + + duration = Calculator::GetInstance().GetDurationFromCost(tariff, + tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + QDateTime d = QDateTime::fromString(duration, Qt::ISODate); + if (!d.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime const &start_parking_time, + double price, + QDateTime &ticketEndTime, + PermitType permitType) +{ + CalcState calcState; + + bool prepaid = true; + + int paymentOptionIndex = getPaymentOptionIndex(*tariff, start_parking_time); + qCritical() << __func__ << ":" << __LINE__ << "payment option index: " << paymentOptionIndex; + if (paymentOptionIndex == -1) { + paymentOptionIndex = tariff->getPaymentOptionIndex(permitType); + } + + qCritical() << __func__ << ":" << __LINE__ << " payment option index: " << paymentOptionIndex; + + int prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + if (prepaid_option_id == 2) { + prepaid = false; + } + bool const nextDay = false; + + // DEBUG + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "compute_duration_for_parking_ticket(2): "; + qCritical() << " payment option index: " << paymentOptionIndex; + qCritical() << " prepaid: " << prepaid; + qCritical() << " price: " << price; + } + + if (start_parking_time.isValid()) { + + int const pop_time_step_config = tariff->getPaymentOptions(paymentOptionIndex).pop_time_step_config; + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle prepaid option + QDateTime effectiveStartTime(start_parking_time); + int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + std::optional prepaidOption = tariff->getPrepaidType(prepaid_option_id); + if (prepaidOption.has_value()) { + ATBPrepaid const &p = prepaidOption.value(); + if (p.never) { + qCritical() << __func__ << __LINE__ << "prepaid: no"; + } else { + if (start_parking_time.time() < p.static_end) { // static_end: e.g. 08:00:00 + effectiveStartTime.setTime(p.static_end); + } else + if (start_parking_time.time() > p.static_start) { // static_start: e.g. 22:00:00 + effectiveStartTime.setTime(p.static_start); + } + } + } + } + + QString cs = start_parking_time.toString(Qt::ISODate); + QString endTime = Calculator::GetInstance().GetDurationFromCost( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, permitType, nextDay, prepaid).c_str(); + + qCritical() << __func__ << ":" << __LINE__ << "endTime:" << ticketEndTime.toString(Qt::ISODate); + + if (endTime == CalcState::SUCCESS) { + calcState.setDesc(QString("SUCCESS")); + calcState.setStatus(endTime); + } else + if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_LOADING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_PARSING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::NEGATIVE_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::INVALID_START_DATE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_PARAM_VALUES) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) { + calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE); + calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE); + return calcState; + } else + if (endTime == CalcState::OVERPAID) { + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } else + if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else { + ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "step-config:" << pop_time_step_config; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) { + // handle carry over for ticket-end-time + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + int weekDay = start_parking_time.date().dayOfWeek(); + int pop_carry_over_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + qCritical() << __func__ << ":" << __LINE__ << "configured carry-over-id" << pop_carry_over_option_id; + + std::optional yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); + if (yperiod.has_value()) { + ATBPeriodYear const &period = yperiod.value(); + pop_carry_over_option_id = period.pye_id; + qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; + } + + QTime carryOverStart; + QTime carryOverEnd; + int carryOverDuration = -1; + + // using TariffCarryOverType = std::multimap; + std::multimap::const_iterator it; + if ((it = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)) != + tariff->TariffCarryOverOptions.cend()) { + carryOverStart = it->second.carryover[weekDay].static_start; + carryOverEnd = it->second.carryover[weekDay].static_end; + carryOverDuration = it->second.carryover[weekDay].duration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid()) { + qCritical() << __func__ << ":" << __LINE__ << "carryOverStart" << carryOverStart.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverEnd" << carryOverEnd.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; + } + + if (carryOverStart.isValid() && carryOverEnd.isValid() && carryOverDuration != -1) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() > carryOverStart) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } else + if (ticketEndTime.time() == carryOverStart) { + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); + ATBPaymentOption const &po = tariff->getPaymentOptions(paymentOptionIndex); + if (po.pop_apply_carry_over_to_ticket_endtime) { + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + } + } else { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + if (ticketEndTime.time() < carryOverEnd) { + // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); + ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); + } + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING: wrong carry-over-settings"; + } + } + + + ticketEndTime.setTime(QTime(ticketEndTime.time().hour(), + ticketEndTime.time().minute(), 0)); + + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + + for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)(ticketEndTime.date().dayOfWeek())); + itr != rangeEnd; + ++itr) { + ATBWeekDay const &wd = itr->second; + bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(start_parking_time, + ticketEndTime, + paymentOptionIndex); + if (parkTimeLimitViolated) { + //QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit(); + //ticketEndTime.setTime(tlimit); + + calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__) + .arg(ticketEndTime.time().toString(Qt::ISODate))); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + } + + if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) { + ticketEndTime = ticketEndTime.addDays(-1); + ticketEndTime.setTime(QTime(23, 59, 0)); + } + + // DEBUG + qCritical() << __func__ << ":" << __LINE__ << " endTime:" << endTime; + qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, + QDateTime const &start_parking_time, + QDateTime &ticketEndTime, + PermitType /* PermitType */) +{ + CalcState calcState; + if (start_parking_time.isValid()) { + + ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff, + start_parking_time, + tariff->getPaymentOptions().pop_payment_method_id, + false); // carry over + + // DEBUG + qCritical() << "compute_duration_for_daily_ticket(): "; + qCritical() << " ticketEndTime: " << ticketEndTime; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(ticketEndTime.toString(Qt::ISODate))); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &startDatetime, + QDateTime &endDatetime, + PERMIT_TYPE permitType, + struct price_t *price) {// return value + CalcState calcState; + + + if (startDatetime.isValid()) { + if (std::optional p = + Calculator::GetInstance().GetDailyTicketPrice(tariff, + startDatetime, + endDatetime, + permitType)) { + *price = p.value(); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + return calcState.set(CalcState::State::SUCCESS); +} + diff --git a/library/src/calculate_price.cpp.stashed b/library/src/calculate_price.cpp.stashed new file mode 100644 index 0000000..1a2631f --- /dev/null +++ b/library/src/calculate_price.cpp.stashed @@ -0,0 +1,762 @@ +#include "calculate_price.h" +#include "configuration.h" +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" + +#include +#include +#include +#include +#include + +QString const CalcState::SUCCESS = "SUCCESS"; +QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR"; +QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF"; +QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF"; +QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME"; +QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE"; +QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES"; +QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT"; +QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME"; +QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE"; +QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE"; +QString const CalcState::OVERPAID = "OVERPAID"; +QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; + +QList CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { + return Calculator::GetInstance().GetTimeSteps(cfg); +} + +int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int minTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + QList const tsteps = Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + Q_UNUSED(tsteps); + minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: + // for each new sell-procedure, recomute the timesteps. implicitly, set + // the minimal parking time. + Calculator::GetInstance().ResetTimeSteps(paymentOptionIndex); + Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex); + minTime = qRound(cfg->getPaymentOptions(paymentOptionIndex).pop_min_time); + } + + return minTime; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxTime = 0; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + default: ; + } + + return maxTime; + +} + +int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex, + QDateTime const &start) { + int minPrice = -1; + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + minPrice = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + } break; + case PERMIT_TYPE::DAY_TICKET: { + minPrice = compute_product_price(cfg, permitType, start); + } break; + default: ; + } + + return minPrice; +} + +int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, + PERMIT_TYPE permitType, + QDateTime const &start, + QDateTime *productStart, + QDateTime *productEnd) { + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_TEEN: + // [[fallthrough]]; + case PERMIT_TYPE::FOOD_STAMP: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + if (product.size() > 0) { + ATBTariffProduct const &p = product[0]; + return p.m_tariff_product_price; +#if 0 + // in case we do not have prepaid-option + QTime const ¤tTime = QDateTime::currentDateTime().time(); + + if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) { + return p.m_tariff_product_price; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "ERROR currentTime" + << currentTime.toString(Qt::ISODate) + << "INVALID (" + << p.m_tariff_product_start.toString(Qt::ISODate) + << p.m_tariff_product_end.toString(Qt::ISODate) << ")"; + } +#endif + } + } + } break; + case PERMIT_TYPE::INVALID: + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + QVector product = products.value(); + int product_price = 0; + + if (productStart && productEnd) { + *productStart = start; + *productEnd = start; + if (product.size() > 0) { + productStart->setTime(product[0].getTimeStart()); + productEnd->setTime(product[0].getTimeEnd()); + } + } + + for (QVector::size_type i=0; i= startTime && start.time() < endTime) { + product_price = p.getProductPrice(); + if (productStart && productEnd) { + productStart->setTime(startTime); + productEnd->setTime(endTime); + } + } + } + + return product_price; + } else { + // SZEGED + int const pop_daily_card_price = cfg->getPaymentOptions().pop_daily_card_price; + + qDebug() << QString("(%1:%2) no products defined in tariff-file").arg(__func__).arg(__LINE__); + qDebug() << QString("(%1:%2) pop_daily_card_price=%3").arg(__func__).arg(__LINE__).arg(pop_daily_card_price); + + // static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + // return Utilities::getDailyTicketCardPrice(cfg, paymentMethodId); + + return pop_daily_card_price; + } + } break; + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + std::optional> products = cfg->getTariffProductForProductId(permitType); + if (products) { + int product_price = 0; + QVector product = products.value(); + + if (product.size() > 0) { + if (productStart && productEnd) { + int pop_min_time = get_minimal_parkingtime(cfg); // in minutes + int pop_max_time = get_maximal_parkingtime(cfg); // in minutes + if (pop_max_time >= pop_min_time) { + *productStart = start; + *productEnd = start.addSecs(pop_max_time*60); + product_price = product[0].getProductPrice(); + } + } + } + + return product_price; + } + + } break; + default: + break; + } + + return 0; +} + +int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, + PERMIT_TYPE permitType, + int paymentOptionIndex) { + int maxPrice = -1; + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + switch(permitType) { + case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281) + if (paymentMethodId == PaymentMethod::Progressive || paymentMethodId == PaymentMethod::Steps) { + maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + } else { // PaymentMethod::Linear -> e.g. szeged + int const key = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const maxTime = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; // maxTime is given in minutes + std::optional> const &pv = cfg->getPaymentRateForKey(key); + if (pv) { + QVector const &paymentRate = pv.value(); + if (paymentRate.size() > 0) { + int const price = paymentRate.last().pra_price; // price is given per hour + maxPrice = qRound((maxTime * price) / 60.0f); + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: + break; + case PERMIT_TYPE::DAY_TICKET_TEEN: + break; + case PERMIT_TYPE::DAY_TICKET_CHILD: + break; + default: ; + } + + return maxPrice; +} + +int CALCULATE_LIBRARY_API get_zone_nr(int zone) +{ + if(zone > -1) return zone; + else + { + QFile zone("/etc/zone_nr"); + if (zone.exists()) { + QFileInfo finfo(zone); + if (finfo.size() <= 4) { // decimal 000\n + if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&zone); + return in.readLine(100).toInt(); + } + } + } + return -1; + } +} + +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { + *tariff = new Configuration(); + + CalcState calcState; +#if __linux__ + + int const zone = get_zone_nr(); + + // DEBUG + qCritical() << "init_tariff:"; + qCritical() << " ... zone = " << zone; + + if (zone <= 0) { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_PARSING_ZONE_NR); + } + + QString confFile(config_file); + if (!confFile.endsWith(QChar('/'))) { + confFile += "/"; + } + + char buffer[32]; + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone); + confFile += buffer; +#else // windows + QString confFile(config_file); +#endif + + // DEBUG + qCritical() << " ... confFile = " << confFile; + + QFile fname(confFile); + if (fname.exists() && + fname.open(QIODevice::ReadOnly | QIODevice::Text)) { + // DEBUG + qCritical() << " ... confFile is open"; + + QString json = fname.readAll(); + if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_PARSING_TARIFF); + } + } else { + delete *tariff; + *tariff = nullptr; + return calcState.set(CalcState::State::ERROR_LOADING_TARIFF); + } + + qCritical() << "init_tariff: Parsing tariff config (" << confFile << ")"; + + return calcState; +} + +void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { + if (tariff != nullptr) { + delete tariff; + } +} + +// +// UpDown 1 -> up; 0 -> down +int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown) +{ + qCritical() << " compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; + qCritical() << " compute_next_timestep() up/down (1=up, 0=down): " << UpDown; + + Configuration const *cfg = tariff; + + // compute payment method id (e.g. Linear=3, Steps=4) + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + switch (paymentMethodId) { + case PaymentMethod::Progressive: + qCritical() << " compute_next_timestep() paymentMethodId: Progressive"; + break; + case PaymentMethod::Degressive: + qCritical() << " compute_next_timestep() paymentMethodId: Degressive"; + break; + case PaymentMethod::Linear: + qCritical() << " compute_next_timestep() paymentMethodId: Linear"; + break; + case PaymentMethod::Steps: + qCritical() << " compute_next_timestep() paymentMethodId: Steps"; + break; + case PaymentMethod::Undefined: + qCritical() << " compute_next_timestep() paymentMethodId: Undefined"; + break; + } + + // use tariff with structure as for instance Schnau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + if ((paymentMethodId == PaymentMethod::Steps) || + // progressive tariff: e.g. Neuhauser, Kirchdorf (743) + (paymentMethodId == PaymentMethod::Progressive)) + { + const QList stepList = Calculator::GetInstance().GetTimeSteps(tariff); + qCritical() << " compute_next_timestep() timeSteps:" << stepList; + + int currentStepIndex = stepList.indexOf(currentTimeMinutes); + + if (currentStepIndex == -1) { + qCritical() << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + + if (UpDown == 1) { // UP + if (stepList[currentStepIndex] == stepList.last()) { + qCritical() << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + return stepList[currentStepIndex + 1]; + } + } + if (UpDown == 0) { // DOWN + if (stepList[currentStepIndex] == stepList.first()) { + qCritical() << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; + } + else { + return stepList[currentStepIndex - 1]; + } + } + } else + if (paymentMethodId == PaymentMethod::Linear) { + + // currentTimeMinutes is the number of minutes actually used. This + // value is an offset from the start time and cannot be used as a + // QDateTime. + + qCritical() << "compute_next_timestep() up/down (1=up, 0=down):" << UpDown; + + // get minimal and maximal parking times + int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + + qCritical() << " compute_next_timestep() maxParkingTime:" << maxParkingTime; + qCritical() << " compute_next_timestep() minParkingTime:" << minParkingTime; + + // use the first (i.e. main duration step contained in the tariff json-file) + int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId); + firstDurationStep = ((UpDown == 1) ? firstDurationStep : -firstDurationStep); + + qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep; + + int const nextTimeStep = currentTimeMinutes + firstDurationStep; + + if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) { + qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep; + return nextTimeStep; + } + } + + qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")"; + return currentTimeMinutes; +} + +// this is currently not used +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, // in minutes + time_t end_parking_time, // netto time in minutes + struct price_t *price) { + CalcState calcState; + double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_max_time; + + if (minMin < 0 || maxMin < 0 || maxMin < minMin) { + calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin)); + return calcState.set(CalcState::State::WRONG_PARAM_VALUES); + } + + int const duration = end_parking_time - start_parking_time; + if (duration < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time, start_parking_time)); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (duration > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (duration < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (duration == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + QDateTime end(start); + if (start.isValid()) { + double cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + start, + end, + duration, false, true); + double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + price->units = cost; + price->netto = cost; + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time, + int netto_parking_time, + QDateTime &end_parking_time, + struct price_t *price, + bool prepaid) +{ + CalcState calcState; + + int paymentOptionIndex = tariff->getPaymentOptionIndex(start_parking_time); + + double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time; + double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time; + + // DEBUG + qCritical() << "compute_price_for_parking_ticket() " << endl + << " paymentOptionIndex: " << paymentOptionIndex << endl + << " start_parking_time: " << start_parking_time << endl + << " netto_parking_time: " << netto_parking_time << endl + << " minMin: " << minMin << endl + << " maxMin: " << maxMin; + + + if (netto_parking_time < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time.toString(Qt::ISODate), + start_parking_time.toString(Qt::ISODate))); + return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME); + } + if (netto_parking_time > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (netto_parking_time < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } + if (netto_parking_time == 0) { + return calcState.set(CalcState::State::SUCCESS); + } + + double cost = -1; + if (start_parking_time.isValid()) { + if (tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id == PaymentMethod::Steps) { + // hier muesste man unterscheiden: uebertrag oder nicht? + calcState = Calculator::GetInstance().isParkingAllowed(tariff, start_parking_time, + netto_parking_time, paymentOptionIndex); + if (calcState.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + // qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + // << calcState.toString(); + return calcState; + } + cost = Calculator::GetInstance().GetCostFromDuration(tariff, start_parking_time, netto_parking_time, paymentOptionIndex); + end_parking_time = start_parking_time.addSecs(netto_parking_time*60); + + // qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + // << "end_parking_time" << end_parking_time.toString(Qt::ISODate); + + } else { + cost = Calculator::GetInstance().GetCostFromDuration( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + start_parking_time, // starting time + end_parking_time, // return value: end time + netto_parking_time, // minutes, netto + false, prepaid); + } + double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + + // DEBUG + qCritical() << " end_parking_time: " << end_parking_time; + qCritical() << " -> calculated cost (netto): " << cost; + + price->brutto = price->vat = price->vat_percentage = 0; + price->units = cost; + price->netto = cost; + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double price, + QString &duration) { + CalcState calcState; + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + + // DEBUG + qCritical() << "compute_duration_for_parking_ticket(): "; + qCritical() << " start (cs): " << cs; + qCritical() << " price: " << price; + + duration = Calculator::GetInstance().GetDurationFromCost(tariff, + tariff->getPaymentOptions().pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, false, true).c_str(); + QDateTime d = QDateTime::fromString(duration, Qt::ISODate); + if (!d.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime const &start_parking_time, + double price, + QDateTime &ticketEndTime) +{ + CalcState calcState; + if (start_parking_time.isValid()) { + QString cs = start_parking_time.toString(Qt::ISODate); + QString endTime = Calculator::GetInstance().GetDurationFromCost( + tariff, + tariff->getPaymentOptions().pop_payment_method_id, + cs.toLocal8Bit().constData(), + price, false, true).c_str(); + + if (endTime == CalcState::SUCCESS) { + calcState.setDesc(QString("SUCCESS")); + calcState.setStatus(endTime); + } else + if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_LOADING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ERROR_PARSING_TARIFF) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::NEGATIVE_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::INVALID_START_DATE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_PARAM_VALUES) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) { + calcState.setStatus(endTime); + return calcState; + } else + if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) { + calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE); + calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE); + return calcState; + } else + if (endTime == CalcState::OVERPAID) { + calcState.setDesc(CalcState::OVERPAID); + calcState.setStatus(CalcState::OVERPAID); + return calcState; + } else + if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) { + calcState.setStatus(endTime); + return calcState; + } else { + ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate); + + // DEBUG + //qCritical() << "compute_duration_for_parking_ticket(): "; + //qCritical() << " endTime: " << endTime; + //qCritical() << " ticketEndTime: " << ticketEndTime; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, QDateTime const &start_parking_time, QDateTime &ticketEndTime) +{ + CalcState calcState; + if (start_parking_time.isValid()) { + + ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff, + start_parking_time, + tariff->getPaymentOptions().pop_payment_method_id, + false); // carry over + + // DEBUG + qCritical() << "compute_duration_for_daily_ticket(): "; + qCritical() << " ticketEndTime: " << ticketEndTime; + + if (!ticketEndTime.isValid()) { + calcState.setDesc(QString("ticketEndTime=%1").arg(ticketEndTime.toString(Qt::ISODate))); + return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); + } + + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + + +CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket( + parking_tariff_t *tariff, + QDateTime const &startDatetime, + QDateTime &endDatetime, + PERMIT_TYPE permitType, + struct price_t *price) {// return value + CalcState calcState; + + + if (startDatetime.isValid()) { + if (std::optional p = + Calculator::GetInstance().GetDailyTicketPrice(tariff, + startDatetime, + endDatetime, + permitType)) { + *price = p.value(); + } + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + return calcState.set(CalcState::State::SUCCESS); +} + diff --git a/library/src/calculator_functions.cpp b/library/src/calculator_functions.cpp index 65b7a9c..5f8cef4 100644 --- a/library/src/calculator_functions.cpp +++ b/library/src/calculator_functions.cpp @@ -1,655 +1,3811 @@ -#include "calculator_functions.h" -#include "payment_option.h" -#include "utilities.h" -#include "tariff_log.h" - -#include -#include -#include - -double total_duration_min = 0.0f; -double total_cost = 0.0f; -bool overtime = false; - -#ifdef _WIN32 -inline struct tm* localtime_r(const time_t *clock, struct tm* result){ - if(!clock || !result) return NULL; - memcpy(result,localtime(clock),sizeof(*result)); - return result; -} -#endif - -QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over) -{ - if(!start_datetime.isValid()) { - return QDateTime(); - } - - double day_price = 0.0f; - int current_special_day_id = -1; - bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price); - - QDateTime inputDateTime = start_datetime; - QTime worktime_from; - QTime worktime_to; - - int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price; - if(daily_card_price <= 0) { - LOG_ERROR("Calculator::GetDailyTicketDuration(): Daily ticket price zero or less"); - return QDateTime(); - } - - if(is_special_day) - { - worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str(), Qt::ISODate); - worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str(),Qt::ISODate); - - if(inputDateTime.time() < worktime_from) inputDateTime.setTime(worktime_from); - if(carry_over) inputDateTime.setTime(worktime_from); - - if(inputDateTime.time() >= worktime_to) - { - // Go to next day if outside worktime - inputDateTime = inputDateTime.addSecs(86400); - return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); - } - - if(day_price <=0) - { - // Go to next day if special day price is 0 - inputDateTime = inputDateTime.addSecs(86400); - return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); - } - - int diff = abs(inputDateTime.time().secsTo(worktime_to)); - inputDateTime = inputDateTime.addSecs(diff); - - //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; - return inputDateTime; - } - else - { - // Get day of week - int weekdayId = 0; - weekdayId = Utilities::ZellersAlgorithm(inputDateTime.date().day(),inputDateTime.date().month(),inputDateTime.date().year()); - - // If no working day found, skip it (recursively call method again) - size_t found = 0; - found = cfg->WeekDaysWorktime.count(weekdayId); - - // When no workday found, go to next available day - if(found <=0) - { - inputDateTime = inputDateTime.addSecs(86400); - return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); - } - else - { - worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str(),Qt::ISODate); - worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str(),Qt::ISODate); - if(inputDateTime.time() < worktime_from) - inputDateTime.setTime(worktime_from); - - if(carry_over) - inputDateTime.setTime(worktime_from); - - if(inputDateTime.time() >= worktime_to) - { - // Go to next day if outside worktime - inputDateTime = inputDateTime.addSecs(86400); - return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); - } - - int diff = abs(inputDateTime.time().secsTo(worktime_to)); - inputDateTime = inputDateTime.addSecs(diff); - - //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; - return inputDateTime; - } - } - - return QDateTime(); -} -/// -std::string Calculator::GetDurationFromCost(Configuration* cfg, - uint8_t payment_option, - char const* start_datetime, // given in local time - double price, - bool nextDay, - bool prepaid) -{ - - // Get input date - QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate); - - // use tariff with structure as for instance Schnau, Koenigsee: - // without given YearPeriod, SpecialDays and SpecialDaysWorktime - if (cfg->YearPeriod.size() == 0 - && cfg->SpecialDays.size() == 0 - && cfg->SpecialDaysWorktime.size() == 0) - { - inputDate = inputDate.addSecs(GetDurationForPrice(cfg, price) * 60); - - return inputDate.toString(Qt::ISODate).toStdString(); - } - - - // Get day of week - int weekdayId = 0; - weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year()); - - //Get min and max time defined in JSON - double minMin = 0; - minMin = cfg->getPaymentOptions().pop_min_time; - - double maxMin = 0; - maxMin = cfg->getPaymentOptions().pop_max_time; - - double min_price = 0; - min_price = cfg->getPaymentOptions().pop_min_price; - - if(price < min_price) - { - return "PARKING NOT ALLOWED"; - } - - if (minMin < 0) minMin = 0; - if (maxMin < 0) maxMin = 0; - if (minMin >= maxMin) - { - LOG_ERROR("Error: min_min cannot be greater or equal to max_min"); - return "PARKING NOT ALLOWED"; - } - - if (maxMin <= minMin) - { - LOG_ERROR("Error: max_min cannot be lower or equal than min_min"); - return "PARKING NOT ALLOWED"; - } - - - // Get payment method - uint8_t p_method = PaymentMethod::Undefined; - p_method = payment_option; - LOG_DEBUG("Payment method id: ", (unsigned)p_method); - - // Check special day - double day_price = 0.0f; - int current_special_day_id = -1; - bool is_special_day = Utilities::CheckSpecialDay(cfg, inputDate.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price); - LOG_DEBUG("Special day: ", is_special_day); - - double money_left = price; - double price_per_unit = 0.0f; - - QTime worktime_from; - QTime worktime_to; - - if(is_special_day) - { - // Set special day price - price_per_unit = Utilities::CalculatePricePerUnit(day_price); - worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str()); - worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str()); - } - else - { - // Set new price for the normal day - int pop_id = cfg->PaymentOption.find(payment_option)->second.pop_id; - day_price = cfg->PaymentRate.find(pop_id)->second.pra_price; - - int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id; - double durationUnit = cfg->Duration.find(durationId)->second.pun_duration; - price_per_unit = Utilities::CalculatePricePerUnit(day_price,durationUnit); - - // If no working day found, skip it (recursively call method again) - size_t found = 0; - found = cfg->WeekDaysWorktime.count(weekdayId); - - // When no workday found, go to next available day - if(found <=0) - { - LOG_DEBUG("- No workday found, trying to find next available day"); - inputDate = inputDate.addDays(1); - return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left,true,prepaid); - } - worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str()); - worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str()); - } - - if (price_per_unit < 0) price_per_unit = 1.0f; - - // if((price/price_per_unit) < minMin) return "PARKING NOT ALLOWED"; - LOG_DEBUG("Calculated price per minute: ", price_per_unit); - - // If overtime flag is set - if (overtime || nextDay) - { - inputDate.setTime(worktime_from); - overtime = false; - } - - // Check prepaid - if (!prepaid) - { - if ((inputDate.time() < worktime_from) || (inputDate.time() > worktime_to)) - { - LOG_DEBUG("[STOP] * Ticket is not valid * "); - return "PARKING NOT ALLOWED"; - } - } - else - { - LOG_DEBUG("* PREPAID MODE ACTIVE *"); - if (inputDate.time() < worktime_from) - { - inputDate.setTime(worktime_from); - } - else if(inputDate.time() > worktime_to) - { - LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day"); - inputDate = inputDate.addDays(1); - return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left, true); - } - } - - while(true) - { - if((int)money_left <= 0) break; - - // Check year period - bool isYearPeriodActive = false; - - //// Parse input date - int dayCurrent = inputDate.date().day(); - int monthCurrent = inputDate.date().month(); - - // Current date time - int cdt = (monthCurrent * 100) + dayCurrent; - - multimap::iterator year_period_itr; - for (year_period_itr = cfg->YearPeriod.begin(); year_period_itr != cfg->YearPeriod.end(); ++year_period_itr) - { - int dStart = year_period_itr->second.pye_start_day; - int dEnd = year_period_itr->second.pye_end_day; - - int mStart = year_period_itr->second.pye_start_month; - int mEnd = year_period_itr->second.pye_end_month; - - int start = (mStart * 100) + dStart; - int end = (mEnd * 100) + dEnd; - - if (cdt >= start && cdt <= end) { - isYearPeriodActive = true; - break; - } - } - if (!isYearPeriodActive) - { - LOG_DEBUG("Year period is not valid"); - return "PARKING NOT ALLOWED"; - } - - if(total_duration_min > maxMin) - { - total_duration_min = maxMin; - break; - } - - // If reached end of worktime go to next day - if(inputDate.time() >= worktime_to) - { - int carry_over_status = 0; - carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over; - if (carry_over_status < 1) break; - - inputDate = inputDate.addDays(1); - overtime = true; - return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left ,true, prepaid); - } - - if(money_left > 1) - inputDate = inputDate.addSecs(60); - - if(price_per_unit > 0) total_duration_min +=1; - money_left -= price_per_unit; - - //qDebug() <<"Timestamp:" << inputDate << ", total duration min: " << total_duration_min << ", money left = " << money_left; - } - - // if ((total_duration_min < minMin) || (price / price_per_unit) < minMin) - // { - // LOG_DEBUG("Total duration is lower than min_min"); - // inputDate.time() = worktime_from; - // total_duration_min = 0; - // } - - double ret_val = 0; - // double calc_price = (int)total_duration_min - (int)price / price_per_unit; - - //if (calc_price > 0 && total_duration_min > 0) - //{ - // inputDate = inputDate.addSecs(-(int)ceil(calc_price) * 60); - //} - - if(price >= min_price && total_duration_min >= minMin) - qDebug() << "GetDurationFromCost(): Valid until: " << inputDate.toString(Qt::ISODate); - else - { - qDebug() << "Parking not allowed"; - total_duration_min = 0; - } - - ret_val = total_duration_min; - if(ret_val < 0) ret_val = 0; - qDebug() << "Duration: " << ret_val; - if (ret_val <= 0) return "PARKING NOT ALLOWED"; - - total_duration_min = 0; - return inputDate.toString(Qt::ISODate).toStdString(); -} - -/////////////////////////////////////// - -/// -/// - -uint32_t Calculator::GetCostFromDuration(Configuration *cfg, - QDateTime const &start, - quint64 timeStepInMinutes) const { - // for instance, a tariff as used in Schoenau, Koenigssee: only steps, no - // special days, nonstop. - if (cfg->YearPeriod.size() == 0 - && cfg->SpecialDays.size() == 0 - && cfg->SpecialDaysWorktime.size() == 0) { - QDateTime const end = start.addSecs(timeStepInMinutes*60); - return GetCostFromDuration(cfg, start, end); - } - return 0; -} - -uint32_t Calculator::GetCostFromDuration(Configuration * cfg, - QDateTime const &start, - QDateTime const &end) const { - if (cfg->YearPeriod.size() == 0 - && cfg->SpecialDays.size() == 0 - && cfg->SpecialDaysWorktime.size() == 0) { - int const timeStepInMinutes = start.secsTo(end) / 60; - return GetPriceForTimeStep(cfg, timeStepInMinutes); - } - return 0; -} - - - - -/////////////////////////////////////// - -/// -double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_option, const QDateTime start_datetime, QDateTime & end_datetime, double durationMin, bool nextDay, bool prepaid) -{ - if (cfg->YearPeriod.size() == 0 - && cfg->SpecialDays.size() == 0 - && cfg->SpecialDaysWorktime.size() == 0) - { - end_datetime = start_datetime.addSecs(durationMin*60); - return GetCostFromDuration(cfg, start_datetime, end_datetime); - } - - // Get input date - QDateTime inputDate = start_datetime; - - // Get day of week - int weekdayId = 0; - weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year()); - - //Get min and max time defined in JSON - double minMin = 0; - minMin = cfg->PaymentOption.find(payment_option)->second.pop_min_time; - - double maxMin = 0; - maxMin = cfg->PaymentOption.find(payment_option)->second.pop_max_time; - - if (minMin < 0) minMin = 0; - if (maxMin < 0) maxMin = 0; - if (minMin >= maxMin) - { - LOG_ERROR("Error: min_min cannot be greater or equal to max_min"); - return 0.0f; - } - if (maxMin <= minMin) - { - LOG_ERROR("Error: max_min cannot be lower or equal than min_min"); - return 0.0f; - } - - // Check overtime - if (!overtime) - { - if (durationMin > maxMin) - { - LOG_WARNING("Total duration is greater or equal to max_min"); - return maxMin; - } - - if (durationMin < minMin) - { - LOG_WARNING("Total duration is lower or equal to min_min"); - return 0.0f; - } - } - - // Get payment method - uint8_t p_method = PaymentMethod::Undefined; - p_method = payment_option; - LOG_DEBUG("Payment method id: ", (unsigned)p_method); - - // Check special day - double day_price = 0.0f; - int current_special_day_id = -1; - bool is_special_day = Utilities::CheckSpecialDay(cfg, inputDate.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price); - LOG_DEBUG("Special day: ", is_special_day); - - total_duration_min = durationMin; - LOG_DEBUG("Total min:", total_duration_min); - - double price_per_unit = 0.0f; - QTime worktime_from; - QTime worktime_to; - - if(is_special_day) - { - // Set special day price - price_per_unit = Utilities::CalculatePricePerUnit(day_price); - worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str()); - worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str()); - } - else - { - // Set new price for the normal day - - int pop_id = cfg->PaymentOption.find(payment_option)->second.pop_id; - day_price = cfg->PaymentRate.find(pop_id)->second.pra_price; - - int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id; - double durationUnit = cfg->Duration.find(durationId)->second.pun_duration; - price_per_unit = Utilities::CalculatePricePerUnit(day_price,durationUnit); - - // If no working day found, skip it (recursively call method again) - size_t found = 0; - found = cfg->WeekDaysWorktime.count(weekdayId); - - // When no workday found, go to next available day - if(found <=0) - { - LOG_DEBUG("- No workday found, trying to find next available day"); - inputDate = inputDate.addDays(1); - return floor(GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid)); - } - worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str()); - worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str()); - } - - if (price_per_unit < 0) price_per_unit = 1.0f; - LOG_DEBUG("Calculated price per minute: ", price_per_unit); - - if (price_per_unit == 0) - { - inputDate = inputDate.addDays(1); - inputDate.setTime(worktime_from); - return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid); - } - - // If overtime flag is set - if (overtime || nextDay) - { - inputDate.setTime(worktime_from); - overtime = false; - } - - // Check prepaid - if (!prepaid) - { - if ((inputDate.time() < worktime_from) || (inputDate.time() > worktime_to)) - { - LOG_DEBUG("[STOP] * Ticket is not valid * "); - return 0.0f; - } - } - else - { - LOG_DEBUG("* PREPAID MODE ACTIVE *"); - if (inputDate.time() < worktime_from) - { - inputDate.setTime(worktime_from); - } - else if(inputDate.time() > worktime_to) - { - LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day"); - inputDate = inputDate.addDays(1); - return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid); - } - } - - while(true) - { - if(total_duration_min <= 0) break; - - // Check year period - bool isYearPeriodActive = false; - - //// Parse input date - int dayCurrent = inputDate.date().day(); - int monthCurrent = inputDate.date().month(); - - // Current date time - int cdt = (monthCurrent * 100) + dayCurrent; - - multimap::iterator year_period_itr; - for (year_period_itr = cfg->YearPeriod.begin(); year_period_itr != cfg->YearPeriod.end(); ++year_period_itr) - { - int dStart = year_period_itr->second.pye_start_day; - int dEnd = year_period_itr->second.pye_end_day; - - int mStart = year_period_itr->second.pye_start_month; - int mEnd = year_period_itr->second.pye_end_month; - - int start = (mStart * 100) + dStart; - int end = (mEnd * 100) + dEnd; - - if (cdt >= start && cdt <= end) { - isYearPeriodActive = true; - break; - } - } - if (!isYearPeriodActive) - { - LOG_DEBUG("Year period is not valid"); - return 0.0f; - } - - int carry_over_status = 0; - carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over; - - // Go to next day if minutes not spent - if(inputDate.time() >= worktime_to) - { - if (carry_over_status < 1) break; - - LOG_DEBUG("Reached end of worktime, searching for the next working day"); - inputDate = inputDate.addDays(1); - overtime = true; - return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, total_duration_min); - } - - // Increment input date minutes for each monetary unit - inputDate = inputDate.addSecs(60); - total_duration_min -=1; - total_cost += price_per_unit; - - } - qDebug() << "GetCostFromDuration(): Valid until:" << inputDate.toString(Qt::ISODate).toStdString().c_str(); - - end_datetime = inputDate; - - double ret_val = total_cost; - total_cost = 0.0f; - return ceil(ret_val); -} - - - -QList Calculator::GetTimeSteps(Configuration *cfg) const { - QList timeSteps; - - int const pop_id = cfg->getPaymentOptions().pop_id; - - for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) - { - int const durationId = itr->second.pra_payment_unit_id; - int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; - timeSteps << durationUnit; - } - - return timeSteps; -} - -uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep) const { - - int const pop_id = cfg->getPaymentOptions().pop_id; - - for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) - { - int const payment_unit_id = itr->second.pra_payment_unit_id; - int const pun_id = cfg->Duration.find(payment_unit_id)->second.pun_id; - - Q_ASSERT(pun_id == payment_unit_id); - - int const pun_duration = cfg->Duration.find(payment_unit_id)->second.pun_duration; - if (timeStep == pun_duration) { - return (uint32_t)(itr->second.pra_price); - } - } - - return 0; -} - -uint32_t Calculator::GetDurationForPrice(Configuration *cfg, int price) const { - int const pop_id = cfg->getPaymentOptions().pop_id; - - - for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) - { - int const payment_unit_id = itr->second.pra_payment_unit_id; - int const pra_price = itr->second.pra_price; - - if (price == pra_price) { - int const durationId = itr->second.pra_payment_unit_id; - int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; - - return durationUnit; - } - } - - return 0; -} +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" +#include "tariff_log.h" +#include "tariff_time_range.h" +#include "ticket.h" +#include "tariff_global_defines.h" +#include "tariff_prepaid.h" +#include "tariff_out_of_service.h" +#include "tariff_service.h" + +#include +#include +#include +#include +#include +#include + +double total_duration_min = 0.0f; +double total_cost = 0.0f; +bool overtime = false; + +#ifdef _WIN32 +inline struct tm* localtime_r(const time_t *clock, struct tm* result){ + if(!clock || !result) return NULL; + memcpy(result,localtime(clock),sizeof(*result)); + return result; +} +#endif + +QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over) +{ + if(!start_datetime.isValid()) { + return QDateTime(); + } + + // qCritical() << __func__ << start_datetime.toString(Qt::ISODate); + + double day_price = 0.0f; + int current_special_day_id = -1; + bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price); + + QDateTime inputDateTime = start_datetime; + QTime worktime_from; + QTime worktime_to; + + int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price; + if(daily_card_price <= 0) { + qCritical() << "Calculator::GetDailyTicketDuration(): Daily ticket price zero or less"; + return QDateTime(); + } + + if(is_special_day) + { + worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str(), Qt::ISODate); + worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str(),Qt::ISODate); + + if(inputDateTime.time() < worktime_from) inputDateTime.setTime(worktime_from); + if(carry_over) inputDateTime.setTime(worktime_from); + + if(inputDateTime.time() >= worktime_to) + { + // Go to next day if outside worktime + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + if(day_price <=0) + { + // Go to next day if special day price is 0 + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + int diff = abs(inputDateTime.time().secsTo(worktime_to)); + inputDateTime = inputDateTime.addSecs(diff); + + //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; + return inputDateTime; + } + else + { + // Get day of week + int const weekdayId = inputDateTime.date().dayOfWeek(); + + // If no working day found, skip it (recursively call method again) + size_t found = cfg->WeekDaysWorktime.count(weekdayId); + + // When no workday found, go to next available day + if(found <=0) + { + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + else + { + worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str(),Qt::ISODate); + worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str(),Qt::ISODate); + if(inputDateTime.time() < worktime_from) + inputDateTime.setTime(worktime_from); + + if(carry_over) + inputDateTime.setTime(worktime_from); + + if(inputDateTime.time() >= worktime_to) + { + // Go to next day if outside worktime + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + int diff = abs(inputDateTime.time().secsTo(worktime_to)); + inputDateTime = inputDateTime.addSecs(diff); + + //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; + return inputDateTime; + } + } + + return QDateTime(); +} + +/// +/// \brief getPrepaid +/// \param cfg +/// \param dt +/// \return +/// + +std::optional getPrepaid(Configuration const *cfg, QDateTime const &dt) { + std::optional value = std::nullopt; + + int weekDay = dt.date().dayOfWeek(); + + // qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay; + + ATBTime inputTime(dt.time()); + QDate d; // check if a special date is configured in tariff-file for this day + auto const &prepaidRange = cfg->TariffPrepaids.equal_range(weekDay); + + for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) { + ATBTariffPrepaid const &prepaid = i->second; + if (!prepaid.m_date.isNull() && prepaid.m_date.isValid() && prepaid.m_date == dt.date()) { + d = dt.date(); + // qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate); + break; + } + } + + if (!d.isNull() && d.isValid()) { + for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) { + ATBTariffPrepaid const &prepaid = i->second; + if (!prepaid.m_date.isNull() && prepaid.m_date.isValid() && prepaid.m_date == d) { + TimeRange const &prepaidTimeRange = prepaid.m_range; + if (inputTime >= prepaidTimeRange.m_start && inputTime < prepaidTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(i->second); + break; + } + } + } + } else { + // qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate); + for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) { + ATBTariffPrepaid const &prepaid = i->second; + if (prepaid.m_date.isNull() || !prepaid.m_date.isValid()) { + qCritical() << __func__ << ":" << __LINE__ << "default"; + TimeRange const &prepaidTimeRange = prepaid.m_range; + if (inputTime >= prepaidTimeRange.m_start && inputTime < prepaidTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(i->second); + break; + } + } + } + } + + return value; +} + +/// +/// \brief getCarryOver +/// \param cfg +/// \param dt +/// \return +/// +std::optional getCarryOver(Configuration const *cfg, QDateTime const &dt) { + std::optional value = std::nullopt; + + + int weekDay = dt.date().dayOfWeek(); + + // qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay; + + ATBTime inputTime(dt.time()); + auto const &carryOverRange = cfg->TariffCarryOvers.equal_range(weekDay); + + QDate d; // check if a special date is configured in tariff-file for this day + for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) { + ATBTariffCarryOver const &carryOver = i->second; + if (!carryOver.m_date.isNull() && carryOver.m_date.isValid() && carryOver.m_date == dt.date()) { + d = dt.date(); + // qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate); + break; + } + } + + if (!d.isNull() && d.isValid()) { + for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) { + ATBTariffCarryOver const &carryOver = i->second; + + if (!carryOver.m_date.isNull() && carryOver.m_date.isValid() && carryOver.m_date == d) { + TimeRange const &carryOverTimeRange = carryOver.m_range; + if (inputTime >= carryOverTimeRange.m_start && inputTime < carryOverTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(carryOver); + break; + } + } + } + } else { + // qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate); + for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) { + ATBTariffCarryOver const &carryOver = i->second; + if (carryOver.m_date.isNull() || !carryOver.m_date.isValid()) { + // qCritical() << __func__ << ":" << __LINE__ << "default"; + TimeRange const &carryOverTimeRange = carryOver.m_range; + if (inputTime >= carryOverTimeRange.m_start && inputTime < carryOverTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(carryOver); + break; + } + } + } + } + + return value; +} + +/// +/// \brief getService +/// \param cfg +/// \param dt +/// \return +/// + +std::optional getService(Configuration const *cfg, QDateTime const &dt) { + std::optional value = std::nullopt; + + int weekDay = dt.date().dayOfWeek(); + + // qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay; + + ATBTime inputTime(dt.time()); + auto const &serviceRange = cfg->TariffServices.equal_range(weekDay); + + QDate d; // check if a special date is configured in tariff-file for this day + for (auto i = serviceRange.first; i != serviceRange.second; ++i) { + ATBTariffService const &service = i->second; + if (!service.m_date.isNull() && service.m_date.isValid() && service.m_date == dt.date()) { + d = dt.date(); + // qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate); + break; + } + } + + if (!d.isNull() && d.isValid()) { + for (auto i = serviceRange.first; i != serviceRange.second; ++i) { + ATBTariffService const &service = i->second; + + if (!service.m_date.isNull() && service.m_date.isValid() && service.m_date == d) { + TimeRange const &serviceTimeRange = service.m_range; + if (inputTime >= serviceTimeRange.m_start && inputTime < serviceTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(service); + break; + } + } + } + } else { + // qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate); + for (auto i = serviceRange.first; i != serviceRange.second; ++i) { + ATBTariffService const &service = i->second; + if (service.m_date.isNull() || !service.m_date.isValid()) { + // qCritical() << __func__ << ":" << __LINE__ << "default"; + TimeRange const &serviceTimeRange = service.m_range; + if (inputTime >= serviceTimeRange.m_start && inputTime < serviceTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(service); + break; + } + } + } + } + + return value; +} + +/// +/// \brief getOutOfService +/// \param cfg +/// \param dt +/// \return +/// +std::optional getOutOfService(Configuration const *cfg, QDateTime const &dt) { + std::optional value = std::nullopt; + + int weekDay = dt.date().dayOfWeek(); + // qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay; + + ATBTime inputTime(dt.time()); + QDate date; + + auto const &outOfServiceRange = cfg->TariffOutOfServices.equal_range(weekDay); + + QDate d; // check if a special date is configured in tariff-file for this day + for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) { + ATBTariffOutOfService const &outOfService = i->second; + if (!outOfService.m_date.isNull() && outOfService.m_date.isValid() && outOfService.m_date == dt.date()) { + d = dt.date(); + // qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate); + break; + } + } + + if (!d.isNull() && d.isValid()) { + for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) { + ATBTariffOutOfService const &outOfService = i->second; + + if (!outOfService.m_date.isNull() && outOfService.m_date.isValid() && outOfService.m_date == d) { + TimeRange const &outOfServiceTimeRange = outOfService.m_range; + if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(outOfService); + break; + } + } + } + } else { + // qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate); + for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) { + ATBTariffOutOfService const &outOfService = i->second; + if (outOfService.m_date.isNull() || !outOfService.m_date.isValid()) { + // qCritical() << __func__ << ":" << __LINE__ << "default"; + TimeRange const &outOfServiceTimeRange = outOfService.m_range; + if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) { + // qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_start.toString(Qt::ISODate); + // qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_end.toString(Qt::ISODate); + value = value.value_or(outOfService); + break; + } + } + } + } + + return value; +} + +std::pair +Calculator::ComputeDurationFromCost(Configuration *cfg, + QDateTime const &startDatetimePassed, // given in local time + int cost) { + + QDateTime inputDate = startDatetimePassed; + inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0)); + + // TODO: + int paymentOptionIndex = 0; + + bool overPaid = false; + bool successMaxPrice = false; + + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price; + int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay; + + int price = 0; + int durationId = 0; + int netto_parking_time_in_minutes = 0; + int brutto_parking_time_in_minutes = 0; + int free_parking_time_in_minutes = 0; + + QMap nettoParktimePrice; + QMap priceNettoParktime; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + durationId = itr->second.pra_payment_unit_id; + + int const pra_price = itr->second.pra_price; + if (pop_accumulate_prices) { + price += pra_price; + } else { + price = pra_price; + } + + //if ((double)price == cost) { + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + // found now the duration in minutes + // check if we are still inside the working-time-range + ATBDuration duration = search->second; + nettoParktimePrice.insert(duration.pun_duration, price); + priceNettoParktime.insert(price, duration.pun_duration); + } + + + //} + } + + // qCritical() << __func__ << ":" << __LINE__ << nettoParktimePrice; + // qCritical() << __func__ << ":" << __LINE__ << priceNettoParktime; + + if (cost == pop_max_price) { + qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + successMaxPrice = true; + } + + if (cost > pop_max_price) { + qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + if (pop_allow_overpay == false) { + return std::make_pair(CalcState(CalcState::State::OVERPAID), QDateTime()); + } + cost = pop_max_price; + overPaid = true; + qCritical() << DBG_HEADER << "OVERPAID, MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + // return CalcState::OVERPAID.toStdString(); + } + + if (cost < pop_min_price) { + qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost; + return std::make_pair(CalcState(CalcState::State::BELOW_MIN_PARKING_PRICE), QDateTime()); + } + + int weekDay = inputDate.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << "START weekDay" << weekDay << inputDate.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "START cost" << cost; + + QDateTime dt; + bool computationStarted = false; + price = 0; + netto_parking_time_in_minutes = 0; + brutto_parking_time_in_minutes = 0; + free_parking_time_in_minutes = 0; + + int const nettoParktimeForCost = priceNettoParktime[int(cost)]; + qCritical() << __func__ << ":" << __LINE__ << QString("cost=%1 nettoParkTimeForCost=%2"). + arg(cost).arg(nettoParktimeForCost); + + int cnt = 0; + while (++cnt < 10 && netto_parking_time_in_minutes < nettoParktimeForCost) { + // qCritical() << __func__ << ":" << __LINE__ << "cnt [" << cnt; + + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + weekDay = dt.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + + if (std::optional oos = getOutOfService(cfg, dt)) { + dt.setTime(QTime(oos.value().m_range.m_start.hour(), + oos.value().m_range.m_start.minute(), 0)); + if (overPaid) { + QList keys = nettoParktimePrice.keys(); + for (int k = 0; k < keys.size(); ++k) { + if (keys[k] < netto_parking_time_in_minutes) { + continue; + } + + int const maxPriceForTimeLimit = nettoParktimePrice[keys[k]]; + if (cost > maxPriceForTimeLimit) { + cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit; + + CalcState cs(CalcState::State::OVERPAID); + return std::make_pair(cs, dt); + } + if (cost == maxPriceForTimeLimit) { + cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit; + + CalcState cs(CalcState::State::SUCCESS_MAXPRICE); + return std::make_pair(cs, dt); + } + } + return std::make_pair(CalcState(CalcState::State::OVERPAID), dt); + } + qCritical() << __func__ << ":" << __LINE__ << "set time-limit reached"; + qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time_in_minutes; + + Calculator::GetInstance().setTimeLimitReached(true); + QList keys = nettoParktimePrice.keys(); + for (int k = 0; k < keys.size(); ++k) { + if (keys[k] < netto_parking_time_in_minutes) { + continue; + } + + int const maxPriceForTimeLimit = nettoParktimePrice[keys[k]]; + qCritical() << __func__ << ":" << __LINE__ << keys[k] << maxPriceForTimeLimit << cost; + // Calculator::GetInstance().setCostAtTimeLimit(nettoParktimePrice[keys[k]]); + if (cost > maxPriceForTimeLimit) { + cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit; + + CalcState cs(CalcState::State::OVERPAID); + return std::make_pair(cs, dt); + } + if (cost == maxPriceForTimeLimit) { + cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit; + + CalcState cs(CalcState::State::SUCCESS_MAXPRICE); + return std::make_pair(cs, dt); + } + + qCritical() << __func__ << ":" << __LINE__ << "DT" << dt.toString(Qt::ISODate); + return std::make_pair(CalcState(CalcState::State::SUCCESS), dt); + } + + qCritical() << __func__ << ":" << __LINE__ << "outside allowed parking time" << dt.toString(Qt::ISODate); + + return std::make_pair(CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + CalcState::OUTSIDE_ALLOWED_PARKING_TIME), dt); + } + + if (computationStarted == false) { + computationStarted = true; + if (std::optional pp = getPrepaid(cfg, dt)) { + TimeRange const &prepaidTimeRange = pp.value().m_range; + ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0); + free_parking_time_in_minutes += t.secsTo(prepaidTimeRange.m_end.toString(Qt::ISODate)) / 60; + } + } + + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + weekDay = dt.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + + if (std::optional co = getCarryOver(cfg, dt)) { + int minutes = co.value().computeMinutesUntilCarryOverEnd(dt); + if (minutes > 0) { + free_parking_time_in_minutes += minutes; + + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + weekDay = dt.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + } + } + + if (std::optional serv = getService(cfg, dt)) { + TimeRange const &serviceTimeRange = serv.value().m_range; + + if (nettoParktimeForCost > netto_parking_time_in_minutes) { + int rest_parking_time_in_minutes = nettoParktimeForCost - netto_parking_time_in_minutes; + ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0); + int timeToServiceEnd = t.secsTo(serviceTimeRange.m_end.toString(Qt::ISODate)) / 60; + + // TODO: wohl aehnlich wie carry-over zu behandlen + if (serviceTimeRange.m_duration > 0) { + if (timeToServiceEnd < rest_parking_time_in_minutes) { + netto_parking_time_in_minutes += timeToServiceEnd; + } else { + netto_parking_time_in_minutes += rest_parking_time_in_minutes; + } + } + } + } + + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + weekDay = dt.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + + // qCritical() << __func__ << ":" << __LINE__ << "cnt" << cnt << "]"; + } + + if (cnt >= 10) { + qCritical() << __func__ << ":" << __LINE__ << "BREAK"; + } + + // configure if last carry-over ranges shall be added to ticket-end-time + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + + cnt = 0; + QVector timeRanges; + while (std::optional co = getCarryOver(cfg, dt)) { + if (++cnt > 10) { + break; + } + TimeRange const &carryOverTimeRange = co.value().m_range; + if (!timeRanges.isEmpty()) { + if (timeRanges.last().m_end != carryOverTimeRange.m_start) { + break; + } + } + timeRanges.push_back(carryOverTimeRange); + + int minutes = co.value().computeMinutesUntilCarryOverEnd(dt); + if (minutes > 0) { + free_parking_time_in_minutes += co.value().computeMinutesUntilCarryOverEnd(dt); + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + + qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + } else break; + } + + brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes; + dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60); + weekDay = dt.date().dayOfWeek(); + + qCritical() << __func__ << ":" << __LINE__ << QString("ticket-end-time %1 (%2): brutto: %3 = netto: %4 + free: %5") + .arg(dt.toString(Qt::ISODate)) + .arg(weekDay) + .arg(brutto_parking_time_in_minutes) + .arg(netto_parking_time_in_minutes) + .arg(free_parking_time_in_minutes); + + if (successMaxPrice) { + qCritical() << __func__ << ":" << __LINE__ << "SUCC" << dt; + return std::make_pair(CalcState(CalcState::State::SUCCESS_MAXPRICE), dt); + } + if (overPaid) { + qCritical() << __func__ << ":" << __LINE__ << "OVER" << dt; + return std::make_pair(CalcState(CalcState::State::OVERPAID), dt); + } + + qCritical() << __func__ << ":" << __LINE__ << "DT" << dt.toString(Qt::ISODate); + return std::make_pair(CalcState(CalcState::State::SUCCESS), dt); +} + +std::pair> +Calculator::ComputeCostFromDuration(Configuration *cfg, QDateTime const &startDatetime, + QDateTime &endDatetime, int nettoParkingTime) { + + // TODO + int paymentOptionIndex = 0; + + std::optional cost{}; + + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + + int price = 0; + int durationId = 0; + int netto_parking_time_in_minutes = 0; + int brutto_parking_time_in_minutes = 0; + int free_parking_time_in_minutes = 0; + + QMap nettoParktimePrice; + QMap priceNettoParktime; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + durationId = itr->second.pra_payment_unit_id; + + int const pra_price = itr->second.pra_price; + if (pop_accumulate_prices) { + price += pra_price; + } else { + price = pra_price; + } + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + // found now the duration in minutes + // check if we are still inside the working-time-range + ATBDuration duration = search->second; + nettoParktimePrice.insert(duration.pun_duration, price); + priceNettoParktime.insert(price, duration.pun_duration); + } + } + + qCritical() << __func__ << ":" << __LINE__ << "START netto-parking-time" << nettoParkingTime; + CalcState returnState; + + QList keys = nettoParktimePrice.keys(); + int index = keys.indexOf(nettoParkingTime); + if (index != -1) { + int c = nettoParktimePrice[keys.at(index)]; + qCritical() << __func__ << ":" << __LINE__ << "cost for netto-parking-time" << c; + + std::pair r = ComputeDurationFromCost(cfg, startDatetime, c); + + qCritical() << __func__ << ":" << __LINE__ << "result" + << r.first.toString() << r.second.toString(Qt::ISODate); + + returnState = r.first; + endDatetime = r.second; + + + if (returnState.getStatus() == CalcState::State::SUCCESS || + returnState.getStatus() == CalcState::State::SUCCESS_MAXPRICE || + returnState.getStatus() == CalcState::State::OVERPAID) { + + qCritical() << __func__ << ":" << __LINE__ << "--- endDateTime" << endDatetime.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "------ r.second" << r.second.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << "status" << returnState.toString() << (int)returnState.getStatus(); + + if (!endDatetime.isNull() && endDatetime.isValid()) { + cost = c; + } + } + } + + if (cost) { + qCritical() << __func__ << ":" << __LINE__ << "--- return cost" << cost.value(); + return std::make_pair(returnState, cost); + } + + qCritical() << __func__ << ":" << __LINE__ << "--- return error for cost" << returnState.toString(); + return std::make_pair(returnState, cost); +} + +/// +std::pair +Calculator::GetDurationFromCost(Configuration* cfg, + uint8_t payment_option, + char const *startDatetimePassed, // given in local time + double cost, + PermitType /*permitType*/, + bool nextDay, + bool prepaid) +{ + Q_UNUSED(payment_option); + Q_UNUSED(nextDay); + + // Get input date + QDateTime inputDate = QDateTime::fromString(startDatetimePassed, Qt::ISODate); + inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0)); + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + bool overPaid = false; + bool successMaxPrice = false; // max-price and cost match + + int paymentOptionIndex = getPaymentOptionIndex(*cfg, inputDate); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(QDateTime::fromString(startDatetimePassed, Qt::ISODate)); + } + + qCritical() << DBG_HEADER << " option index:" << paymentOptionIndex; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << " start:" << inputDate.toString(Qt::ISODate); + qCritical() << DBG_HEADER << " option index:" << paymentOptionIndex; + qCritical() << DBG_HEADER << "paymentMethodId:" << static_cast(paymentMethodId); + qCritical() << DBG_HEADER << " prepaid:" << prepaid; + qCritical() << DBG_HEADER << " cost (price):" << cost; + } + + QList tsteps = Calculator::GetInstance().GetTimeSteps(cfg, paymentOptionIndex, inputDate); + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << " time steps:" << tsteps; + } else { + Q_UNUSED(tsteps); + } + + if (paymentMethodId == PaymentMethod::Degressive) { + + if (static_cast(cost) < cfg->getPaymentOptions(paymentOptionIndex).pop_min_price) { + // minimal price is set by GetTimeSteps() + qCritical() << DBG_HEADER << " provided price (cost):" << cost; + qCritical() << DBG_HEADER << "configured minimal price:" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + return std::make_pair(CalcState::BELOW_MIN_PARKING_PRICE.toStdString(), QDateTime()); + } + + if (prepaid == false) { + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations; + + // qCritical() << DBG_HEADER << " pop id:" << pop_id; + + int price = 0; + int new_price = 0; + int durationInMinutes = 0; + uint32_t duration_previous = 0; + // bool found = false; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const pra_price = itr->second.pra_price; + int const durationId = itr->second.pra_payment_unit_id; + if (pop_accumulate_prices) { + price += pra_price; + } else { + price = pra_price; + } + + // qCritical() << DBG_HEADER << " PRICE" << price << "COST" << cost; + // qCritical() << DBG_HEADER << " duration id" << durationId; + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + // found now the duration in minutes + // check if we are still inside the working-time-range + ATBDuration duration = search->second; + + if (pop_accumulate_prices) { + uint32_t const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + + new_price += pra_price; + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") old price" << price << ", new_price:" << new_price; + if (new_price <= cost) { + duration_previous = durationUnit; + if (pop_accumulate_durations) { + durationInMinutes += durationUnit; + } + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration_previous" << duration_previous; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration in minutes" << durationInMinutes; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") old price" << price << ", new_price:" << new_price; + } else { + //found = true; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration_previous" << duration_previous; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration in minutes" << durationInMinutes; + QDateTime d; + if (pop_accumulate_durations) { + d = inputDate.addSecs(durationInMinutes * 60); + } else { + d = inputDate.addSecs(duration_previous * 60); + } + + qCritical() << DBG_HEADER << " provided price (cost):" << cost; + qCritical() << DBG_HEADER << " computed time for price (minutes):" << duration_previous; + qCritical() << DBG_HEADER << " minimal parking time (minutes):" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + + if (duration_previous < cfg->getPaymentOptions(paymentOptionIndex).pop_min_time) { + return std::make_pair(CalcState::BELOW_MIN_PARKING_TIME.toStdString(), d); // minimal parking time is set by GetTimeSteps() + } + return std::make_pair(d.toString(Qt::ISODate).toStdString(), d); + } + } + + if ((double)price == cost) { + QDateTime d(inputDate.addSecs(durationInMinutes * 60)); + + QString const durationStr(d.toString(Qt::ISODate)); + + qCritical() << DBG_HEADER << " duration in minutes:" << durationInMinutes; + qCritical() << DBG_HEADER << " provided price (cost):" << cost; + qCritical() << DBG_HEADER << " duration for price:" << durationStr; + + return std::make_pair(durationStr.toStdString(), d); + } + } + } + + } else { + qCritical() << DBG_HEADER << " TODO"; + } + } else + if (paymentMethodId == PaymentMethod::Unified) { + std::pair r = + ComputeDurationFromCost(cfg, QDateTime::fromString(startDatetimePassed, Qt::ISODate), cost); + + CalcState cs = r.first; + + qCritical() << __func__ << ":" << __LINE__ << cs.toString(); + qCritical() << __func__ << ":" << __LINE__ << r.second.toString(Qt::ISODate); + + return std::make_pair(r.first.toString().toStdString(), r.second); + } else + if (paymentMethodId == PaymentMethod::Steps) { + if (tariffIs24_7(cfg)) { + // use tariff with structure as for instance Schoenau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + inputDate = inputDate.addSecs(GetDurationForPrice(cfg, cost) * 60); + return std::make_pair(inputDate.toString(Qt::ISODate).toStdString(), inputDate); + } else { + if (Utilities::IsYearPeriodActive(cfg, inputDate)) { + if (!prepaid) { + CalcState cs = isParkingAllowed(cfg, inputDate); + if (cs) { + inputDate.setTime(cs.getAllowedTimeRange().getTimeUntil()); + return std::make_pair(inputDate.toString(Qt::ISODate).toStdString(), inputDate); + } + } + + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price; + //int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time; + int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; + int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay; + int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + int price = 0; + + if (cost == pop_max_price) { + qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + successMaxPrice = true; + } + + if (cost > pop_max_price) { + qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + if (pop_allow_overpay == false) { + return std::make_pair(CalcState::OVERPAID.toStdString(), QDateTime()); + } + cost = pop_max_price; + overPaid = true; + qCritical() << DBG_HEADER << "OVERPAID, MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; + // return CalcState::OVERPAID.toStdString(); + } + + if (cost < pop_min_price) { + qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost; + return std::make_pair(CalcState::BELOW_MIN_PARKING_PRICE.toStdString(), QDateTime()); + } + + // int const pop_pre_paid = 1; + + if (prepaid) { + // no limits on pre-pay-option, i.e. pre-pay-ranges are exactly + // the complements of operational-ranges + + // find out if we are in a pre-pay-range. + // in this case, adapt inputDate accordingly. + + +#define DEBUG_GET_DURATION_FROM_COST 0 +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "PRE-PAID-OPTION: ADAPT-INPUT-DATE" << inputDate.toString(Qt::ISODate); +#endif + + QTime currentTime = inputDate.time(); + int pwd_period_day_in_week_id = inputDate.date().dayOfWeek(); + + bool useWeekDaysWorkTimeOfOtherDay = true; + + for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_day_in_week_id); iter != rEnd; ++iter) { + QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate); + QTime pwd_time_to = QTime::fromString(QString::fromStdString(iter->second.pwd_time_to), Qt::ISODate); + + //qCritical() << DBG_HEADER << "from" << pwd_time_from.toString(Qt::ISODate); + //qCritical() << DBG_HEADER << " to" << pwd_time_to.toString(Qt::ISODate); + + if (inputDate.time() < pwd_time_from) { + inputDate.setTime(pwd_time_from); + useWeekDaysWorkTimeOfOtherDay = false; + break; + } + if (currentTime <= pwd_time_to) { + useWeekDaysWorkTimeOfOtherDay = false; + break; + } + } + + if (useWeekDaysWorkTimeOfOtherDay) {// for the current day, we are above + // the latest worktime-range -> find the next valid range + + QTime pwd_time_from_next_valid_range(0, 0, 0); + int pwd_period_next_day_in_week_id = pwd_period_day_in_week_id; + for (int days = 1; days < 8; ++days) { + pwd_period_next_day_in_week_id += 1; + if (pwd_period_next_day_in_week_id > (int)Qt::Sunday) { + pwd_period_next_day_in_week_id = Qt::Monday; + } + + if (cfg->WeekDaysWorktime.count(pwd_period_next_day_in_week_id) > 0) { + for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_next_day_in_week_id); iter != rEnd; ++iter) { + QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate); + if (pwd_time_from_next_valid_range < pwd_time_from) { + pwd_time_from_next_valid_range = pwd_time_from; + break; + } + } + inputDate = inputDate.addDays(days); + inputDate.setTime(pwd_time_from_next_valid_range); + break; + } + } + } + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << "no prepaid"; + } + +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "(ADAPTED) INPUT-DATE" << inputDate.toString(Qt::ISODate); +#endif + //qCritical() << __func__ << __LINE__; + + // inputDate is now located in a valid operational-working-range + // find this working-time-range + int pwd_period_day_in_week_id = inputDate.date().dayOfWeek(); + //qCritical() << __func__ << __LINE__ << pwd_period_day_in_week_id; + //qCritical() << __func__ << __LINE__ << cfg->WeekDaysWorktime.count(pwd_period_day_in_week_id); + + if (cfg->WeekDaysWorktime.count(pwd_period_day_in_week_id) == 0) { + qCritical() << DBG_HEADER + << "ERROR" << inputDate.toString(Qt::ISODate) + << "NOT IN VALID WORKING TIME-RANGE"; + return std::make_pair("", QDateTime()); + } + + //qCritical() << __func__ << __LINE__; + + QTime current_working_time_from; + QTime current_working_time_to; + + for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_day_in_week_id); iter != rEnd; ++iter) { + QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate); + QTime pwd_time_to = QTime::fromString(QString::fromStdString(iter->second.pwd_time_to), Qt::ISODate); + //qCritical() << __func__ << pwd_time_from.toString(Qt::ISODate); + //qCritical() << __func__ << pwd_time_to.toString(Qt::ISODate); + //qCritical() << __func__ << inputDate.toString(Qt::ISODate); + if (pwd_time_from <= inputDate.time() && inputDate.time() <= pwd_time_to) { + current_working_time_from = pwd_time_from; + current_working_time_to = pwd_time_to; + } + } + + if (current_working_time_from.isNull() || current_working_time_to.isNull()) { + // can never happen + qCritical() << DBG_HEADER + << "ERROR" << inputDate.toString(Qt::ISODate) + << "NOT IN VALID WORKING TIME-RANGE"; + return std::make_pair("", QDateTime()); + } + +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "CURRENT WORKING-TIME-FROM" << current_working_time_from.toString(Qt::ISODate); + qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate); +#endif + + // int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + // int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations; + // int price = 0; + int new_price = 0; + int durationInSecs = 0; + uint32_t duration_previous = 0; + // bool found = false; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const pra_price = itr->second.pra_price; + int const durationId = itr->second.pra_payment_unit_id; + if (pop_accumulate_prices) { + price += pra_price; + } else { + price = pra_price; + } + + // qCritical() << DBG_HEADER << " PRICE" << price << "COST" << cost; + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + // found now the duration in minutes + // check if we are still inside the working-time-range + ATBDuration duration = search->second; + + if (pop_accumulate_prices) { + uint32_t const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + + new_price += pra_price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") XXXXXX price:" << price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") YYYYYY new_price:" << new_price; + if (new_price <= cost) { + duration_previous = durationUnit; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") ZZZZZZ duration_previous" << duration_previous; + } else { + //found = true; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") WWWWWW duration_previous" << duration_previous; + QString s = inputDate.toString(Qt::ISODate); + QDateTime d(QDateTime::fromString(s, Qt::ISODate)); + d = d.addSecs(duration_previous * 60); + //qCritical() << DBG_HEADER << "XXXXXXXXXXXXXXXXXXXXX" << d; + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), d); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), d); + } + return std::make_pair(d.toString(Qt::ISODate).toStdString(), d); + } + } else { + durationInSecs = cfg->Duration.find(durationId)->second.pun_duration * 60; + //qCritical() << DBG_HEADER << "DURATION-SECS" << durationInSecs; + //qCritical() << DBG_HEADER << "DURATION-MINS" << durationInSecs / 60; + } + + if ((double)price == cost) { + QDateTime current_working_date_time_to = inputDate; + current_working_date_time_to.setTime(current_working_time_to); + +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << " DURATION ID" << duration.pun_id; + qCritical() << DBG_HEADER << "DURATION IN MINUTES" << durationInSecs / 60; + qCritical() << DBG_HEADER << "DURATION IN SECONDS" << durationInSecs; + qCritical() << DBG_HEADER << "CURRENT-WORKING-DATE-TIME-TO" + << current_working_date_time_to.toString(Qt::ISODate); + qCritical() << DBG_HEADER << "NEW INPUT DATE" << inputDate.addSecs(durationInSecs).toString(Qt::ISODate); +#endif + + if (inputDate.addSecs(durationInSecs) > current_working_date_time_to) { + QTime next_working_time_from; + if (cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over != 0) { +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "CARRY-OVER SET"; +#endif + // check for next working-time-range on same day + int day_in_week_id = inputDate.date().dayOfWeek(); + for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(day_in_week_id); iter != rEnd; ++iter) { + QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate); + if (pwd_time_from > current_working_time_to) { + next_working_time_from = pwd_time_from; +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "NEXT-WORKING-TIME-FROM" + << next_working_time_from.toString(Qt::ISODate); +#endif + break; + } + } + // check for next working-time-range on following day(s) + if (next_working_time_from.isNull()) { + next_working_time_from = QTime(0, 0, 0); + for (int days = 1; days < 8; ++days) { + day_in_week_id += 1; + if (day_in_week_id > (int)Qt::Sunday) { + day_in_week_id = Qt::Monday; + } + if (cfg->WeekDaysWorktime.count(day_in_week_id) > 0) { + for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(day_in_week_id); iter != rEnd; ++iter) { + QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate); + if (next_working_time_from < pwd_time_from) { + next_working_time_from = pwd_time_from; + qCritical() << DBG_HEADER << "next working time from" << next_working_time_from.toString(Qt::ISODate); + break; + } + } + + //qCritical() << DBG_HEADER << "DAYS" << days; + //qCritical() << DBG_HEADER << "DURATION-SECS" << durationInSecs; + //qCritical() << DBG_HEADER << "DURATION-MINS" << durationInSecs / 60; + + QDateTime upper = inputDate.addDays(days); + upper.setTime(next_working_time_from); + + //qCritical() << DBG_HEADER << "UPPER" << upper.toString(Qt::ISODate); + + QDateTime lower = inputDate; + lower.setTime(current_working_time_to); + + //qCritical() << DBG_HEADER << "LOWER" << lower.toString(Qt::ISODate); + + // inputDate = inputDate.addSecs(lower.secsTo(upper)); + + //qCritical() << DBG_HEADER << "NEW INPUT" << inputDate.toString(Qt::ISODate); + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + if (pop_carry_over) { + int weekDay = inputDate.date().dayOfWeek(); + int const pop_carry_over_option_id = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + if (pop_carry_over_option_id != -1) { + int const carryOverDuration = cfg->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + inputDate = inputDate.addSecs(carryOverDuration * 60); + } + } + + inputDate = inputDate.addSecs(durationInSecs); +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate); +#endif + break; + } + } // for (int days = 1; days < 8; ++days) { + } else { // next working-time is on same day + QDateTime upper = inputDate; + upper.setTime(next_working_time_from); + + QDateTime lower = inputDate; + lower.setTime(current_working_time_to); + + inputDate = inputDate.addSecs(lower.secsTo(upper) + durationInSecs); +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate); +#endif + } + } + } else { + inputDate = inputDate.addSecs(duration.pun_duration * 60); + +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "INPUT-DATE" << inputDate.toString(Qt::ISODate); +#endif + + } + + QString const &s = inputDate.toString(Qt::ISODate); + +#if DEBUG_GET_DURATION_FROM_COST==1 + qCritical() << DBG_HEADER << "TICKET-END" << s; +#endif + + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), inputDate); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), inputDate); + } + return std::make_pair(s.toStdString(), inputDate); + } // if ((double)price == cost) { + else { + //qCritical() << DBG_HEADER; + } + } else { + //qCritical() << __func__ << __LINE__; + } + } + + return std::make_pair("", QDateTime()); + } + } + } else + if (paymentMethodId == PaymentMethod::Progressive) { + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + static const bool carryOverNotSet = Utilities::isCarryOverNotSet(cfg, paymentMethodId); + static const uint minParkingPrice = Utilities::getMinimalParkingPrice(cfg, paymentMethodId); + static const uint maxParkingPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + + if (cost < minParkingPrice) { + qCritical() << QString("ERROR: COST < MIN_PARKING_PRICE (%1 < %2)").arg(cost).arg(minParkingPrice); + return std::make_pair(QDateTime().toString(Qt::ISODate).toStdString(), QDateTime()); + } + + if (cost > maxParkingPrice) { + qCritical() << QString("WARN: COST > MAX_PARKING_PRICE (%1 > %2)").arg(cost).arg(maxParkingPrice); + cost = maxParkingPrice; + } + + Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)"); + Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)"); + + QDateTime start_datetime = QDateTime::fromString(QString(startDatetimePassed), Qt::ISODate); + QDateTime start = start_datetime; + QDateTime end_datetime = QDateTime(); + + int weekdayId = -1; + int weekdayIdLast = -1; + int durationMinutes = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + int durationMinutesBrutto = 0; + +#ifdef _DEBUG_ +#undef _DEBUG_ +#endif + +//#define _DEBUG_ 1 +#define _DEBUG_ 0 + + QDateTime current = start; + + int days = 7; + while (--days > 0) { + weekdayId = current.date().dayOfWeek(); + weekdayIdLast = weekdayId; // TODO: some end condition in json-file + + while (cfg->WeekDaysWorktime.count(weekdayId) == 0) { + current = current.addDays(1); + weekdayId = current.date().dayOfWeek(); + if (weekdayId == weekdayIdLast) { + qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED"; + return std::make_pair(QDateTime().toString(Qt::ISODate).toStdString(), QDateTime()); + } + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + QTime to = QTime(0, 0, 0); + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr); + + if (to < t) { + to = t; + } + } + + if (current.time() >= to) { + if (carryOverNotSet) { + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } else { + QDateTime const dt = start; + start = start.addDays(1); + start.setTime(QTime(0, 0, 0)); + + durationMinutesBrutto += dt.secsTo(start) / 60; + current = start; + } + } else { + break; + } + } + + int durationMinutesNetto = 0; + uint price = 0; + + if (carryOverNotSet) { + int minsToCarryOver = 0; // from one work-time to the other on the same day + int minsUsed = 0; + QDateTime lastCurrent = QDateTime(); + + QVector weekDayWorkTimeRanges; + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + weekDayWorkTimeRanges.append(itr->second); // working with vector is easier + } + + int weekDayWorkTimeIndex = 0; + bool moveToNextTimeRange = false; + + // time ranges for Neuhauser-Kirchdorf (743): 30, 5, 5, ... 5 + auto timeRangeIt = cfg->TimeRange.cbegin(); + while (timeRangeIt != cfg->TimeRange.cend()) { // ; ++timeRangeIt) { + + if (weekDayWorkTimeIndex >= weekDayWorkTimeRanges.size()) { + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "weekDayWorkTimeRanges.size()" << weekDayWorkTimeRanges.size() + << "price" << price; +#endif + end_datetime = current; + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + + QTime const &from = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_from.c_str(), Qt::ISODate); + QTime const &to = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_to.c_str(), Qt::ISODate); + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "from" << from.toString(Qt::ISODate) + << "to" << to.toString(Qt::ISODate); +#endif + + Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES"); + + if (current.time() >= to) { + ++weekDayWorkTimeIndex; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "try to use next available work-time with" + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "price" << price; +#endif + // time range is not affected + continue; + } else + if (current.time() <= from) { + if (prepaid) { + lastCurrent = current; + current.setTime(from); // move current forward (range==1), + // as prepaid is set + uint const minutesMoved = lastCurrent.secsTo(current) / 60; + durationMinutesBrutto += minutesMoved; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "minutesMoved" << minutesMoved + << "durationMinutesBrutto" << durationMinutesBrutto; +#endif + + if (weekDayWorkTimeIndex == 0) { + start_datetime = current; + } + } + } + + ATBTimeRange timeRange = timeRangeIt->second; + + timeRange.computeQTimes(current.time()); + + int duration = timeRange.time_range_to_in_minutes_from_start - + timeRange.time_range_from_in_minutes_from_start; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "price" << price; +#endif + + if (minsToCarryOver > 0) { // the price for this time range + // has been is paid already + Q_ASSERT_X(weekDayWorkTimeIndex > 0, __func__, "WRONG-WORK-TIME"); + + current = current.addSecs(minsToCarryOver*60); + + durationMinutes -= minsToCarryOver; + durationMinutesNetto += minsToCarryOver; + durationMinutesBrutto += minsToCarryOver; + + minsToCarryOver = 0; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "durationMinutes" << durationMinutes + << "durationMinutesNetto" << durationMinutesNetto + << "durationMinutesBrutto" << durationMinutesBrutto + << "price" << price; +#endif + if (price >= cost) { + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + } + + if (current.addSecs(duration * 60).time() <= to) { + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "current.addSecs(" << duration * 60 << ")" << current.addSecs(duration*60).time().toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes; +#endif + + moveToNextTimeRange = false; + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + if (price >= maxParkingPrice) { + price = maxParkingPrice; + } + + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + + current = current.addSecs(duration * 60); + + if (price >= cost) { + end_datetime = current; +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + + // price has been updated; use next time range + moveToNextTimeRange = true; + break; + } + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "price" << price + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes + << "durationMinutesNetto" << durationMinutesNetto + << "durationMinutesBrutto" << durationMinutesBrutto; +#endif + + if (price >= cost) { + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + + if (moveToNextTimeRange) { + if (++timeRangeIt != cfg->TimeRange.cend()) { + continue; + } + } + + // havin a new time range means that we always have a new + // work-time-range + // ++timeRangeIt; + + } else { // current.addSecs(duration * 60).time() > to + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "current.addSecs(" << duration * 60 << ")" << current.addSecs(duration*60).time().toString(Qt::ISODate) + << "duration" << duration + << ", to:" << to.toString(Qt::ISODate); +#endif + + lastCurrent = current; + current.setTime(to); + minsUsed = lastCurrent.secsTo(current) / 60; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes; +#endif + + // mod duration: possibly discard some minutes in + // the next time-range + if (duration >= minsUsed) { + minsToCarryOver = duration - minsUsed; + } + + durationMinutes -= minsUsed; + durationMinutesNetto += minsUsed; + durationMinutesBrutto += minsUsed; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes + << "price" << price; +#endif + + moveToNextTimeRange = false; + + if (minsUsed > 0) { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + if (price >= maxParkingPrice) { + price = maxParkingPrice; + } + + if (price >= cost) { + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + + // return end_datetime.toString(Qt::ISODate).toStdString(); + } + + // price has been updated; use next time range + moveToNextTimeRange = true; + break; + } + } + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "minsUsed" << minsUsed + << "durationMinutes" << durationMinutes + << "moveToNextTimeRange" << moveToNextTimeRange + << "price" << price; +#endif + + if (moveToNextTimeRange) { + if (++timeRangeIt != cfg->TimeRange.cend()) { + continue; + } + + // no valid time range left + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + if (successMaxPrice) { + return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + } + + end_datetime = start.addSecs(durationMinutesBrutto * 60); + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "start" << start.toString(Qt::ISODate) + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "final price" << std::max(price, minParkingPrice); +#endif + + if (overPaid) { + return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime); + } + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } // while (timeRangeIt != cfg->TimeRange.cend()) { + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "INVALID END TIME"; +#endif + end_datetime = QDateTime(); + return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime); + } + + Ticket t = private_GetDurationFromCost(cfg, inputDate, cost, prepaid); + + // qCritical().noquote() << t; + + // TODO: im fehlerfall + return std::make_pair(t.getValidUntil().toString(Qt::ISODate).toStdString(), t.getValidUntil()); +} +#undef _DEBUG_ + +/////////////////////////////////////// + +/// +/// + +uint32_t Calculator::GetCostFromDuration(Configuration *cfg, + QDateTime const &start, + quint64 timeStepInMinutes, + int paymentOptionIndex) const { + // for instance, a tariff as used in Schoenau, Koenigssee: only steps, no + // special days, nonstop. + //qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps || + paymentMethodId == PaymentMethod::Degressive) { + QDateTime const end = start.addSecs(timeStepInMinutes*60); + return GetCostFromDuration(cfg, start, end, paymentOptionIndex); + } + return 0; +} + +uint32_t Calculator::GetCostFromDuration(Configuration * cfg, + QDateTime const &start, + QDateTime const &end, + int paymentOptionIndex) const { + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + //qCritical() << __func__ << __LINE__ << "paymentOptionIndex" << paymentOptionIndex; + + if (paymentMethodId == PaymentMethod::Steps || + paymentMethodId == PaymentMethod::Degressive) { + int const timeStepInMinutes = start.secsTo(end) / 60; + QList tlist = Calculator::GetInstance().GetTimeSteps(cfg, paymentOptionIndex, start); + qCritical() << DBG_HEADER << "timeStepList" << timeStepInMinutes << tlist; + qCritical() << DBG_HEADER << "timeStepInMinutes" << timeStepInMinutes << start.toString(Qt::ISODate); + + return GetPriceForTimeStep(cfg, timeStepInMinutes, paymentOptionIndex); + } + return 0; +} + +CalcState Calculator::isParkingAllowedForWeekDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { + + //qCritical() << DBG_HEADER << "start" << start.toString(Qt::ISODate) + // << "paymentOptionIndex" << paymentOptionIndex; + + // TODO: wieder entfernen + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", QTime(), QTime()); + + QString errorStr = "UNKNOWN ERROR"; + + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + uint64_t const businessHours = cfg->getPaymentOptions(paymentOptionIndex).pop_business_hours; + + if (cfg->isDayIncluded(businessHours, start)) { + if (businessHours == BusinessHours::NO_RESTRICTION_24_7) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + QTime(0, 0, 0), QTime(23, 59, 59)); + } + + int const weekdayId = start.date().dayOfWeek(); + + // qCritical() << DBG_HEADER + // << "weekdayId" << weekdayId + // << "count" << cfg->WeekDaysWorktime.count(weekdayId); + + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + + qCritical() << DBG_HEADER + << "CHECK IF PARKING IS ALLOWED IN TIME-RANGE (" + << from.toString(Qt::ISODate) << "->" << until.toString(Qt::ISODate) << ") ..."; + + QTime const &startTime = start.time(); + + // qCritical() << DBG_HEADER << "START TIME" << startTime.toString(Qt::ISODate); + + if (startTime >= from && startTime <= until) { + QDateTime const end = start.addSecs(netto_parking_time*60); + + //qCritical() << DBG_HEADER << "END-DATE-TIME" << end.toString(Qt::ISODate); + + QTime const endTime = end.time(); + if (endTime <= until && start.date().dayOfWeek() == end.date().dayOfWeek()) { + qCritical() << DBG_HEADER; + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", from, until); + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(endTime.toString(Qt::ISODate)); + } + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)); + } + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + + // qCritical() << DBG_HEADER + // << "paymentOptionIndex" << paymentOptionIndex + // << "pop_carry_over" << pop_carry_over; + + if (pop_carry_over == 1) { + // qCritical() << DBG_HEADER + // << "NO. CHECK IF PARKING IS ALLOWED WITH CARRY-OVER ..."; + + int const pop_carry_over_start_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_start_time_range; + int const pop_carry_over_end_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_end_time_range; + + // qCritical() << DBG_HEADER + // << "pop_carry_over_start_time_range" << pop_carry_over_start_time_range + // << "pop_carry_over_end_time_range" << pop_carry_over_end_time_range; + + if ((int)cfg->TimeRange.count(pop_carry_over_start_time_range) <= 0 && + (int)cfg->TimeRange.count(pop_carry_over_end_time_range) <= 0) { + + qCritical() << DBG_HEADER << "PARKING_ALLOWED. startTime" << startTime.toString(Qt::ISODate); + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", startTime, QTime()); + + } else + // search entry in time-range-field of tariff-file + if (cfg->TimeRange.count(pop_carry_over_start_time_range) == 1 && + cfg->TimeRange.count(pop_carry_over_end_time_range) == 1) { + + ATBTimeRange s = cfg->TimeRange.find(pop_carry_over_start_time_range)->second; + ATBTimeRange e = cfg->TimeRange.find(pop_carry_over_end_time_range)->second; + + //qCritical() << DBG_HEADER << "startTime" << startTime.toString(Qt::ISODate); + //qCritical() << DBG_HEADER << "s: time range from" << s.getTimeFrom().toString(Qt::ISODate); + //qCritical() << DBG_HEADER << "s: time range until" << s.getTimeUntil().toString(Qt::ISODate); + + if (startTime >= s.getTimeFrom() && startTime <= s.getTimeUntil()) { + + QDateTime sd = start; + sd.setTime(s.getTimeUntil()); + + //qCritical() << DBG_HEADER << "jumpFrom" << sd.toString(Qt::ISODate); + + QDateTime ed = start.addDays(1); + ed.setTime(e.getTimeFrom()); + + //qCritical() << DBG_HEADER << "to" << ed.toString(Qt::ISODate); + + int const jumpSecs = sd.secsTo(ed); + + //qCritical() << DBG_HEADER << "jumpSecs" << jumpSecs; + + QDateTime const end = start.addSecs(netto_parking_time*60 + jumpSecs); + + //qCritical() << DBG_HEADER << "new end" << end.toString(Qt::ISODate); + + if (end.time() <= e.getTimeUntil()) { + + qCritical() << DBG_HEADER + << "PARKING IS ALLOWED WITH CARRY-OVER (" + << start.toString(Qt::ISODate) << "->" << ed.toString(Qt::ISODate) << ")"; + + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + startTime, end.time()); + } else { + errorStr = QString("endTime %1 outside [%2, %3))") + .arg(end.toString(Qt::ISODate)) + .arg(sd.toString(Qt::ISODate)) + .arg(ed.toString(Qt::ISODate)); + } + } else { + errorStr = QString("startTime %1 outside [%2, %3))") + .arg(startTime.toString(Qt::ISODate)) + .arg(s.getTimeFrom().toString(Qt::ISODate)) + .arg(s.getTimeUntil().toString(Qt::ISODate)); + } + } else { + errorStr = "no carry-over limits configured"; + } + } else { + errorStr = "no carry-over configured"; + } + } + } else { + errorStr = QString("no weekday configured for day-id %1").arg(weekdayId); + } + + } else { + errorStr = QString("start %1 not contained in business hours %2") + .arg(start.toString(Qt::ISODate)) + .arg(businessHours); + } + } + + qCritical() << DBG_HEADER << "errorStr" << errorStr; + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, errorStr, + QTime(), QTime()); +} + + +CalcState Calculator::isParkingAllowedForSpecialDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { + QString errorStr = "UNKNOWN ERROR"; + + qCritical() << DBG_HEADER << "start" << start.toString(Qt::ISODate) + << "paymentOptionIndex" << paymentOptionIndex; + + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + //uint64_t const businessHours = cfg->getPaymentOptions(paymentOptionIndex).pop_business_hours; + int const specialDayId = cfg->specialDayId(start); + if ((specialDayId > 0) && (cfg->SpecialDaysWorktime.count(specialDayId) > 0)) { + using SDIterator = Configuration::SpecialDaysWorktimeType::const_iterator; + std::pair p = cfg->SpecialDaysWorktime.equal_range(specialDayId); + + for (SDIterator it = p.first; it != p.second; ++it) { + QTime const &from = Utilities::SpecialDaysWorkTimeFrom(it); + QTime const &until = Utilities::SpecialDaysWorkTimeUntil(it); + + qCritical() << DBG_HEADER + << "CHECK IF PARKING IS ALLOWED IN TIME-RANGE (" + << from.toString(Qt::ISODate) << "->" << until.toString(Qt::ISODate) << ") ..."; + + QTime const &startTime = start.time(); + + if (startTime >= from && startTime <= until) { + QTime const endTime = start.addSecs(netto_parking_time*60).time(); + if (endTime <= until) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", from, until); + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(endTime.toString(Qt::ISODate)); + } + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)); + } + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + if (pop_carry_over == 1) { + qCritical() << DBG_HEADER << "NO. CHECK IF PARKING IS ALLOWED WITH CARRY-OVER ..."; + + int const pop_carry_over_start_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_start_time_range; + int const pop_carry_over_end_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_end_time_range; + + if (cfg->TimeRange.count(pop_carry_over_start_time_range) == 1 && + cfg->TimeRange.count(pop_carry_over_end_time_range) == 1) { + + ATBTimeRange s = cfg->TimeRange.find(pop_carry_over_start_time_range)->second; + ATBTimeRange e = cfg->TimeRange.find(pop_carry_over_end_time_range)->second; + + if (startTime >= s.getTimeFrom() && startTime <= s.getTimeUntil()) { + QDateTime sd = start; + sd.setTime(s.getTimeUntil()); + + QDateTime ed = start.addDays(1); + ed.setTime(e.getTimeFrom()); + + int const jumpSecs = sd.secsTo(ed); + QDateTime const end = start.addSecs(netto_parking_time*60 + jumpSecs); + if (end.time() <= e.getTimeUntil()) { + + ed.setTime(e.getTimeUntil()); // for printing + + qCritical() << DBG_HEADER + << "PARKING IS ALLOWED WITH CARRY-OVER (" + << start.toString(Qt::ISODate) << "->" << ed.toString(Qt::ISODate) << ")"; + + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + startTime, end.time()); + } else { + ed.setTime(e.getTimeUntil()); // for printing + + errorStr = QString("endTime %1 exceeds [%2, %3))") + .arg(end.toString(Qt::ISODate)) + .arg(sd.toString(Qt::ISODate)) + .arg(ed.toString(Qt::ISODate)); + } + } else { + errorStr = QString("startTime %1 exceeds [%2, %3))") + .arg(startTime.toString(Qt::ISODate)) + .arg(s.getTimeFrom().toString(Qt::ISODate)) + .arg(s.getTimeUntil().toString(Qt::ISODate)); + } + } else { + errorStr = "no carry-over limits configured"; + } + } else { + errorStr = "no carry-over configured"; + } + } + } + } + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, errorStr, + QTime(), QTime()); +} + + +CalcState Calculator::isParkingAllowed(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { + + qCritical() << DBG_HEADER << "CHECK IF PARKING IS ALLOWED AT" + << start.toString(Qt::ISODate) << "..."; + + CalcState cs; + + if ((cs = isParkingAllowedForWeekDay(cfg, start, netto_parking_time, paymentOptionIndex))) { + return cs; + } + + qCritical() << DBG_HEADER << QString(cs); + + if ((cs = isParkingAllowedForSpecialDay(cfg, start, netto_parking_time, paymentOptionIndex))) { + return cs; + } + + qCritical() << DBG_HEADER << QString(cs); + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, "UNKNOWN ERROR", + QTime(), QTime()); +} + +CalcState Calculator::isParkingAllowed(Configuration const *cfg, + QDateTime const &start) { + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if (paymentMethodId == PaymentMethod::Steps) { + int const weekdayId = start.date().dayOfWeek(); + BusinessHours businessHours = Utilities::getBusinessHours(cfg, paymentMethodId); + if (businessHours == BusinessHours::NoRestriction_24_7) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + QTime(0, 0, 0), QTime(23, 59, 59)); + } else + if (businessHours == BusinessHours::OnlyWeekDays) { + if (weekdayId != (int)Qt::Saturday && weekdayId != (int)Qt::Sunday) { // e.g. Neuhauser, Linsinger Maschinenbau (741) + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + QTime const &startTime = start.time(); + if (from > startTime) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 < %2").arg(from.toString(Qt::ISODate)) + .arg(startTime.toString(Qt::ISODate)), from, until); + } else + if (startTime >= until) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 >= %2").arg(startTime.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)), from, until); + } + return CalcState(CalcState::State::SUCCESS, + "PARKING ALLOWED", from, until); + } + } + } + } else + if (businessHours == BusinessHours::AllDaysWithRestrictedHours) { // e.g. for Neuhauser, NAZ (744) + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + QTime const &startTime = start.time(); + if (from > startTime) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 < %2").arg(from.toString(Qt::ISODate)) + .arg(startTime.toString(Qt::ISODate)), from, until); + } else + if (startTime >= until) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 >= %2").arg(startTime.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)), from, until); + } + return CalcState(CalcState::State::SUCCESS, + "PARKING ALLOWED", from, until); + } + } + } + } + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, "UNKNOWN ERROR", + QTime(), QTime()); +} + + +/////////////////////////////////////// + +/// +double Calculator::GetCostFromDuration(Configuration* cfg, + uint8_t payment_option, + QDateTime &start_datetime, + QDateTime &end_datetime, + int durationMinutes, + PermitType permitType, + bool nextDay, + bool prepaid) { + Q_UNUSED(payment_option); + Q_UNUSED(nextDay); + + int paymentOptionIndex = getPaymentOptionIndex(*cfg, start_datetime); + if (paymentOptionIndex == -1) { + paymentOptionIndex = cfg->getPaymentOptionIndex(permitType.get()); + } + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + if (tariffIs24_7(cfg)) { + end_datetime = start_datetime.addSecs(durationMinutes*60); + return GetCostFromDuration(cfg, start_datetime, end_datetime, paymentOptionIndex); + } else { + if (Utilities::IsYearPeriodActive(cfg, start_datetime)) { + if (!prepaid) { + CalcState cs = isParkingAllowed(cfg, start_datetime); + if (cs) { + end_datetime = start_datetime.addSecs(durationMinutes*60); + double cost = GetCostFromDuration(cfg, start_datetime, end_datetime, paymentOptionIndex); + end_datetime = start_datetime; + end_datetime.setTime(cs.getAllowedTimeRange().getTimeUntil()); + return cost; + } + } else { + // it might be that in such a case even prepaid ("vorkauf") + // is not allowed at any moment + } + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << "NOT YET IMPLEMENTED"; + end_datetime = QDateTime(); + return 0; + } + } + } else + if (paymentMethodId == PaymentMethod::Progressive) { + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + static const bool carryOverNotSet = Utilities::isCarryOverNotSet(cfg, paymentMethodId); + static const uint minParkingPrice = Utilities::getMinimalParkingPrice(cfg, paymentMethodId); + + Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)"); + Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)"); + + QDateTime start = start_datetime; + + int weekdayId = -1; + int weekdayIdLast = -1; + int durationMinutesBrutto = 0; + +#ifdef _DEBUG_ +#undef _DEBUG_ +#endif + +//#define _DEBUG_ 1 +#define _DEBUG_ 0 + + QDateTime current = start; + + int days = 7; + while (--days > 0) { + weekdayId = current.date().dayOfWeek(); + weekdayIdLast = weekdayId; // TODO: some end condition in json-file + + while (cfg->WeekDaysWorktime.count(weekdayId) == 0) { + current = current.addDays(1); + weekdayId = current.date().dayOfWeek(); + if (weekdayId == weekdayIdLast) { + qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED"; + return 0; + } + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + QTime to = QTime(0, 0, 0); + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr); + + if (to < t) { + to = t; + } + } + + if (current.time() >= to) { + if (carryOverNotSet) { + end_datetime = start; + return 0; + } else { + QDateTime const dt = start; + start = start.addDays(1); + start.setTime(QTime(0, 0, 0)); + + durationMinutesBrutto += dt.secsTo(start) / 60; + current = start; + } + } else { + break; + } + } + + int durationMinutesNetto = 0; + uint price = 0; + + if (carryOverNotSet) { + int minsToCarryOver = 0; // from one work-time to the other on the same day + int minsUsed = 0; + QDateTime lastCurrent = QDateTime(); + + QVector weekDayWorkTimeRanges; + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + weekDayWorkTimeRanges.append(itr->second); // working with vector is easier + } + + int weekDayWorkTimeIndex = 0; + bool moveToNextTimeRange = false; + + // time ranges for Neuhauser-Kirchdorf (743): 30, 5, 5, ... 5 + auto timeRangeIt = cfg->TimeRange.cbegin(); + while (timeRangeIt != cfg->TimeRange.cend()) { // ; ++timeRangeIt) { + + if (weekDayWorkTimeIndex >= weekDayWorkTimeRanges.size()) { + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "weekDayWorkTimeRanges.size()" << weekDayWorkTimeRanges.size(); +#endif + end_datetime = current; + return price; + } + + QTime const &from = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_from.c_str(), Qt::ISODate); + QTime const &to = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_to.c_str(), Qt::ISODate); + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "from" << from.toString(Qt::ISODate) + << "to" << to.toString(Qt::ISODate); +#endif + + Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES"); + + if (current.time() >= to) { + ++weekDayWorkTimeIndex; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "try to use next available work-time with" + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "price" << price; +#endif + // time range is not affected + continue; + } else + if (current.time() <= from) { + if (prepaid) { + lastCurrent = current; + current.setTime(from); // move current forward (range==1), + // as prepaid is set + uint const minutesMoved = lastCurrent.secsTo(current) / 60; + durationMinutesBrutto += minutesMoved; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "minutesMoved" << minutesMoved + << "durationMinutesBrutto" << durationMinutesBrutto; +#endif + + if (weekDayWorkTimeIndex == 0) { + start_datetime = current; + } + } + } + + ATBTimeRange timeRange = timeRangeIt->second; + + timeRange.computeQTimes(current.time()); + + int duration = timeRange.time_range_to_in_minutes_from_start - + timeRange.time_range_from_in_minutes_from_start; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "price" << price; +#endif + + if (minsToCarryOver > 0) { // the price for this time range + // has been is paid already + Q_ASSERT_X(weekDayWorkTimeIndex > 0, __func__, "WRONG-WORK-TIME"); + + current = current.addSecs(minsToCarryOver*60); + + durationMinutes -= minsToCarryOver; + durationMinutesNetto += minsToCarryOver; + durationMinutesBrutto += minsToCarryOver; + + minsToCarryOver = 0; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "durationMinutes" << durationMinutes + << "durationMinutesNetto" << durationMinutesNetto + << "durationMinutesBrutto" << durationMinutesBrutto; +#endif + if (durationMinutes <= 0) { + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + + return price; + } + } + + if (current.addSecs(duration * 60).time() <= to) { + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "current.addSecs(" << duration * 60 << ")" << current.addSecs(duration*60).time().toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes; +#endif + + moveToNextTimeRange = false; + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + + current = current.addSecs(duration * 60); + + // price has been updated; use next time range + moveToNextTimeRange = true; + break; + } + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "price" << price + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes + << "durationMinutesNetto" << durationMinutesNetto + << "durationMinutesBrutto" << durationMinutesBrutto; +#endif + + if (durationMinutes <= 0) { + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + + return price; + } + + if (moveToNextTimeRange) { + if (++timeRangeIt != cfg->TimeRange.cend()) { + continue; + } + } + + // havin a new time range means that we always have a new + // work-time-range + // ++timeRangeIt; + + } else { // current.addSecs(duration * 60).time() > to + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "current.addSecs(" << duration * 60 << ")" << current.addSecs(duration*60).time().toString(Qt::ISODate) + << "duration" << duration + << ", to:" << to.toString(Qt::ISODate); +#endif + + lastCurrent = current; + current.setTime(to); + minsUsed = lastCurrent.secsTo(current) / 60; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes; +#endif + + // mod duration: possibly discard some minutes in + // the next time-range + if (duration >= minsUsed) { + minsToCarryOver = duration - minsUsed; + } + + durationMinutes -= minsUsed; + durationMinutesNetto += minsUsed; + durationMinutesBrutto += minsUsed; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "lastCurrent" << lastCurrent.toString(Qt::ISODate) + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "to" << to.toString(Qt::ISODate) + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver + << "weekDayWorkTimeIndex" << weekDayWorkTimeIndex + << "durationMinutes" << durationMinutes + << "price" << price; +#endif + + moveToNextTimeRange = false; + + if (minsUsed > 0) { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + // price has been updated; use next time range + moveToNextTimeRange = true; + break; + } + } + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "minsUsed" << minsUsed + << "durationMinutes" << durationMinutes + << "moveToNextTimeRange" << moveToNextTimeRange + << "price" << price; +#endif + + if (moveToNextTimeRange) { + if (++timeRangeIt != cfg->TimeRange.cend()) { + continue; + } + + // no valid time range left + end_datetime = current; + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "price" << price; +#endif + + return price; + } + } + + end_datetime = start.addSecs(durationMinutesBrutto * 60); + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "start" << start.toString(Qt::ISODate) + << "end_datetime" << end_datetime.toString(Qt::ISODate) + << "final price" << std::max(price, minParkingPrice); +#endif + + return std::max(price, minParkingPrice); + } // while (timeRangeIt != cfg->TimeRange.cend()) { + } + +#if _DEBUG_==1 + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "INVALID END TIME"; +#endif + end_datetime = QDateTime(); + return 0; + } + + QDateTime start = start_datetime; + + Ticket t = private_GetCostFromDuration(cfg, start, + durationMinutes, + prepaid); + if (t) { + // qCritical().noquote() << t; + } + + end_datetime = t.getValidUntil(); + + return t.getPrice(); +} + +bool Calculator::checkDurationMinutes(int minParkingTime, + int maxParkingTime, + int durationMinutes) { + if (durationMinutes > maxParkingTime) { + qWarning() << QString("Total duration >= max_min (%1 >= %2)").arg(durationMinutes).arg(maxParkingTime); + return false; + } + if (durationMinutes < minParkingTime) { + qWarning() << QString("Total duration <= minMin (%1 <= %2)").arg(durationMinutes).arg(minParkingTime); + return false; + } + + return true; +} + +int Calculator::findWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size) { + for (size_t w = 0; w < size; ++w) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if ((dt.time() >= worktime_from) && (dt.time() < worktime_to)) { + return w; + } + } + return -1; +} + +int Calculator::findNextWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size) { + int nextWorkTimeRange = -1; + for (size_t w = 0; w < size; ++w) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + + if (dt.time() < worktime_from) { + nextWorkTimeRange = w; + break; + } + } + return nextWorkTimeRange; +} + +using namespace Utilities; + +Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg, + QDateTime const &start, + int durationMinutes, // Netto + bool prepaid) { + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId); + static const int minParkingTimeMinutes = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + static const int maxParkingTimeMinutes = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes); + static const int durationMinutesNetto = durationMinutes; + static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId); + static const double weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId); + static const double specialDaysDurationUnit = 60.0; + + if (!checkMinMaxMinutes) { + qCritical() << QString( + "ERROR: CONDITION minMin < maxMin (%1 < %2) IS NOT VALID") + .arg(minParkingTimeMinutes).arg(maxParkingTimeMinutes); + return Ticket(); + } + + if (!checkDurationMinutes(minParkingTimeMinutes, + maxParkingTimeMinutes, durationMinutes)) { + return Ticket(); + } + + uint32_t price = 0; + uint32_t costFromDuration = 0; + double durationUnit = 0.0; + int specialDayId = -1; + bool isSpecialDay = false; + Ticket ticket; + QDateTime end = start; + QDateTime current; + int totalTimeRanges = 0; + + for (current = start; durationMinutes > 0; current = current.addDays(1)) { + int const weekdayId = current.date().dayOfWeek(); + + specialDayId = -1; + + // find worktime ranges for the current day + int const timeRanges = std::max((int)cfg->WeekDaysWorktime.count(weekdayId), 1); + QScopedArrayPointer worktime(new TariffTimeRange[timeRanges]); + int ranges = 0; + + if((isSpecialDay = Utilities::CheckSpecialDay(cfg, current, &specialDayId, &price))) { + // Set special day price: + durationUnit = specialDaysDurationUnit; + worktime[ranges].setTimeRange(SpecialDaysWorkTimeFrom(cfg, specialDayId), + SpecialDaysWorkTimeUntil(cfg, specialDayId)); + ranges = 1; + } else { + // Set new price for the normal day: do not use a floating-point type + // for the price, rather compute with integers. Only at the very end of + // the computation the price is divided by durationUnit. + price = weekDaysPrice; + durationUnit = weekDaysDurationUnit; + + // If no working day found, skip it (epsecially Sundays!) + if (cfg->WeekDaysWorktime.count(weekdayId) <= 0) { + qDebug() << "No workday found, trying to find next available day"; + end = current; + current.setTime(QTime()); // start at midnight on the next day + continue; + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + worktime[ranges].setTimeRange(WeekDaysWorkTimeFrom(itr), + WeekDaysWorkTimeUntil(itr)); + ranges += 1; + } + } + + QTime const &lastWorktimeTo = worktime[ranges-1].getTimeUntil(); + + // qCritical() << "start" << start.toString(Qt::ISODate) + // << "current" << current.toString(Qt::ISODate) << lastWorktimeTo; + + // find worktime range to start with + int currentRange = 0; + if (!isSpecialDay) { + if (start != current) { // on next day + current.setTime(worktime[currentRange].getTimeFrom()); + } else { + // check if inputDate is located inside a valid worktime-range... + if ((currentRange = findWorkTimeRange(current, worktime, ranges)) == -1) { + if (!prepaid && carryOverNotSet) { // parking is not allowed + return Ticket(start, QDateTime(), durationMinutesNetto, 0, + 0, Ticket::s[INVALID_FROM_DATETIME]); + } + // find the next worktime-range (on the same day), and start from there + if ((currentRange = findNextWorkTimeRange(current, worktime, ranges)) == -1) { + end = current; + continue; + } + current.setTime(worktime[currentRange].getTimeFrom()); + } + } + } + + // qCritical() << "current" << current.toString(Qt::ISODate); + + for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + if (durationMinutes > 0) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if (totalTimeRanges) { + // durationMinutes are always meant as netto time and + // the time between worktime-ranges are free. + current.setTime(worktime_from); + } + + if (price == 0) { + end = current; + current.setTime(QTime()); + continue; + } + + if (current.time() == worktime_to) { + end = current; + current.setTime(QTime()); + continue; + } + + // Check prepaid + if (!prepaid) { + if ((current.time() < worktime_from) || (current.time() > worktime_to)) { + qDebug() << "[STOP] * Ticket is not valid * "; + return Ticket(); + } + } else { + //qDebug() << "* PREPAID MODE ACTIVE *"; + //qCritical() << "current" << current.toString(Qt::ISODate) << worktime_from << lastWorktimeTo; + if (current.time() < worktime_from) { + current.setTime(worktime_from); + end = current; + } else if(current.time() > lastWorktimeTo) { + //qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day"; + end = current; + current.setTime(QTime()); + continue; + } + } + + while(durationMinutes > 0) { + // Check for active year period + if (!IsYearPeriodActive(cfg, current)) { + return Ticket(); + } + if(current.time() >= lastWorktimeTo) { + // Go to next day if minutes not spent + if (carryOverNotSet) { + // no carry_over, so stop computation + break; + } + current.setTime(QTime()); + break; // stop while, and continue in outer loop + } else { + //qCritical() << "current" << current.toString(Qt::ISODate) << worktime_to; + if(current.time() < worktime_to) { + // Increment input date minutes for each monetary unit + current = current.addSecs(60); + end = current; + durationMinutes -= 1; + //costFromDuration += price_per_unit; + costFromDuration += price; + //qCritical() << "current" << current.toString(Qt::ISODate); + } else break; + } + } // while(durationMinutes > 0) { + } // if (durationMinutes > 0) { + } // for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + } // for (current = start; durationMinutes > 0; current = current.addDays(1)) { + + int durationMinutesBrutto = start.secsTo(end) / 60; + + return + Ticket(start, end, durationMinutesNetto, durationMinutesBrutto, + ceil(Utilities::CalculatePricePerUnit(costFromDuration, durationUnit)), + Ticket::s[VALID]); +} + + +Ticket Calculator::private_GetDurationFromCost(Configuration *cfg, + QDateTime const &start, + uint32_t cost, + bool prepaid) { + // Get input date + QDateTime current = start; + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId); + static const uint32_t minParkingTimeMinutes = std::max(Utilities::getMinimalParkingTime(cfg, paymentMethodId), 0); + static const uint32_t maxParkingTimeMinutes = std::max(Utilities::getMaximalParkingTime(cfg, paymentMethodId), 0); + static const uint32_t minParkingPrice = getMinimalParkingPrice(cfg, paymentMethodId); + // static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes); + static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId); + static const uint32_t weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId); + static const uint32_t specialDaysDurationUnit = 60; + + if(cost < minParkingPrice) { + uint64_t const durationMinutes = GetDurationForPrice(cfg, cost); + return Ticket(start, current, durationMinutes, durationMinutes, + cost, Ticket::s[INVALID_PRICE]); + } + if (minParkingTimeMinutes >= maxParkingTimeMinutes) { + // TODO + return Ticket(); + } + if (maxParkingTimeMinutes <= minParkingTimeMinutes) { + // TODO + return Ticket(); + } + + uint32_t durationMinutesNetto = 0; + double moneyLeft = cost; + double durationUnit = 1; + int specialDayId = -1; + bool isSpecialDay = false; + QDateTime end = start; + int totalTimeRanges = 0; + double price = 0; + + for (current = start; moneyLeft > 0 && moneyLeft >= price; current = current.addDays(1)) { + int const weekdayId = current.date().dayOfWeek(); + + specialDayId = -1; + + // find worktime ranges for the current day + int const timeRanges = std::max((int)cfg->WeekDaysWorktime.count(weekdayId), 1); + QScopedArrayPointer worktime(new TariffTimeRange[timeRanges]); + int ranges = 0; + + uint32_t p = 0; + if((isSpecialDay = Utilities::CheckSpecialDay(cfg, current, &specialDayId, &p))) { + // Set special day price: + durationUnit = specialDaysDurationUnit; + price = p / durationUnit; + price = std::round(price * 1000.0) / 1000.0; + worktime[ranges].setTimeRange(SpecialDaysWorkTimeFrom(cfg, specialDayId), + SpecialDaysWorkTimeUntil(cfg, specialDayId)); + ranges = 1; + } else { + // Set new price for the normal day: do not use a floating-point type + // for the price, rather compute with integers. Only at the very end of + // the computation the price is divided by durationUnit. + price = weekDaysPrice; + durationUnit = weekDaysDurationUnit; + price /= durationUnit; + price = std::round(price * 1000.0) / 1000.0; // round to 3 decimals + + // If no working day found, skip it (epsecially Sundays!) + if (cfg->WeekDaysWorktime.count(weekdayId) <= 0) { + // qDebug() << "No workday found, trying to find next available day"; + end = current; + current.setTime(QTime()); // start at midnight on the next day + continue; + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + worktime[ranges].setTimeRange(WeekDaysWorkTimeFrom(itr), + WeekDaysWorkTimeUntil(itr)); + ranges += 1; + } + } + + QTime const &lastWorktimeTo = worktime[ranges-1].getTimeUntil(); + + // find worktime range to start with + int currentRange = 0; + if (!isSpecialDay) { + if (start != current) { // on next day + current.setTime(worktime[currentRange].getTimeFrom()); + } else { + // check if inputDate is located inside a valid worktime-range... + if ((currentRange = findWorkTimeRange(current, worktime, ranges)) == -1) { + if (!prepaid && carryOverNotSet) { // parking is not allowed + return Ticket(start, QDateTime(), durationMinutesNetto, 0, + 0, Ticket::s[INVALID_FROM_DATETIME]); + } + // find the next worktime-range (on the same day), and start from there + if ((currentRange = findNextWorkTimeRange(current, worktime, ranges)) == -1) { + end = current; + continue; + } + current.setTime(worktime[currentRange].getTimeFrom()); + } + } + } + + for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + if (moneyLeft > 0) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if (totalTimeRanges) { + // durationMinutes are always meant as netto time and + // the time between worktime-ranges are free. + current.setTime(worktime_from); + } + + if (price == 0) { + // inputDate = inputDate.addDays(1); + // inputDate.setTime(worktime_from); + end = current; + current.setTime(QTime()); + continue; + } + + if (current.time() == worktime_to) { + end = current; + current.setTime(QTime()); + continue; + } + + // Check prepaid + if (!prepaid) { + if (current.time() < worktime_from) { + qDebug() << "[STOP] TICKET IS NOT VALID: " + << QString("%1 (current) < %2 (start)") + .arg(current.toString(Qt::ISODate) + .arg(worktime_from.toString(Qt::ISODate))); + return Ticket(); + } else + if (current.time() > worktime_to) { + qDebug() << "[STOP] TICKET IS NOT VALID: " + << QString("%1 (current) > %2 (end)") + .arg(current.toString(Qt::ISODate) + .arg(worktime_to.toString(Qt::ISODate))); + return Ticket(); + } + } else { + if (current.time() < worktime_from) { + qDebug() << "*** PREPAID *** Current time is before time range start, fast-forward to start" + << worktime_from.toString(Qt::ISODate); + current.setTime(worktime_from); + end = current; + } else if(current.time() > lastWorktimeTo) { + qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day"; + end = current; + current.setTime(QTime()); + continue; + } + } + + while(moneyLeft >= price) { + // Check for active year period + if (!IsYearPeriodActive(cfg, current)) { + return Ticket(); + } + // if(durationMinutesNetto >= maxParkingTimeMinutes) { + // might be useful for overpayment + // durationMinutesNetto = maxParkingTimeMinutes; + // int durationMinutesBrutto = start.secsTo(end) / 60; + // + // return + // Ticket(start, end, durationMinutesNetto, + // durationMinutesBrutto, cost, Ticket::s[INVALID_PRICE]); + // + // } + if(current.time() >= lastWorktimeTo) { + // Go to next day if minutes not spent + if (carryOverNotSet) { + // no carry_over, so stop computation + break; + } + current.setTime(QTime()); + break; // stop while, and continue in outer loop + } else { + if(current.time() < worktime_to) { + // Increment input date minutes for each monetary unit + durationMinutesNetto += 1; + moneyLeft -= price; + moneyLeft = std::round(moneyLeft * 1000.0) / 1000.0; + current = current.addSecs(60); + + //qCritical() << "moneyLeft" << moneyLeft + // << "durationMinutesNetto" << durationMinutesNetto + // << "current" << current.toString(Qt::ISODate); + + if(durationMinutesNetto <= maxParkingTimeMinutes) { + // stop updating of end-date if parking time is + // overshot + end = current; + } + } else break; + } + } // while(durationMinutes > 0) { + } // if (durationMinutes > 0) { + } // for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + } // for (current = start; durationMinutes > 0; current = current.addDays(1)) { + + int durationMinutesBrutto = start.secsTo(end) / 60; + + //qCritical() << "start" << start.toString(Qt::ISODate) << "end" + // << end.toString(Qt::ISODate) << durationMinutesBrutto; + + return + Ticket(start, end, durationMinutesNetto, durationMinutesBrutto, + cost, Ticket::s[VALID]); +} + +QList Calculator::GetPriceSteps(Configuration * /*cfg*/) const { + return QList(); +} + + +#define DEBUG_GET_TIME_STEPS (1) + +QList &Calculator::GetTimeSteps(Configuration *cfg, int paymentOptionIndex, + QDateTime const &s) const { + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") paymentOptionIndex:" << paymentOptionIndex; + } + + if (m_timeSteps.size() > paymentOptionIndex) { + + //if (!m_timeSteps[paymentOptionIndex].isEmpty()) { + // return m_timeSteps[paymentOptionIndex]; + //} + + // recompute time steps + m_timeSteps[paymentOptionIndex].clear(); + + } else { + while (m_timeSteps.size() <= paymentOptionIndex) { + m_timeSteps.push_back(QList()); + } + } + + QDateTime start = s; + start.setTime(QTime(s.time().hour(), s.time().minute(), 0)); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") start:" << start.toString(Qt::ISODate); + } + + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + int const pop_time_step_config = cfg->getPaymentOptions(paymentOptionIndex).pop_time_step_config; + int const pop_prepaid_option_id = cfg->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; + + static PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") start parking time:" << start.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") payment option id:" << pop_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") payment method id:" << static_cast(paymentMethodId); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") time step config:" << pop_time_step_config; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") prepaid option id:" << pop_prepaid_option_id; + } + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) { + //qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::DYNAMIC"; + + if (paymentMethodId == PaymentMethod::Progressive) { // e.g. neuhauser kirchdorf (743) + std::size_t const s = cfg->TimeRange.size(); + for (std::size_t id = 1; id <= s; ++id) { + int const step = Utilities::getTimeRangeStep(cfg, id, paymentMethodId); + m_timeSteps[paymentOptionIndex].append(step); + } + } else + if (paymentMethodId == PaymentMethod::Degressive) { // e.g. fuchs, valser alm (fane) (502) + // with growing time, the price goes down + // for instance: until 13.59: price 8, from 14:00: price 5, then for the next day: 8 + // for the following days: 8 euros + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") degressive:"; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") paymentOptionIndex:" << paymentOptionIndex; + m_timeSteps[paymentOptionIndex].clear(); + + // lookup pop_next_id in worktimes; + std::optional> const &w = cfg->getAllWeekDayWorkTimes(); + if (w.has_value()) { + QVector const &vec = w.value(); + + //if (pop_carry_over == false) { + for (int i = 1; i <= vec.size(); ++i) { + QTime const &from = QTime::fromString(QString::fromStdString(vec[i-1].pwd_time_from), Qt::ISODate); + QString const &toStr = QString::fromStdString(vec[i-1].pwd_time_to); + QTime const &to = QTime::fromString(toStr, Qt::ISODate); + + int weekDayId = vec[i-1].pwd_period_day_in_week_id; + if (start.date().dayOfWeek() == weekDayId) { + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << weekDayId; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") from" << from.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") to" << to.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") start" << start.toString(Qt::ISODate); + } + + if (start.time() >= from && start.time() < to) { + int runtimeInMinutes = (start.time().secsTo(to) / 60); + if (to.hour() == 23 && to.minute() == 59) { + runtimeInMinutes += 1; + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") runTimeInMinutes" << runtimeInMinutes; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") index" << paymentOptionIndex; + } + // m_timeSteps[paymentOptionIndex] << runtimeInMinutes; + + cfg->getPaymentOptions(paymentOptionIndex).pop_min_time = runtimeInMinutes; + + int pop_id = vec[i-1].pwd_pop_id; + // int pwd_id = vec[i-1].pwd_id; + // int pwd_next_id = vec[i-1].pwd_next_id; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pop_id" << pop_id; + } + + int price = -1; + int durationId = -1; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + durationId = itr->second.pra_payment_unit_id; + + price = itr->second.pra_price; + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + ATBDuration duration = search->second; + duration.pun_duration = runtimeInMinutes; + search->second = duration; + break; + } + } + + if (price >= 0 && durationId >= 0) { + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") durationId" << durationId; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") price" << price; + } + + pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + if (durationId == itr->second.pra_payment_unit_id) { + itr->second.pra_price = price; + cfg->getPaymentOptions(paymentOptionIndex).pop_min_price = price; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") park min price" << price; + break; + } + } + } + + break; + } // if (start.time() >= from && start.time() < to) { + } // if (start.date().dayOfWeek() == weekDayId) { + } // for (int i = 1; i <= vec.size(); ++i) { + + m_timeSteps[paymentOptionIndex].clear(); + int runtimeInMinutes = 0; + for (Configuration::TariffDurationType::const_iterator it = cfg->Duration.cbegin(); + it != cfg->Duration.cend(); + ++it) { + runtimeInMinutes += it->second.pun_duration; + m_timeSteps[paymentOptionIndex] << runtimeInMinutes; + } + + //} // if (pop_carry_over == false) { + } // if (w.has_value()) { + } else { + uint16_t timeStepCompensation = 0; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") payment option carry over:" << pop_carry_over; + } + + if (pop_carry_over) { + int const pop_carry_over_time_range_id = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_time_range_id; + int const pop_carry_over_option_id = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + int const pop_truncate_last_interpolation_step = cfg->getPaymentOptions(paymentOptionIndex).pop_truncate_last_interpolation_step; + QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from; + QTime const carryOverTimeRangeTo = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_to; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over time range id:" << pop_carry_over_time_range_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over option id:" << pop_carry_over_time_range_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over time from:" << carryOverTimeRangeFrom.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over time to:" << carryOverTimeRangeTo.toString(Qt::ISODate); + } + + int weekDay = start.date().dayOfWeek(); + QTime const carryOverStart = cfg->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + QTime const carryOverEnd = cfg->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_end; + int const carryOverDuration = cfg->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over start:" << carryOverStart.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over end:" << carryOverEnd.toString(Qt::ISODate); + } + + // TODO: reparieren + + if (carryOverTimeRangeFrom.secsTo(carryOverTimeRangeTo) <= 60) { // carry over time point, usually 00:00:00 + if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + ATBDuration duration = search->second; + if (durationId == 1) { + QDateTime carryOver = start; + carryOver = carryOver.addDays(1); + carryOver.setTime(QTime(0, 0, 0)); + + int const timeStep = std::ceil(start.secsTo(carryOver) / 60.0); + if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) { + qCritical() + << QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)") + .arg(timeStep).arg(duration.pun_duration_min) + .arg(timeStep).arg(duration.pun_duration_max); + break; + } + qCritical() << "(" << __func__ << ":" << __LINE__ << ") configured minimal parking time:" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + + // set dynamic minimal parking time + cfg->getPaymentOptions(paymentOptionIndex).pop_min_time = timeStep; + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") computed minimal parking time:" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + + duration.pun_duration = timeStep; + timeStepCompensation = duration.pun_duration_max - duration.pun_duration; + m_timeSteps[paymentOptionIndex] << duration.pun_duration; + } else { + duration.pun_duration = duration.pun_duration_max - timeStepCompensation; + m_timeSteps[paymentOptionIndex] << duration.pun_duration; + } + + cfg->Duration.erase(search); + cfg->Duration.insert(pair(duration.pun_id, duration)); + + } else { // if (search != cfg->Duration.end()) { + // TODO + } + } + } else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { + //if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over time range from:" << carryOverTimeRangeFrom.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carry over time range to:" << carryOverTimeRangeTo.toString(Qt::ISODate); + //} + + m_timeSteps[paymentOptionIndex].clear(); + + std::optional prepaidStart = cfg->prepaidStart(start, pop_prepaid_option_id); + // TODO: zusaetzlicher faktor falls vorkauf-option zieht + if (prepaidStart) { + start = prepaidStart.value(); + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") prepaid adapted start:" << start.toString(Qt::ISODate); + } + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } + + // TODO: check if needed + QDateTime interpolationEnd; + std::optional interpolationEndDate = cfg->getInterpolationEnd(start, paymentOptionIndex); + if (interpolationEndDate) { + interpolationEnd = interpolationEndDate.value(); + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") interpolation end:" << interpolationEnd.toString(Qt::ISODate); + } + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } + + // int const start_time = start.time().hour() * 60 + start.time().minute(); + QDateTime nextTimeStep = start; + int runtimeInMinutes = 0; + + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes (1):" << runtimeInMinutes; + + // int const pop_truncate_last_interpolation_step = cfg->getPaymentOptions(paymentOptionIndex).pop_truncate_last_interpolation_step; + + // TODO: auslagern + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + ATBDuration duration = search->second; + duration.pun_duration = duration.pun_duration_saved; + search->second = duration; + } + } + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes:" << runtimeInMinutes; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") durationId" << durationId; + // int const price = itr->second.pra_price; + + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + ATBDuration duration = search->second; + // ATBDuration &previous = search->second; + + if (duration.pun_interpolation_id == -1) { + + // should never happen -> misconfigured tariff-file + qCritical() << "(" << __func__ << ":" << __LINE__ << ") ERROR pun_interpolation not set!"; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") See for instance customer_505/6"; + + break; + } + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes:" << runtimeInMinutes; + + std::optional ipolCheck = cfg->getInterpolationType(duration.pun_interpolation_id); + if (ipolCheck) { + ATBInterpolation interpolation = ipolCheck.value(); + + if (duration.pun_interpolation_id == (int)ATBInterpolation::DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_PRICE) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") HIER NICHT"; + + interpolation.dynamic_start = start.time(); + interpolation.dynamic_start.setHMS(start.time().hour(), start.time().minute(), 0); + + // int const end_time = interpolation.dynamic_end.hour() * 60 + interpolation.dynamic_end.minute(); + + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_duration:" << duration.pun_duration; + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_interpolation:" << duration.pun_interpolation_id; + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") interpolation dynamic end:" << interpolationEnd.toString(Qt::ISODate); + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") interpolation dynamic end time:" << end_time; + + // int pop_min_time = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; + + runtimeInMinutes += duration.pun_duration; + nextTimeStep = start.addSecs(runtimeInMinutes * 60); + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes (1):" << runtimeInMinutes; + + if (nextTimeStep.time() > carryOverStart) { + int const backTime = carryOverStart.secsTo(nextTimeStep.time()) / 60; + runtimeInMinutes -= backTime; + nextTimeStep.setTime(carryOverStart); + nextTimeStep = nextTimeStep.addSecs((backTime + carryOverDuration) * 60); + runtimeInMinutes += (backTime + carryOverDuration); + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") next time step:" << nextTimeStep.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes:" << runtimeInMinutes; + } + + int rest = nextTimeStep.secsTo(interpolationEnd); + if (nextTimeStep <= interpolationEnd) { + if (rest > 0 && rest < duration.pun_duration) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") rest minutes:" << rest; + // last time step before switching to dayticket (see Schnals 505/506) + //if (duration.pun_duration > 0) { + // m_timeSteps[paymentOptionIndex] << duration.pun_duration; + //} + } else { + m_timeSteps[paymentOptionIndex] << runtimeInMinutes; + } + } + + duration.pun_duration = runtimeInMinutes; + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id:" << duration.pun_id; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_duration:" << duration.pun_duration; + + search->second = duration; + } else + if (duration.pun_interpolation_id == (int)ATBInterpolation::NO_INTERPOLATION) { + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id:" << duration.pun_id; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun duration:" << duration.pun_duration; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") next time step:" << nextTimeStep.toString(Qt::ISODate); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes (2):" << runtimeInMinutes; + + if (paymentOptionIndex == 1) { // testing TODO: muss in die payment options hinein + if (runtimeInMinutes == 0) { + if (start.time() < carryOverStart) { + runtimeInMinutes = start.time().secsTo(carryOverStart) / 60; + duration.pun_duration = runtimeInMinutes; + m_timeSteps[paymentOptionIndex] << duration.pun_duration; + search->second = duration; + cfg->getPaymentOptions(paymentOptionIndex).pop_min_time = runtimeInMinutes; + continue; + } + } + } + + if (runtimeInMinutes == 0) { + if (start.time() < carryOverStart) { + runtimeInMinutes = start.time().secsTo(carryOverStart) / 60; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") start:" << start.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") carryOverStart:" << carryOverStart.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes:" << runtimeInMinutes; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id:" << duration.pun_id; + duration.pun_duration = runtimeInMinutes; + m_timeSteps[paymentOptionIndex] << duration.pun_duration; + search->second = duration; + cfg->getPaymentOptions(paymentOptionIndex).pop_min_time = runtimeInMinutes; + } + continue; + } + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes:" << runtimeInMinutes; + + QDateTime s = start.addSecs(runtimeInMinutes * 60); + // int const minutes = s.time().secsTo(carryOverStart) / 60; + +#if 0 + if (minutes > 0) { + runtimeInMinutes += minutes; + previous.pun_duration += minutes; + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") previous:" << previous.pun_duration; + + if (!m_timeSteps[paymentOptionIndex].isEmpty()) { + m_timeSteps[paymentOptionIndex].last() += minutes; + } + } +#endif + + + nextTimeStep = start.addSecs(runtimeInMinutes * 60); + + runtimeInMinutes += duration.pun_duration; + nextTimeStep = start.addSecs(runtimeInMinutes * 60); + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") carryOverStart:" << carryOverStart.toString(Qt::ISODate); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") nextTimeStep.time():" << nextTimeStep.time().toString(Qt::ISODate); + + // TOOO: truncate-flag == false + if (nextTimeStep.time() > carryOverStart) { + int const backTime = carryOverStart.secsTo(nextTimeStep.time()); + runtimeInMinutes -= backTime; + nextTimeStep.setTime(carryOverStart); + nextTimeStep = nextTimeStep.addSecs((backTime + carryOverDuration) * 60); + runtimeInMinutes += (backTime + carryOverDuration); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runTimeInMinutes:" << runtimeInMinutes; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") nextTimeStep.time():" << nextTimeStep.time().toString(Qt::ISODate); + } else + if (nextTimeStep.time() < carryOverStart) { + int const forwardTime = nextTimeStep.time().secsTo(carryOverStart) / 60; + runtimeInMinutes += forwardTime; + nextTimeStep.setTime(carryOverStart); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") runTimeInMinutes:" << runtimeInMinutes; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") nextTimeStep.time():" << nextTimeStep.time().toString(Qt::ISODate); + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id:" << duration.pun_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun duration:" << duration.pun_duration; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") next time step:" << nextTimeStep.toString(Qt::ISODate); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") runtime in minutes (2):" << runtimeInMinutes; + } + + duration.pun_duration = runtimeInMinutes; + // duration.pun_duration = runtimeInMinutes - carryOverDuration; + m_timeSteps[paymentOptionIndex] << duration.pun_duration; + search->second = duration; + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") HIER NICHT"; + cfg->Duration.erase(search); + } + } + } + } + } + } else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) { + // TODO + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } + } else { // if (pop_carry_over) { + // TODO + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } + } + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") payment option time step config:" << "TimeStepConfig::STATIC"; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const durationId = itr->second.pra_payment_unit_id; + int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + int size = m_timeSteps.size(); + + while (size <= paymentOptionIndex) { + m_timeSteps.push_back(QList()); + size = m_timeSteps.size(); + } + + m_timeSteps[paymentOptionIndex] << durationUnit; + } + } + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") NEW timeSteps:" << m_timeSteps; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") NEW timeSteps:" << m_timeSteps; + + for (int i = 0; i < m_timeSteps[paymentOptionIndex].size(); ++i) { + QDateTime nextTime = s; + // nextTime.setTime(QTime(0, 0, 0)); + int const secs = m_timeSteps[paymentOptionIndex][i] * 60; + nextTime = nextTime.addSecs(secs); + qCritical() << "(" << __func__ << ":" << __LINE__ << ") step" + << i << secs << m_timeSteps[0][i] << "->" << nextTime.toString(Qt::ISODate); + + } + } + + return m_timeSteps[paymentOptionIndex]; +} + +#undef DEBUG_GET_TIME_STEPS + +uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep, int paymentOptionIndex) const { + + // test + // paymentOptionIndex = 1; + + int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations; + int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices; + + uint32_t price = 0; + int pun_duration = 0; + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") paymentOptionIndex" << paymentOptionIndex; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") timeStep" << timeStep; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pop_id" << pop_id; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const payment_unit_id = itr->second.pra_payment_unit_id; + int const pun_id = cfg->Duration.find(payment_unit_id)->second.pun_id; + + Q_ASSERT(pun_id == payment_unit_id); + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id" << pun_id; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_unit_id" << payment_unit_id; + + if (pop_accumulate_durations) { + pun_duration += cfg->Duration.find(payment_unit_id)->second.pun_duration; + } else { + pun_duration = cfg->Duration.find(payment_unit_id)->second.pun_duration; + } + + if (pop_accumulate_prices) { + price += itr->second.pra_price; + } else { + price = (uint32_t)(itr->second.pra_price); + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") price" << price; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_id" << pun_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_unit_id" << payment_unit_id; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun_duration" << pun_duration; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") timeStep" << timeStep; + } + + if (timeStep == pun_duration) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") return price" << price; + return price; + } + } + + return 0; +} + +uint32_t Calculator::GetDurationForPrice(Configuration *cfg, int price) const { + int const pop_id = cfg->getPaymentOptions().pop_id; + int const pop_accumulate_prices = cfg->getPaymentOptions().pop_accumulate_prices; + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") accumulate prices" << pop_accumulate_prices; + + int new_price = 0; + uint32_t duration = 0; + uint32_t duration_previous = 0; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const durationId = itr->second.pra_payment_unit_id; + int const pra_price = itr->second.pra_price; + + uint32_t const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + + if (pra_price == price) { + return durationUnit; + } + + if (pra_price < price) { + duration = durationUnit; + } + + if (pop_accumulate_prices) { + new_price += pra_price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pra_price:" << pra_price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") new_price:" << new_price; + if (new_price <= price) { + duration_previous = durationUnit; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration_previous" << duration_previous; + } else { + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration_previous" << duration_previous; + return duration_previous; + } + } + } + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") duration" << duration << "for price" << price; + return duration; +} + +std::optional +Calculator::GetDailyTicketPrice(Configuration* cfg, + QDateTime const &startDatetime, + QDateTime &endTime, + PERMIT_TYPE permitType) { + struct price_t price; + std::optional value; + + std::optional workTime = + cfg->getWeekDayWorkTime(startDatetime.time(), + (Qt::DayOfWeek)startDatetime.date().dayOfWeek()); + if (workTime) { + ATBWeekDaysWorktime const &wt = workTime.value(); + endTime = startDatetime; + endTime.setTime(QTime::fromString(wt.pwd_time_to.c_str(), Qt::ISODate)); + std::optional> dailyTickets = cfg->getDailyTicketsForAllKeys(); + if (dailyTickets) { + QVector const tickets = dailyTickets.value(); + switch (permitType) { + case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: { + // TODO + } break; + case PERMIT_TYPE::FOOD_STAMP: { + // TODO + } break; + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::ADULT); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::TEEN); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::CHILD); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } + // [[fallthrough]]; + case PERMIT_TYPE::SHORT_TERM_PARKING: { + } + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + } break; + case PERMIT_TYPE::DAY_TICKET_PKW: { + PermitType const permitType(PERMIT_TYPE::DAY_TICKET_PKW); + std::optional paymentOption = cfg->getPaymentOptionForKey(permitType.get()); + if (paymentOption) { + ATBPaymentOption option = paymentOption.value(); + int pop_id = option.pop_id; + int pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "( GetDailyTicketPrice():" << __LINE__ << ")"; + qCritical() << " PERMIT-TYPE:" << permitType.toString(); + qCritical() << " option id:" << pop_id; + qCritical() << "daily_ticket_card_price:" << pop_daily_card_price; + + price.netto = pop_daily_card_price; + value = value.value_or(price); + } + } break; + case PERMIT_TYPE::DAY_TICKET_BUS: { + } break; + case PERMIT_TYPE::DAY_TICKET_CAMPER: { + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_PKW: { + PermitType const permitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + std::optional paymentOption = cfg->getPaymentOptionForKey(permitType.get()); + if (paymentOption) { + ATBPaymentOption option = paymentOption.value(); + int pop_id = option.pop_id; + int pop_daily_card_price = option.pop_daily_card_price; + qCritical() << "( GetDailyTicketPrice():" << __LINE__ << ")"; + qCritical() << " PERMIT-TYPE:" << permitType.toString(); + qCritical() << " option id:" << pop_id; + qCritical() << "daily_ticket_card_price:" << pop_daily_card_price; + + price.netto = pop_daily_card_price; + value = value.value_or(price); + } + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_BUS: { + } break; + case PERMIT_TYPE::SHORT_TERM_PARKING_CAMPER: { + } break; + case PERMIT_TYPE::SZEGED_START: { + } break; + case PERMIT_TYPE::SZEGED_STOP: { + } break; + case PERMIT_TYPE::INVALID: { + } break; + } + } else { + // for projects which have not defined a daily ticket in their + // tariff-files (e.g. szeged) + price.netto = cfg->getPaymentOptions().pop_daily_card_price; + + qCritical() << "( GetDailyTicketPrice():" << __LINE__ << ")"; + qCritical() << " start:" << startDatetime.toString(Qt::ISODate); + qCritical() << " workTime from:" << QTime::fromString(QString(wt.pwd_time_from.c_str()), Qt::ISODate); + qCritical() << " workTime to:" << QTime::fromString(QString(wt.pwd_time_to.c_str()), Qt::ISODate); + qCritical() << "daily_ticket_card_price:" << price.netto; + + value = value.value_or(price); + } + } + + return value; +} diff --git a/library/src/calculator_functions.cpp.kirchdorf b/library/src/calculator_functions.cpp.kirchdorf new file mode 100644 index 0000000..8a0e2ed --- /dev/null +++ b/library/src/calculator_functions.cpp.kirchdorf @@ -0,0 +1,1469 @@ +#include "calculator_functions.h" +#include "payment_option.h" +#include "utilities.h" +#include "tariff_log.h" +#include "tariff_time_range.h" +#include "ticket.h" + +#include +#include +#include +#include +#include + +double total_duration_min = 0.0f; +double total_cost = 0.0f; +bool overtime = false; + +#ifdef _WIN32 +inline struct tm* localtime_r(const time_t *clock, struct tm* result){ + if(!clock || !result) return NULL; + memcpy(result,localtime(clock),sizeof(*result)); + return result; +} +#endif + +QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over) +{ + if(!start_datetime.isValid()) { + return QDateTime(); + } + + double day_price = 0.0f; + int current_special_day_id = -1; + bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price); + + QDateTime inputDateTime = start_datetime; + QTime worktime_from; + QTime worktime_to; + + int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price; + if(daily_card_price <= 0) { + qCritical() << "Calculator::GetDailyTicketDuration(): Daily ticket price zero or less"; + return QDateTime(); + } + + if(is_special_day) + { + worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str(), Qt::ISODate); + worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str(),Qt::ISODate); + + if(inputDateTime.time() < worktime_from) inputDateTime.setTime(worktime_from); + if(carry_over) inputDateTime.setTime(worktime_from); + + if(inputDateTime.time() >= worktime_to) + { + // Go to next day if outside worktime + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + if(day_price <=0) + { + // Go to next day if special day price is 0 + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + int diff = abs(inputDateTime.time().secsTo(worktime_to)); + inputDateTime = inputDateTime.addSecs(diff); + + //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; + return inputDateTime; + } + else + { + // Get day of week + int const weekdayId = inputDateTime.date().dayOfWeek(); + + // If no working day found, skip it (recursively call method again) + size_t found = cfg->WeekDaysWorktime.count(weekdayId); + + // When no workday found, go to next available day + if(found <=0) + { + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + else + { + worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str(),Qt::ISODate); + worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str(),Qt::ISODate); + if(inputDateTime.time() < worktime_from) + inputDateTime.setTime(worktime_from); + + if(carry_over) + inputDateTime.setTime(worktime_from); + + if(inputDateTime.time() >= worktime_to) + { + // Go to next day if outside worktime + inputDateTime = inputDateTime.addSecs(86400); + return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true); + } + + int diff = abs(inputDateTime.time().secsTo(worktime_to)); + inputDateTime = inputDateTime.addSecs(diff); + + //qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60; + return inputDateTime; + } + } + + return QDateTime(); +} +/// +std::string Calculator::GetDurationFromCost(Configuration* cfg, + uint8_t payment_option, + char const *startDatetimePassed, // given in local time + double cost, + bool nextDay, + bool prepaid) +{ + Q_UNUSED(payment_option); + Q_UNUSED(nextDay); + + // Get input date + QDateTime inputDate = QDateTime::fromString(startDatetimePassed,Qt::ISODate); + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + if (tariffIs24_7(cfg)) { + // use tariff with structure as for instance Schoenau, Koenigsee: + // without given YearPeriod, SpecialDays and SpecialDaysWorktime + inputDate = inputDate.addSecs(GetDurationForPrice(cfg, cost) * 60); + return inputDate.toString(Qt::ISODate).toStdString(); + } else { + if (Utilities::IsYearPeriodActive(cfg, inputDate)) { + if (!prepaid) { + CalcState cs = isParkingAllowed(cfg, inputDate); + if (cs) { + inputDate.setTime(cs.getAllowedTimeRange().getTimeUntil()); + return inputDate.toString(Qt::ISODate).toStdString(); + } + } + + qCritical() << __func__ << ":" << __LINE__ << "NOT YET IMPLEMENTED"; + return ""; + } + } + } else + if (paymentMethodId == PaymentMethod::Progressive) { + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + static const bool carryOverNotSet = Utilities::isCarryOverNotSet(cfg, paymentMethodId); + static const uint minParkingPrice = Utilities::getMinimalParkingPrice(cfg, paymentMethodId); + static const uint maxParkingPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId); + + if (cost < minParkingPrice) { + qCritical() << QString("ERROR: COST < MIN_PARKING_PRICE (%1 < %2)").arg(cost).arg(minParkingPrice); + return QDateTime().toString(Qt::ISODate).toStdString(); + } + + if (cost > maxParkingPrice) { + qCritical() << QString("WARN: COST > MAX_PARKING_PRICE (%1 > %2)").arg(cost).arg(maxParkingPrice); + cost = maxParkingPrice; + } + + Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)"); + Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)"); + + QDateTime start_datetime = QDateTime::fromString(QString(startDatetimePassed), Qt::ISODate); + QDateTime start = start_datetime; + QDateTime end_datetime = QDateTime(); + + int weekdayId = -1; + int weekdayIdLast = -1; + int durationMinutes = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + int durationMinutesBrutto = 0; + + QDateTime current = start; + + int days = 7; + while (--days > 0) { + weekdayId = current.date().dayOfWeek(); + weekdayIdLast = weekdayId; // TODO: some end condition in json-file + + while (cfg->WeekDaysWorktime.count(weekdayId) == 0) { + current = current.addDays(1); + weekdayId = current.date().dayOfWeek(); + if (weekdayId == weekdayIdLast) { + qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED"; + return QDateTime().toString(Qt::ISODate).toStdString(); + } + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + QTime to = QTime(0, 0, 0); + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr); + + if (to < t) { + to = t; + } + } + + if (current.time() >= to) { + if (carryOverNotSet) { + return end_datetime.toString(Qt::ISODate).toStdString(); + } else { + QDateTime const dt = start; + start = start.addDays(1); + start.setTime(QTime(0, 0, 0)); + + durationMinutesBrutto += dt.secsTo(start) / 60; + current = start; + } + } else { + break; + } + } + + int durationMinutesNetto = 0; + uint price = 0; + + if (carryOverNotSet) { + int range = 0; + int minsToCarryOver = 0; // from one work-time to the other on the same day + int minsUsed = 0; + QDateTime lastCurrent = QDateTime(); + + auto timeRangeIt = cfg->TimeRange.cbegin(); + for (; timeRangeIt != cfg->TimeRange.cend(); ++timeRangeIt) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + ++range; + + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &to = Utilities::WeekDaysWorkTimeUntil(itr); + + Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES"); + + if (current.time() >= to) { + continue; // try to use next available work-time + } else + if (current.time() <= from) { + if (prepaid) { + lastCurrent = current; + current.setTime(from); // move current forward (range==1), + // as prepaid is set + uint const minutesMoved = lastCurrent.secsTo(current) / 60; + durationMinutesBrutto += minutesMoved; + + if (range == 1) { + start_datetime = current; + } + } + } + + while (timeRangeIt != cfg->TimeRange.cend()) { + ATBTimeRange timeRange = timeRangeIt->second; + + timeRange.computeQTimes(current.time()); + + int duration = timeRange.time_range_to_in_minutes_from_start - + timeRange.time_range_from_in_minutes_from_start; + + if (minsUsed > 0) { + duration -= minsUsed; + minsUsed = 0; + } + + if (current.addSecs(duration * 60).time() <= to) { + if (minsToCarryOver > 0) { // the price for this time range + // has been is paid already + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + current = current.addSecs(duration*60); + minsToCarryOver = 0; + } else { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + if (price >= maxParkingPrice) { + price = maxParkingPrice; + } + + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + + current = current.addSecs(duration * 60); + + if (price >= cost) { + end_datetime = current; + return end_datetime.toString(Qt::ISODate).toStdString(); + } + + break; + } + } + } + + if (durationMinutes <= 0) { + end_datetime = current; + return end_datetime.toString(Qt::ISODate).toStdString(); + } + + ++timeRangeIt; + + } else { + + lastCurrent = current; + current.setTime(to); + minsUsed = lastCurrent.secsTo(current) / 60; + + // mod duration: possibly discard some minutes in + // the next time-range + if (durationMinutes >= minsUsed) { + minsToCarryOver = durationMinutes - minsUsed; + } + + durationMinutes -= minsUsed; + durationMinutesNetto += minsUsed; + durationMinutesBrutto += minsUsed; + + if (minsUsed > 0) { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + if (price >= maxParkingPrice) { + price = maxParkingPrice; + } + + if (price >= cost) { + end_datetime = current; + // return end_datetime.toString(Qt::ISODate).toStdString(); + } + break; + } + } + } + break; + } + } + } + + end_datetime = start.addSecs(durationMinutesBrutto * 60); + return end_datetime.toString(Qt::ISODate).toStdString(); + } + } + + end_datetime = QDateTime(); + return end_datetime.toString(Qt::ISODate).toStdString(); + } + + Ticket t = private_GetDurationFromCost(cfg, inputDate, cost, prepaid); + + // qCritical().noquote() << t; + + // TODO: im fehlerfall + return t.getValidUntil().toString(Qt::ISODate).toStdString(); +} + +/////////////////////////////////////// + +/// +/// + +uint32_t Calculator::GetCostFromDuration(Configuration *cfg, + QDateTime const &start, + quint64 timeStepInMinutes) const { + // for instance, a tariff as used in Schoenau, Koenigssee: only steps, no + // special days, nonstop. + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + QDateTime const end = start.addSecs(timeStepInMinutes*60); + return GetCostFromDuration(cfg, start, end); + } + return 0; +} + +uint32_t Calculator::GetCostFromDuration(Configuration * cfg, + QDateTime const &start, + QDateTime const &end) const { + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + int const timeStepInMinutes = start.secsTo(end) / 60; + return GetPriceForTimeStep(cfg, timeStepInMinutes); + } + return 0; +} + + +CalcState Calculator::isParkingAllowed(Configuration const *cfg, QDateTime const &start) { + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + + if (paymentMethodId == PaymentMethod::Steps) { + int const weekdayId = start.date().dayOfWeek(); + BusinessHours businessHours = Utilities::getBusinessHours(cfg, paymentMethodId); + if (businessHours == BusinessHours::OnlyWeekDays) { + if (weekdayId != (int)Qt::Saturday && weekdayId != (int)Qt::Sunday) { // e.g. Neuhauser, Linsinger Maschinenbau (741) + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + QTime const &startTime = start.time(); + if (from > startTime) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 < %2").arg(from.toString(Qt::ISODate)) + .arg(startTime.toString(Qt::ISODate)), from, until); + } else + if (startTime >= until) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 >= %2").arg(startTime.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)), from, until); + } + return CalcState(CalcState::State::SUCCESS, + "PARKING ALLOWED", from, until); + } + } + } + } else + if (businessHours == BusinessHours::AllDaysWithRestrictedHours) { // e.g. for Neuhauser, NAZ (744) + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + QTime const &startTime = start.time(); + if (from > startTime) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 < %2").arg(from.toString(Qt::ISODate)) + .arg(startTime.toString(Qt::ISODate)), from, until); + } else + if (startTime >= until) { + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, + QString("%1 >= %2").arg(startTime.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)), from, until); + } + return CalcState(CalcState::State::SUCCESS, + "PARKING ALLOWED", from, until); + } + } + } + } + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, "UNKNOWN ERROR", + QTime(), QTime()); +} + + +/////////////////////////////////////// + +/// +double Calculator::GetCostFromDuration(Configuration* cfg, + uint8_t payment_option, + QDateTime &start_datetime, + QDateTime &end_datetime, + int durationMinutes, + bool nextDay, + bool prepaid) { + Q_UNUSED(payment_option); + Q_UNUSED(nextDay); + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + if (tariffIs24_7(cfg)) { + end_datetime = start_datetime.addSecs(durationMinutes*60); + return GetCostFromDuration(cfg, start_datetime, end_datetime); + } else { + if (Utilities::IsYearPeriodActive(cfg, start_datetime)) { + if (!prepaid) { + CalcState cs = isParkingAllowed(cfg, start_datetime); + if (cs) { + end_datetime = start_datetime.addSecs(durationMinutes*60); + double cost = GetCostFromDuration(cfg, start_datetime, end_datetime); + end_datetime = start_datetime; + end_datetime.setTime(cs.getAllowedTimeRange().getTimeUntil()); + return cost; + } + } else { + // it might be that in such a case even prepaid ("vorkauf") + // is not allowed at any moment + } + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << "NOT YET IMPLEMENTED"; + end_datetime = QDateTime(); + return 0; + } + } + } else + if (paymentMethodId == PaymentMethod::Progressive) { + // started with Neuhauser, Kirchdorf: merge into main algo. later + // for now try out some ideas + + static const bool carryOverNotSet = Utilities::isCarryOverNotSet(cfg, paymentMethodId); + static const uint minParkingPrice = Utilities::getMinimalParkingPrice(cfg, paymentMethodId); + + Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)"); + Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)"); + + QDateTime start = start_datetime; + + int weekdayId = -1; + int weekdayIdLast = -1; + int durationMinutesBrutto = 0; + + QDateTime current = start; + + int days = 7; + while (--days > 0) { + weekdayId = current.date().dayOfWeek(); + weekdayIdLast = weekdayId; // TODO: some end condition in json-file + + while (cfg->WeekDaysWorktime.count(weekdayId) == 0) { + current = current.addDays(1); + weekdayId = current.date().dayOfWeek(); + if (weekdayId == weekdayIdLast) { + qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED"; + return 0; + } + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + QTime to = QTime(0, 0, 0); + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr); + + if (to < t) { + to = t; + } + } + + if (current.time() >= to) { + if (carryOverNotSet) { + end_datetime = start; + return 0; + } else { + QDateTime const dt = start; + start = start.addDays(1); + start.setTime(QTime(0, 0, 0)); + + durationMinutesBrutto += dt.secsTo(start) / 60; + current = start; + } + } else { + break; + } + } + + int durationMinutesNetto = 0; + uint price = 0; + + if (carryOverNotSet) { + int range = 0; + int minsToCarryOver = 0; // from one work-time to the other on the same day + int minsUsed = 0; + QDateTime lastCurrent = QDateTime(); + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + ++range; + + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &to = Utilities::WeekDaysWorkTimeUntil(itr); + + Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES"); + + if (current.time() >= to) { + continue; // try to use next available work-time + } else + if (current.time() <= from) { + if (prepaid) { + lastCurrent = current; + current.setTime(from); // move current forward (range==1), + // as prepaid is set + uint const minutesMoved = lastCurrent.secsTo(current) / 60; + durationMinutesBrutto += minutesMoved; + + if (range == 1) { + start_datetime = current; + } + } + } + + for (auto timeRangeIt = cfg->TimeRange.cbegin(); timeRangeIt != cfg->TimeRange.cend(); ++timeRangeIt) { + + ATBTimeRange timeRange = timeRangeIt->second; + + timeRange.computeQTimes(current.time()); + + int duration = timeRange.time_range_to_in_minutes_from_start - + timeRange.time_range_from_in_minutes_from_start; + + qCritical() << __func__ << ":" << __LINE__ + << "current" << current.toString(Qt::ISODate) + << "duration" << duration + << "minsUsed" << minsUsed + << "minsToCarryOver" << minsToCarryOver; + + + //if (minsUsed > 0) { + // duration -= minsUsed; + // minsUsed = 0; + //} + + if (current.addSecs(duration * 60).time() <= to) { + if (minsToCarryOver > 0) { // the price for this time range + // has been is paid already + if (minsUsed == 0) { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + + current = current.addSecs(duration * 60); + + if (durationMinutes <= 0) { + end_datetime = current; + return price; + } + + break; + } + } + } else { + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + current = current.addSecs(duration*60); + minsToCarryOver = 0; + } + } else { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + + durationMinutes -= duration; + durationMinutesNetto += duration; + durationMinutesBrutto += duration; + + current = current.addSecs(duration * 60); + break; + } + } + } + + if (durationMinutes <= 0) { + end_datetime = current; + return price; + } + + //++timeRangeIt; + + } else { + + lastCurrent = current; + current.setTime(to); + minsUsed = lastCurrent.secsTo(current) / 60; + + // mod duration: possibly discard some minutes in + // the next time-range + if (durationMinutes >= minsUsed) { + minsToCarryOver = durationMinutes - minsUsed; + } + + durationMinutes -= minsUsed; + durationMinutesNetto += minsUsed; + durationMinutesBrutto += minsUsed; + + if (minsUsed > 0) { + for(const auto &x: cfg->PaymentRate) { + ATBPaymentRate const rate = x.second; + if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) { + price += (uint)rate.pra_price; + break; + } + } + } + // break; + } + } // for (WTIterator itr = p.first; itr != p.second; ++itr) { + + end_datetime = start.addSecs(durationMinutesBrutto * 60); + return std::max(price, minParkingPrice); + } + } + + end_datetime = QDateTime(); + return 0; + } + + QDateTime start = start_datetime; + + Ticket t = private_GetCostFromDuration(cfg, start, + durationMinutes, + prepaid); + if (t) { + // qCritical().noquote() << t; + } + + end_datetime = t.getValidUntil(); + + return t.getPrice(); +} + +bool Calculator::checkDurationMinutes(int minParkingTime, + int maxParkingTime, + int durationMinutes) { + if (durationMinutes > maxParkingTime) { + qWarning() << QString("Total duration >= max_min (%1 >= %2)").arg(durationMinutes).arg(maxParkingTime); + return false; + } + if (durationMinutes < minParkingTime) { + qWarning() << QString("Total duration <= minMin (%1 <= %2)").arg(durationMinutes).arg(minParkingTime); + return false; + } + + return true; +} + +int Calculator::findWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size) { + for (size_t w = 0; w < size; ++w) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if ((dt.time() >= worktime_from) && (dt.time() < worktime_to)) { + return w; + } + } + return -1; +} + +int Calculator::findNextWorkTimeRange(QDateTime const &dt, + QScopedArrayPointer const &worktime, + size_t size) { + int nextWorkTimeRange = -1; + for (size_t w = 0; w < size; ++w) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + + if (dt.time() < worktime_from) { + nextWorkTimeRange = w; + break; + } + } + return nextWorkTimeRange; +} + +using namespace Utilities; + +Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg, + QDateTime const &start, + int durationMinutes, // Netto + bool prepaid) { + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId); + static const int minParkingTimeMinutes = Utilities::getMinimalParkingTime(cfg, paymentMethodId); + static const int maxParkingTimeMinutes = Utilities::getMaximalParkingTime(cfg, paymentMethodId); + static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes); + static const int durationMinutesNetto = durationMinutes; + static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId); + static const double weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId); + static const double specialDaysDurationUnit = 60.0; + + if (!checkMinMaxMinutes) { + qCritical() << QString( + "ERROR: CONDITION minMin < maxMin (%1 < %2) IS NOT VALID") + .arg(minParkingTimeMinutes).arg(maxParkingTimeMinutes); + return Ticket(); + } + + if (!checkDurationMinutes(minParkingTimeMinutes, + maxParkingTimeMinutes, durationMinutes)) { + return Ticket(); + } + + uint32_t price = 0; + uint32_t costFromDuration = 0; + double durationUnit = 0.0; + int specialDayId = -1; + bool isSpecialDay = false; + Ticket ticket; + QDateTime end = start; + QDateTime current; + int totalTimeRanges = 0; + + for (current = start; durationMinutes > 0; current = current.addDays(1)) { + int const weekdayId = current.date().dayOfWeek(); + + specialDayId = -1; + + // find worktime ranges for the current day + int const timeRanges = std::max((int)cfg->WeekDaysWorktime.count(weekdayId), 1); + QScopedArrayPointer worktime(new TariffTimeRange[timeRanges]); + int ranges = 0; + + if((isSpecialDay = Utilities::CheckSpecialDay(cfg, current, &specialDayId, &price))) { + // Set special day price: + durationUnit = specialDaysDurationUnit; + worktime[ranges].setTimeRange(SpecialDaysWorkTimeFrom(cfg, specialDayId), + SpecialDaysWorkTimeUntil(cfg, specialDayId)); + ranges = 1; + } else { + // Set new price for the normal day: do not use a floating-point type + // for the price, rather compute with integers. Only at the very end of + // the computation the price is divided by durationUnit. + price = weekDaysPrice; + durationUnit = weekDaysDurationUnit; + + // If no working day found, skip it (epsecially Sundays!) + if (cfg->WeekDaysWorktime.count(weekdayId) <= 0) { + qDebug() << "No workday found, trying to find next available day"; + end = current; + current.setTime(QTime()); // start at midnight on the next day + continue; + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + worktime[ranges].setTimeRange(WeekDaysWorkTimeFrom(itr), + WeekDaysWorkTimeUntil(itr)); + ranges += 1; + } + } + + QTime const &lastWorktimeTo = worktime[ranges-1].getTimeUntil(); + + // qCritical() << "start" << start.toString(Qt::ISODate) + // << "current" << current.toString(Qt::ISODate) << lastWorktimeTo; + + // find worktime range to start with + int currentRange = 0; + if (!isSpecialDay) { + if (start != current) { // on next day + current.setTime(worktime[currentRange].getTimeFrom()); + } else { + // check if inputDate is located inside a valid worktime-range... + if ((currentRange = findWorkTimeRange(current, worktime, ranges)) == -1) { + if (!prepaid && carryOverNotSet) { // parking is not allowed + return Ticket(start, QDateTime(), durationMinutesNetto, 0, + 0, Ticket::s[INVALID_FROM_DATETIME]); + } + // find the next worktime-range (on the same day), and start from there + if ((currentRange = findNextWorkTimeRange(current, worktime, ranges)) == -1) { + end = current; + continue; + } + current.setTime(worktime[currentRange].getTimeFrom()); + } + } + } + + // qCritical() << "current" << current.toString(Qt::ISODate); + + for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + if (durationMinutes > 0) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if (totalTimeRanges) { + // durationMinutes are always meant as netto time and + // the time between worktime-ranges are free. + current.setTime(worktime_from); + } + + if (price == 0) { + end = current; + current.setTime(QTime()); + continue; + } + + if (current.time() == worktime_to) { + end = current; + current.setTime(QTime()); + continue; + } + + // Check prepaid + if (!prepaid) { + if ((current.time() < worktime_from) || (current.time() > worktime_to)) { + qDebug() << "[STOP] * Ticket is not valid * "; + return Ticket(); + } + } else { + //qDebug() << "* PREPAID MODE ACTIVE *"; + //qCritical() << "current" << current.toString(Qt::ISODate) << worktime_from << lastWorktimeTo; + if (current.time() < worktime_from) { + current.setTime(worktime_from); + end = current; + } else if(current.time() > lastWorktimeTo) { + //qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day"; + end = current; + current.setTime(QTime()); + continue; + } + } + + while(durationMinutes > 0) { + // Check for active year period + if (!IsYearPeriodActive(cfg, current)) { + return Ticket(); + } + if(current.time() >= lastWorktimeTo) { + // Go to next day if minutes not spent + if (carryOverNotSet) { + // no carry_over, so stop computation + break; + } + current.setTime(QTime()); + break; // stop while, and continue in outer loop + } else { + //qCritical() << "current" << current.toString(Qt::ISODate) << worktime_to; + if(current.time() < worktime_to) { + // Increment input date minutes for each monetary unit + current = current.addSecs(60); + end = current; + durationMinutes -= 1; + //costFromDuration += price_per_unit; + costFromDuration += price; + //qCritical() << "current" << current.toString(Qt::ISODate); + } else break; + } + } // while(durationMinutes > 0) { + } // if (durationMinutes > 0) { + } // for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + } // for (current = start; durationMinutes > 0; current = current.addDays(1)) { + + int durationMinutesBrutto = start.secsTo(end) / 60; + + return + Ticket(start, end, durationMinutesNetto, durationMinutesBrutto, + ceil(Utilities::CalculatePricePerUnit(costFromDuration, durationUnit)), + Ticket::s[VALID]); +} + + +Ticket Calculator::private_GetDurationFromCost(Configuration *cfg, + QDateTime const &start, + uint32_t cost, + bool prepaid) { + // Get input date + QDateTime current = start; + + static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); + static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId); + static const uint32_t minParkingTimeMinutes = std::max(Utilities::getMinimalParkingTime(cfg, paymentMethodId), 0); + static const uint32_t maxParkingTimeMinutes = std::max(Utilities::getMaximalParkingTime(cfg, paymentMethodId), 0); + static const uint32_t minParkingPrice = getMinimalParkingPrice(cfg, paymentMethodId); + // static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes); + static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId); + static const uint32_t weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId); + static const uint32_t specialDaysDurationUnit = 60; + + if(cost < minParkingPrice) { + uint64_t const durationMinutes = GetDurationForPrice(cfg, cost); + return Ticket(start, current, durationMinutes, durationMinutes, + cost, Ticket::s[INVALID_PRICE]); + } + if (minParkingTimeMinutes >= maxParkingTimeMinutes) { + // TODO + return Ticket(); + } + if (maxParkingTimeMinutes <= minParkingTimeMinutes) { + // TODO + return Ticket(); + } + + uint32_t durationMinutesNetto = 0; + double moneyLeft = cost; + double durationUnit = 1; + int specialDayId = -1; + bool isSpecialDay = false; + QDateTime end = start; + int totalTimeRanges = 0; + double price = 0; + + for (current = start; moneyLeft > 0 && moneyLeft >= price; current = current.addDays(1)) { + int const weekdayId = current.date().dayOfWeek(); + + specialDayId = -1; + + // find worktime ranges for the current day + int const timeRanges = std::max((int)cfg->WeekDaysWorktime.count(weekdayId), 1); + QScopedArrayPointer worktime(new TariffTimeRange[timeRanges]); + int ranges = 0; + + uint32_t p = 0; + if((isSpecialDay = Utilities::CheckSpecialDay(cfg, current, &specialDayId, &p))) { + // Set special day price: + durationUnit = specialDaysDurationUnit; + price = p / durationUnit; + price = std::round(price * 1000.0) / 1000.0; + worktime[ranges].setTimeRange(SpecialDaysWorkTimeFrom(cfg, specialDayId), + SpecialDaysWorkTimeUntil(cfg, specialDayId)); + ranges = 1; + } else { + // Set new price for the normal day: do not use a floating-point type + // for the price, rather compute with integers. Only at the very end of + // the computation the price is divided by durationUnit. + price = weekDaysPrice; + durationUnit = weekDaysDurationUnit; + price /= durationUnit; + price = std::round(price * 1000.0) / 1000.0; // round to 3 decimals + + // If no working day found, skip it (epsecially Sundays!) + if (cfg->WeekDaysWorktime.count(weekdayId) <= 0) { + // qDebug() << "No workday found, trying to find next available day"; + end = current; + current.setTime(QTime()); // start at midnight on the next day + continue; + } + + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + worktime[ranges].setTimeRange(WeekDaysWorkTimeFrom(itr), + WeekDaysWorkTimeUntil(itr)); + ranges += 1; + } + } + + QTime const &lastWorktimeTo = worktime[ranges-1].getTimeUntil(); + + // find worktime range to start with + int currentRange = 0; + if (!isSpecialDay) { + if (start != current) { // on next day + current.setTime(worktime[currentRange].getTimeFrom()); + } else { + // check if inputDate is located inside a valid worktime-range... + if ((currentRange = findWorkTimeRange(current, worktime, ranges)) == -1) { + if (!prepaid && carryOverNotSet) { // parking is not allowed + return Ticket(start, QDateTime(), durationMinutesNetto, 0, + 0, Ticket::s[INVALID_FROM_DATETIME]); + } + // find the next worktime-range (on the same day), and start from there + if ((currentRange = findNextWorkTimeRange(current, worktime, ranges)) == -1) { + end = current; + continue; + } + current.setTime(worktime[currentRange].getTimeFrom()); + } + } + } + + for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + if (moneyLeft > 0) { + QTime const &worktime_from = worktime[w].getTimeFrom(); + QTime const &worktime_to = worktime[w].getTimeUntil(); + + if (totalTimeRanges) { + // durationMinutes are always meant as netto time and + // the time between worktime-ranges are free. + current.setTime(worktime_from); + } + + if (price == 0) { + // inputDate = inputDate.addDays(1); + // inputDate.setTime(worktime_from); + end = current; + current.setTime(QTime()); + continue; + } + + if (current.time() == worktime_to) { + end = current; + current.setTime(QTime()); + continue; + } + + // Check prepaid + if (!prepaid) { + if (current.time() < worktime_from) { + qDebug() << "[STOP] TICKET IS NOT VALID: " + << QString("%1 (current) < %2 (start)") + .arg(current.toString(Qt::ISODate) + .arg(worktime_from.toString(Qt::ISODate))); + return Ticket(); + } else + if (current.time() > worktime_to) { + qDebug() << "[STOP] TICKET IS NOT VALID: " + << QString("%1 (current) > %2 (end)") + .arg(current.toString(Qt::ISODate) + .arg(worktime_to.toString(Qt::ISODate))); + return Ticket(); + } + } else { + if (current.time() < worktime_from) { + qDebug() << "*** PREPAID *** Current time is before time range start, fast-forward to start" + << worktime_from.toString(Qt::ISODate); + current.setTime(worktime_from); + end = current; + } else if(current.time() > lastWorktimeTo) { + qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day"; + end = current; + current.setTime(QTime()); + continue; + } + } + + while(moneyLeft >= price) { + // Check for active year period + if (!IsYearPeriodActive(cfg, current)) { + return Ticket(); + } + // if(durationMinutesNetto >= maxParkingTimeMinutes) { + // might be useful for overpayment + // durationMinutesNetto = maxParkingTimeMinutes; + // int durationMinutesBrutto = start.secsTo(end) / 60; + // + // return + // Ticket(start, end, durationMinutesNetto, + // durationMinutesBrutto, cost, Ticket::s[INVALID_PRICE]); + // + // } + if(current.time() >= lastWorktimeTo) { + // Go to next day if minutes not spent + if (carryOverNotSet) { + // no carry_over, so stop computation + break; + } + current.setTime(QTime()); + break; // stop while, and continue in outer loop + } else { + if(current.time() < worktime_to) { + // Increment input date minutes for each monetary unit + durationMinutesNetto += 1; + moneyLeft -= price; + moneyLeft = std::round(moneyLeft * 1000.0) / 1000.0; + current = current.addSecs(60); + + //qCritical() << "moneyLeft" << moneyLeft + // << "durationMinutesNetto" << durationMinutesNetto + // << "current" << current.toString(Qt::ISODate); + + if(durationMinutesNetto <= maxParkingTimeMinutes) { + // stop updating of end-date if parking time is + // overshot + end = current; + } + } else break; + } + } // while(durationMinutes > 0) { + } // if (durationMinutes > 0) { + } // for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) { + } // for (current = start; durationMinutes > 0; current = current.addDays(1)) { + + int durationMinutesBrutto = start.secsTo(end) / 60; + + //qCritical() << "start" << start.toString(Qt::ISODate) << "end" + // << end.toString(Qt::ISODate) << durationMinutesBrutto; + + return + Ticket(start, end, durationMinutesNetto, durationMinutesBrutto, + cost, Ticket::s[VALID]); +} + +QList Calculator::GetPriceSteps(Configuration * /*cfg*/) const { + return QList(); +} + +QList Calculator::GetTimeSteps(Configuration *cfg) const { + if (m_timeSteps.size() > 0) { + //qCritical() << __PRETTY_FUNCTION__ << "timeSteps:" << m_timeSteps; + return m_timeSteps; + } + + QDateTime start = QDateTime::currentDateTime(); + start.setTime(QTime(start.time().hour(), start.time().minute(), 0)); + + int const pop_id = cfg->getPaymentOptions().pop_id; + int const pop_carry_over = cfg->getPaymentOptions().pop_carry_over; + int const pop_time_step_config = cfg->getPaymentOptions().pop_time_step_config; + + static PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + + qCritical() << __func__ << ":" << __LINE__ << " start parking time:" << start.toString(Qt::ISODate); + qCritical() << __func__ << ":" << __LINE__ << " payment option id:" << pop_id; + qCritical() << __func__ << ":" << __LINE__ << "payment option carry over:" << pop_carry_over; + + if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) { + //qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::DYNAMIC"; + + if (paymentMethodId == PaymentMethod::Progressive) { // e.g. neuhauser kirchdorf (743) + std::size_t const s = cfg->TimeRange.size(); + for (std::size_t id = 1; id <= s; ++id) { + int const step = Utilities::getTimeRangeStep(cfg, id, paymentMethodId); + m_timeSteps.append(step); + } + } else { + uint16_t timeStepCompensation = 0; + + if (pop_carry_over) { + int const pop_carry_over_time_range_id = cfg->getPaymentOptions().pop_carry_over_time_range_id; + QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from; + QTime const carryOverTimeRangeTo = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_to; + + if (carryOverTimeRangeFrom.secsTo(carryOverTimeRangeTo) <= 60) { // carry over time point, usually 00:00:00 + if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + auto search = cfg->Duration.find(durationId); + if (search != cfg->Duration.end()) { + ATBDuration duration = search->second; + if (durationId == 1) { + QDateTime carryOver = start; + carryOver = carryOver.addDays(1); + carryOver.setTime(QTime(0, 0, 0)); + + int const timeStep = std::ceil(start.secsTo(carryOver) / 60.0); + if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) { + qCritical() + << QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)") + .arg(timeStep).arg(duration.pun_duration_min) + .arg(timeStep).arg(duration.pun_duration_max); + break; + } + qCritical() << __PRETTY_FUNCTION__ << "configured minimal parking time:" << cfg->getPaymentOptions().pop_min_time; + + // set dynamic minimal parking time + cfg->getPaymentOptions().pop_min_time = timeStep; + + qCritical() << __PRETTY_FUNCTION__ << " computed minimal parking time:" << cfg->getPaymentOptions().pop_min_time; + + duration.pun_duration = timeStep; + timeStepCompensation = duration.pun_duration_max - duration.pun_duration; + m_timeSteps << duration.pun_duration; + } else { + duration.pun_duration = duration.pun_duration_max - timeStepCompensation; + m_timeSteps << duration.pun_duration;; + } + + cfg->Duration.erase(search); + cfg->Duration.insert(pair(duration.pun_id, duration)); + + } else { // if (search != cfg->Duration.end()) { + // TODO + } + } + } else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { + // TODO + } + } else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) { + // TODO + } + } else { // if (pop_carry_over) { + // TODO + } + } + } else { + qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::STATIC"; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const durationId = itr->second.pra_payment_unit_id; + int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + m_timeSteps << durationUnit; + } + } + + qCritical() << __PRETTY_FUNCTION__ << "NEW timeSteps:" << m_timeSteps; + + return m_timeSteps; +} + +uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep) const { + + int const pop_id = cfg->getPaymentOptions().pop_id; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const payment_unit_id = itr->second.pra_payment_unit_id; + int const pun_id = cfg->Duration.find(payment_unit_id)->second.pun_id; + + Q_ASSERT(pun_id == payment_unit_id); + + int const pun_duration = cfg->Duration.find(payment_unit_id)->second.pun_duration; + if (timeStep == pun_duration) { + return (uint32_t)(itr->second.pra_price); + } + } + + return 0; +} + +uint32_t Calculator::GetDurationForPrice(Configuration *cfg, int price) const { + int const pop_id = cfg->getPaymentOptions().pop_id; + + uint32_t duration = 0; + + for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) + { + int const durationId = itr->second.pra_payment_unit_id; + int const pra_price = itr->second.pra_price; + + uint32_t const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; + + if (pra_price == price) { + return durationUnit; + } + + if (pra_price < price) { + duration = durationUnit; + } + } + + return duration; +} + +std::optional +Calculator::GetDailyTicketPrice(Configuration* cfg, + QDateTime const &startDatetime, + QDateTime &endTime, + PERMIT_TYPE permitType) { + struct price_t price; + std::optional value; + + std::optional workTime = + cfg->getWeekDayWorkTime(startDatetime.time(), + (Qt::DayOfWeek)startDatetime.date().dayOfWeek()); + if (workTime) { + ATBWeekDaysWorktime const &wt = workTime.value(); + endTime = startDatetime; + endTime.setTime(QTime::fromString(wt.pwd_time_to.c_str(), Qt::ISODate)); + std::optional> dailyTickets = cfg->getDailyTicketsForAllKeys(); + if (dailyTickets) { + QVector const tickets = dailyTickets.value(); + switch (permitType) { + case PERMIT_TYPE::DAY_TICKET_ADULT: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::ADULT); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_TEEN: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::TEEN); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } break; + case PERMIT_TYPE::DAY_TICKET_CHILD: { + std::optional c = cfg->getCustomerForType(ATBCustomer::CustomerType::CHILD); + if (c) { + for (QVector::size_type i=0; i const &paymentOptions = cfg->getAllPaymentOptions(); + for (QVector::size_type j=0; j < paymentOptions.size(); ++j) { + int const pop_id = paymentOptions.at(j).pop_id; + std::optional> const &paymentRates = cfg->getPaymentRateForKey(pop_id); + if (paymentRates) { + QVector const &pr = paymentRates.value(); + for (QVector::size_type k=0; k < pr.size(); ++k) { + if (pr.at(k).pra_payment_option_id == pop_id) { + if (priceId == pr.at(k).pra_payment_unit_id) { + price.netto = pr.at(k).pra_price; + value = value.value_or(price); + } + } + } + } + } + } + } + } + } + // [[fallthrough]]; + case PERMIT_TYPE::SHORT_TERM_PARKING: { + } + // [[fallthrough]]; + case PERMIT_TYPE::DAY_TICKET: { + } + // [[fallthrough]]; + case PERMIT_TYPE::SZEGED_START: + // [[fallthrough]]; + case PERMIT_TYPE::SZEGED_STOP: + // [[fallthrough]]; + case PERMIT_TYPE::INVALID: + break; + } + } else { + // for projects which have not defined a daily ticket in their + // tariff-files (e.g. szeged) + price.netto = cfg->getPaymentOptions().pop_daily_card_price; + + qCritical() << "( GetDailyTicketPrice():" << __LINE__ << ")"; + qCritical() << " start:" << startDatetime.toString(Qt::ISODate); + qCritical() << " workTime from:" << QTime::fromString(QString(wt.pwd_time_from.c_str()), Qt::ISODate); + qCritical() << " workTime to:" << QTime::fromString(QString(wt.pwd_time_to.c_str()), Qt::ISODate); + qCritical() << "daily_ticket_card_price:" << price.netto; + + value = value.value_or(price); + } + } + + return value; +} diff --git a/library/src/configuration.cpp b/library/src/configuration.cpp index 2dbdc99..c9f9353 100644 --- a/library/src/configuration.cpp +++ b/library/src/configuration.cpp @@ -1,269 +1,2346 @@ -#include "configuration.h" - -/// -MemberType Configuration::IdentifyJsonMember(const char* member_name) -{ - if (strcmp(member_name, "Currency") == 0) return MemberType::CurrencyType; - if (strcmp(member_name, "PaymentMethod") == 0) return MemberType::PaymentMethodType; - if (strcmp(member_name, "PaymentRate") == 0) return MemberType::PaymentRateType; - if (strcmp(member_name, "PaymentOption") == 0) return MemberType::PaymentOptionType; - if (strcmp(member_name, "Duration") == 0) return MemberType::DurationType; - //if (strcmp(member_name, "WeekDays") == 0) return MemberType::WeekDaysType; - if (strcmp(member_name, "WeekDaysWorktime") == 0) return MemberType::WeekDaysWorkTimeType; - if (strcmp(member_name, "SpecialDaysWorktime") == 0) return MemberType::SpecialDaysWorktimeType; - if (strcmp(member_name, "SpecialDays") == 0) return MemberType::SpecialDaysType; - if (strcmp(member_name, "PeriodYear") == 0) return MemberType::PeriodYearType; - else return MemberType::UnknownType; -} - -/// -bool Configuration::ParseJson(Configuration* cfg, const char* json) -{ - try - { - if (cfg == nullptr) - { - printf("TariffConfiguration pointer not set\n"); - return false; - } - if (json == NULL) - { - printf("%s", "Input JSON string is NULL\n"); - return false; - } - - // Parse JSON to document - Document document; - document.Parse(json); - - // Return if parse error has been found - ParseErrorCode err = document.GetParseError(); - if (err != 0) - { - printf("%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err)); - return false; - } - - // Validate JSON, check if it's a JSON object - printf("%s", "JSON parsing has been successful\n"); - if (!document.IsObject()) { - printf("%s", "Error: not a (valid) JSON object\n"); - return false; - } - printf("%s", "Valid JSON object identified\n"); - - // Validate JSON, check configuration members - if (!document.HasMember("Currency") - || !document.HasMember("PaymentMethod") - || !document.HasMember("PaymentOption") - || !document.HasMember("PaymentRate") - || !document.HasMember("Duration") - //|| !document.HasMember("WeekDays") - //|| !document.HasMember("SpecialDaysWorktime") - //|| !document.HasMember("SpecialDays") - ) - { - printf("%s", "Error: not a valid configuration JSON\n"); - return false; - } - printf("%s", "Valid JSON configuration identified\n"); - - ATBCurrency Currency; - ATBDuration Duration; - ATBPaymentMethod PaymentMethod; - ATBPaymentRate PaymentRate; - ATBSpecialDaysWorktime SpecialDaysWorktime; - ATBSpecialDays SpecialDays; - ATBWeekDays WeekDays; - ATBWeekDaysWorktime WeekDaysWorktime; - ATBPaymentOption PaymentOption; - ATBPeriodYear YearPeriod; - MemberType mb_type; - - // Get all JSON object members - // This code should run only once (to load JSON variables into memory) - for (auto i = document.MemberBegin(); i != document.MemberEnd(); i++) - { - // Get name of all general members of JSON, don't print name if NULL - const char* mb_name = i->name.GetString(); - if (mb_name == NULL) continue; - - if (document[mb_name].IsString()) { - QString const _mb_name(mb_name); - if (_mb_name.startsWith("Project", Qt::CaseInsensitive)) { - cfg->project.project = document[mb_name].GetString(); - continue; - } - if (_mb_name.startsWith("Version", Qt::CaseInsensitive)) { - cfg->project.version = document[mb_name].GetString(); - continue; - } - if (_mb_name.startsWith("Info", Qt::CaseInsensitive)) { - cfg->project.info = document[mb_name].GetString(); - continue; - } - } - - // ... everything else should be an array - if (!document[mb_name].IsArray()) { - continue; - } - - //printf(" -%s\n", mb_name); - - // Get array for each JSON object member - auto mb_array = document[mb_name].GetArray(); - if (mb_array.Size() <= 0) break; - - //Iterate over provided array - for (auto j = 0; j < mb_array.Size(); j++) - { - // Get all inner objects, don't print name if NULL - auto inner_obj = mb_array[j].GetObject(); - if (inner_obj.MemberCount() <= 0) break; - - // Iterate over inner object JSON members - for (auto k = inner_obj.MemberBegin(); k != inner_obj.MemberEnd(); k++) - { - // Get inner object JSON member, don't print name if NULL - const char* inner_obj_name = k->name.GetString(); - if (inner_obj_name == NULL) - { - printf("Inner object name is NULL\n"); - continue; - } - - // Identify member type - mb_type = IdentifyJsonMember(mb_name); - -//#pragma region Get_values - switch (mb_type) - { - case MemberType::UnknownType: - break; - case MemberType::CurrencyType: - if (strcmp(inner_obj_name, "pcu_id") == 0) Currency.pcu_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pcu_sign") == 0) Currency.pcu_sign = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_major") == 0) Currency.pcu_major = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool(); - break; - case MemberType::PaymentMethodType: - if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString(); - break; - case MemberType::PaymentRateType: - if (strcmp(inner_obj_name, "pra_payment_option_id") == 0) PaymentRate.pra_payment_option_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pra_payment_unit_id") == 0) PaymentRate.pra_payment_unit_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pra_price") == 0) PaymentRate.pra_price = k->value.GetDouble(); - break; - case MemberType::PaymentOptionType: - if (strcmp(inner_obj_name, "pop_id") == 0) PaymentOption.pop_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pop_label") == 0) PaymentOption.pop_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pop_payment_method_id") == 0) PaymentOption.pop_payment_method_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pop_day_end_time") == 0) PaymentOption.pop_day_end_time = k->value.GetString(); - else if (strcmp(inner_obj_name, "pop_day_night_end_time") == 0) PaymentOption.pop_day_night_end_time = k->value.GetString(); - else if (strcmp(inner_obj_name, "pop_price_night") == 0) PaymentOption.pop_price_night = k->value.GetDouble(); - else if (strcmp(inner_obj_name, "pop_min_time") == 0) PaymentOption.pop_min_time = k->value.GetDouble(); - else if (strcmp(inner_obj_name, "pop_max_time") == 0) PaymentOption.pop_max_time = k->value.GetDouble(); - else if (strcmp(inner_obj_name, "pop_min_price") == 0) PaymentOption.pop_min_price = k->value.GetDouble(); - else if (strcmp(inner_obj_name, "pop_carry_over") == 0) PaymentOption.pop_carry_over = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) PaymentOption.pop_daily_card_price = k->value.GetInt(); - this->currentPaymentOptions = PaymentOption; - break; - case MemberType::DurationType: - if (strcmp(inner_obj_name, "pun_id") == 0) Duration.pun_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pun_label") == 0) Duration.pun_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pun_duration") == 0) Duration.pun_duration = k->value.GetDouble(); - break; - case MemberType::SpecialDaysWorktimeType: - if (strcmp(inner_obj_name, "pedwt_id") == 0) SpecialDaysWorktime.pedwt_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pedwt_period_exc_day_id") == 0) SpecialDaysWorktime.pedwt_period_exc_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pedwt_time_from") == 0) SpecialDaysWorktime.pedwt_time_from = k->value.GetString(); - else if (strcmp(inner_obj_name, "pedwt_time_to") == 0) SpecialDaysWorktime.pedwt_time_to = k->value.GetString(); - else if (strcmp(inner_obj_name, "pedwt_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble(); - break; - /*case MemberType::WeekDaysType: - if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pdiw_label") == 0) WeekDays.pdiw_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pdiw_index") == 0) WeekDays.pdiw_index = k->value.GetInt(); - break;*/ - case MemberType::WeekDaysWorkTimeType: - if (strcmp(inner_obj_name, "pwd_id") == 0) WeekDaysWorktime.pwd_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_period_week_day_id") == 0) WeekDaysWorktime.pwd_period_week_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_period_day_in_week_id") == 0) WeekDaysWorktime.pwd_period_day_in_week_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_time_from") == 0) WeekDaysWorktime.pwd_time_from = k->value.GetString(); - else if (strcmp(inner_obj_name, "pwd_time_to") == 0) WeekDaysWorktime.pwd_time_to = k->value.GetString(); - case MemberType::SpecialDaysType: - if (strcmp(inner_obj_name, "ped_id") == 0) SpecialDays.ped_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "ped_label") == 0) SpecialDays.ped_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_date_start") == 0) SpecialDays.ped_date_start = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_date_end") == 0) SpecialDays.ped_date_end = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_period_special_day_id") == 0) SpecialDays.ped_period_special_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "ped_year") == 0) SpecialDays.ped_year = k->value.GetInt(); - break; - case MemberType::PeriodYearType: - if (strcmp(inner_obj_name, "pye_id") == 0) YearPeriod.pye_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_label") == 0) YearPeriod.pye_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pye_start_month") == 0) YearPeriod.pye_start_month = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_start_day") == 0) YearPeriod.pye_start_day = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_end_month") == 0) YearPeriod.pye_end_month = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_end_day") == 0) YearPeriod.pye_end_day = k->value.GetInt(); - break; - default: - break; - } -//#pragma endregion - } - - // Push to specific list depending on member type - switch (mb_type) - { - case MemberType::UnknownType: - break; - case MemberType::PaymentMethodType: - cfg->PaymentMethod.insert(pair(PaymentMethod.pme_id, PaymentMethod)); - break; - case MemberType::PaymentRateType: - cfg->PaymentRate.insert(pair(PaymentRate.pra_payment_option_id, PaymentRate)); - break; - case MemberType::PaymentOptionType: - cfg->PaymentOption.insert(pair(PaymentOption.pop_payment_method_id, PaymentOption)); - break; - case MemberType::DurationType: - cfg->Duration.insert(pair(Duration.pun_id, Duration)); - break; - case MemberType::SpecialDaysWorktimeType: - cfg->SpecialDaysWorktime.insert(pair(SpecialDaysWorktime.pedwt_period_exc_day_id, SpecialDaysWorktime)); - break; - //case MemberType::WeekDaysType: - // cfg->WeekDays.insert(pair(WeekDays.pdiw_index, WeekDays)); - // break; - case MemberType::WeekDaysWorkTimeType: - cfg->WeekDaysWorktime.insert(pair(WeekDaysWorktime.pwd_period_day_in_week_id, WeekDaysWorktime)); - break; - case MemberType::SpecialDaysType: - cfg->SpecialDays.insert(pair(SpecialDays.ped_id, SpecialDays)); - break; - case MemberType::PeriodYearType: - cfg->YearPeriod.insert(pair(YearPeriod.pye_id, YearPeriod)); - break; - default: - break; - } - } - } - return true; - } - catch (...) { - printf("%s\n", "General exception has occurred while parsing JSON\n"); - return false; - } -} - - - -const ATBPaymentOption & Configuration::getPaymentOptions() -{ - return this->currentPaymentOptions; -} +#include "configuration.h" +#include "utilities.h" +#include "tariff_timebase.h" +#include "time_range_header.h" +#include "tariff_timestep_config.h" +#include "tariff_permit_type.h" +#include "tariff_business_hours.h" +#include "tariff_global_defines.h" +#include "tariff_carryover.h" +#include "tariff_global_defines.h" +#include "tariff_settings.h" +#include "tariff_carryover_settings.h" +#include "atb_time.h" +#include "tariff_prepaid.h" +#include "tariff_carryover.h" + +#include +#include +#include + +/// +MemberType Configuration::IdentifyJsonMember(const char* member_name) +{ + if (strcmp(member_name, "Currency") == 0) return MemberType::CurrencyType; + if (strcmp(member_name, "PaymentMethod") == 0) return MemberType::PaymentMethodType; + if (strcmp(member_name, "PaymentRate") == 0) return MemberType::PaymentRateType; + if (strcmp(member_name, "PaymentOption") == 0) return MemberType::PaymentOptionType; + if (strcmp(member_name, "Duration") == 0) return MemberType::DurationType; + if (strcmp(member_name, "Monday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Tuesday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Wednesday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Thursday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Friday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Saturday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "Sunday") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "WeekDaysWorktime") == 0) return MemberType::WeekDaysWorkTimeType; + if (strcmp(member_name, "SpecialDaysWorktime") == 0) return MemberType::SpecialDaysWorktimeType; + if (strcmp(member_name, "SpecialDays") == 0) return MemberType::SpecialDaysType; + if (strcmp(member_name, "PeriodYear") == 0) return MemberType::PeriodYearType; + if (strcmp(member_name, "DailyTicket") == 0) return MemberType::DailyTicketType; + if (strcmp(member_name, "TimeBase") == 0) return MemberType::TimeBaseType; + if (strcmp(member_name, "Customer") == 0) return MemberType::CustomerType; + if (strcmp(member_name, "TimeRange") == 0) return MemberType::TimeRangeType; + if (strcmp(member_name, "TimeStepConfig") == 0) return MemberType::TimeStepConfigType; + if (strcmp(member_name, "Product") == 0) return MemberType::ProductType; + if (strcmp(member_name, "Interpolation") == 0) return MemberType::InterpolationType; + if (strcmp(member_name, "Prepaid") == 0) return MemberType::PrepaidType; + if (strcmp(member_name, "CarryOver") == 0) return MemberType::CarryOverType; + else return MemberType::UnknownType; +} + +ATBWeekDay parseWeekDay(Configuration &cfg, + rapidjson::GenericMemberIterator, + rapidjson::MemoryPoolAllocator> k, + QString const &innerObjName, + Qt::DayOfWeek weekDay, + QString const &weekDayName) { + int max_price = 0; + int min_price = 0; + int min_time = 0; + int max_time = 0; + int duration = 0; + ATBWeekDay WeekDay; + QTime start, end, parking_time_limit, about_to_exceed_limit; + ATBTariffCarryOverSettings::ParkingTimeLimitChecker parkTimeLimitChecker; + QDate const &d = QDate::fromString(innerObjName, Qt::ISODate); + if (innerObjName == QString("default") || + (!d.isNull() && d.isValid())) { // special day, given in date-format + // start with new implementation of tariff-calculator + // see for instance: bad neuenahr (249), Zone5 + + // qCritical() << __func__ << ":" << __LINE__ << innerObjName; + + if (k->value.IsObject()) { + auto obj = k->value.GetObject(); + for (auto m = obj.MemberBegin(); m != obj.MemberEnd(); ++m) { + QString const &name = m->name.GetString(); + if (name == "payment_settings") { + if (m->value.IsArray()) { + auto payment = m->value.GetArray(); + if (payment.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no payment settings for" << weekDayName; + } else { + for (rapidjson::SizeType j = 0; j < payment.Size(); ++j) { + if (payment[j].IsObject()) { + auto paymentSetting = payment[j].GetObject(); + for (auto n = paymentSetting.MemberBegin(); n != paymentSetting.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "min_time") { + if (n->value.IsInt()) { min_time = n->value.GetInt(); } + } else if (name == "max_time") { + if (n->value.IsInt()) { max_time = n->value.GetInt(); } + } else if (name == "min_price") { + if (n->value.IsInt()) { min_price = n->value.GetInt(); } + } else if (name == "max_price") { + if (n->value.IsInt()) { max_price = n->value.GetInt(); } + } + } + } + } + } + } + + } else + if (name == "prepaid_settings") { + if (m->value.IsArray()) { + auto prepaid = m->value.GetArray(); + if (prepaid.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no prepaid-settings for" << weekDayName; + } else { + ATBTariffPrepaid TariffPrepaid; + for (rapidjson::SizeType j = 0; j < prepaid.Size(); ++j) { + if (prepaid[j].IsObject()) { + auto prepaidSetting = prepaid[j].GetObject(); + for (auto n = prepaidSetting.MemberBegin(); n != prepaidSetting.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "prepaid_ranges") { + if (n->value.IsArray()) { + auto prepaidRanges = n->value.GetArray(); + if (prepaidRanges.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no prepaid-ranges for" << weekDayName; + } else { + QString prepaidStartStr; + QString prepaidEndStr; + QString prepaidIf; + int prepaidDuration = -1; + for (rapidjson::SizeType i = 0; i < prepaidRanges.Size(); ++i) { + if (prepaidRanges[j].IsObject()) { + auto prepaidRange = prepaidRanges[i].GetObject(); + for (auto r = prepaidRange.MemberBegin(); r != prepaidRange.MemberEnd(); ++r) { + QString const &memName = QString::fromStdString(r->name.GetString()); + if (memName == "prepaid_id") { + if (r->value.IsInt()) { + TariffPrepaid.m_id = r->value.GetInt(); + } else { + qCritical() << __func__ << ":" << __LINE__ << "prepaidId not an integer"; + } + } else + if (memName == "prepaid_duration") { + if (r->value.IsInt()) { + prepaidDuration = r->value.GetInt(); + } + } else + if (memName == "prepaid_start") { + if (r->value.IsString()) { + prepaidStartStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "prepaid_end") { + if (r->value.IsString()) { + prepaidEndStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "prepaid_if") { + if (r->value.IsString()) { + prepaidIf = QString::fromStdString(r->value.GetString()); + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown prepaid setting" << memName; + } + } + } + + if (!prepaidStartStr.isEmpty() && !prepaidEndStr.isEmpty() && prepaidDuration != -1) { + ATBTime prepaidStart(prepaidStartStr); + ATBTime prepaidEnd(prepaidEndStr); + if (prepaidStart.isValid() && prepaidEnd.isValid()) { + TariffPrepaid.m_range = TimeRange(prepaidStart, prepaidEnd, prepaidDuration); + TariffPrepaid.m_weekDay = weekDayName; + if (!d.isNull() && d.isValid()) { + TariffPrepaid.m_date = d; + } + TariffPrepaid.setPrepaidIf(prepaidIf); + + qCritical() << TariffPrepaid; + + cfg.TariffPrepaids.insert(std::pair(weekDay, TariffPrepaid)); + } + } + } + } + } + } else { + + } + } + } + } + } + } + } else + if (name == "carry_over_settings") { + if (m->value.IsArray()) { + auto carryOver = m->value.GetArray(); + if (carryOver.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no carry-over-settings for" << weekDayName; + } else { + ATBTariffCarryOver TariffCarryOver; + for (rapidjson::SizeType j = 0; j < carryOver.Size(); ++j) { + if (carryOver[j].IsObject()) { + auto carryOverSetting = carryOver[j].GetObject(); + for (auto n = carryOverSetting.MemberBegin(); n != carryOverSetting.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "carry_over_ranges") { + if (n->value.IsArray()) { + auto carryOverRanges = n->value.GetArray(); + if (carryOverRanges.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no carry-over-ranges for" << weekDayName; + } else { + QString carryOverStartStr; + QString carryOverEndStr; + QString carryOverIf; + int carryOverDuration = -1; + for (rapidjson::SizeType i = 0; i < carryOverRanges.Size(); ++i) { + if (carryOverRanges[j].IsObject()) { + auto carryOverRange = carryOverRanges[i].GetObject(); + for (auto r = carryOverRange.MemberBegin(); r != carryOverRange.MemberEnd(); ++r) { + QString const &memName = QString::fromStdString(r->name.GetString()); + if (memName == "carry_over_id") { + if (r->value.IsInt()) { + TariffCarryOver.m_id = r->value.GetInt(); + } else { + qCritical() << __func__ << ":" << __LINE__ << "carryOverId not an integer"; + } + } else + if (memName == "carry_over_duration") { + if (r->value.IsInt()) { + carryOverDuration = r->value.GetInt(); + } + } else + if (memName == "carry_over_start") { + if (r->value.IsString()) { + carryOverStartStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "carry_over_end") { + if (r->value.IsString()) { + carryOverEndStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "carry_over_if") { + if (r->value.IsString()) { + carryOverIf = QString::fromStdString(r->value.GetString()); + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown carry-over setting" << memName; + } + } + } + + if (!carryOverStartStr.isEmpty() && !carryOverEndStr.isEmpty() && carryOverDuration != -1) { + ATBTime carryOverStart(carryOverStartStr); + ATBTime carryOverEnd(carryOverEndStr); + if (carryOverStart.isValid() && carryOverEnd.isValid()) { + TariffCarryOver.m_range = TimeRange(carryOverStart, carryOverEnd, carryOverDuration); + TariffCarryOver.m_weekDay = weekDayName; + if (!d.isNull() && d.isValid()) { + TariffCarryOver.m_date = d; + } + if (!carryOverIf.isEmpty()) { + TariffCarryOver.setCarryOverIf(carryOverIf); + } + + // qCritical() << TariffCarryOver; + + cfg.TariffCarryOvers.insert(std::pair(weekDay, TariffCarryOver)); + } + } + } + } + } + } else { + + } + } + } + } + } + } + } else + if (name == "service_settings") { + ATBTariffService TariffService; + if (m->value.IsArray()) { + auto service = m->value.GetArray(); + if (service.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no service settings for" << weekDayName; + } else { + for (rapidjson::SizeType j = 0; j < service.Size(); ++j) { + if (service[j].IsObject()) { + auto serviceSetting = service[j].GetObject(); + for (auto n = serviceSetting.MemberBegin(); n != serviceSetting.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "service_ranges") { + if (n->value.IsArray()) { + auto serviceRanges = n->value.GetArray(); + if (serviceRanges.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no service ranges for" << weekDayName; + } else { + QString serviceStartStr; + QString serviceEndStr; + QString serviceIf; + int serviceDuration = -1; + for (rapidjson::SizeType i = 0; i < serviceRanges.Size(); ++i) { + if (serviceRanges[j].IsObject()) { + auto serviceRange = serviceRanges[i].GetObject(); + for (auto r = serviceRange.MemberBegin(); r != serviceRange.MemberEnd(); ++r) { + QString const &memName = QString::fromStdString(r->name.GetString()); + if (memName == "service_id") { + if (r->value.IsInt()) { + TariffService.m_id = r->value.GetInt(); + } else { + qCritical() << __func__ << ":" << __LINE__ << "serviceId not an integer"; + } + } else + if (memName == "service_duration") { + if (r->value.IsInt()) { + serviceDuration = r->value.GetInt(); + } + } else + if (memName == "service_start") { + if (r->value.IsString()) { + serviceStartStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "service_end") { + if (r->value.IsString()) { + serviceEndStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "service_if") { + if (r->value.IsString()) { + serviceIf = QString::fromStdString(r->value.GetString()); + } + + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown service setting" << memName; + } + } + } + + if (!serviceStartStr.isEmpty() && !serviceEndStr.isEmpty() && serviceDuration != -1) { + ATBTime serviceStart(serviceStartStr); + ATBTime serviceEnd(serviceEndStr); + if (serviceStart.isValid() && serviceEnd.isValid()) { + TariffService.m_range = TimeRange(serviceStart, serviceEnd, serviceDuration); + TariffService.m_weekDay = weekDayName; + if (!d.isNull() && d.isValid()) { + TariffService.m_date = d; + } + if (!serviceIf.isEmpty()) { + TariffService.setServiceIf(serviceIf); + } + + // qCritical() << TariffService; + + cfg.TariffServices.insert(std::pair(weekDay, TariffService)); + } + } + } + } + } + } else { + + } + } + } + } + } + } + } else + if (name == "out_of_service_settings") { + ATBTariffOutOfService TariffOutOfService; + if (m->value.IsArray()) { + auto outOfService = m->value.GetArray(); + if (outOfService.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no out of service settings for" << weekDayName; + } else { + for (rapidjson::SizeType j = 0; j < outOfService.Size(); ++j) { + if (outOfService[j].IsObject()) { + auto outOfServiceSetting = outOfService[j].GetObject(); + for (auto n = outOfServiceSetting.MemberBegin(); n != outOfServiceSetting.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "out_of_service_ranges") { + if (n->value.IsArray()) { + auto outOfServiceRanges = n->value.GetArray(); + if (outOfServiceRanges.Size() == 0) { + qCritical() << __func__ << ":" << __LINE__ << "no out of service ranges for" << weekDayName; + } else { + QString outOfServiceStartStr; + QString outOfServiceEndStr; + QString outOfServiceIf; + int outOfServiceDuration = -1; + for (rapidjson::SizeType i = 0; i < outOfServiceRanges.Size(); ++i) { + if (outOfServiceRanges[j].IsObject()) { + auto outOfServiceRange = outOfServiceRanges[i].GetObject(); + for (auto r = outOfServiceRange.MemberBegin(); r != outOfServiceRange.MemberEnd(); ++r) { + QString const &memName = QString::fromStdString(r->name.GetString()); + if (memName == "out_of_service_id") { + if (r->value.IsInt()) { + TariffOutOfService.m_id = r->value.GetInt(); + } else { + qCritical() << __func__ << ":" << __LINE__ << "outOfServiceId not an integer"; + } + } else + if (memName == "out_of_service_duration") { + if (r->value.IsInt()) { + outOfServiceDuration = r->value.GetInt(); + } + } else + if (memName == "out_of_service_start") { + if (r->value.IsString()) { + outOfServiceStartStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "out_of_service_end") { + if (r->value.IsString()) { + outOfServiceEndStr = QString::fromStdString(r->value.GetString()); + } + } else + if (memName == "out_of_service_if") { + if (r->value.IsString()) { + outOfServiceIf = QString::fromStdString(r->value.GetString()); + } + } else { + qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown out of service setting" << memName; + } + } + } + + if (!outOfServiceStartStr.isEmpty() && !outOfServiceEndStr.isEmpty() && outOfServiceDuration != -1) { + ATBTime outOfServiceStart(outOfServiceStartStr); + ATBTime outOfServiceEnd(outOfServiceEndStr); + if (outOfServiceStart.isValid() && outOfServiceEnd.isValid()) { + TariffOutOfService.m_range = TimeRange(outOfServiceStart, outOfServiceEnd, outOfServiceDuration); + TariffOutOfService.m_weekDay = weekDayName; + if (!d.isNull() && d.isValid()) { + TariffOutOfService.m_date = d; + } + if (!outOfServiceIf.isEmpty()) { + TariffOutOfService.setOutOfServiceIf(outOfServiceIf); + } + + // qCritical() << TariffOutOfService; + + cfg.TariffOutOfServices.insert(std::pair(weekDay, TariffOutOfService)); + } + } + } + } + } + } else { + + } + } + } + } + } + } + } else { + + } + } + } + } else + if (innerObjName == QString("week_day_default")) { + if (k->value.IsObject()) { + auto obj = k->value.GetObject(); + for (auto m = obj.MemberBegin(); m != obj.MemberEnd(); ++m) { + QString const &name = m->name.GetString(); + if (name == "week_day_type") { + // + } else + if (name == "tariff_settings") { + if (m->value.IsObject()) { + auto obj = m->value.GetObject(); + for (auto n = obj.MemberBegin(); n != obj.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "min_time") { + if (n->value.IsInt()) { min_time = n->value.GetInt(); } + } else if (name == "max_time") { + if (n->value.IsInt()) { max_time = n->value.GetInt(); } + } else if (name == "min_price") { + if (n->value.IsInt()) { min_price = n->value.GetInt(); } + } else if (name == "max_price") { + if (n->value.IsInt()) { max_price = n->value.GetInt(); } + } + } + } + } else + if (name == "carry_over_settings") { + if (m->value.IsObject()) { + auto obj = m->value.GetObject(); + for (auto n = obj.MemberBegin(); n != obj.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "duration") { + if (n->value.IsInt()) { + duration = n->value.GetInt(); + } + } else + if (name == "start") { + if (n->value.IsString()) { + start = QTime::fromString(QString::fromStdString(n->value.GetString()), Qt::ISODate); + } + } else + if (name == "end") { + if (n->value.IsString()) { + end = QTime::fromString(QString::fromStdString(n->value.GetString()), Qt::ISODate); + } + } else + if (name == "parking_time_limit") { + if (n->value.IsObject()) { + auto o = n->value.GetObject(); + for (auto l = o.MemberBegin(); l != o.MemberEnd(); ++l) { + if (l->name.IsString()) { + QString const &member = QString::fromStdString(l->name.GetString()); + if (member == "prev_day_sunday?") { + if (l->value.IsArray()) { + auto limits = l->value.GetArray(); + if (limits.Size() >= 2) { + about_to_exceed_limit = QTime::fromString(QString::fromStdString(limits[0].GetString()), Qt::ISODate); + parking_time_limit = QTime::fromString(QString::fromStdString(limits[1].GetString()), Qt::ISODate); + } + parkTimeLimitChecker = [&cfg, weekDay, weekDayName](ATBTariffCarryOverSettings const& cs, + QDateTime const &startTime, + QDateTime const &endTime, + int paymentOptionIndex) { + if (startTime.date() < endTime.date()) { // start end end on different days + if (endTime.date().dayOfWeek() == (int)weekDay) { + if (endTime.time() > cs.m_parking_time_limit) { + qCritical() << __func__ << ":" << __LINE__ + << QString("ERROR time limit for end-time violated: [%1, %2 end-time=%3], but time-limit=%4") + .arg(weekDayName) + .arg(endTime.date().toString(Qt::ISODate)) + .arg(endTime.time().toString(Qt::ISODate)) + .arg(cs.m_parking_time_limit.toString(Qt::ISODate)); + return true; + } + if (endTime.time() >= cs.m_about_to_exceed_parking_time_limit) { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = 1; + } else { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps_saved; + } + } + } + return false; + }; + } + } else + if (member == "prev_day_holiday?") { + if (l->value.IsArray()) { + auto limits = l->value.GetArray(); + if (limits.Size() >= 2) { + about_to_exceed_limit = QTime::fromString(QString::fromStdString(limits[0].GetString()), Qt::ISODate); + parking_time_limit = QTime::fromString(QString::fromStdString(limits[1].GetString()), Qt::ISODate); + } + parkTimeLimitChecker = [&cfg, weekDayName](ATBTariffCarryOverSettings const& cs, + QDateTime const &startTime, + QDateTime const &endTime, + int paymentOptionIndex) { + if (startTime.date() < endTime.date()) { // start end end on different days + if (previousDayHoliday(cfg, endTime)) { + if (endTime.time() > cs.m_parking_time_limit) { + qCritical() << __func__ << ":" << __LINE__ + << QString("ERROR time limit for end-time violated: [%1, %2, end-time=%3], but time-limit=%4") + .arg(weekDayName) + .arg(endTime.date().toString(Qt::ISODate)) + .arg(endTime.time().toString(Qt::ISODate)) + .arg(cs.m_parking_time_limit.toString(Qt::ISODate)); + return true; + } + if (endTime.time() >= cs.m_about_to_exceed_parking_time_limit) { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = 1; + } else { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps_saved; + } + } + } + return false; + }; + } + } + } + } + } + } + } + } + } + } + ATBTariffSettings ts(max_price, min_price, max_time, min_time); + ATBTariffCarryOverSettings cs(duration, start, end, parking_time_limit, about_to_exceed_limit, + parkTimeLimitChecker); + WeekDay = ATBWeekDay(weekDay, weekDayName, ATBWeekDay::USUAL_WEEKDAY, QDate(), ts, cs); + + } // if (k->value.IsObject()) { + } else { + QDate date(QDate::fromString(innerObjName, Qt::ISODate)); + if (date.isValid()) { + if (k->value.IsObject()) { + auto obj = k->value.GetObject(); + for (auto m = obj.MemberBegin(); m != obj.MemberEnd(); ++m) { + QString const &name = m->name.GetString(); + if (name == "week_day_type") { + // TODO + } else + if (name == "tariff_settings") { + if (m->value.IsObject()) { + auto obj = m->value.GetObject(); + for (auto n = obj.MemberBegin(); n != obj.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "min_time") { + if (n->value.IsInt()) { min_time = n->value.GetInt(); } + } else if (name == "max_time") { + if (n->value.IsInt()) { max_time = n->value.GetInt(); } + } else if (name == "min_price") { + if (n->value.IsInt()) { min_price = n->value.GetInt(); } + } else if (name == "max_price") { + if (n->value.IsInt()) { max_price = n->value.GetInt(); } + } + } + } + } else + if (name == "carry_over_settings") { + if (m->value.IsObject()) { + auto obj = m->value.GetObject(); + for (auto n = obj.MemberBegin(); n != obj.MemberEnd(); ++n) { + QString const &name = QString::fromStdString(n->name.GetString()); + if (name == "duration") { + if (n->value.IsInt()) { + duration = n->value.GetInt(); + } + } else + if (name == "start") { + if (n->value.IsString()) { + start = QTime::fromString(QString::fromStdString(n->value.GetString()), Qt::ISODate); + } + } else + if (name == "end") { + if (n->value.IsString()) { + end = QTime::fromString(QString::fromStdString(n->value.GetString()), Qt::ISODate); + } + } else + if (name == "parking_time_limit") { + if (n->value.IsObject()) { + auto o = n->value.GetObject(); + for (auto l = o.MemberBegin(); l != o.MemberEnd(); ++l) { + if (l->name.IsString()) { + QString const &member = QString::fromStdString(l->name.GetString()); + if (member == "default") { + if (l->value.IsArray()) { + auto limits = l->value.GetArray(); + if (limits.Size() >= 2) { + about_to_exceed_limit = QTime::fromString(QString::fromStdString(limits[0].GetString()), Qt::ISODate); + parking_time_limit = QTime::fromString(QString::fromStdString(limits[1].GetString()), Qt::ISODate); + } + } + + parkTimeLimitChecker = [&cfg, weekDay](ATBTariffCarryOverSettings const& cs, + QDateTime const &startTime, + QDateTime const &endTime, + int paymentOptionIndex) { + if (startTime.date() < endTime.date()) { // start end end on different days + if (endTime.date().dayOfWeek() == (int)weekDay) { + if (endTime.time() > cs.m_parking_time_limit) { + qCritical() << __func__ << ":" << __LINE__ + << QString("ERROR time limit for end-time violated: end-time=%1, but time-limit=%2") + .arg(endTime.time().toString(Qt::ISODate)) + .arg(cs.m_parking_time_limit.toString(Qt::ISODate)); + return true; + } + if (endTime.time() >= cs.m_about_to_exceed_parking_time_limit) { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = 1; + } else { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps_saved; + } + } + } + return false; + }; + } else + if (member == "prev_day_holiday?") { + if (l->value.IsArray()) { + auto limits = l->value.GetArray(); + if (limits.Size() >= 2) { + about_to_exceed_limit = QTime::fromString(QString::fromStdString(limits[0].GetString()), Qt::ISODate); + parking_time_limit = QTime::fromString(QString::fromStdString(limits[1].GetString()), Qt::ISODate); + } + } + parkTimeLimitChecker = [&cfg](ATBTariffCarryOverSettings const& cs, + QDateTime const &startTime, + QDateTime const &endTime, + int paymentOptionIndex) { + if (startTime.date() < endTime.date()) { // start end end on different days + if (previousDayHoliday(cfg, endTime)) { + if (endTime.time() > cs.m_parking_time_limit) { + qCritical() << __func__ << ":" << __LINE__ + << QString("ERROR time limit for end-time violated: end-time=%1, but time-limit=%2") + .arg(endTime.time().toString(Qt::ISODate)) + .arg(cs.m_parking_time_limit.toString(Qt::ISODate)); + return true; + } + if (endTime.time() >= cs.m_about_to_exceed_parking_time_limit) { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = 1; + } else { + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps = + cfg.getPaymentOptions(paymentOptionIndex).pop_plus_steps_saved; + } + } + } + return false; + }; + } + } + } + } + } + } + } + } + } + ATBTariffSettings ts(max_price, min_price, max_time, min_time); + ATBTariffCarryOverSettings cs(duration, start, end, parking_time_limit, + about_to_exceed_limit, parkTimeLimitChecker); + WeekDay = ATBWeekDay(weekDay, weekDayName, ATBWeekDay::HOLIDAY, date, ts, cs); + + } else {// if (k->value.IsObject()) { + qCritical() << __func__ << ":" << __LINE__ << "ERROR: no object"; + } + + } else { + qCritical() << __func__ << __LINE__ + << "ERROR: invalid date for" << weekDayName << "," << innerObjName; + } + } + + return WeekDay; +} + +/// +bool Configuration::ParseJson(Configuration* cfg, const char* json) +{ + try + { + if (cfg == nullptr) + { + printf("TariffConfiguration pointer not set\n"); + return false; + } + if (json == NULL) + { + printf("%s", "Input JSON string is NULL\n"); + return false; + } + + // Parse JSON to document + Document document; + document.Parse(json); + + // Return if parse error has been found + ParseErrorCode err = document.GetParseError(); + if (err != 0) + { + printf("%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err)); + return false; + } + + // Validate JSON, check if it's a JSON object + qCritical() << "JSON parsing has been successful"; + if (!document.IsObject()) { + printf("%s", "Error: not a (valid) JSON object\n"); + return false; + } + qCritical() << "Valid JSON object identified"; + + // Validate JSON, check configuration members + if (!document.HasMember("Currency") + || !document.HasMember("PaymentMethod") + || !document.HasMember("PaymentOption") + || !document.HasMember("PaymentRate") + || !document.HasMember("Duration") + //|| !document.HasMember("WeekDays") + //|| !document.HasMember("SpecialDaysWorktime") + //|| !document.HasMember("SpecialDays") + ) + { + printf("%s", "Error: not a valid configuration JSON\n"); + return false; + } + qCritical() << "Valid JSON configuration identified"; + + ATBCurrency Currency; + ATBDuration Duration; + ATBPaymentMethod PaymentMethod; + ATBPaymentRate PaymentRate; + ATBSpecialDaysWorktime SpecialDaysWorktime; + ATBSpecialDays SpecialDays; + //ATBWeekDay WeekDay; + ATBWeekDaysWorktime WeekDaysWorktime; + ATBPeriodYear YearPeriod; + ATBDailyTicket DailyTicket; + ATBTimeBase TimeBase; + ATBCustomer Customer; + ATBTimeRange TimeRange; + ATBTimeStepConfig TimeStepConfig; + ATBTariffProduct TariffProduct; + ATBInterpolation TariffInterpolation; + ATBPrepaid TariffPrepaidOption; + ATBCarryOver TariffCarryOver; + + MemberType mb_type = MemberType::UnknownType; + this->currentPaymentOptions.clear(); + + // Get all JSON object members + // This code should run only once (to load JSON variables into memory) + for (auto i = document.MemberBegin(); i != document.MemberEnd(); i++) + { + // Get name of all general members of JSON, don't print name if NULL + const char* mb_name = i->name.GetString(); + if (mb_name == NULL) continue; + + if (document[mb_name].IsString()) { + QString const _mb_name(mb_name); + if (_mb_name.startsWith("Project", Qt::CaseInsensitive)) { + cfg->project.project = document[mb_name].GetString(); + continue; + } + if (_mb_name.startsWith("Version", Qt::CaseInsensitive)) { + cfg->project.version = document[mb_name].GetString(); + continue; + } + if (_mb_name.startsWith("Info", Qt::CaseInsensitive)) { + cfg->project.info = document[mb_name].GetString(); + continue; + } + } + + // ... everything else should be an array + if (!document[mb_name].IsArray()) { + continue; + } + + qCritical() << " -" << mb_name; + + // Get array for each JSON object member + auto mb_array = document[mb_name].GetArray(); + if (mb_array.Size() <= 0) break; + + //Iterate over provided array + for (rapidjson::SizeType j = 0; j < mb_array.Size(); j++) { + // Get all inner objects, don't print name if NULL + auto inner_obj = mb_array[j].GetObject(); + if (inner_obj.MemberCount() <= 0) break; + + // Iterate over inner object JSON members + for (auto k = inner_obj.MemberBegin(); k != inner_obj.MemberEnd(); k++) + { + // Get inner object JSON member, don't print name if NULL + const char* inner_obj_name = k->name.GetString(); + if (inner_obj_name == NULL) + { + printf("Inner object name is NULL\n"); + continue; + } + + // Identify member type + mb_type = IdentifyJsonMember(mb_name); + + switch (mb_type) + { + case MemberType::UnknownType: + break; + case MemberType::WeekDaysType: { + ATBWeekDay WeekDay; + if (QString(mb_name) == "Monday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Monday, mb_name); + } else + if (QString(mb_name) == "Tuesday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Tuesday, mb_name); + } else + if (QString(mb_name) == "Wednesday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Wednesday, mb_name); + } else + if (QString(mb_name) == "Thursday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Thursday, mb_name); + } else + if (QString(mb_name) == "Friday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Friday, mb_name); + } else + if (QString(mb_name) == "Saturday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Saturday, mb_name); + } else + if (QString(mb_name) == "Sunday") { + WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Sunday, mb_name); + } else { + qCritical() << "ERROR: unknown week day" << mb_name; + } + + cfg->WeekDays.insert(pair(WeekDay.m_id, WeekDay)); + // qCritical() << WeekDay; + + } break; + case MemberType::CarryOverType: { + if (QString(inner_obj_name) == QString("carry_over_id")) { + if (k->value.IsInt()) { + int const &x = k->value.GetInt(); + TariffCarryOver.id = x; + } + } else + if (QString(inner_obj_name) == QString("carry_over_week")) { + if (k->value.IsArray()) { + auto days = k->value.GetArray(); + for (rapidjson::SizeType j=0; j < days.Size(); ++j) { + if (days[j].IsObject()) { + auto weekday = days[j].GetObject(); + for (auto w = weekday.MemberBegin(); w != weekday.MemberEnd(); ++w) { + int day = j+1; // 8 entries + QString member(QString::fromStdString(w->name.GetString())); + if (member == "carry_over_day") { + if (w->value.IsInt()) { + rapidjson::SizeType const d = w->value.GetInt(); + if (d != (j+1)) { + qCritical() << "ERROR: misconfigured jsonfile" << d << "!=" << (j+1); + } + TariffCarryOver.carryover[day].day = day; + } + } else + if (member == "carry_over_duration") { + if (w->value.IsInt()) { + TariffCarryOver.carryover[day].duration = w->value.GetInt(); + } + } else + if (member == "carry_over_seemless") { + if (w->value.IsBool()) { + bool b = w->value.GetBool(); + TariffCarryOver.carryover[day].seemless = b; + } + } else + if (member == "carry_over_never") { + if (w->value.IsBool()) { + bool b = w->value.GetBool(); + TariffCarryOver.carryover[day].never = b; + } + } else + if (member == "carry_over_static_start") { + if (w->value.IsString()) { + QTime const &t = QTime::fromString(w->value.GetString(), Qt::ISODate); + TariffCarryOver.carryover[day].static_start = t; + } + } else + if (member == "carry_over_static_end") { + if (w->value.IsString()) { + QTime const &t = QTime::fromString(w->value.GetString(), Qt::ISODate); + TariffCarryOver.carryover[day].static_end = t; + } + } + } + } + } + } + } + } break; + case MemberType::PrepaidType: { + if (QString(inner_obj_name) == QString("prepaid_id")) { + if (k->value.IsInt()) { + int const &x = k->value.GetInt(); + TariffPrepaidOption.id = x; + } + } else + if (QString(inner_obj_name) == QString("prepaid_anytime")) { + if (k->value.IsBool()) { + bool const &x = k->value.GetBool(); + TariffPrepaidOption.anytime = x; + } + } else + if (QString(inner_obj_name) == QString("prepaid_never")) { + if (k->value.IsBool()) { + bool const &x = k->value.GetBool(); + TariffPrepaidOption.never = x; + } + } else + if (QString(inner_obj_name) == QString("prepaid_static_start")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffPrepaidOption.static_start = t; + } + } else + if (QString(inner_obj_name) == QString("prepaid_static_end")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffPrepaidOption.static_end = t; + } + } else + if (QString(inner_obj_name) == QString("prepaid_week")) { + if (k->value.IsArray()) { + auto days = k->value.GetArray(); + for (rapidjson::SizeType j=0; j < days.Size(); ++j) { + if (days[j].IsObject()) { + auto weekday = days[j].GetObject(); + for (auto w = weekday.MemberBegin(); w != weekday.MemberEnd(); ++w) { + int day = j+1; // 8 entries + + TariffPrepaidOption.prepaid[day].day = 0; + + QString member(QString::fromStdString(w->name.GetString())); + if (member == "prepaid_day") { + if (w->value.IsInt()) { + rapidjson::SizeType const d = w->value.GetInt(); + if (d != (j+1)) { + qCritical() << "ERROR: misconfigured jsonfile" << d << "!=" << (j+1); + } + TariffPrepaidOption.prepaid[day].day = day; + } + } else + if (member == "prepaid_duration") { + if (w->value.IsInt()) { + TariffPrepaidOption.prepaid[day].duration = w->value.GetInt(); + } + } else + if (member == "prepaid_static_start") { + if (w->value.IsString()) { + QTime const &t = QTime::fromString(w->value.GetString(), Qt::ISODate); + TariffPrepaidOption.prepaid[day].static_start = t; + } + } else + if (member == "prepaid_static_end") { + if (w->value.IsString()) { + QTime const &t = QTime::fromString(w->value.GetString(), Qt::ISODate); + TariffPrepaidOption.prepaid[day].static_end = t; + } + } + } + } + } + } + } + } break; + case MemberType::InterpolationType: { + if (QString(inner_obj_name) == QString("interpol_id")) { + if (k->value.IsInt()) { + int const &x = k->value.GetInt(); + TariffInterpolation.id = x; + } + } else + if (QString(inner_obj_name) == QString("interpol_static_start")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffInterpolation.static_start = t; + } + } else + if (QString(inner_obj_name) == QString("interpol_static_end")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffInterpolation.static_end = t; + } + } else + if (QString(inner_obj_name) == QString("interpol_static_start_str")) { + if (k->value.IsString()) { + QString const &s = k->value.GetString(); + TariffInterpolation.static_start_str = s; + } + } else + if (QString(inner_obj_name) == QString("interpol_static_end_str")) { + if (k->value.IsString()) { + QString const &s = k->value.GetString(); + TariffInterpolation.static_end_str = s; + } + } else + if (QString(inner_obj_name) == QString("interpol_static_duration")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffInterpolation.static_duration = x; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_start")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffInterpolation.dynamic_start = t; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_end")) { + if (k->value.IsString()) { + QTime const &t = QTime::fromString(k->value.GetString(), Qt::ISODate); + TariffInterpolation.dynamic_end = t; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_start_str")) { + if (k->value.IsString()) { + QString const &s = k->value.GetString(); + TariffInterpolation.dynamic_start_str = s; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_end_str")) { + if (k->value.IsString()) { + QString const &s = k->value.GetString(); + TariffInterpolation.dynamic_end_str = s; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_duration")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffInterpolation.dynamic_duration = x; + } + } else + if (QString(inner_obj_name) == QString("interpol_dynamic_until_price")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffInterpolation.dynamic_until_price = x; + } + } else + if (QString(inner_obj_name) == QString("interpol_seemless")) { + if (k->value.IsBool()) { + bool const x = k->value.GetBool(); + TariffInterpolation.seemless = x; + } + } + if (QString(inner_obj_name) == QString("interpol_never")) { + if (k->value.IsBool()) { + bool const x = k->value.GetBool(); + TariffInterpolation.never = x; + } + } + } break; + case MemberType::ProductType: { + if (QString(inner_obj_name) == QString("tariff_product_id")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_id = PermitType(x); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_price")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_price = x; + } + } else + if (QString(inner_obj_name) == QString("tariff_product_name")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_name = QString::fromStdString(s); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_start")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_start = QTime::fromString(QString::fromStdString(s), Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_end")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_end = QTime::fromString(QString::fromStdString(s), Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_from_in_minutes_from_start")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_from_in_minutes_from_start = x; + } + } else + if (QString(inner_obj_name) == QString("tariff_product_to_in_minutes_from_start")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_to_in_minutes_from_start = x; + } + } + } break; + case MemberType::TimeRangeType: + if (QString(inner_obj_name) == QString("time_range_id")) { + if (k->value.IsInt()) { + TimeRange.time_range_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("time_range_from")) { + if (k->value.IsString()) { + QTime timeRangeFrom = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); + TimeRange.time_range_from = timeRangeFrom; + } else + if (k->value.IsInt()) { + int timeRangeFrom = k->value.GetInt(); + TimeRange.time_range_from_in_minutes_from_start = timeRangeFrom; + } + } else + if (QString(inner_obj_name) == QString("time_range_to")) { + if (k->value.IsString()) { + QTime timeRangeTo = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); + TimeRange.time_range_to = timeRangeTo; + } else + if (k->value.IsInt()) { + int timeRangeTo = k->value.GetInt(); + TimeRange.time_range_to_in_minutes_from_start = timeRangeTo; + } + } else + if (QString(inner_obj_name) == QString("time_range_tbase_id")) { + if (k->value.IsInt()) { + int tbase = k->value.GetInt(); + TimeRange.time_range_tbase_id = tbase; + } + } else + if (QString(inner_obj_name) == QString("time_range_payment_rate_id")) { + if (k->value.IsInt()) { + int ptype = k->value.GetInt(); + TimeRange.time_range_payment_type_id = ptype; + } + } + break; + case MemberType::TimeBaseType: + if (QString(inner_obj_name) == QString("tbase_id")) { + if (k->value.IsInt()) { + TimeBase.tbase_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("tbase_type")) { + if (k->value.IsInt()) { + int timeBase = k->value.GetInt(); + switch (timeBase) { + case (int)ATBTimeBase::TimeBaseType::ABSOLUTE: + TimeBase.tbase_type = ATBTimeBase::TimeBaseType::ABSOLUTE; + break; + case (int)ATBTimeBase::TimeBaseType::RELATIVE: + TimeBase.tbase_type = ATBTimeBase::TimeBaseType::RELATIVE; + break; + } + } + } + break; + case MemberType::TimeStepConfigType: + if (QString(inner_obj_name) == QString("tsconfig_id")) { + if (k->value.IsInt()) { + TimeStepConfig.tsconfig_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("tsconfig_label")) { + if (k->value.IsString()) { + TimeStepConfig.tsconfig_label = QString::fromStdString(k->value.GetString()); + } + } + break; + case MemberType::DailyTicketType: + if (QString(inner_obj_name) == QString("daily_ticket_payment_option_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_payment_option_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_price_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_price_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_tb_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_tb_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_clearance_customer_ids")) { + if (k->value.IsArray()) { + auto customerIds = k->value.GetArray(); + for (rapidjson::SizeType i=0; i < customerIds.Size(); ++i) { + if (customerIds[i].IsInt()) { + DailyTicket.daily_ticket_clearance_customer_ids.append(customerIds[i].GetInt()); + } + } + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_from_min")) { + if (k->value.IsString()) { + std::string const from_min = k->value.GetString(); + char const *from_min_c_str = from_min.c_str(); // for debugging + DailyTicket.daily_ticket_from_min = QTime::fromString(from_min_c_str, Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_to_max")) { + if (k->value.IsString()) { + std::string const to_max = k->value.GetString(); + char const *to_max_c_str = to_max.c_str(); + DailyTicket.daily_ticket_to_max = QTime::fromString(to_max_c_str, Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_from_offset_min")) { + if (k->value.IsInt()) { + int const from_offset_min = k->value.GetInt(); + DailyTicket.daily_ticket_from_offset_min = from_offset_min; + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_to_offset_max")) { + if (k->value.IsInt()) { + int to_offset_max = k->value.GetInt(); + DailyTicket.daily_ticket_to_offset_max = to_offset_max; + } + } + break; + case MemberType::CustomerType: + if (QString(inner_obj_name) == QString("cust_id")) { + if (k->value.IsInt()) { + Customer.cust_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("cust_type")) { + if (k->value.IsInt()) { + int cust_type = k->value.GetInt(); + switch (cust_type) { + case (int)ATBCustomer::CustomerType::ADULT: + Customer.cust_type = ATBCustomer::CustomerType::ADULT; + break; + case (int)ATBCustomer::CustomerType::CHILD: + Customer.cust_type = ATBCustomer::CustomerType::CHILD; + break; + case (int)ATBCustomer::CustomerType::TEEN: + Customer.cust_type = ATBCustomer::CustomerType::TEEN; + break; + } + } + } else + if (QString(inner_obj_name) == QString("cust_label")) { + if (k->value.IsString()) { + QString label(QString::fromStdString(k->value.GetString())); + if (label.contains("ADULT", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } else + if (label.contains("CHILD", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } else + if (label.contains("TEEN", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } + } + } + break; + case MemberType::CurrencyType: + if (strcmp(inner_obj_name, "pcu_id") == 0) Currency.pcu_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pcu_sign") == 0) Currency.pcu_sign = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_major") == 0) Currency.pcu_major = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool(); + break; + case MemberType::PaymentMethodType: + if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString(); + break; + case MemberType::PaymentRateType: + if (strcmp(inner_obj_name, "pra_payment_option_id") == 0) PaymentRate.pra_payment_option_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pra_payment_unit_id") == 0) PaymentRate.pra_payment_unit_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pra_price") == 0) PaymentRate.pra_price = k->value.GetDouble(); + break; + case MemberType::PaymentOptionType: + if (strcmp(inner_obj_name, "pop_id") == 0) { + this->currentPaymentOptions.append(ATBPaymentOption()); + this->currentPaymentOptions.last().reset(); + this->currentPaymentOptions.last().pop_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_label") == 0) { + this->currentPaymentOptions.last().pop_label = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_product_id") == 0) { + this->currentPaymentOptions.last().pop_product_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_product_name") == 0) { + if (k->value.IsString()) { + QString const &s = QString::fromStdString(k->value.GetString()); + this->currentPaymentOptions.last().pop_product_name = s; + } + } else if (strcmp(inner_obj_name, "pop_use_only_upto_datetime") == 0) { + if (k->value.IsString()) { + QString const &s = QString::fromStdString(k->value.GetString()); + this->currentPaymentOptions.last().pop_use_only_upto_datetime = s; + } + } else if (strcmp(inner_obj_name, "pop_use_only_for_duration") == 0) { + if (k->value.IsInt()) { + this->currentPaymentOptions.last().pop_use_only_for_duration = k->value.GetInt(); + } + } else if (strcmp(inner_obj_name, "pop_plus_steps") == 0) { + if (k->value.IsInt()) { + this->currentPaymentOptions.last().pop_plus_steps = k->value.GetInt(); + this->currentPaymentOptions.last().pop_plus_steps_saved = k->value.GetInt(); + } + } else if (strcmp(inner_obj_name, "pop_minus_steps") == 0) { + if (k->value.IsInt()) { + this->currentPaymentOptions.last().pop_minus_steps = k->value.GetInt(); + } + } else if (strcmp(inner_obj_name, "pop_allow_overpay") == 0) { + if (k->value.IsBool()) { + this->currentPaymentOptions.last().pop_allow_overpay = k->value.GetBool(); + } + } else if (strcmp(inner_obj_name, "pop_apply_carry_over_to_ticket_endtime") == 0) { + if (k->value.IsBool()) { + this->currentPaymentOptions.last().pop_apply_carry_over_to_ticket_endtime = k->value.GetBool(); + } + } else if (strcmp(inner_obj_name, "pop_payment_method_id") == 0) { + this->currentPaymentOptions.last().pop_payment_method_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_day_end_time") == 0) { + this->currentPaymentOptions.last().pop_day_end_time = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_day_night_end_time") == 0) { + this->currentPaymentOptions.last().pop_day_night_end_time = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_price_night") == 0) { + this->currentPaymentOptions.last().pop_price_night = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_min_time") == 0) { + this->currentPaymentOptions.last().pop_min_time = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_max_price") == 0) { + this->currentPaymentOptions.last().pop_max_price = k->value.GetDouble(); + this->currentPaymentOptions.last().pop_max_price_save = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_max_time") == 0) { + this->currentPaymentOptions.last().pop_max_time = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_min_price") == 0) { + this->currentPaymentOptions.last().pop_min_price = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_prepaid_option_id") == 0) { + this->currentPaymentOptions.last().pop_prepaid_option_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_truncate_last_interpolation_step") == 0) { + this->currentPaymentOptions.last().pop_truncate_last_interpolation_step = k->value.GetBool(); + } else if (strcmp(inner_obj_name, "pop_accumulate_prices") == 0) { + this->currentPaymentOptions.last().pop_accumulate_prices = k->value.GetBool(); + } else if (strcmp(inner_obj_name, "pop_accumulate_durations") == 0) { + this->currentPaymentOptions.last().pop_accumulate_durations = k->value.GetBool(); + } else if (strcmp(inner_obj_name, "pop_carry_over_option_id") == 0) { + this->currentPaymentOptions.last().pop_carry_over_option_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over") == 0) { + this->currentPaymentOptions.last().pop_carry_over = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_time_range_id") == 0) { + this->currentPaymentOptions.last().pop_carry_over_time_range_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_start_time_range") == 0) { + this->currentPaymentOptions.last().pop_carry_over_start_time_range = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_end_time_range") == 0) { + this->currentPaymentOptions.last().pop_carry_over_end_time_range = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) { + this->currentPaymentOptions.last().pop_daily_card_price = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_business_hours") == 0) { + if (k->value.IsInt()) { + int const v = k->value.GetInt(); + this->currentPaymentOptions.last().pop_business_hours = v; + } else + if (k->value.IsString()) { + bool ok; + uint64_t const v = QString::fromStdString(k->value.GetString()).toLongLong(&ok); + if (ok) { + this->currentPaymentOptions.last().pop_business_hours = v; + } + } + } else if (strcmp(inner_obj_name, "pop_time_step_config") == 0) { + this->currentPaymentOptions.last().pop_time_step_config = k->value.GetInt(); + } else if ((strcmp(inner_obj_name, "pop_min_date_time") == 0) + || (strcmp(inner_obj_name, "pop_max_date_time") == 0)) { + if (k->value.IsString()) { // -w0dFriT16:20:00 or +w0dMonT00:00:00 + static const QRegularExpression re(R"(([+-])w([0-9]+)d([A-Za-z]{3})T([0-9]{2}:[0-9]{2}:[0-9]{2}))"); + QString const &s = QString::fromStdString(k->value.GetString()); + QRegularExpressionMatch match = re.match(s); + if (match.hasMatch()) { + ATBPaymentOption::ATBMaxDateTime dt; + int lastCaptured = match.lastCapturedIndex(); + if (lastCaptured == 4) { + dt.direction = (match.captured(1) == "-") ? -1 : +1; + + bool ok; + uint8_t week = match.captured(2).toUInt(&ok); + if (ok) { + dt.week = week; + } + + QString const &day = match.captured(3); + if (day.compare("Mon", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Monday; + } else if (day.compare("Tue", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Tuesday; + } else if (day.compare("Wed", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Wednesday; + } else if (day.compare("Thu", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Thursday; + } else if (day.compare("Fri", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Friday; + } else if (day.compare("Sat", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Saturday; + } else if (day.compare("Sun", Qt::CaseInsensitive) == 0) { + dt.day = (int)Qt::Sunday; + } + + QTime t = QTime::fromString(match.captured(4), Qt::ISODate); + if (t.isValid()) { + dt.time = t; + } + } + + if (strcmp(inner_obj_name, "pop_min_date_time") == 0) { + this->currentPaymentOptions.last().pop_min_date_time = dt; + } else + if (strcmp(inner_obj_name, "pop_max_date_time") == 0) { + this->currentPaymentOptions.last().pop_max_date_time = dt; + } + } + } + } else if (strcmp(inner_obj_name, "pop_carry_over_target") == 0) { + if (k->value.IsBool()) { + bool const v = k->value.GetBool(); + this->currentPaymentOptions.last().pop_carry_over_target = v; + } + } + break; + case MemberType::DurationType: + if (strcmp(inner_obj_name, "pun_id") == 0) Duration.pun_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pun_label") == 0) Duration.pun_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "pun_duration") == 0) { + Duration.pun_duration = k->value.GetDouble(); + Duration.pun_duration_saved = Duration.pun_duration; + } else if (strcmp(inner_obj_name, "pun_duration_min") == 0) Duration.pun_duration_min = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pun_duration_max") == 0) Duration.pun_duration_max = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pun_interpolation_id") == 0) Duration.pun_interpolation_id = k->value.GetInt(); + break; + case MemberType::SpecialDaysWorktimeType: + if (strcmp(inner_obj_name, "pedwt_id") == 0) SpecialDaysWorktime.pedwt_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pedwt_period_exc_day_id") == 0) SpecialDaysWorktime.pedwt_period_exc_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pedwt_time_from") == 0) SpecialDaysWorktime.pedwt_time_from = k->value.GetString(); + else if (strcmp(inner_obj_name, "pedwt_time_to") == 0) SpecialDaysWorktime.pedwt_time_to = k->value.GetString(); + else if (strcmp(inner_obj_name, "pedwt_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble(); + else if (strcmp(inner_obj_name, "pedwt_paid") == 0) SpecialDaysWorktime.pedwt_paid = k->value.GetInt(); + break; + /*case MemberType::WeekDaysType: + if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pdiw_label") == 0) WeekDays.pdiw_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "pdiw_index") == 0) WeekDays.pdiw_index = k->value.GetInt(); + break;*/ + case MemberType::WeekDaysWorkTimeType: + if (strcmp(inner_obj_name, "pwd_id") == 0) WeekDaysWorktime.pwd_id = k->value.GetInt(); + if (strcmp(inner_obj_name, "pwd_pop_id") == 0) WeekDaysWorktime.pwd_pop_id = k->value.GetInt(); + if (strcmp(inner_obj_name, "pwd_next_id") == 0) WeekDaysWorktime.pwd_next_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_period_week_day_id") == 0) WeekDaysWorktime.pwd_period_week_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_period_day_in_week_id") == 0) WeekDaysWorktime.pwd_period_day_in_week_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_time_from") == 0) WeekDaysWorktime.pwd_time_from = k->value.GetString(); + else if (strcmp(inner_obj_name, "pwd_time_to") == 0) WeekDaysWorktime.pwd_time_to = k->value.GetString(); + break; + case MemberType::SpecialDaysType: + if (strcmp(inner_obj_name, "ped_id") == 0) SpecialDays.ped_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_label") == 0) SpecialDays.ped_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_date_start") == 0) SpecialDays.ped_date_start = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_date_end") == 0) SpecialDays.ped_date_end = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_period_special_day_id") == 0) SpecialDays.ped_period_special_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_payment_option_id") == 0) SpecialDays.ped_payment_option_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_year") == 0) SpecialDays.ped_year = k->value.GetInt(); + break; + case MemberType::PeriodYearType: + if (strcmp(inner_obj_name, "pye_id") == 0) YearPeriod.pye_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_label") == 0) YearPeriod.pye_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "pye_start_month") == 0) YearPeriod.pye_start_month = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_start_day") == 0) YearPeriod.pye_start_day = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_end_month") == 0) YearPeriod.pye_end_month = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_end_day") == 0) YearPeriod.pye_end_day = k->value.GetInt(); + break; + default: + break; + } +//#pragma endregion + } + + // Push to specific list depending on member type + switch (mb_type) { + case MemberType::UnknownType: + break; + case MemberType::WeekDaysType: + // qCritical() << "INSERT" << (int)WeekDay.m_id << WeekDay.m_date.toString(Qt::ISODate); + // cfg->WeekDays.insert(pair(WeekDay.m_id, WeekDay)); + // qCritical() << WeekDay; + break; + case MemberType::PaymentMethodType: + cfg->PaymentMethod.insert(pair(PaymentMethod.pme_id, PaymentMethod)); + break; + case MemberType::PaymentRateType: + // qCritical() << "PaymentRate" << PaymentRate.pra_price << PaymentRate.pra_payment_option_id; + cfg->PaymentRate.insert(pair(PaymentRate.pra_payment_option_id, PaymentRate)); + break; + case MemberType::PaymentOptionType: { + if (!this->currentPaymentOptions.isEmpty()) { + ATBPaymentOption const &PaymentOption = this->currentPaymentOptions.last(); + cfg->PaymentOption.insert(pair(PaymentOption.pop_payment_method_id, PaymentOption)); + } + } break; + case MemberType::DurationType: + cfg->Duration.insert(pair(Duration.pun_id, Duration)); + // qCritical() << Duration; + break; + case MemberType::SpecialDaysWorktimeType: + cfg->SpecialDaysWorktime.insert(pair(SpecialDaysWorktime.pedwt_period_exc_day_id, SpecialDaysWorktime)); + break; + //case MemberType::WeekDaysType: + // cfg->WeekDays.insert(pair(WeekDays.pdiw_index, WeekDays)); + // break; + case MemberType::WeekDaysWorkTimeType: + cfg->WeekDaysWorktime.insert(pair(WeekDaysWorktime.pwd_period_day_in_week_id, WeekDaysWorktime)); + break; + case MemberType::SpecialDaysType: + cfg->SpecialDays.insert(pair(SpecialDays.ped_id, SpecialDays)); + break; + case MemberType::PeriodYearType: + cfg->YearPeriod.insert(pair(YearPeriod.pye_id, YearPeriod)); + break; + case MemberType::DailyTicketType: + cfg->DailyTicket.insert(pair(DailyTicket.daily_ticket_id, DailyTicket)); + // qCritical() << DailyTicket; + DailyTicket.reset(); + break; + case MemberType::CustomerType: + cfg->Customer.insert(pair(Customer.cust_id, Customer)); + // qCritical() << Customer; + break; + case MemberType::TimeBaseType: + cfg->TimeBase.insert(pair(TimeBase.tbase_id, TimeBase)); + // qCritical() << TimeBase; + break; + case MemberType::TimeRangeType: + cfg->TimeRange.insert(pair(TimeRange.time_range_id, TimeRange)); + //qCritical() << TimeRange; + break; + case MemberType::TimeStepConfigType: + cfg->TimeStepConfig.insert(pair(TimeStepConfig.tsconfig_id, TimeStepConfig)); + // qCritical() << TimeStepConfig; + break; + case MemberType::ProductType: + cfg->TariffProduct.insert(pair(TariffProduct.m_tariff_product_id, TariffProduct)); + // qCritical() << TariffProduct; + break; + case MemberType::InterpolationType: + cfg->TariffInterpolations.insert(pair(TariffInterpolation.id, TariffInterpolation)); + // qCritical() << TariffInterpolation; + break; + case MemberType::PrepaidType: + cfg->TariffPrepaidOptions.insert(pair(TariffPrepaidOption.id, TariffPrepaidOption)); + // qCritical() << TariffPrepaidOption; + break; + case MemberType::CarryOverType: + cfg->TariffCarryOverOptions.insert(pair(TariffCarryOver.id, TariffCarryOver)); + // qCritical() << TariffCarryOver; + break; + default: + break; + } + } + } + return true; + } + catch (...) { + printf("%s\n", "General exception has occurred while parsing JSON\n"); + return false; + } +} + +std::optional Configuration::getInterpolationEnd(QDateTime const &start, int paymentOptionIndex) const { + int const pop_id = getPaymentOptions(paymentOptionIndex).pop_id; + int const pop_carry_over_option_id = getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id; + int const pop_truncate_last_interpolation_step = getPaymentOptions(paymentOptionIndex).pop_truncate_last_interpolation_step; + int const weekDay = start.date().dayOfWeek(); + //QTime const &carryOverStart = TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start; + //QTime const &carryOverEnd = TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_end; + //bool const carry_over_seemless = TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].seemless; + //bool const carry_over_never = TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].never; + int const carryOverDuration = TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration; + + std::optional value = std::nullopt; + + QDateTime interpolationEndTime = start; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") computed interpol end:" << interpolationEndTime.toString(Qt::ISODate); + + int price = 0; + + for (auto[itr, rangeEnd] = PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { + int const durationId = itr->second.pra_payment_unit_id; + // int const price = itr->second.pra_price; + + auto search = Duration.find(durationId); + if (search != Duration.end()) { + ATBDuration duration = search->second; + + if (duration.pun_interpolation_id == -1) { + // should never happen -> misconfigured tariff-file + qCritical() << "(" << __func__ << ":" << __LINE__ << ") ERROR pun_interpolation not set!"; + qCritical() << "(" << __func__ << ":" << __LINE__ << ") See for instance customer_505/6"; + break; + } + + std::optional ipolCheck = getInterpolationType(duration.pun_interpolation_id); + if (ipolCheck) { + ATBInterpolation interpolation = ipolCheck.value(); + switch (duration.pun_interpolation_id) { + case static_cast(ATBInterpolation::NO_INTERPOLATION): + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") NO_INTERPOLATION"; + break; + case static_cast(ATBInterpolation::STATIC_WALLCLOCK_TIME_VALUES): + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + break; + case static_cast(ATBInterpolation::STATIC_TIMEPOINT_AND_DURATION): + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + break; + case static_cast(ATBInterpolation::DYNAMIC_TIMEPOINT_AND_STATIC_DURATION): + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + break; + case static_cast(ATBInterpolation::DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_DURATION): + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + break; + case static_cast(ATBInterpolation::DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_PRICE): { + interpolation.dynamic_start = start.time(); + interpolation.dynamic_start.setHMS(start.time().hour(), start.time().minute(), 0); + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") interpol start:" << interpolation.dynamic_start.toString(Qt::ISODate); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") computed interpol end so far:" << interpolationEndTime.toString(Qt::ISODate); + + if (interpolation.seemless) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } else + if (interpolation.never) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } else { + QDateTime const &s = interpolationEndTime.addSecs(duration.pun_duration * 60); + int const minutesToStaticEnd = s.time().secsTo(interpolation.static_end) / 60; + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") computed interpol end so far:" << s.toString(Qt::ISODate); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") interpol static end:" << interpolation.static_end.toString(Qt::ISODate); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") minutes to static end:" << minutesToStaticEnd; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") pun-id:" << duration.pun_id; + + int p = 0; + for (auto[it, rangeEnd] = this->PaymentRate.equal_range(pop_id); it != rangeEnd; ++it) { + if (it->second.pra_payment_unit_id == duration.pun_id) { + if (minutesToStaticEnd >= 0) { + // the end of the interpolation for this day must be before a possible carry over interval + p = it->second.pra_price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") next price:" << p; + price += p; + interpolationEndTime = s; + } else { + if (pop_truncate_last_interpolation_step == false) { + p = it->second.pra_price; + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") next price:" << p; + price += p; + interpolationEndTime = s; + interpolationEndTime = interpolationEndTime.addSecs(carryOverDuration * 60); + } else { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") TODO"; + } + } + } + } + + //qCritical() << "(" << __func__ << ":" << __LINE__ << ") price:" << price; + + if (price >= interpolation.dynamic_until_price) { + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") price:" << price; + // qCritical() << "(" << __func__ << ":" << __LINE__ << ") computed interpol end:" << interpolationEndTime.toString(Qt::ISODate); + value = value.value_or(interpolationEndTime); + break; + } + } + } + break; + case static_cast(ATBInterpolation::DYNAMIC_ABSTRACT_TIMEPOINT_AND_STATIC_END_TIME): + break; + default:; + } + } + } + } + + return value; +} + + +int Configuration::getPaymentOptionIndexIfSpecialDay(QDateTime const &dt) const { + if (isSpecialDay(dt)) { + int const numOptions = getAllPaymentOptions().size(); + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_business_hours = getPaymentOptions(opt).pop_business_hours; + if ((pop_business_hours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + return opt; + } + } + } + return -1; +} + +int Configuration::getPaymentOptionIndex(QDateTime const &dt) const { + int const numOptions = getAllPaymentOptions().size(); + + // special days are handled before usual week days + int const sid = specialDayId(dt); + if (sid > 0) { + ATBSpecialDays const sd = specialDay(dt); + if (sd.ped_id != 0) { + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_id = getPaymentOptions(opt).pop_id; + if (pop_id == (uint64_t)sd.ped_payment_option_id) { + + qCritical() << __func__ << __LINE__ << opt; + + return opt; + } + } + } + } + + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_business_hours = getPaymentOptions(opt).pop_business_hours; + + if (pop_business_hours == 0) { // 0 == 24/7 + return opt; + } + + uint64_t p = 0; + int const dayOfWeek = dt.date().dayOfWeek(); + + switch (dayOfWeek) { + case (int)Qt::Monday: { + p = BusinessHours::MON; + } break; + case (int)Qt::Tuesday: { + p = BusinessHours::TUE; + } break; + case (int)Qt::Wednesday: { + p = BusinessHours::WED; + } break; + case (int)Qt::Thursday: { + p = BusinessHours::THU; + } break; + case (int)Qt::Friday: { + p = BusinessHours::FRI; + } break; + case (int)Qt::Saturday: { + p = BusinessHours::SAT; + } break; + case (int)Qt::Sunday: { + p = BusinessHours::SUN; + qCritical() << DBG_HEADER << Utilities::dumpBusinessHours(pop_business_hours) << pop_business_hours << p; + } break; + } + + if ((pop_business_hours & p) == p) { + + qCritical() << __func__ << __LINE__ << opt; + + return opt; + } + } + + qCritical() << DBG_HEADER << "ERROR: DEFAULT VALUE OF '0' RETURNED AS STATIC VALUE"; + return 0; +} + +ATBSpecialDays Configuration::specialDay(QDateTime const &dt) const { + SpecialDaysType::const_iterator it; + for (it = SpecialDays.cbegin(); it != SpecialDays.cend(); ++it) { + if (dt.date().toString(Qt::ISODate) == QString::fromStdString(it->second.ped_date_start)) { + return it->second; + } + } + + return ATBSpecialDays(); +} + +int Configuration::specialDayId(QDateTime const &dt) const { + SpecialDaysType::const_iterator it; + for (it = SpecialDays.cbegin(); it != SpecialDays.cend(); ++it) { + if (dt.date().toString(Qt::ISODate) == QString::fromStdString(it->second.ped_date_start)) { + int const specialDayId = it->second.ped_id; + return specialDayId; // must be > 0 + } + } + return 0; +} + +bool Configuration::isSpecialDay(QDateTime const &dt) const { + return (specialDayId(dt) > 0); +} + +bool Configuration::isDayIncludedAsSpecialDay(uint64_t businessHours, int specialDayId) const { + if (specialDayId > 0) { + bool const &r = ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY); + return r; + } + return false; +} + +bool Configuration::isDayIncludedAsSpecialDay(uint64_t businessHours, QDateTime const &dt) const { + // included in 'businessHours' + + if (isSpecialDay(dt)) { + bool const &r = ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY); + return r; + } + + return false; +} + +bool Configuration::isDayIncluded(uint64_t businessHours, QDateTime const &dt) const { + return Utilities::isDayIncluded(businessHours, dt); +} + +ATBPaymentOption const &Configuration::getPaymentOptions(int paymentOptionsIndex) const { + Q_ASSERT(!this->currentPaymentOptions.isEmpty()); + return this->currentPaymentOptions.at(paymentOptionsIndex); +} + +ATBPaymentOption &Configuration::getPaymentOptions(int paymentOptionsIndex) { + Q_ASSERT(!this->currentPaymentOptions.isEmpty()); + return this->currentPaymentOptions[paymentOptionsIndex]; +} + +QVector const &Configuration::getAllPaymentOptions() const { + return this->currentPaymentOptions; +} + +QVector &Configuration::getAllPaymentOptions() { + return this->currentPaymentOptions; +} + +std::optional> +Configuration::getTariffProductForAllKeys() const { + QVector products; + std::optional> value; + + products.clear(); + + for (std::multimap::const_iterator it = this->TariffProduct.cbegin(); + it != this->TariffProduct.cend(); ++it) { + products.append(it->second); + } + + if (products.size() > 0) { + value = value.value_or(products); + } + + return value; +} + +std::optional> +Configuration::getTariffProductForProductTypeName(QString const &permitTypeName) const { + QVector products; + std::optional> value; + + products.clear(); + + for(const auto &product: this->TariffProduct) { + ATBTariffProduct const &v = product.second; + if (v.m_tariff_product_name == permitTypeName) { + products.append(v); + } + } + + if (products.size() > 0) { + value = value.value_or(products); + } + + return value; +} + +int Configuration::getPaymentOptionIndex(PERMIT_TYPE permitType) { + + std::optional> paymentOptions = getPaymentOptionsForAllKeys(); + if (paymentOptions) { + QVector const vec = paymentOptions.value(); + PermitType const p(permitType); + + for (int i = 0; i < vec.size(); ++i) { + if (vec[i].pop_product_name == p.toString()) { + return i; + } + } + } + + return 0; +} + +int Configuration::getPaymentOptionIndex(PERMIT_TYPE permitType) const { + std::optional> paymentOptions = getPaymentOptionsForAllKeys(); + if (paymentOptions) { + + QVector const vec = paymentOptions.value(); + PermitType const p(permitType); + + for (int i = 0; i < vec.size(); ++i) { + if (vec[i].pop_product_name == p.toString()) { + return i; + } + } + } + + return 0; +} + +int getPaymentOptionIndex(Configuration const &cfg, QDateTime const &dt) { + + int const numOptions = cfg.getAllPaymentOptions().size(); + + // qCritical() << __func__ << ":" << __LINE__ << "numOptions" << numOptions; + + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_business_hours = cfg.getPaymentOptions(opt).pop_business_hours; + + if (pop_business_hours == 0) { // 0 == 24/7 + return opt; + } + + // QDateTime const dt = QDateTime::currentDateTime(); + int const dayOfWeek = dt.date().dayOfWeek(); + + // qCritical() << __func__ << ":" << __LINE__ << "dayOfWeek" << dayOfWeek; + + if (isHoliday(cfg, dt)) { + if (pop_business_hours & BusinessHours::OFFICIAL_HOLIDAY) { + return opt; + } + } else { + switch (dayOfWeek) { + case (int)Qt::Monday: { + if (pop_business_hours & BusinessHours::MON) { + return opt; + } + } break; + case (int)Qt::Tuesday: { + if (pop_business_hours & BusinessHours::TUE) { + return opt; + } + } break; + case (int)Qt::Wednesday: { + if (pop_business_hours & BusinessHours::WED) { + return opt; + } + } break; + case (int)Qt::Thursday: { + if (pop_business_hours & BusinessHours::THU) { + return opt; + } + } break; + case (int)Qt::Friday: { + if (pop_business_hours & BusinessHours::FRI) { + return opt; + } + } break; + case (int)Qt::Saturday: { + if (pop_business_hours & BusinessHours::SAT) { + return opt; + } + } break; + case (int)Qt::Sunday: { + if (pop_business_hours & BusinessHours::SUN) { + qCritical() << __func__ << ":" << __LINE__ << "opt" << opt; + return opt; + } + } break; + } + } + } + + return -1; +} + +std::optional> +Configuration::getTariffProductForProductId(PermitType permitType) const { + QString permitTypeName(permitType); + return getTariffProductForProductTypeName(permitTypeName); + + /* + QVector products; + std::optional> value; + + products.clear(); + + + for (auto[it, rangeEnd] = this->TariffProduct.equal_range(permitType); it != rangeEnd; ++it) { + products.append(it->second); + } + + if (products.size() > 0) { + value = value.value_or(products); + } + + return value; + */ +} + +std::optional> +Configuration::getTariffProductForProductId(int id) const { + return getTariffProductForProductId(PermitType(id)); +} + +std::optional> +Configuration::getDailyTicketsForAllKeys() const { + QVector tickets; + std::optional> value; + + for (std::multimap::const_iterator it = this->DailyTicket.cbegin(); + it != this->DailyTicket.cend(); ++it) { + tickets.append(it->second); + } + + if (tickets.size() > 0) { + value = value.value_or(tickets); + } + + return value; +} + +std::optional Configuration::getInterpolationType(int key) const { + std::optional value; + for (auto[it, rangeEnd] = this->TariffInterpolations.equal_range(key); it != rangeEnd; ++it) { + value = value.value_or(it->second); + } + return value; +} + +std::optional Configuration::getPrepaidType(int key) const { + std::optional value; + for (auto[it, rangeEnd] = this->TariffPrepaidOptions.equal_range(key); it != rangeEnd; ++it) { + value = value.value_or(it->second); + } + return value; +} + +std::optional Configuration::prepaidStart(QDateTime const &start, int prepaid_option_id) { + std::optional value; + QDateTime s = start; + + qCritical() << "(" << __func__ << ":" << __LINE__ << ") prepaid option id:" << prepaid_option_id; + + std::optional prepaid_option = getPrepaidType(prepaid_option_id); + if (prepaid_option.has_value()) { + ATBPrepaid prepaid = prepaid_option.value(); + + if (prepaid.never == false) { + // start: 22:00, end: 08:00 + QTime prepaidStart = TariffPrepaidOptions.find(prepaid_option_id)->second.static_start; + QTime prepaidEnd = TariffPrepaidOptions.find(prepaid_option_id)->second.static_end; + + if (s.time() >= prepaidStart) { + s = s.addDays(1); + s.setTime(prepaidEnd); + } else + if (s.time() < prepaidEnd) { + s.setTime(prepaidEnd); + } + s.setTime(QTime(s.time().hour(), s.time().minute(), 0)); + value = value.value_or(s); + } + } + return value; +} + +std::optional> +Configuration::getDailyTicketsForKey(int key) const { + QVector tickets; + std::optional> value; + + tickets.clear(); + + for (auto[it, rangeEnd] = this->DailyTicket.equal_range(key); it != rangeEnd; ++it) { + tickets.append(it->second); + } + + if (tickets.size() > 0) { + value = value.value_or(tickets); + } + + return value; +} + +std::optional +Configuration::getPaymentOptionForId(int key) const { + ATBPaymentOption option; + std::optional value; + + for (auto[it, rangeEnd] = this->PaymentOption.equal_range(key); it != rangeEnd; ++it) { + value = value.value_or(it->second); + } + + return value; +} + +std::optional> +Configuration::getPaymentOptionsForAllKeys() const { + QVector paymentOptions; + std::optional> value; + for (std::multimap::const_iterator it = this->PaymentOption.cbegin(); + it != this->PaymentOption.cend(); ++it) { + paymentOptions.append(it->second); + } + + if (paymentOptions.size() > 0) { + value = value.value_or(paymentOptions); + } + + return value; +} + +// TODO: umbenennen: getPaymentOptionForPermitType +std::optional +Configuration::getPaymentOptionForKey(PERMIT_TYPE permitType) const { + return getPaymentOptionForKey(static_cast(permitType)); +} + + +// TODO: umbenennen: getPaymentOptionForPermitType +std::optional +Configuration::getPaymentOptionForKey(int permitType) const { + std::optional value; + + for (std::multimap::const_iterator it = this->PaymentOption.cbegin(); + it != this->PaymentOption.cend(); ++it) { + ATBPaymentOption const &paymentOption = it->second; + if (paymentOption.pop_product_id == permitType) { + value = value.value_or(paymentOption); + break; + } + } + + return value; +} + +// TODO: umbenennen: getPaymentOptionForPermitType +std::optional +Configuration::getPaymentOptionForKey(QString const &permitTypeStr) const { + PERMIT_TYPE permitType = PermitType::toPermitType(permitTypeStr); + return getPaymentOptionForKey(static_cast(permitType)); +} + +std::optional> +Configuration::getPaymentRateForAllKeys() const { + QVector paymentRates; + std::optional> value; + + for (std::multimap::const_iterator it = this->PaymentRate.cbegin(); + it != this->PaymentRate.cend(); ++it) { + paymentRates.append(it->second); + } + + if (paymentRates.size() > 0) { + value = value.value_or(paymentRates); + } + + return value; + +} + +std::optional> +Configuration::getPaymentRateForKey(int key) const { + QVector paymentRate; + std::optional> value; + + paymentRate.clear(); + + for (auto[it, rangeEnd] = this->PaymentRate.equal_range(key); it != rangeEnd; ++it) { + paymentRate.append(it->second); + } + + if (paymentRate.size() > 0) { + value = value.value_or(paymentRate); + } + + return value; +} + +std::optional +Configuration::getCustomerForType(ATBCustomer::CustomerType customerType) { + for (std::multimap::const_iterator it = this->Customer.cbegin(); + it != this->Customer.cend(); ++it) { + ATBCustomer const &customer = it->second; + if (customer.cust_type == customerType) { + return customer; + } + } + + return std::nullopt; +} + +std::optional> +Configuration::getAllWeekDayWorkTimes() { + QVector worktimes; + std::optional> value; + + worktimes.clear(); + + for (std::multimap::const_iterator it = this->WeekDaysWorktime.cbegin(); + it != this->WeekDaysWorktime.cend(); ++it) { + worktimes.append(it->second); + } + + if (worktimes.size() > 0) { + value = value.value_or(worktimes); + } + + return value; +} + +std::optional +Configuration::getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek) { + ATBWeekDaysWorktime worktime; + std::optional value; + + std::multimap::const_iterator it = this->WeekDaysWorktime.find((int)dayOfWeek); + if (it != this->WeekDaysWorktime.cend()) { + + ATBWeekDaysWorktime const &wt = it->second; + + if (time >= QTime::fromString(wt.pwd_time_from.c_str(), Qt::ISODate) + && time < QTime::fromString(wt.pwd_time_to.c_str(), Qt::ISODate)) { + value = value.value_or(wt); + } + } + + return value; +} + +bool isHoliday(Configuration const &cfg, QDateTime const &t) { + int const weekDay = t.date().dayOfWeek(); + + for (auto[iter, rEnd] = cfg.WeekDays.equal_range(static_cast(weekDay)); + iter != rEnd; + ++iter) { + + if (iter->second.m_type == ATBWeekDay::WeekDayType::HOLIDAY) { + QDate const &d = iter->second.m_date; + if (!d.isNull() && d.isValid()) { + if (t.date() == d) { + return true; + } + } + } + } + return false; +} + +bool previousDayHoliday(Configuration const &cfg, QDateTime const &t) { + int const weekDay = t.date().dayOfWeek(); + int const previousWeekDay = (weekDay == static_cast(Qt::Monday)) ? + static_cast(Qt::Sunday) : (weekDay - 1); + + for (auto[iter, rEnd] = cfg.WeekDays.equal_range(static_cast(previousWeekDay)); + iter != rEnd; + ++iter) { + + if (iter->second.m_type == ATBWeekDay::WeekDayType::HOLIDAY) { + QDate const &d = iter->second.m_date; + if (!d.isNull() && d.isValid()) { + if (t.addDays(-1).date() == d) { + return true; + } + } + } + } + return false; +} diff --git a/library/src/tariff_global_defines.cpp b/library/src/tariff_global_defines.cpp new file mode 100644 index 0000000..162c745 --- /dev/null +++ b/library/src/tariff_global_defines.cpp @@ -0,0 +1,5 @@ +#include "tariff_global_defines.h" + +int DBG_LEVEL = DBG_NOTICE; +// int DBG_LEVEL = DBG_INFORMATION; +// int DBG_LEVEL = DBG_DEBUG; diff --git a/library/src/ticket.cpp b/library/src/ticket.cpp new file mode 100644 index 0000000..e86bf99 --- /dev/null +++ b/library/src/ticket.cpp @@ -0,0 +1,85 @@ +#include "ticket.h" + +Ticket::Ticket() + : m_status(Ticket::s[NOT_INITIALIZED]) + , m_validFrom() + , m_validUntil() + , m_durationMinutesNetto(0) + , m_durationMinutesBrutto(0) + , m_price() { +} + +Ticket::Ticket(QDateTime const &s, QDateTime const &e, + int durationMinutesNetto, int durationMinutesBrutto, + uint32_t price, Ticket::Status status) + : m_status(status) + , m_validFrom(s) + , m_validUntil(e) + , m_durationMinutesNetto(durationMinutesNetto) + , m_durationMinutesBrutto(durationMinutesBrutto) + , m_price(price) { +} + + +Ticket::Status Ticket::setStatus(Status status) { + Status old = m_status; + m_status = status; + return old; +} + +Ticket::Status Ticket::getStatus() const { + return m_status; +} + +void Ticket::setValidFrom(QDateTime const &validFrom) { + m_validFrom = validFrom; +} + +void Ticket::setValidUntil(QDateTime const &validUntil) { + m_validUntil = validUntil; +} + +QDateTime Ticket::getValidFrom() const { + if (std::get(m_status) == VALID) { + return m_validFrom; + } + return QDateTime(); +} + +QDateTime Ticket::getValidUntil() const { + if (std::get(m_status) == VALID) { + return m_validUntil; + } + return QDateTime(); +} + +uint32_t Ticket::getPrice() const { + return m_price; +} + +void Ticket::setPrice(uint32_t price) { + m_price = price; +} + +Ticket::operator QString() { + QStringList status; + status << QString("**********************"); + status << QString("Status ............. : %1 (%2)") + .arg(std::get<0>(m_status)) + .arg(std::get<2>(m_status)); + status << QString("Valid from ......... : %1").arg(m_validFrom.toString(Qt::ISODate)); + status << QString("Valid until ........ : %1").arg(m_validUntil.toString(Qt::ISODate)); + status << QString("Duration (netto) ... : %1").arg(m_durationMinutesNetto); + status << QString("Duration (brutto)... : %1").arg(m_durationMinutesBrutto); + status << QString("Price .............. : %1").arg(m_price); + status << QString("**********************"); + + return status.join('\n'); +} + +QDebug operator<<(QDebug debug, Ticket::Status const &status) { + QDebugStateSaver saver(debug); + debug << "Ticket-Status: " << std::get<1>(status) + << "(" << std::get<2>(status) << ")"; + return debug; +} diff --git a/library/src/utilities.cpp b/library/src/utilities.cpp index cb5d896..9600ae7 100644 --- a/library/src/utilities.cpp +++ b/library/src/utilities.cpp @@ -1,273 +1,604 @@ -#include "utilities.h" -#include "tariff_log.h" - -static int protection_counter = 0; - -/// -/// Helper function -/// -/// -/// -double Utilities::CalculatePricePerUnit(double pra_price, double durationUnit) -{ - try - { - double price_per_unit = pra_price; - double unit = durationUnit; - - if(unit < 0 || unit > 65535 ) unit = 60.0f; - price_per_unit /= unit; // Divided by 60 because price per unit is set per hour and we are using minutes - //printf("Price per unit (min) is: %lf\n", price_per_unit); - return price_per_unit; - } - catch (...) - { - throw std::invalid_argument("An error has occurred in CalculatePricePerUnit() function\n"); - } -} - -/// -time_t Utilities::GetCurrentLocalTime() -{ - try - { - time_t curr_time = time(NULL); - tm tm_curr_time = {}; - memset(&tm_curr_time, '\0', sizeof(struct tm)); - - tm_curr_time = *localtime(&curr_time); - curr_time = mktime(&tm_curr_time); //- timezone; - return curr_time; - } - catch (...) - { - throw std::invalid_argument("An error has occurred in GetCurrentLocalTime() function\n"); - } -} - -/// -int Utilities::ZellersAlgorithm(int day, int month, int year) -{ - int mon; - if (month > 2) mon = month; //for march to december month code is same as month - else { - mon = (12 + month); //for Jan and Feb, month code will be 13 and 14 - year--; //decrease year for month Jan and Feb - } - int y = year % 100; //last two digit - int c = year / 100; //first two digit - int w = (day + floor((13 * (mon + 1)) / 5) + y + floor(y / 4) + floor(c / 4) + (5 * c)); - w = ((w + 5) % 7) + 1; //w % 7; - return w; -} - -/// -struct tm Utilities::DateToStructTm(const char* dateStr) -{ - struct tm t = {}; - memset(&t, '\0', sizeof(struct tm)); - - if (dateStr == nullptr || strlen(dateStr) <= 0) throw std::invalid_argument("DateToStructTm has failed parsing date string (null or empty)\n"); - try - { - int success = sscanf(dateStr, "%d-%d-%d", &t.tm_year, &t.tm_mon, &t.tm_mday); - if (success != 3) throw std::invalid_argument("DateToStructTm() has failed parsing datetime string\n"); - - t.tm_year = t.tm_year - 1900; - t.tm_mon = t.tm_mon - 1; - t.tm_isdst = 0; - return t; - } - catch (...) - { - throw std::invalid_argument("An error has occurred in DateToStructTm() function\n"); - } -} - -/// -struct tm Utilities::TimeToStructTm(const char* timeStr, int year, int mon, int mday, int wday) -{ - struct tm t = {}; - memset(&t, '\0', sizeof(struct tm)); - - if (timeStr == nullptr || strlen(timeStr) <= 0) throw std::invalid_argument("TimeToStructTm() has failed parsing time string (null or empty)\n"); - try - { - int success_time = sscanf(timeStr, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); - if (success_time != 3) throw std::invalid_argument("TimeToStructTm() has failed parsing time string\n"); - - struct tm tm_struct; - t.tm_year = year; - t.tm_mon = mon; - t.tm_mday = mday; - t.tm_wday = wday; - t.tm_isdst = 0; - return t; - } - catch (...) - { - throw std::invalid_argument("An error has occurred in TimeToStructTm() function\n"); - } -} - -/// -struct tm Utilities::DateTimeToStructTm(const char* dateTimeStr) -{ - struct tm t = {}; - memset(&t, '\0', sizeof(struct tm)); - - if (dateTimeStr == nullptr || strlen(dateTimeStr) <= 0) throw std::invalid_argument("DateTimeToStructTm() has failed parsing date string (null or empty)"); - try - { - int success = sscanf(dateTimeStr, "%d-%d-%dT%d:%d:%dZ", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec); - if (success != 6) throw std::invalid_argument("DateTimeToStructTm() has failed parsing datetime string\n"); - - t.tm_year = t.tm_year - 1900; - t.tm_mon = t.tm_mon - 1; - t.tm_isdst = 0; - return t; - } - catch (...) - { - throw std::invalid_argument("An error has occurred in DateTimeToStructTm() function\n"); - } -} - -/// -DayOfWeek Utilities::GetDayOfWeek(struct tm* t) -{ - if (t == nullptr) throw std::invalid_argument("GetDayOfWeekFromDate() => parameter 't' is null\n"); - try - { - int d = t->tm_mday; - int m = t->tm_mon + 1; - int y = t->tm_year + 1900; - - int wd = Utilities::ZellersAlgorithm(d, m, y); - return static_cast(wd); - } - catch (...) - { - throw std::invalid_argument("An error has occurred in GetDayOfWeekFromDate() function\n"); - } -} - -/// -bool Utilities::IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTime_tm) -{ - if (cfg == nullptr) throw std::invalid_argument("IsYearPeriodActive() = > Configuration not set\n"); - if (currentDateTime_tm == nullptr) throw std::invalid_argument("IsYearPeriodActive() = > Current datetime not set\n"); - - try - { - //// Parse input date - int dayCurrent = currentDateTime_tm->tm_mday; - int monthCurrent = currentDateTime_tm->tm_mon + 1; - - // Current date time - int cdt = (monthCurrent * 100) + dayCurrent; - - multimap::iterator year_period_itr; - for (year_period_itr = cfg->YearPeriod.begin(); year_period_itr != cfg->YearPeriod.end(); ++year_period_itr) - { - int dStart = year_period_itr->second.pye_start_day; - int dEnd = year_period_itr->second.pye_end_day; - - int mStart = year_period_itr->second.pye_start_month; - int mEnd = year_period_itr->second.pye_end_month; - - int start = (mStart * 100) + dStart; - int end = (mEnd * 100) + dEnd; - - if (cdt >= start && cdt <= end) - { - return true; - } - } - return false; - } - catch (...) - { - cout << "IsYearPeriodActive() => An exception has occurred, ignoring check, returning true" << endl; - return true; - } -} - -/// -bool Utilities::CheckSpecialDay(Configuration* cfg, const char* currentDateTimeStr, int* specialDayId, double* specialDayPrice) -{ - try - { - *specialDayId = -1; - *specialDayPrice = 0.0f; - - if (cfg == nullptr) throw std::invalid_argument("CheckSpecialDay() => configuration is not set\n"); - if (currentDateTimeStr == nullptr) throw std::invalid_argument("CheckSpecialDay() => invalid date/time string set\n"); - - - struct tm current_tm = Utilities::DateTimeToStructTm(currentDateTimeStr); - //cout << "CheckSpecialDay() => Current: " << asctime(¤t_tm) << endl; - - multimap::iterator spec_days_itr; - - for (spec_days_itr = cfg->SpecialDays.begin(); spec_days_itr != cfg->SpecialDays.end(); spec_days_itr++) - { - int repeat_every_year = 0; - repeat_every_year = spec_days_itr->second.ped_year; - - string start = spec_days_itr->second.ped_date_start; - if (start.length() <= 0) continue; - //cout << "CheckSpecialDay() => Start: " << start << endl; - - string end = spec_days_itr->second.ped_date_end; - if (end.length() <= 0) continue; - //cout << "CheckSpecialDay() => End: " << end << endl; - - struct tm start_tm = Utilities::DateToStructTm(start.c_str()); - //cout << "CheckSpecialDay() => Start: " << asctime(&start_tm) << endl; - - struct tm end_tm = Utilities::DateToStructTm(end.c_str()); - //cout << "CheckSpecialDay() => End: " << asctime(&end_tm) << endl; - - if (repeat_every_year <= 0) - { - //cout << "CheckSpecialDay() => Repeat every year is: 0" << endl; - if ((current_tm.tm_year == start_tm.tm_year) && (current_tm.tm_year == end_tm.tm_year)) - { - if ((current_tm.tm_mon >= start_tm.tm_mon) && (current_tm.tm_mon <= end_tm.tm_mon)) - { - //cout << "CheckSpecialDay() => Month is in range between start and end" << endl; - if ((current_tm.tm_mday >= start_tm.tm_mday) && (current_tm.tm_mday <= end_tm.tm_mday)) - { - LOG_DEBUG("CheckSpecialDay() => SPECIAL DAY"); - *specialDayId = spec_days_itr->second.ped_id; - *specialDayPrice = cfg->SpecialDaysWorktime.find(*specialDayId)->second.pedwt_price; - return true; - } - } - } - } - else - { - if ((current_tm.tm_mon >= start_tm.tm_mon) && (current_tm.tm_mon <= end_tm.tm_mon)) - { - //cout << "CheckSpecialDay() => Month is in range between start and end" << endl; - if ((current_tm.tm_mday >= start_tm.tm_mday) && (current_tm.tm_mday <= end_tm.tm_mday)) - { - LOG_DEBUG("CheckSpecialDay() => SPECIAL DAY"); - *specialDayId = spec_days_itr->second.ped_id; - *specialDayPrice = cfg->SpecialDaysWorktime.find(*specialDayId)->second.pedwt_price; - return true; - } - } - } - } - //cout << "CheckSpecialDay() => NOT SPECIAL DAY" << endl; - return false; - } - catch (...) - { - throw std::invalid_argument("CheckSpecialDay() => An error has occurred\n"); - return false; - } -} +#include "utilities.h" +#include "tariff_log.h" +#include "tariff_business_hours.h" + +#include +#include + +// static int protection_counter = 0; + +/// +/// Helper function +/// +/// +/// +double Utilities::CalculatePricePerUnit(double pra_price, double durationUnit) +{ + try + { + double price_per_unit = pra_price; + double unit = durationUnit; + + if(unit < 0 || unit > 65535 ) unit = 60.0f; + price_per_unit /= unit; // Divided by 60 because price per unit is set per hour and we are using minutes + //printf("Price per unit (min) is: %lf\n", price_per_unit); + return price_per_unit; + } + catch (...) + { + throw std::invalid_argument("An error has occurred in CalculatePricePerUnit() function\n"); + } +} + +/// +time_t Utilities::GetCurrentLocalTime() +{ + try + { + time_t curr_time = time(NULL); + tm tm_curr_time = {}; + memset(&tm_curr_time, '\0', sizeof(struct tm)); + + tm_curr_time = *localtime(&curr_time); + curr_time = mktime(&tm_curr_time); //- timezone; + return curr_time; + } + catch (...) + { + throw std::invalid_argument("An error has occurred in GetCurrentLocalTime() function\n"); + } +} + +/// +int Utilities::ZellersAlgorithm(int day, int month, int year) +{ + int mon; + if (month > 2) mon = month; //for march to december month code is same as month + else { + mon = (12 + month); //for Jan and Feb, month code will be 13 and 14 + year--; //decrease year for month Jan and Feb + } + int y = year % 100; //last two digit + int c = year / 100; //first two digit + int w = (day + floor((13 * (mon + 1)) / 5) + y + floor(y / 4) + floor(c / 4) + (5 * c)); + w = ((w + 5) % 7) + 1; //w % 7; + return w; +} + +/// +struct tm Utilities::DateToStructTm(const char* dateStr) +{ + struct tm t = {}; + memset(&t, '\0', sizeof(struct tm)); + + if (dateStr == nullptr || strlen(dateStr) <= 0) throw std::invalid_argument("DateToStructTm has failed parsing date string (null or empty)\n"); + try + { + int success = sscanf(dateStr, "%d-%d-%d", &t.tm_year, &t.tm_mon, &t.tm_mday); + if (success != 3) throw std::invalid_argument("DateToStructTm() has failed parsing datetime string\n"); + + t.tm_year = t.tm_year - 1900; + t.tm_mon = t.tm_mon - 1; + t.tm_isdst = 0; + return t; + } + catch (...) + { + throw std::invalid_argument("An error has occurred in DateToStructTm() function\n"); + } +} + +/// +struct tm Utilities::TimeToStructTm(const char* timeStr, int year, int mon, int mday, int wday) +{ + struct tm t = {}; + memset(&t, '\0', sizeof(struct tm)); + + if (timeStr == nullptr || strlen(timeStr) <= 0) throw std::invalid_argument("TimeToStructTm() has failed parsing time string (null or empty)\n"); + try + { + int success_time = sscanf(timeStr, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (success_time != 3) throw std::invalid_argument("TimeToStructTm() has failed parsing time string\n"); + + struct tm tm_struct; + t.tm_year = year; + t.tm_mon = mon; + t.tm_mday = mday; + t.tm_wday = wday; + t.tm_isdst = 0; + return t; + } + catch (...) + { + throw std::invalid_argument("An error has occurred in TimeToStructTm() function\n"); + } +} + +/// +struct tm Utilities::DateTimeToStructTm(const char* dateTimeStr) +{ + struct tm t = {}; + memset(&t, '\0', sizeof(struct tm)); + + if (dateTimeStr == nullptr || strlen(dateTimeStr) <= 0) throw std::invalid_argument("DateTimeToStructTm() has failed parsing date string (null or empty)"); + try + { + int success = sscanf(dateTimeStr, "%d-%d-%dT%d:%d:%dZ", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec); + if (success != 6) throw std::invalid_argument("DateTimeToStructTm() has failed parsing datetime string\n"); + + t.tm_year = t.tm_year - 1900; + t.tm_mon = t.tm_mon - 1; + t.tm_isdst = 0; + return t; + } + catch (...) + { + throw std::invalid_argument("An error has occurred in DateTimeToStructTm() function\n"); + } +} + +/// +DayOfWeek Utilities::GetDayOfWeek(struct tm* t) +{ + if (t == nullptr) throw std::invalid_argument("GetDayOfWeekFromDate() => parameter 't' is null\n"); + try + { + int d = t->tm_mday; + int m = t->tm_mon + 1; + int y = t->tm_year + 1900; + + int wd = Utilities::ZellersAlgorithm(d, m, y); + return static_cast(wd); + } + catch (...) + { + throw std::invalid_argument("An error has occurred in GetDayOfWeekFromDate() function\n"); + } +} + +/// +bool Utilities::IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTime_tm) +{ + if (cfg == nullptr) throw std::invalid_argument("IsYearPeriodActive() = > Configuration not set\n"); + if (currentDateTime_tm == nullptr) throw std::invalid_argument("IsYearPeriodActive() = > Current datetime not set\n"); + + try + { + //// Parse input date + int dayCurrent = currentDateTime_tm->tm_mday; + int monthCurrent = currentDateTime_tm->tm_mon + 1; + + // Current date time + int cdt = (monthCurrent * 100) + dayCurrent; + + multimap::iterator year_period_itr; + for (year_period_itr = cfg->YearPeriod.begin(); year_period_itr != cfg->YearPeriod.end(); ++year_period_itr) + { + int dStart = year_period_itr->second.pye_start_day; + int dEnd = year_period_itr->second.pye_end_day; + + int mStart = year_period_itr->second.pye_start_month; + int mEnd = year_period_itr->second.pye_end_month; + + int start = (mStart * 100) + dStart; + int end = (mEnd * 100) + dEnd; + + if (cdt >= start && cdt <= end) + { + return true; + } + } + return false; + } + catch (...) + { + cout << "IsYearPeriodActive() => An exception has occurred, ignoring check, returning true" << endl; + return true; + } +} + +bool Utilities::IsYearPeriodActive(Configuration const *cfg, QDateTime const &dt) { + if ((cfg->YearPeriod.size() > 0) && + std::none_of(cfg->YearPeriod.cbegin(), + cfg->YearPeriod.cend(), + [&dt](std::pair const &year) { + QDate const d(2004, // 2004 is a leap year + dt.date().month(), + dt.date().day()); + QDate const s(2004, year.second.pye_start_month, year.second.pye_start_day); + QDate const e(2004, year.second.pye_end_month, year.second.pye_end_day); + //qCritical() << __func__ << __LINE__ << " d" << d.toString(Qt::ISODate); + //qCritical() << __func__ << __LINE__ << "start" << s.toString(Qt::ISODate); + //qCritical() << __func__ << __LINE__ << " end" << e.toString(Qt::ISODate); + if (s <= e) { + return (d >= s && d <= e); + } + return (d >= s || d <= e); + })) { + qCritical() << "NO VALID YEAR PERIOD"; + return false; + } + return true; +} + +std::optional +Utilities::GetYearPeriodActive(Configuration const *cfg, QDateTime const ¤tDateTime) { + + ATBPeriodYear period; + std::optional value; + + for (multimap::const_iterator it = cfg->YearPeriod.cbegin(); + it != cfg->YearPeriod.cend(); + ++it) { + QDate const s(currentDateTime.date().year(), it->second.pye_start_month, it->second.pye_start_day); + QDate const e(currentDateTime.date().year(), it->second.pye_end_month, it->second.pye_end_day); + + QDateTime start(currentDateTime); + QDateTime end(currentDateTime); + + start.setDate(s); + end.setDate(e); + + if (start.date().dayOfYear() < end.date().dayOfYear()) { + // start and end in the same year + if (currentDateTime.date().dayOfYear() >= start.date().dayOfYear() && + currentDateTime.date().dayOfYear() <= end.date().dayOfYear()) { + value = value.value_or(it->second); + break; + } + } else { + if (currentDateTime.date().dayOfYear() >= start.date().dayOfYear() || + currentDateTime.date().dayOfYear() <= end.date().dayOfYear()) { + value = value.value_or(it->second); + break; + } + } + } + + return value; +} + +/// +bool Utilities::CheckSpecialDay(Configuration* cfg, const char* currentDateTimeStr, int* specialDayId, double* specialDayPrice) +{ + try + { + *specialDayId = -1; + *specialDayPrice = 0.0f; + + if (cfg == nullptr) throw std::invalid_argument("CheckSpecialDay() => configuration is not set\n"); + if (currentDateTimeStr == nullptr) throw std::invalid_argument("CheckSpecialDay() => invalid date/time string set\n"); + + + struct tm current_tm = Utilities::DateTimeToStructTm(currentDateTimeStr); + //cout << "CheckSpecialDay() => Current: " << asctime(¤t_tm) << endl; + + multimap::iterator spec_days_itr; + + for (spec_days_itr = cfg->SpecialDays.begin(); spec_days_itr != cfg->SpecialDays.end(); spec_days_itr++) + { + int repeat_every_year = 0; + repeat_every_year = spec_days_itr->second.ped_year; + + string start = spec_days_itr->second.ped_date_start; + if (start.length() <= 0) continue; + //cout << "CheckSpecialDay() => Start: " << start << endl; + + string end = spec_days_itr->second.ped_date_end; + if (end.length() <= 0) continue; + //cout << "CheckSpecialDay() => End: " << end << endl; + + struct tm start_tm = Utilities::DateToStructTm(start.c_str()); + //cout << "CheckSpecialDay() => Start: " << asctime(&start_tm) << endl; + + struct tm end_tm = Utilities::DateToStructTm(end.c_str()); + //cout << "CheckSpecialDay() => End: " << asctime(&end_tm) << endl; + + if (repeat_every_year <= 0) + { + //cout << "CheckSpecialDay() => Repeat every year is: 0" << endl; + if ((current_tm.tm_year == start_tm.tm_year) && (current_tm.tm_year == end_tm.tm_year)) + { + if ((current_tm.tm_mon >= start_tm.tm_mon) && (current_tm.tm_mon <= end_tm.tm_mon)) + { + //cout << "CheckSpecialDay() => Month is in range between start and end" << endl; + if ((current_tm.tm_mday >= start_tm.tm_mday) && (current_tm.tm_mday <= end_tm.tm_mday)) + { + //LOG_DEBUG("CheckSpecialDay() => SPECIAL DAY"); + *specialDayId = spec_days_itr->second.ped_id; + *specialDayPrice = cfg->SpecialDaysWorktime.find(*specialDayId)->second.pedwt_price; + return true; + } + } + } + } + else + { + if ((current_tm.tm_mon >= start_tm.tm_mon) && (current_tm.tm_mon <= end_tm.tm_mon)) + { + //cout << "CheckSpecialDay() => Month is in range between start and end" << endl; + if ((current_tm.tm_mday >= start_tm.tm_mday) && (current_tm.tm_mday <= end_tm.tm_mday)) + { + //LOG_DEBUG("CheckSpecialDay() => SPECIAL DAY"); + *specialDayId = spec_days_itr->second.ped_id; + *specialDayPrice = cfg->SpecialDaysWorktime.find(*specialDayId)->second.pedwt_price; + return true; + } + } + } + } + //cout << "CheckSpecialDay() => NOT SPECIAL DAY" << endl; + return false; + } + catch (...) + { + throw std::invalid_argument("CheckSpecialDay() => An error has occurred\n"); + return false; + } +} + +bool Utilities::CheckSpecialDay(Configuration const *cfg, + QDateTime const ¤tDateTime, + int* specialDayId, + uint32_t *specialDayPrice) { + *specialDayId = -1; + *specialDayPrice = 0; + + std::multimap::const_iterator spec_days_itr; + + for (spec_days_itr = cfg->SpecialDays.cbegin(); spec_days_itr != cfg->SpecialDays.cend(); ++spec_days_itr) { + int repeat_every_year = spec_days_itr->second.ped_year; + QDate start = QDate::fromString(spec_days_itr->second.ped_date_start.c_str(), Qt::ISODate); + QDate end = QDate::fromString(spec_days_itr->second.ped_date_end.c_str(), Qt::ISODate); + if (start.isValid() && end.isValid()) { + if ((currentDateTime.date().month() >= start.month()) && + (currentDateTime.date().month() <= end.month())) { + if ((currentDateTime.date().day() >= start.day()) && + (currentDateTime.date().day() <= end.day())) { + if (repeat_every_year <= 0) { + if ((currentDateTime.date().year() != start.year()) || + (currentDateTime.date().year() != end.year())) { + continue; + } + } + //qDebug() << "CheckSpecialDay() => SPECIAL DAY"; + *specialDayId = spec_days_itr->second.ped_id; + *specialDayPrice = cfg->SpecialDaysWorktime.find(*specialDayId)->second.pedwt_price; + return true; + } + } + } + } + + return false; +} + +QTime Utilities::SpecialDaysWorkTimeFrom(Configuration const *cfg, int specialDayId) { + return QTime::fromString(cfg->SpecialDaysWorktime.find(specialDayId)->second.pedwt_time_from.c_str(), Qt::ISODate); +} + +QTime Utilities::SpecialDaysWorkTimeFrom(Configuration::SpecialDaysWorktimeType::const_iterator const &it) { + return QTime::fromString(it->second.pedwt_time_from.c_str(), Qt::ISODate); +} + +QTime Utilities::SpecialDaysWorkTimeUntil(Configuration::SpecialDaysWorktimeType::const_iterator const &it) { + return QTime::fromString(it->second.pedwt_time_to.c_str(), Qt::ISODate); +} + +QTime Utilities::SpecialDaysWorkTimeUntil(Configuration const *cfg, int specialDayId) { + return QTime::fromString(cfg->SpecialDaysWorktime.find(specialDayId)->second.pedwt_time_to.c_str(), Qt::ISODate); +} + +QTime Utilities::WeekDaysWorkTimeFrom(std::multimap::const_iterator const &itr) { + return QTime::fromString(itr->second.pwd_time_from.c_str(), Qt::ISODate); +} + +QTime Utilities::WeekDaysWorkTimeUntil(std::multimap::const_iterator const &itr) { + return QTime::fromString(itr->second.pwd_time_to.c_str(), Qt::ISODate); +} + +int Utilities::WeekDayId(std::multimap::const_iterator const &itr) { + return itr->second.pwd_period_day_in_week_id; +} + +bool Utilities::isCarryOverSet(Configuration const *cfg, PaymentMethod paymentMethodId) { + return !isCarryOverNotSet(cfg, paymentMethodId); +} + +bool Utilities::isCarryOverNotSet(Configuration const *cfg, PaymentMethod paymentMethodId) { + return (cfg->PaymentOption.find(paymentMethodId)->second.pop_carry_over < 1); +} + +PaymentMethod Utilities::getPaymentMethodId(Configuration const *cfg) { + if (cfg->PaymentOption.size() == 0) { + return PaymentMethod::Undefined; + } + + std::multimap::const_iterator it = + cfg->PaymentOption.cbegin(); + + if (it != cfg->PaymentOption.cend()) { + switch (it->first) { + case PaymentMethod::Linear: + return PaymentMethod::Linear; + case PaymentMethod::Steps: + return PaymentMethod::Steps; + case PaymentMethod::Degressive: + return PaymentMethod::Degressive; + case PaymentMethod::Progressive: + return PaymentMethod::Progressive; + case PaymentMethod::Unified: + return PaymentMethod::Unified; + } + } + + return PaymentMethod::Undefined; +} + +int Utilities::getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_time, 0); +} + +int Utilities::getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_time, 0); +} + +uint32_t Utilities::getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_price, 0); +} + +uint32_t Utilities::getMaximalParkingPrice(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_price, 0); +} + +uint32_t Utilities::getDailyTicketCardPrice(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_daily_card_price, 0); +} + +uint32_t Utilities::getTimeRangeStep(Configuration const *cfg, int step, PaymentMethod methodId) { + if (methodId == PaymentMethod::Progressive) { + Configuration::TimeRangeType::const_iterator it = cfg->TimeRange.find(step); + if (it != cfg->TimeRange.cend()) { + return std::max((int)(it->second.time_range_to_in_minutes_from_start), 0); + } + } + + return 0; +} + +uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId) { + + int const popId = cfg->PaymentOption.find(methodId)->second.pop_id; + int const punId = cfg->PaymentRate.find(popId)->second.pra_payment_unit_id; + uint32_t const firstDurationStep= cfg->Duration.find(punId)->second.pun_duration; + + qCritical() << "getFirstDurationStep() payment-method-id:" << (int)methodId; + qCritical() << "getFirstDurationStep() pop-id:" << popId; + qCritical() << "getFirstDurationStep() pun-id:" << punId; + qCritical() << "getFirstDurationStep() first-step:" << firstDurationStep; + + return firstDurationStep; +} + +BusinessHours Utilities::getBusinessHours(Configuration const *cfg, PaymentMethod methodId) { + uint64_t businessHours = cfg->PaymentOption.find(methodId)->second.pop_business_hours; + + switch (businessHours) { + //case NoRestriction_24_7: return BusinessHours::NoRestriction_24_7; + case OnlyWorkingDays: return BusinessHours::OnlyWorkingDays; + case OnlyWeekDays: return BusinessHours::OnlyWeekDays; + case OnlyWeekEnd: return BusinessHours::OnlyWeekEnd; + case OnlyOfficialHolidays: return BusinessHours::OnlyOfficialHolidays; + case OnlySpecialDays: return BusinessHours::OnlySpecialDays; + case OnlySchoolHolidays: return BusinessHours::OnlySchoolHolidays; + case SpecialAndSchoolHolidays: return BusinessHours::SpecialAndSchoolHolidays; + case OnlyOpenForBusinessDays: return BusinessHours::OnlyOpenForBusinessDays; + case AllDaysWithRestrictedHours: return BusinessHours::AllDaysWithRestrictedHours; + case _NO_RESTRICTION_24_7_: return BusinessHours::NO_RESTRICTION_24_7; + case _MON_: return BusinessHours::MON; + case _TUE_: return BusinessHours::TUE; + case _WED_: return BusinessHours::WED; + case _THU_: return BusinessHours::THU; + case _FRI_: return BusinessHours::FRI; + case _SAT_: return BusinessHours::SAT; + case _SUN_: return BusinessHours::SUN; + case _WEEK_DAYS_: return BusinessHours::WEEK_DAYS; + case _WORKING_DAYS_: return BusinessHours::WORKING_DAYS; + case _ALL_DAYS_: return BusinessHours::ALL_DAYS; + case _OFFICIAL_HOLIDAY_: return BusinessHours::OFFICIAL_HOLIDAY; + case _ONLY_WEEKEND_: return BusinessHours::ONLY_WEEKEND; + case _ONLY_OPEN_FOR_BUSINESS_DAYS_: return BusinessHours::ONLY_OPEN_FOR_BUSINESS_DAYS; + case _NOT_DEFINED_: return BusinessHours::NOT_DEFINED; + } + return BusinessHours::NoBusinessHoursDefined; +} + +uint32_t Utilities::computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id) { + int pop_id = cfg->PaymentOption.find(id)->second.pop_id; + return cfg->PaymentRate.find(pop_id)->second.pra_price; +} + +double Utilities::computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id) { + int pop_id = cfg->PaymentOption.find(id)->second.pop_id; + int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id; + return (double)(cfg->Duration.find(durationId)->second.pun_duration); +} + +bool Utilities::isDayIncluded(uint64_t businessHours, QDateTime const &dt) { + int dayOfWeek = dt.date().dayOfWeek(); + switch (dayOfWeek) { + case Qt::Monday: + return ((businessHours & BusinessHours::MON) == BusinessHours::MON); + case Qt::Tuesday: + return ((businessHours & BusinessHours::TUE) == BusinessHours::TUE); + case Qt::Wednesday: + return ((businessHours & BusinessHours::WED) == BusinessHours::WED); + case Qt::Thursday: + return ((businessHours & BusinessHours::THU) == BusinessHours::THU); + case Qt::Friday: + return ((businessHours & BusinessHours::FRI) == BusinessHours::FRI); + case Qt::Saturday: + return ((businessHours & BusinessHours::SAT) == BusinessHours::SAT); + case Qt::Sunday: + return ((businessHours & BusinessHours::SUN) == BusinessHours::SUN); + default:; + } + + return false; +} + +QStringList Utilities::dumpBusinessHours(uint64_t businessHours) { + QStringList s; + + if ((businessHours & BusinessHours::MON) == BusinessHours::MON) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "MON (Holiday)"; + } else { + s << "MON"; + } + } + if ((businessHours & BusinessHours::TUE) == BusinessHours::TUE) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "TUE (Holiday)"; + } else { + s << "TUE"; + } + } + if ((businessHours & BusinessHours::WED) == BusinessHours::WED) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "WED (Holiday)"; + } else { + s << "WED"; + } + } + if ((businessHours & BusinessHours::THU) == BusinessHours::THU) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "THU (Holiday)"; + } else { + s << "THU"; + } + } + if ((businessHours & BusinessHours::FRI) == BusinessHours::FRI) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "FRI (Holiday)"; + } else { + s << "FRI"; + } + } + if ((businessHours & BusinessHours::SAT) == BusinessHours::SAT) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "SAT (Holiday)"; + } else { + s << "SAT"; + } + } + if ((businessHours & BusinessHours::SUN) == BusinessHours::SUN) { + if ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + s << "SUN (Holiday)"; + } else { + s << "SUN"; + } + } + + return s; +} diff --git a/main/MessageHelper.cpp b/main/MessageHelper.cpp new file mode 100644 index 0000000..f3526df --- /dev/null +++ b/main/MessageHelper.cpp @@ -0,0 +1,882 @@ +#include "MessageHelper.h" +#include "terminal_utils.h" +#include "aes128.h" + +#include +#include + +#define IUC_ASYNCHPOS_COINCOIDE_H 0x09 +#define IUC_ASYNCHPOS_COINCOIDE_L 0x78 +#define IUC_ASYNCHPOS_MAX_ARRAY_SIZE 1024 +#define IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE 300 +#define IUC_ASYNCHPOS_MAX_RX_PACKET_SIZE 10000 // 17000 +#define IUC_ASYNCHPOS_MIN_PACKET_SIZE 16 +#define IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE 32 +#define IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE 16 +#define IUC_ASYNCHPOS_POLYNOME 0xedb88320 // 0x04C11DB7 +#define IUC_ASYNCHPOS_POLYNOME_INITIAL 0 // 0xFFFFFFFF +#define IUC_ASYNCHPOS_PRINTTIMOUT 1000 + +#define PACKET_ID_SIZE 8 +#define MAX_POSID_LENGTH 255 + +#define STX ((char)0x01) +#define ETX1 ((char)0x02) +#define ETX2 ((char)0x03) +#define EOT ((char)0x04) +#define ENQ ((char)0x05) +#define ACK1 ((char)0x06) +#define ACK2 ((char)0x07) +#define DLE ((char)0x10) +#define NAK ((char)0x15) + + +#define DBG_HEADER "(" << __func__ << ":" << __LINE__ << ")" + +#define DBG_EMERGENCY (0) // System is unusable +#define DBG_ALERT (1) // Action must be taken immediately +#define DBG_CRITICAL (2) // Critical conditions +#define DBG_ERROR (3) // Error conditions +#define DBG_WARNING (4) // Warning conditions +#define DBG_NOTICE (5) // Normal but significant conditions + // Conditions that are not error conditions, but that may require special handling +#define DBG_INFORMATION (6) // Informational messages + // Confirmation that the program is working as expected +#define DBG_DEBUG (7) // Debug-level messages + // Messages that contain information normally of use only when debugging a program + +static int DBG_LEVEL = DBG_INFORMATION; +//static int DBG_LEVEL = DBG_DEBUG; + +struct MessageHeader { + uint8_t packetType; + uint8_t packetID[PACKET_ID_SIZE]; + uint8_t POSIDLength; + uint8_t POSID[MAX_POSID_LENGTH]; +}; + + +MessageHelper::AsynchBillData MessageHelper::m_asyncBillData; +MessageHelper::AuthorizationResult MessageHelper::m_authorizationResult; + +MessageHelper::MessageHelper(QString const &posID, QString const &apak) + : m_posID(posID.toUtf8().constData()) + , m_posIDLength(m_posID.size()) + , m_messageHeaderPrefix(1 + PACKET_ID_SIZE + 1, 0x00) + , m_rawPacket(IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE, 0x00) { + m_messageHeaderPrefix[9] = (uint8_t)m_posID.size(); + + for (int p = 0; p < apak.size(); p+=2) { + uint8_t n = strtoul(apak.mid(p, 2).toStdString().c_str(), nullptr, 16); + m_apak.push_back(n); + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << apak << m_apak.toHex(':'); + qCritical() << DBG_HEADER << m_posID.toHex(':'); + qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':'); + } +} + +MessageHelper::MessageHelper(QByteArray const &posID, QString const &apak) + : m_posID(posID) + , m_posIDLength(m_posID.size()) + , m_messageHeaderPrefix(1 + PACKET_ID_SIZE + 1, 0x00) + , m_rawPacket(IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE, 0x00) { + m_messageHeaderPrefix[9] = (uint8_t)m_posID.size(); + + for (int p = 0; p < apak.size(); p+=2) { + uint8_t n = strtoul(apak.mid(p, 2).toStdString().c_str(), nullptr, 16); + m_apak.push_back(n); + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << apak << m_apak.toHex(':'); + qCritical() << DBG_HEADER << m_posID.toHex(':'); + qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':'); + } +} + +MessageHelper::~MessageHelper() { + +} + +void MessageHelper::handleMessage(char const *pData) { + +#if 0 + //unsigned char marker = pData[0]; +// unsigned int tagNameLength = pData[1]; + unsigned char tagName[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; +// unsigned int curElementLength = 0; + //unsigned char curElement[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; + //unsigned char receiptData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1]; + unsigned char rxBuf[20]; +// unsigned char flags[129]; +// unsigned char docNr[32]; + //unsigned char messageType = pData[1]; + + unsigned int uitmp = 0; + unsigned int uitmp2 = 0; + + iuc_asynchpos_sub_initArray(tagName, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + //iuc_asynchpos_sub_initArray(curElement, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + + uitmp = biox_FindStrInBufferInt("LoginResult",pData) | biox_FindStrInBuffer("LOGINRESULT",pData); + if (uitmp) { + asynchState = 0x02; //eingeloggt + /*rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,40,0x69,0);*/ + } + + uitmp = biox_FindStrInBufferInt("AuthorizationStarted",pData) | biox_FindStrInBuffer("AUTHORIZATIONSTARTED",pData); + if (uitmp) { + iuc_asynchpos_sub_initArray(rxBuf,5); + rxBuf[0] = 0x53; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,5,0x69,0); + } + + uitmp = biox_FindStrInBufferInt("AuthorizationResult",pData) | biox_FindStrInBuffer("AUTHORIZATIONRESULT",pData); + if (uitmp) { + asynchState = 0x03; //successfully authorized + iuc_asynchpos_sub_clear_message(0x00); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]); + //uitmp = biox_FindStrInBuffer("Result",pData) | biox_FindStrInBuffer("RESULT",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.result, 0, pData[uitmp + 1]); + + brd_SendDiagStr("->IUC ASYNCHPOS message ID: ",0); + brd_SendDiagBlock(asynchBill.id,1,36); + + /*if (iuc_asynch_PrintControl) { + brd_SendDiagStr("->IUC ASYNCHPOS print data send AUTH: ",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + iuc_asynch_PrintControl = 0x00; + //biox_delay_ms(750); + } else { + brd_SendDiagStr("->IUC ASYNCHPOS sending authorization: ",1); + iuc_asynch_PrintControl = 0x01; + }*/ + + uitmp = biox_FindStrInBufferInt("ERROR",pData); + if (!uitmp/*biox_FindStrInBuffer("OK",pData) | biox_FindStrInBuffer("Approved",pData) | biox_FindStrInBuffer("APPROVED",asynchBill.result)*/) { + iuc_asynch_PrintControl |= 0xF0; + /*uitmp = biox_FindStrInBufferInt("Amount",pData) | biox_FindStrInBufferInt("AMOUNT",pData); + //if (pData[uitmp + 1] <= 10) { + biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, pData[uitmp + 1]); + //} else { + //biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, 10); + //}*/ + + //uitmp = biox_FindStrInBuffer("Token",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.token, 0, pData[uitmp + 1]); + /*uitmp = biox_FindStrInBufferInt("Authcode",pData) | biox_FindStrInBufferInt("AUTHCODE",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.authCode, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("RRN",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.rrn, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("STAN",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.stan, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("CardType",pData) | biox_FindStrInBufferInt("CARDTYPE",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.cardtype, 0, pData[uitmp + 1]);*/ + asynchState = 0x04; + + brd_SendDiagStr("->IUC ASYNCHPOS authorization confirmed.",1); + + /*iuc_asynchpos_sub_initArray(rxBuf,20); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,20,0x69,0);*/ + + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_command_close_Document(); + } else { + iuc_asynch_PrintControl |= 0xF0; + //uitmp = biox_FindStrInBufferInt("ErrCode",pData) | biox_FindStrInBufferInt("ERRCODE",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.errCode, 0, pData[uitmp + 1]); + + brd_SendDiagStr("->IUC ASYNCHPOS authorization failed.",1); + + /*iuc_asynchpos_sub_initArray(rxBuf,20); + rxBuf[0] = 0x45; + rxBuf[1] = 0xFF; + biox_CopyBlock(pData, uitmp + 2, rxBuf, 2, pData[uitmp + 1]); + vmc_SendWithBuffer(rxBuf,20,0x69,0);*/ + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + } + } + + uitmp = biox_FindStrInBufferInt("PrintReceipt",pData) | biox_FindStrInBufferInt("PRINTRECEIPT",pData); + if (uitmp) { + asynchState = 0x03; //Customer receipt recieved + //iuc_asynchpos_sub_initArray(flags,129); + //uitmp = biox_FindStrInBufferInt("Flag",pData) | biox_FindStrInBufferInt("FLAG",pData) | biox_FindStrInBufferInt("Flags",pData) | biox_FindStrInBufferInt("FLAGS",pData); + /*if (uitmp) { + biox_CopyBlock(pData, uitmp + 2, flags, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("CD",flags) | biox_FindStrInBufferInt("LR",flags); + }*/ + + /*iuc_asynchpos_sub_clear_message(0x00); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]);*/ + iuc_asynchpos_sub_initArray(asynchBill.printId,129); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.printId, 0, pData[uitmp + 1]); + + //if(asynchState == 0x02/* && uitmp biox_FindStrInBufferInt("CD",flags) || biox_FindStrInBufferInt("LR",flags)*/) { + if((!iuc_asynch_PRNrecieved) && (biox_FindStrInBufferInt("CD",pData) || biox_FindStrInBufferInt("LR",pData)) ) { + iuc_asynch_PRNrecieved = 0x01; + iuc_asynchpos_sub_initArray(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1); + uitmp = /*biox_FindStrInBuffer("ReceiptText",pData) | */biox_FindStrInBufferInt("RECEIPTTEXT",pData); + uitmp2 = (pData[uitmp] * 256) + pData[uitmp + 1]; + + //if (uitmp2 <= IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + if (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + uitmp2 = IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large! Cutting off.",1); + /*receiptData[0] = 0x50; + biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*); + //uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + //uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0); + brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynch_PrintControl |= 0x0F;*/ + + /*if (iuc_asynch_PrintControl) { + brd_SendDiagStr("->IUC ASYNCHPOS print data send: ",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + iuc_asynch_PrintControl = 0x00; + } else { + brd_SendDiagStr("->IUC ASYNCHPOS print data stored: ",1); + iuc_asynch_PrintControl = 0x01; + }*/ + //biox_delay_ms(750); + + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_command_close_Document(); + + //iuc_asynchpos_resetBuffers(0x02); + //iuc_asynchpos_command_print_Result(0x01); + } + + receiptData[0] = 0x50; + biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*/); + + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0); + brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynch_PrintControl |= 0x0F; + + /* else { + //receiptData[0] = 0x50; + //iuc_asynchpos_sub_initZero(receiptData,1); + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large!",1); + iuc_asynch_PrintControl |= 0x0E; + } */ + /* else { + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x00); + }*/ + } + + //++iuc_print_counter; + + //if(asynchState == 0x04 && iuc_asynch_PrintControl == 0) { + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_resetBuffers(0x00); + //iuc_asynchpos_command_print_Result(0x01); + /*} /else { + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x01); + }*/ + //iuc_asynchpos_command_print_Result(0x01); + + /*while (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + biox_CopyBlock(pData, uitmp + 2, receiptData, 0, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + } + + //Rest des Packets + biox_CopyBlock(pData, uitmp + 2, receiptData, 0, uitmp2); + vmc_SendWithBuffer(receiptData,uitmp2,0x69,0); + + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x01);*/ + } + + uitmp = biox_FindStrInBufferInt("VoidResult",pData) | biox_FindStrInBufferInt("VOIDRESULT",pData); + if (uitmp) { + asynchState = 0x01; //There was a cancel. Relogin and try again. + uitmp = biox_FindStrInBufferInt("ERROR",pData); + if (uitmp) { + rxBuf[0] = 0x45; + rxBuf[1] = 0x56; + rxBuf[2] = 0x45; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + } + + uitmp = biox_FindStrInBufferInt("REFUND",pData); + if (uitmp) { + rxBuf[0] = 0x45; + rxBuf[1] = 0x56; + rxBuf[2] = 0x52; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + //TODO refund bill here. Should not trigger, but it might. + } + } + + uitmp = biox_FindStrInBufferInt("DocClosed",pData); + if (uitmp) { + asynchState = 0x01; //Transaction successful + + //if (VendRequest) + GWstate.VendRequest=0; + } +#endif +} + +void MessageHelper::handleCommand(AsyncPosCommand command, char status) { + //r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt + +#if 0 + UCHAR tempBuf[3]; + UCHAR rxBuf[8]; +// UINT uitemp = 0; +UINT uitmp= 700; + + tempBuf[0] = 0x00; + tempBuf[1] = 0x00; + tempBuf[2] = 0x00; + + timeHoldISMAS = GWglobTime.SecOfDay; + + iuc_asynchpos_sub_initArray(rxBuf,8); + //iuc_asynchpos_resetBuffers(0x00); + + switch (command) { + case 0x72: //registration + //iuc_asynchpos_init(); + asynchState = 0x01; + iuc_asynchpos_command_Login(); + GWstate.VendRequest=1; + break; + case 0x61: //authorisation + iuc_asynch_keepAlive = 0x01; + iuc_asynch_PrintControl = 0; + iuc_asynchpos_sub_clear_message(0x01); + //VendRequest=1; + iuc_asynchpos_resetBuffers(0x00); + ///#ifdef IUC_ASYCHNPOS_TESTMODE + //iuc_asynchpos_command_authorize(uitmp); + //#else + iuc_asynchpos_command_authorize(Vend.Amount); + //#endif + break; + case 0x63: //cancel + case 0x73: //storno + /*if (asynchState <= 0x02 != 0) { //Authorization result recieved? + iuc_asynchpos_command_cancel_authorize(); + } else {*/ + iuc_asynchpos_command_close_Document(0x01); + //} + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + break; + case 0x6B: //kassenschnitt + iuc_asynchpos_command_Logout(); + break; + case 0x62: //get last bill + //iuc_zvt_getLastBill(tempBuf); + break; + case 0x01: iuc_asynchpos_command_close_Document(0x00); + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + break; + case 0x70: iuc_asynchpos_command_ping_terminal(); + break; + default: + break; + } +#endif +} + +void MessageHelper::createRawPacket(PacketType packetType, + QByteArray const &encryptedPacketID, + QByteArray const &message) { + if (createMessageHeaderPrefix(packetType, encryptedPacketID)) { + QByteArray ba(m_messageHeaderPrefix); + ba = ba.append(m_posID); + ba = ba.append(message); + + uint16_t const size = ba.size(); + + ba.push_front((char)size); + ba.push_front((char)(size >> 8)); + + m_rawPacket = ba; + } +} + +bool MessageHelper::setMessageHeaderPacketType(PacketType packetType) { + + switch (packetType) { + case PacketType::POS_ECR: + case PacketType::MESSAGE_RECEIVED_POSITIVE_ACK: + case PacketType::MESSAGE_RECEIVED_NEGATIVE_ACK: + m_messageHeaderPrefix[0] = (uint8_t)packetType; + break; + default: + return false; + } + return true; +} + +bool MessageHelper::createMessageHeaderPrefix(PacketType packetType, QByteArray const &encryptedPacketID) { + if (encryptedPacketID.size() == PACKET_ID_SIZE) { + if (setMessageHeaderPacketType(packetType)) { + for (int i = 1; i <= 8; ++i) { + m_messageHeaderPrefix[i] = (uint8_t)encryptedPacketID[i-1]; + } + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':'); + } + return true; + } + } + return false; +} + + +QByteArray const &MessageHelper::generateUniqueTransactionID(QString const &machineNr, + QString const &customerNr) { + + // TODO: wieder entfernen + QDateTime dt(QDateTime::fromString("2024-06-18T12:00:00", Qt::ISODate)); + + uint64_t const transID = MessageHelper::secsSinceJan2017(dt); + + m_uniqueTransactionID.clear(); + m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(std::to_string(transID).c_str(), 9).rightJustified(10, '0')); + m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(machineNr.toStdString().c_str()).rightJustified(5, '0')); + m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(customerNr.toStdString().c_str()).rightJustified(4, '0')); + + return m_uniqueTransactionID; +} + +// actual payment. amount to pay is known. +void MessageHelper::createAuthorizeMessage() { + m_authorizeMessage.clear(); + + m_authorizeMessage.push_back((char)0x89); // 9 in 0x89 is the size + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Authorize")); + + QString const &price= m_price.setNum(1000); + + m_authorizeMessage.push_back((char)0x06); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Amount")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)price.size()); + m_authorizeMessage = m_authorizeMessage.append(QByteArray(price.toStdString().c_str())); + + m_authorizeMessage.push_back((char)0x04); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Cash")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)0x01); + m_authorizeMessage.push_back((char)0x30); + + m_authorizeMessage.push_back((char)0x08); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Currency")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)0x03); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("978")); + + m_authorizeMessage.push_back((char)0x05); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("DocNr")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)0x13); + m_authorizeMessage = m_authorizeMessage.append(generateUniqueTransactionID("1000", "100")); + + m_authorizeMessage.push_back((char)0x04); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Time")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)0x13); + + QDateTime current = QDateTime::currentDateTime(); + // TODO: wieder entfernen + current.setTime(QTime(12, 0, 0)); + current.setDate(QDate(2024, 6, 18)); + + QByteArray time(current.toString(Qt::ISODate).toStdString().c_str()); + time[10] = ' '; + m_authorizeMessage = m_authorizeMessage.append(QByteArray(time)); + + m_authorizeMessage.push_back((char)0x04); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("Lang")); + m_authorizeMessage.push_back((char)0x00); + m_authorizeMessage.push_back((char)0x02); + m_authorizeMessage = m_authorizeMessage.append(QByteArray("lt")); + + m_authorizeMessage.push_back((char)0x00); +} + +void MessageHelper::createCancelAuthorizeMessage() { + m_cancelAuthorizeMessage.clear(); + + m_cancelAuthorizeMessage.push_back((char)0x96); // 0x80 + 0x16 + m_cancelAuthorizeMessage = m_cancelAuthorizeMessage.append(QByteArray("AuthorizationCancelled")); + + m_cancelAuthorizeMessage.push_back((char)0x02); + m_cancelAuthorizeMessage = m_authorizeMessage.append(QByteArray("ID")); + + m_cancelAuthorizeMessage.push_back((char)0x00); + m_cancelAuthorizeMessage.push_back((char)QByteArray(m_asyncBillData.id).size()); + m_cancelAuthorizeMessage = m_cancelAuthorizeMessage.append(QByteArray(m_asyncBillData.id)); + + m_cancelAuthorizeMessage.push_back((char)0x00); +} + +void MessageHelper::createPingMessage() { + m_pingMessage.clear(); + + m_pingMessage.push_back((char)0x84); // 4 in 0x84 is the size + m_pingMessage = m_pingMessage.append(QByteArray("Ping")); + + m_pingMessage.push_back((char)0x04); + m_pingMessage = m_authorizeMessage.append(QByteArray("Time")); + m_pingMessage.push_back((char)0x00); + m_pingMessage.push_back((char)0x13); + + QDateTime current = QDateTime::currentDateTime(); + // TODO: wieder entfernen + current.setTime(QTime(12, 0, 0)); + current.setDate(QDate(2024, 6, 18)); + + QByteArray time(current.toString(Qt::ISODate).toStdString().c_str()); + time[10] = ' '; + m_pingMessage = m_pingMessage.append(QByteArray(time)); + + m_pingMessage.push_back((char)0x00); +} + +void MessageHelper::createCloseDocumentMessage(bool storno) { + m_closeDocumentMessage.clear(); + + m_closeDocumentMessage.push_back((char)0x89); // 9 in 0x89 is the size + m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("DocClosed")); + + m_closeDocumentMessage.push_back((char)0x05); + m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("DocNr")); + + uint16_t const docNrSize = m_uniqueTransactionID.size(); + + m_closeDocumentMessage.push_back((char)(docNrSize >> 8)); + m_closeDocumentMessage.push_back((char)(docNrSize)); + m_closeDocumentMessage = m_closeDocumentMessage.append(m_uniqueTransactionID); + + if (!storno) { + m_closeDocumentMessage.push_back((char)0x06); + m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("AuthID")); + + QByteArray ba(m_authorizationResult.m_id.toStdString().c_str()); + uint16_t const authIdSize = ba.size(); + + m_closeDocumentMessage.push_back((char)(authIdSize >> 8)); + m_closeDocumentMessage.push_back((char)(authIdSize)); + + m_closeDocumentMessage = m_closeDocumentMessage.append(ba); + } + + m_closeDocumentMessage.push_back((char)0x00); +} + +void MessageHelper::createPrintResultMessage() { + m_printResultMessage.clear(); +} + +uint32_t MessageHelper::secsSinceJan2017(QDateTime const &dt) { + return QDateTime(QDateTime::fromString("2017-01-01T00:00:00", Qt::ISODate)).secsTo(dt); +} + +void MessageHelper::createLoginMessage() { + m_loginMessage.clear(); + + m_loginMessage.push_back((char)0x85); // 5 in 0x85 is the size + m_loginMessage = m_loginMessage.append(QByteArray("Login")); + + m_loginMessage.push_back((char)0x04); + m_loginMessage = m_loginMessage.append(QByteArray("Time")); + m_loginMessage.push_back((char)0x00); + m_loginMessage.push_back((char)0x13); + + QDateTime current = QDateTime::currentDateTime(); + // TODO: wieder entfernen + current.setTime(QTime(12, 0, 0)); + current.setDate(QDate(2024, 6, 18)); + + QByteArray time(current.toString(Qt::ISODate).toStdString().c_str()); + time[10] = ' '; + m_loginMessage = m_loginMessage.append(time); + + m_loginMessage.push_back((char)0x05); + m_loginMessage = m_loginMessage.append(QByteArray("Flags")); + m_loginMessage.push_back((char)0x00); + m_loginMessage.push_back((char)0x06); + m_loginMessage = m_loginMessage.append(QByteArray("AP3|LR")); + + m_loginMessage.push_back((char)0x00); + + if (DBG_LEVEL >= DBG_INFORMATION) { + qCritical() << DBG_HEADER << "loginMessage" << m_loginMessage.toHex(':'); + } +} + +void MessageHelper::createLogoutMessage() { + m_logoutMessage.clear(); + + m_logoutMessage.push_back((char)0x86); // 6 in 0x86 is the size + m_logoutMessage = m_loginMessage.append(QByteArray("Logout")); + + m_loginMessage.push_back((char)0x04); + m_loginMessage = m_loginMessage.append(QByteArray("Time")); + m_loginMessage.push_back((char)0x00); + m_loginMessage.push_back((char)0x13); + + QDateTime current = QDateTime::currentDateTime(); + // TODO: wieder entfernen + current.setTime(QTime(12, 0, 0)); + current.setDate(QDate(2024, 6, 18)); + + QByteArray time(current.toString(Qt::ISODate).toStdString().c_str()); + time[10] = ' '; + m_logoutMessage = m_logoutMessage.append(time); + + m_loginMessage.push_back((char)0x00); + + if (DBG_LEVEL >= DBG_INFORMATION) { + qCritical() << DBG_HEADER << "loginMessage" << m_logoutMessage.toHex(':'); + } +} + +QByteArrayList const &MessageHelper::createMessageChunksToSend(AsyncPosCommand cmd, char etx) { + QByteArray encryptedPacketID(QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08")); + + m_messageChunkList.clear(); + + switch (cmd) { + case (int)MessageHelper::AsyncPosCommand::LOGIN: + createLoginMessage(); + createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_loginMessage); + break; + case (int)MessageHelper::AsyncPosCommand::LOGOUT: + createLogoutMessage(); + createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_logoutMessage); + break; + case (int)MessageHelper::AsyncPosCommand::AUTHORIZE: + createAuthorizeMessage(); + createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_authorizeMessage); + break; + case (int)MessageHelper::AsyncPosCommand::CLOSE_DOCUMENT: + createCloseDocumentMessage(); // actung: hier default parameter + createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_closeDocumentMessage); + break; + default:; + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << m_rawPacket.toHex(':'); + } + + QByteArray const &ba = m_rawPacket.mid(11); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << ba.toHex(':'); + } + + // calculate crc32 on message starting from (including) POSID length + uint32_t crc = TU::crc32(ba); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << "crc32" << hex << crc; + } + + unsigned char cipherText[256]; + memset(cipherText, 0, sizeof(cipherText)); + + // XOR crc32-value (4 bytes) with APAK starting from left + // (rest of APAK untouched) + QByteArray clearText(m_apak); + clearText[0] = clearText[0] ^ ((uint8_t)(crc >> 24)); + clearText[1] = clearText[1] ^ ((uint8_t)(crc >> 16)); + clearText[2] = clearText[2] ^ ((uint8_t)(crc >> 8)); + clearText[3] = clearText[3] ^ ((uint8_t)(crc >> 0)); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << "clearText" << clearText.toHex(); + } + + // encrypt XOR result with APAK using AES129, ECB mode + aes_encrypt((uint8_t *)clearText.data(), + (uint8_t *)cipherText, + (uint8_t *)m_apak.toStdString().c_str()); + + // 8 left bytes of encryption result is signature (Packet ID) + encryptedPacketID = QByteArray((const char *)cipherText, 8); + + if (DBG_LEVEL >= DBG_INFORMATION) { + qCritical() << DBG_HEADER << "cipherText (new PacketID)" << encryptedPacketID.toHex(':'); + } + + // insert PacketID in packet + if (insertEncryptedPacketID(encryptedPacketID)) { + + // build chunks to be sent over serial line + + int const chunks = m_rawPacket.size() / IUC_ASYNCHPOS_MIN_PACKET_SIZE; + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << "nr of chunks" << chunks; + } + + int i = 0; + for (; i < chunks; ++i) { + QByteArray messageChunk = m_rawPacket.mid(IUC_ASYNCHPOS_MIN_PACKET_SIZE*i, + IUC_ASYNCHPOS_MIN_PACKET_SIZE); + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << i << "unmasked" << messageChunk.toHex(':'); + } + + messageChunk = MessageHelper::mask(messageChunk); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << i << " masked" << messageChunk.toHex(':'); + } + + messageChunk.push_back(etx == ACK1 ? ETX2 : ETX1); // etx must be ACK1 or ACK2 + + char const lrc = TU::lrc(messageChunk); + messageChunk.push_back(lrc); + messageChunk.push_front(STX); + + if (DBG_LEVEL >= DBG_INFORMATION) { + qCritical() << DBG_HEADER << "chunk to send" << messageChunk.toHex(':'); + } + + m_messageChunkList += messageChunk; + } + + int const rest = m_rawPacket.size() % IUC_ASYNCHPOS_MIN_PACKET_SIZE; + if (rest) { + QByteArray messageChunk = m_rawPacket.mid(IUC_ASYNCHPOS_MIN_PACKET_SIZE*chunks, rest); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << i << "unmasked" << messageChunk.toHex(':'); + } + + messageChunk = mask(messageChunk); + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << i << " masked" << messageChunk.toHex(':'); + } + + messageChunk.push_back(etx == ACK1 ? ETX2 : ETX1); // etx must be ACK1 or ACK2 + + char const lrc = TU::lrc(messageChunk); + messageChunk.push_back(lrc); + messageChunk.push_front(STX); + + + if (DBG_LEVEL >= DBG_INFORMATION) { + qCritical() << DBG_HEADER << "chunk to send" << messageChunk.toHex(':'); + } + + m_messageChunkList += messageChunk; + } + } + + return m_messageChunkList; +} + +QByteArrayList MessageHelper::createLoginMessageChunksToSend(char etx) { + return createMessageChunksToSend(AsyncPosCommand::LOGIN, etx); +} + +QByteArrayList MessageHelper::createLogoutMessageChunksToSend(char etx) { + return createMessageChunksToSend(AsyncPosCommand::LOGOUT, etx); +} + +QByteArrayList MessageHelper::createAuthorizeMessageChunksToSend(char etx) { + return createMessageChunksToSend(AsyncPosCommand::AUTHORIZE, etx); +} + +QByteArrayList MessageHelper::createCloseDocumentMessageChunksToSend(char etx) { + return createMessageChunksToSend(AsyncPosCommand::CLOSE_DOCUMENT, etx); +} + +bool MessageHelper::insertEncryptedPacketID(QByteArray const &encryptedPacketID) { + if (encryptedPacketID.size() == PACKET_ID_SIZE) { + // m_rawPacket has already full length + for (int i = 0; i < PACKET_ID_SIZE; ++i) { + m_messageHeaderPrefix[i+1] = encryptedPacketID[i]; + m_rawPacket[i+3] = encryptedPacketID[i]; + } + + if (DBG_LEVEL >= DBG_DEBUG) { + qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':'); + qCritical() << DBG_HEADER << m_rawPacket.toHex(':'); + } + + return true; + } + return false; +} + +QByteArray const &MessageHelper::mask(QByteArray &messageChunk) { + QByteArray ba; + for (int i = 0; i < messageChunk.size(); ++i) { + char const c = messageChunk[i]; + switch(c) { + case STX: __attribute__((fallthrough)); + case ETX1: __attribute__((fallthrough)); + case ETX2: __attribute__((fallthrough)); + case EOT: __attribute__((fallthrough)); + case ENQ: __attribute__((fallthrough)); + case ACK1: __attribute__((fallthrough)); + case ACK2: __attribute__((fallthrough)); + case DLE: __attribute__((fallthrough)); + case NAK: + ba.push_back(char(DLE)); + ba.push_back(c + 0x30); + break; + default: + ba.push_back(c); + } + } + + messageChunk = ba; + return messageChunk; +} + +QByteArray const &MessageHelper::unMask(QByteArray &messageChunk) { + QByteArray ba; + for (int i = 0; i < messageChunk.size(); ++i) { + char c = messageChunk[i]; + if (c == (char)0x10) /* DEL */ { + if ((i+1) < messageChunk.size()) { + c = messageChunk[i+1] - (char)0x30; + } + } + ba.push_back(c); + } + messageChunk = ba; + return messageChunk; +} diff --git a/main/MessageHelper.h b/main/MessageHelper.h new file mode 100644 index 0000000..422112a --- /dev/null +++ b/main/MessageHelper.h @@ -0,0 +1,112 @@ +#ifndef MESSAGE_HELPER_H_INCLUDED +#define MESSAGE_HELPER_H_INCLUDED + +#include +#include +#include +#include +#include + +class MessageHelper { +public: + enum PacketType : std::uint8_t { + POS_ECR = 0, + // POS_EXT = 1, + MESSAGE_RECEIVED_POSITIVE_ACK = 0x0A, + MESSAGE_RECEIVED_NEGATIVE_ACK = 0x0F + // POS_HOST_FORMAT_1_ENCRYPTED = 0x11, + // POS_HOST_FORMAT_1_UNENCRYPTED = 0x21 + }; + + enum AsyncPosCommand : std::uint8_t { + LOGIN = 0, + LOGOUT = 1, + AUTHORIZE = 2, + CLOSE_DOCUMENT = 3 + }; + + explicit MessageHelper(QString const &posID = "T-TPS-SELF2002in", + QString const &apak = "8AC304380E0E476BA2558B75DB9E2516"); + explicit MessageHelper(QByteArray const &posID, QString const &apak); + ~MessageHelper(); + + + void createRawPacket(PacketType PacketType, + QByteArray const &encryptedPacketId, + QByteArray const &message); + + bool insertEncryptedPacketID(QByteArray const &encryptedPacketID); + + QByteArrayList createLoginMessageChunksToSend(char etx); + QByteArrayList createLogoutMessageChunksToSend(char etx); + QByteArrayList createAuthorizeMessageChunksToSend(char etx); + QByteArrayList createCloseDocumentMessageChunksToSend(char etx); + QByteArrayList const &createMessageChunksToSend(AsyncPosCommand cmd, char etx); + +// private: + + QByteArray m_posID; + QByteArray m_apak; + uint8_t m_posIDLength; + QByteArray m_messageHeaderPrefix; + QByteArray m_rawPacket; // without leading STX and trailing [ETX(1/2), LRC] + QByteArray m_loginMessage; + QByteArray m_logoutMessage; + QByteArray m_authorizeMessage; + QByteArray m_cancelAuthorizeMessage; + QByteArray m_pingMessage; + QByteArray m_printResultMessage; + QByteArray m_closeDocumentMessage; + QByteArray m_uniqueTransactionID; + QString m_price; + QByteArrayList m_messageChunkList; + + bool setMessageHeaderPacketType(PacketType packetType); + + bool createMessageHeaderPrefix(PacketType packetType, QByteArray const &encryptedPacketID); + void createLoginMessage(); + void createLogoutMessage(); + void createAuthorizeMessage(); + void createCancelAuthorizeMessage(); + void createPingMessage(); + void createCloseDocumentMessage(bool storno = false); + void createPrintResultMessage(); + + void handleCommand(AsyncPosCommand command, char status); + //r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt + + void handleMessage(char const *pData); + + QByteArray const &generateUniqueTransactionID(QString const &machineNr, QString const &customerNumer); + + static QByteArray const &mask(QByteArray &messageChunk); + static QByteArray const &unMask(QByteArray &messageChunk); + static uint32_t secsSinceJan2017(QDateTime const &dt = QDateTime::currentDateTime()); + + struct AsynchBillData { + char time[20]; + char id[37]; + char printId[129]; + char docNr[33]; + //unsigned char amount[10]; + //unsigned char token[25]; + //unsigned char result[8]; + //unsigned char authCode[7]; + //unsigned char rrn[13]; + //unsigned char stan[7]; + //unsigned char cardtype[33]; + char errCode[17]; + //unsigned char receiptData[IUC_ASYNCHPOS_RECEIPT_LENGTH]; + }; + + struct AuthorizationResult { + QString m_id; // max. 36 + QString m_docNr; // max. 32 + QString m_result; // "OK" or "ERROR" + }; + + static AsynchBillData m_asyncBillData; + static AuthorizationResult m_authorizationResult; +}; + +#endif // MESSAGE_HELPER_H_INCLUDED diff --git a/main/aes128.cpp b/main/aes128.cpp new file mode 100755 index 0000000..555aede --- /dev/null +++ b/main/aes128.cpp @@ -0,0 +1,625 @@ +/* + * aes128.c + * + * Created: 27.11.2017 13:33:29 + * Author: Matthias + */ + +#include + +/* the expanded keySize */ +#define EXPANDED_KEY_SIZE 176 +//int expandedKeySize; + +/* the expanded key */ +//unsigned char expandedKey[EXPANDED_KEY_SIZE]; + +/* the cipher key */ +//unsigned char key[16]; + +/* the cipher key size */ + +enum keySize{ + SIZE_16 = 16, + SIZE_24 = 24, + SIZE_32 = 32 +}; + +//enum keySize size; + +unsigned char sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E +0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F + +unsigned char rsbox[256] = +{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 +, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; + +unsigned char Rcon[256] = { + + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, + 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, + 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, + 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, + 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, + 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, + 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, + 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, + 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, + 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, + 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, +0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d}; + +void aes_init() { + //UINT uitemp = 0; + /* the expanded keySize */ + //expandedKeySize = EXPANDED_KEY_SIZE; + + /* the cipher key */ + //for (uitemp = 0; uitemp < 16; ++uitemp) + //key[uitemp] = 0x00; + + /* the cipher key size */ + //size = SIZE_16; +} + +unsigned char getSBoxValue(unsigned char num) +{ + return sbox[num]; +} + +unsigned char getSBoxInvert(unsigned char num) +{ + return rsbox[num]; +} + +//Key generation + +/* Rijndael's key schedule rotate operation + * rotate the word eight bits to the left + * + * rotate(1d2c3a4f) = 2c3a4f1d + * + * word is an char array of size 4 (32 bit) + */ +void rotate(unsigned char *word) +{ + unsigned char c; + int i; + + c = word[0]; + for (i = 0; i < 3; i++) + word[i] = word[i+1]; + word[3] = c; +} + +unsigned char getRconValue(unsigned char num) +{ + return Rcon[num]; +} + +void core(unsigned char *word, int iteration) +{ + int i; + + /* rotate the 32-bit word 8 bits to the left */ + rotate(word); + + /* apply S-Box substitution on all 4 parts of the 32-bit word */ + for (i = 0; i < 4; ++i) + { + word[i] = getSBoxValue(word[i]); + } + + /* XOR the output of the rcon operation with i to the first part (leftmost) only */ + word[0] = word[0]^getRconValue(((unsigned char) iteration)); +} + +/* Rijndael's key expansion + * expands an 128,192,256 key into an 176,208,240 bytes key + * + * expandedKey is a pointer to an char array of large enough size + * key is a pointer to a non-expanded key + */ + +void expandKey(unsigned char *expandedKey, + unsigned char *key, + enum keySize size, + /*size_t*/ unsigned int expandedKeySize) +{ + /* current expanded keySize, in bytes */ + int currentSize = 0; + int rconIteration = 1; + int i; + unsigned char t[4] = {0,0,0,0}; // temporary 4-byte variable + + /* set the 16,24,32 bytes of the expanded key to the input key */ + for (i = 0; i < size; i++) + expandedKey[i] = key[i]; + currentSize += size; + + while (currentSize < expandedKeySize) + { + /* assign the previous 4 bytes to the temporary value t */ + for (i = 0; i < 4; i++) + { + t[i] = expandedKey[(currentSize - 4) + i]; + } + + /* every 16,24,32 bytes we apply the core schedule to t + * and increment rconIteration afterwards + */ + if(currentSize % size == 0) + { + core(t, rconIteration++); + } + + /* For 256-bit keys, we add an extra sbox to the calculation */ + if(size == SIZE_32 && ((currentSize % size) == 16)) { + for(i = 0; i < 4; i++) + t[i] = getSBoxValue(t[i]); + } + + /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key. + * This becomes the next four bytes in the expanded key. + */ + for(i = 0; i < 4; i++) { + expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[i]; + currentSize++; + } + } +} + +//Encrypt + +void subBytes(unsigned char *state) +{ + int i; + /* substitute all the values from the state with the value in the SBox + * using the state value as index for the SBox + */ + for (i = 0; i < 16; i++) + state[i] = getSBoxValue(state[i]); +} + +void shiftRow(unsigned char *state, unsigned char nbr) +{ + int i, j; + unsigned char tmp; + /* each iteration shifts the row to the left by 1 */ + for (i = 0; i < nbr; i++) + { + tmp = state[0]; + for (j = 0; j < 3; j++) + state[j] = state[j+1]; + state[3] = tmp; + } +} + +void shiftRows(unsigned char *state) +{ + int i; + /* iterate over the 4 rows and call shiftRow() with that row */ + for (i = 0; i < 4; i++) + shiftRow(state+i*4, i); +} + +void addRoundKey(unsigned char *state, unsigned char *roundKey) +{ + int i; + for (i = 0; i < 16; i++) + state[i] = state[i] ^ roundKey[i] ; +} + +unsigned char galois_multiplication(unsigned char a, unsigned char b) +{ + unsigned char p = 0; + unsigned char counter; + unsigned char hi_bit_set; + for(counter = 0; counter < 8; counter++) { + if((b & 1) == 1) + p ^= a; + hi_bit_set = (a & 0x80); + a <<= 1; + if(hi_bit_set == 0x80) + a ^= 0x1b; + b >>= 1; + } + return p; +} + +void mixColumn(unsigned char *column) +{ + unsigned char cpy[4]; + int i; + for(i = 0; i < 4; i++) + { + cpy[i] = column[i]; + } + column[0] = galois_multiplication(cpy[0],2) ^ + galois_multiplication(cpy[3],1) ^ + galois_multiplication(cpy[2],1) ^ + galois_multiplication(cpy[1],3); + + column[1] = galois_multiplication(cpy[1],2) ^ + galois_multiplication(cpy[0],1) ^ + galois_multiplication(cpy[3],1) ^ + galois_multiplication(cpy[2],3); + + column[2] = galois_multiplication(cpy[2],2) ^ + galois_multiplication(cpy[1],1) ^ + galois_multiplication(cpy[0],1) ^ + galois_multiplication(cpy[3],3); + + column[3] = galois_multiplication(cpy[3],2) ^ + galois_multiplication(cpy[2],1) ^ + galois_multiplication(cpy[1],1) ^ + galois_multiplication(cpy[0],3); +} + +void mixColumns(unsigned char *state) +{ + int i, j; + unsigned char column[4]; + + /* iterate over the 4 columns */ + for (i = 0; i < 4; i++) + { + /* construct one column by iterating over the 4 rows */ + for (j = 0; j < 4; j++) + { + column[j] = state[(j*4)+i]; + } + + /* apply the mixColumn on one column */ + mixColumn(column); + + /* put the values back into the state */ + for (j = 0; j < 4; j++) + { + state[(j*4)+i] = column[j]; + } + } +} + +void aes_round(unsigned char *state, unsigned char *roundKey) +{ + subBytes(state); + shiftRows(state); + mixColumns(state); + addRoundKey(state, roundKey); +} + +void createRoundKey(unsigned char *expandedKey, unsigned char *roundKey) +{ + int i,j; + /* iterate over the columns */ + for (i = 0; i < 4; i++) + { + /* iterate over the rows */ + for (j = 0; j < 4; j++) + roundKey[(i+(j*4))] = expandedKey[(i*4)+j]; + } +} + +void aes_main(unsigned char *state, unsigned char *expandedKey, int nbrRounds) +{ + int i = 0; + + unsigned char roundKey[16]; + + createRoundKey(expandedKey, roundKey); + addRoundKey(state, roundKey); + + for (i = 1; i < nbrRounds; i++) { + createRoundKey(expandedKey + 16*i, roundKey); + aes_round(state, roundKey); + } + + createRoundKey(expandedKey + 16*nbrRounds, roundKey); + subBytes(state); + shiftRows(state); + addRoundKey(state, roundKey); +} + +char aes_encrypt(unsigned char *input, + unsigned char *output, + unsigned char *key + /*, enum keySize size*/) +{ + enum keySize size = SIZE_16; + /* the expanded keySize */ + int expandedKeySize; + + /* the number of rounds */ + int nbrRounds = 10; //NOTE: modded + + /* the expanded key */ + //NOTE: modded: unsigned char *expandedKey = 0x00; + //unsigned char expandedKey[(16*(nbrRounds+1))]; + unsigned char expandedKey[176]; + + /* the 128 bit block to encode */ + unsigned char block[16]; + + int i,j; + + /* set the number of rounds */ + /*switch (size) + { + case SIZE_16: + nbrRounds = 10; + break; + case SIZE_24: + nbrRounds = 12; + break; + case SIZE_32: + nbrRounds = 14; + break; + default: + return 1; //UNKNOWN_KEYSIZE; + break; + }*/ //NOTE: modded + + expandedKeySize = (16*(nbrRounds+1)); + /*if ((expandedKey = malloc(expandedKeySize * sizeof(char))) == NULL) + { + return MEMORY_ALLOCATION_PROBLEM; + }*/ + + /* Set the block values, for the block: + * a0,0 a0,1 a0,2 a0,3 + * a1,0 a1,1 a1,2 a1,3 + * a2,0 a2,1 a2,2 a2,3 + * a3,0 a3,1 a3,2 a3,3 + * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3 + */ + + /* iterate over the columns */ + for (i = 0; i < 4; i++) + { + /* iterate over the rows */ + for (j = 0; j < 4; j++) + block[(i+(j*4))] = input[(i*4)+j]; + } + + /* expand the key into an 176, 208, 240 bytes key */ + expandKey(expandedKey, key, size, expandedKeySize); + + /* encrypt the block using the expandedKey */ + aes_main(block, expandedKey, nbrRounds); + + /* unmap the block again into the output */ + for (i = 0; i < 4; i++) + { + /* iterate over the rows */ + for (j = 0; j < 4; j++) + output[(i*4)+j] = block[(i+(j*4))]; + } + return 0; +} + +//Decrypt +void invSubBytes(unsigned char *state) +{ + int i; + /* substitute all the values from the state with the value in the SBox + * using the state value as index for the SBox + */ + for (i = 0; i < 16; i++) + state[i] = getSBoxInvert(state[i]); +} + +void invShiftRow(unsigned char *state, unsigned char nbr) +{ + int i, j; + unsigned char tmp; + /* each iteration shifts the row to the right by 1 */ + for (i = 0; i < nbr; i++) + { + tmp = state[3]; + for (j = 3; j > 0; j--) + state[j] = state[j-1]; + state[0] = tmp; + } +} + +void invShiftRows(unsigned char *state) +{ + int i; + /* iterate over the 4 rows and call invShiftRow() with that row */ + for (i = 0; i < 4; i++) + invShiftRow(state+i*4, i); +} + +void invMixColumn(unsigned char *column) +{ + unsigned char cpy[4]; + int i; + for(i = 0; i < 4; i++) + { + cpy[i] = column[i]; + } + column[0] = galois_multiplication(cpy[0],14) ^ + galois_multiplication(cpy[3],9) ^ + galois_multiplication(cpy[2],13) ^ + galois_multiplication(cpy[1],11); + column[1] = galois_multiplication(cpy[1],14) ^ + galois_multiplication(cpy[0],9) ^ + galois_multiplication(cpy[3],13) ^ + galois_multiplication(cpy[2],11); + column[2] = galois_multiplication(cpy[2],14) ^ + galois_multiplication(cpy[1],9) ^ + galois_multiplication(cpy[0],13) ^ + galois_multiplication(cpy[3],11); + column[3] = galois_multiplication(cpy[3],14) ^ + galois_multiplication(cpy[2],9) ^ + galois_multiplication(cpy[1],13) ^ + galois_multiplication(cpy[0],11); +} + +void invMixColumns(unsigned char *state) +{ + int i, j; + unsigned char column[4]; + + /* iterate over the 4 columns */ + for (i = 0; i < 4; i++) + { + /* construct one column by iterating over the 4 rows */ + for (j = 0; j < 4; j++) + { + column[j] = state[(j*4)+i]; + } + + /* apply the invMixColumn on one column */ + invMixColumn(column); + + /* put the values back into the state */ + for (j = 0; j < 4; j++) + { + state[(j*4)+i] = column[j]; + } + } +} + +void aes_invRound(unsigned char *state, unsigned char *roundKey) +{ + + invShiftRows(state); + invSubBytes(state); + addRoundKey(state, roundKey); + invMixColumns(state); +} + +void aes_invMain(unsigned char *state, unsigned char *expandedKey, int nbrRounds) +{ + int i = 0; + + unsigned char roundKey[16]; + + createRoundKey(expandedKey + 16*nbrRounds, roundKey); + addRoundKey(state, roundKey); + + for (i = nbrRounds-1; i > 0; i--) { + createRoundKey(expandedKey + 16*i, roundKey); + aes_invRound(state, roundKey); + } + + createRoundKey(expandedKey, roundKey); + invShiftRows(state); + invSubBytes(state); + addRoundKey(state, roundKey); +} + +char aes_decrypt(unsigned char *input, + unsigned char *output, + unsigned char *key + /*´, enum keySize size*/) +{ + enum keySize size = SIZE_16; + /* the expanded keySize */ + int expandedKeySize; + + /* the number of rounds */ + int nbrRounds; + + /* the expanded key */ + unsigned char *expandedKey = 0x00; + + /* the 128 bit block to decode */ + unsigned char block[16]; + + int i,j; + + /* set the number of rounds */ + switch (size) + { + case SIZE_16: + nbrRounds = 10; + break; + case SIZE_24: + nbrRounds = 12; + break; + case SIZE_32: + nbrRounds = 14; + break; + default: + return 1; //UNKNOWN_KEYSIZE; + break; + } + + expandedKeySize = (16*(nbrRounds+1)); + /*if ((expandedKey = malloc(expandedKeySize * sizeof(char))) == NULL) + { + return MEMORY_ALLOCATION_PROBLEM; + }*/ + + /* Set the block values, for the block: + * a0,0 a0,1 a0,2 a0,3 + * a1,0 a1,1 a1,2 a1,3 + * a2,0 a2,1 a2,2 a2,3 + * a3,0 a3,1 a3,2 a3,3 + * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3 + */ + + /* iterate over the columns */ + for (i = 0; i < 4; i++) + { + /* iterate over the rows */ + for (j = 0; j < 4; j++) + block[(i+(j*4))] = input[(i*4)+j]; + } + + /* expand the key into an 176, 208, 240 bytes key */ + expandKey(expandedKey, key, size, expandedKeySize); + + /* decrypt the block using the expandedKey */ + aes_invMain(block, expandedKey, nbrRounds); + + /* unmap the block again into the output */ + for (i = 0; i < 4; i++) + { + /* iterate over the rows */ + for (j = 0; j < 4; j++) + output[(i*4)+j] = block[(i+(j*4))]; + } + return 0; +} diff --git a/main/aes128.h b/main/aes128.h new file mode 100755 index 0000000..ddbe524 --- /dev/null +++ b/main/aes128.h @@ -0,0 +1,8 @@ +#ifndef AES128_H +#define AES128_H + +void aes_init(); +char aes_encrypt(unsigned char *input,unsigned char *output,unsigned char *key); +char aes_decrypt(unsigned char *input,unsigned char *output,unsigned char *key); + +#endif \ No newline at end of file diff --git a/main/cc_iuc_asynchpos.cpp b/main/cc_iuc_asynchpos.cpp new file mode 100755 index 0000000..a6686d6 --- /dev/null +++ b/main/cc_iuc_asynchpos.cpp @@ -0,0 +1,2131 @@ +/* + * cc_iuc_asynchpos.c + * + * Created: 21.11.2017 16:36:28 + * Author: Matthias + */ + +#include "cc_iuc_asynchpos.h" +#include "aes128.h" + +#include +#include + +//#include + +uint32_t iuc_asynchpos_sub_updateCRC(uint32_t crc, char* pData, size_t len) { + // berechne CRC32 nach Polynom x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + + QByteArray a(pData, len); + qCritical() << "updateCRC" << a.toHex(' '); + qCritical() << "updateCRC" << len; + + int i = 0; + int j = 0; +// unsigned long rem; +// unsigned char octet; +// UCHAR *p, *q; + unsigned char ucCarry = 0x00; + + crc = ~crc; + while (len > 0) { + crc ^= (uint32_t) pData[i]; + ++i; + + for (j = 0; j < 8; ++j) { + ucCarry = crc & 1; + crc >>= 1; + + if (ucCarry) { + crc ^= IUC_ASYNCHPOS_POLYNOME; + } + } + --len; + } + + return ~crc; + +} + +#if 0 + +#include + +extern struct T_CONF eeprom Conf; +extern struct T_dynamicData GWglobTime; +extern struct T_vend Vend; +static struct billAsynchData asynchBill; +extern struct T_GWstate GWstate; +//extern UCHAR GWstate.VendRequest; + +unsigned static char messageData[IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE]; + +ULONG com_totalSecSince1jan2017(void) +{ + // eine Zahl erzeugen die sich jede sec ändert und nicht 2x vorkommen darf + // Zeit und Datum in Sekunden umrechnen. Beginne bei 1.1.2017 um 0:00Uhr + // die nächsten Schaltjahre: 2020, 2024, 2028... + // Der Wert wird sich in den nächsten 130 Jahren nicht gleichen/wiederholen + + UINT uitmp; + ULONG ultmp; + + //uitmp=com_totalDaysSince1Jan2017(GlobTime.Year, GlobTime.Month, GlobTime.Day); + uitmp= ((UINT)GWglobTime.dayOfMon) + ((UINT)GWglobTime.month) * 30; + ultmp=(ULONG)uitmp; + ultmp*=1440L; // Tage--->min + ultmp+=(ULONG) (GWglobTime.MinOfDay);//GlobTime.MinOfDay; // min von heute drauf + ultmp*=60L; + return ultmp; +} + +void generate_UniqueTransNr(UCHAR *buf) +{ + // buf>=20 bytes! + UCHAR tmp12[12]; + ULONG ultmp = 0; + ULONG transID = com_totalSecSince1jan2017(); + + // a) Transaction ID, max 19 chars + // ab April 2017: TID muss über alle Automaten und über alle Zeiten eindeutig sein, + // sonst gibt SessionBase keine Antwort. + //uitmp=VKdata.TransID; sub_BufferNummEntry(ultmp); // einfache Version bis März 2017 + biox_ClearMem(buf, '0', 19); + biox_ClearMem(tmp12, 0, 12); + //VdKdata.TransID = com_totalSecSince1jan2017(); + //biox_ultoa(VKdata.TransID, tmp12); + biox_ultoa(transID, tmp12); + biox_MemCpPos(tmp12, buf, 1); + + // Automaten-nr auch rein, sonst können versch. Automaten die gleiche Nummer haben! + biox_ClearMem(tmp12, 0, 12); + ultmp=(ULONG) Conf.MachNr; //.MachineID; + biox_ultoa(ultmp, tmp12); + biox_MemCpPos(tmp12, buf, 11); + + biox_ClearMem(tmp12, 0, 12); + ultmp=(ULONG)Conf.CustomNr; //.CustID; + biox_ultoa(ultmp, tmp12); + biox_MemCpPos(tmp12, buf, 16); + buf[19]=0; +} + +void iuc_asynchpos_sub_initArray(unsigned char* pArray, int length) { + unsigned int uitemp = 0; + + for (uitemp = 0; uitemp < length; ++uitemp) + pArray[uitemp] = 0x00; +} + +void iuc_asynchpos_setTerminalID(unsigned char *pID, unsigned int length) { + unsigned int uctemp = 0; + + if (!biox_StrComp(pID,terminalID,length)) { + for (uctemp = 0; uctemp < length; ++uctemp) { + terminalID[uctemp] = pID[uctemp]; + } + } +} + +void iuc_asynchpos_setTerminalAPAK(unsigned char *pAPAK, unsigned int length) { + unsigned char uctemp = 0; + + if (!biox_StrComp(pAPAK,terminalAPAK,length)) { + for (uctemp = 0; uctemp < length; ++uctemp) { + terminalAPAK[uctemp] = pAPAK[uctemp]; + Conf.APAK_backup[uctemp] = pAPAK[uctemp]; + } + } +} + +ULONG iuc_asynchpos_sub_updateCRC(ULONG crc, UCHAR* pData, UINT len) //TODO +{ + // berechne CRC32 nach Polynom x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + + int i = 0; + int j = 0; +// unsigned long rem; +// unsigned char octet; +// UCHAR *p, *q; + unsigned char ucCarry = 0x00; + + crc = ~crc; + while (len > 0) { + crc ^= (ULONG) pData[i]; + ++i; + + for (j = 0; j < 8; ++j) { + ucCarry = crc & 1; + crc >>= 1; + + if (ucCarry) { + crc ^= IUC_ASYNCHPOS_POLYNOME; + } + } + --len; + } + + return ~crc; +} + +unsigned char iuc_asynchpos_rts() { + unsigned char timeOut = 0x00; + unsigned char uctmp = 0x00; + + brd_switch_RS3(RS3SW2IUC); + biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none); + uctmp = EOT; + biox_Usart3_ClearRecBuffer(); + biox_Usart3_SendBlock(&uctmp,1); + + while (timeOut < 0x06 && uctmp != ENQ) { + biox_delay_ms(400); + if (biox_Usart3_NewTelegram()) { + brd_SendDiagStr("->IUC ASYNCHPOS 0x05 (ENQ) received. RTS.",1); + biox_Usart3_GetRecBuffer(&uctmp,1); + biox_Usart3_ClearRecBuffer(); + iucAsynchpoxDataContext = 0x00; + } else { + brd_SendDiagStr("->IUC ASYNCHPOS waiting for 0x05 (ENQ).",1); + biox_Usart3_ClearRecBuffer(); + biox_Usart3_SendBlock(&uctmp,1); + } + ++timeOut; + } + + if (uctmp == ENQ) + return 0; + + return 1; +} + +unsigned char iuc_asynchpos_cts() { + unsigned int recLength; + unsigned char uctmp = ENQ; + + recLength = biox_Usart3BuffSize(); + + if (recLength > 0) { + biox_Usart3_GetRecBuffer(&uctmp,1); + + if (uctmp == EOT) { //The terminal is trying to send us data + uctmp = ENQ; + biox_Usart3_ClearRecBuffer(); + biox_Usart3_SendBlock(&uctmp,1); + biox_delay_ms(10); + return 1; + } + } + + return 0; +} + +unsigned char iuc_asynchpos_waitforACK() { + //unsigned char timeOut = 0x00; + unsigned char retVal = 0x00; + unsigned char rxData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; + unsigned int uitmp = 0; + + uitmp = biox_Usart3BuffSize(); + + if (uitmp > 1) { + //iuc_asynchpos_sub_initArray(rxData_,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + biox_Usart3_GetRecBuffer(rxData_,uitmp); + if (GWstate.DebugLevel & 0x10) + { + brd_SendDiagStr("->IUC ASYNCHPOS (ACK/NACK) rx data: ",0); + brd_SendDiagBlock(rxData_,1,uitmp); + } + + retVal = rxData_[0]; + + for (;uitmp > 0;--uitmp) { + if (rxData_[uitmp] == 0x0A) { + retVal |= 0xA0; + } + + if (rxData_[uitmp] == 0x0F) { + retVal |= 0xF0; + } + } + } else { + + //if (uitmp == 1) + biox_Usart3_GetRecBuffer(&retVal,1); + } + + biox_Usart3_ClearRecBuffer(); + return retVal; +} + +unsigned char iuc_asynchpos_send_serial(unsigned char* pData, unsigned int length, unsigned char needRTS, unsigned char overrideACK) { + unsigned int uitmp = 0; + unsigned int uitmp2 = 0; + unsigned int uitmp3 = 0; + unsigned int txCounter = 0; + unsigned int dxCounter = 0; + unsigned char uctmp = 0x00; +// unsigned char uctmp2 =0x00; + unsigned char chksum = 0x00; + //unsigned char dataContext = 0x00; + unsigned int retryCount = 0; + unsigned long lastRetry = 0; + unsigned int dxLength; +// unsigned int dx = biox_StrLen(pData) + 1; + unsigned char rxBuf[8]; + //unsigned char pData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; +// unsigned int loopCount = 1000; +// unsigned char retVal = 0x01; + + //preparing to send + if (needRTS) { + brd_SendDiagStr("->IUC ASYNCHPOS sending 0x04 (EOT).",1); + uctmp = iuc_asynchpos_rts(); + } + + //sending data + if (!uctmp) { + brd_SendDiagStr("----->IUC ASYNCHPOS",1); + iuc_asynchpos_sub_initArray(txAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + //iuc_asynchpos_sub_initArray(pData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + + //biox_CopyBlock(pData,0,pData_,0,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + + /*dxCounter = 0; + for (uitmp = 0; uitmp < dx + dxCounter; ++uitmp) { + if ((pData[uitmp] >= STX && pData[uitmp] <= ACK2) + || (pData[uitmp] == DLE) || (pData[uitmp] == NAK)) { + + pData[uitmp] = (pData[uitmp] + 0x30); + + for (uitmp2 = uitmp; uitmp2 < dx + dxCounter; ++uitmp2) { + pData[uitmp2 + 1] = pData[uitmp2]; + } + + pData[uitmp] = DLE; + ++dxCounter; + } + } + + dxCounter = 0;*/ + + for (uitmp = 0; uitmp < length; uitmp += IUC_ASYNCHPOS_MIN_PACKET_SIZE) { + + //if (dxCounter > 0) + //uitmp -= dxCounter; + + uctmp = 0x00; + dxCounter = 0; + chksum = 0x00; + dxLength = IUC_ASYNCHPOS_MIN_PACKET_SIZE; + + if (length - uitmp <= IUC_ASYNCHPOS_MIN_PACKET_SIZE) + dxLength = 2 + length - uitmp; + + iuc_asynchpos_sub_initArray(txAsynchData, 3 + IUC_ASYNCHPOS_MIN_PACKET_SIZE); + + //Packet structure is STX ETX1|ETX2 {LRC} + txAsynchData[0] = STX; + + for (txCounter = 0; (txCounter/* + dxCounter*/) < dxLength; ++txCounter) { + //for (txCounter = 0; txCounter < dxLength; ++txCounter) { + + /*if ((pData[uitmp + txCounter] >= STX && pData[uitmp + txCounter] <= ACK2) + || (pData[uitmp + txCounter] == DLE) || (pData[uitmp + txCounter] == NAK)) { + txAsynchData[1 + txCounter + dxCounter] = DLE; + uctmp = (pData[uitmp + txCounter] + 0x30); + ++dxCounter; + txAsynchData[1 + txCounter + dxCounter] = uctmp; //(pData[uitmp + txCounter] + 0x30); + } else {*/ + txAsynchData[1 + txCounter/* + dxCounter*/] = pData[uitmp + txCounter]; + + if ((pData[uitmp + txCounter] >= STX && pData[uitmp + txCounter] <= ACK2) + || (pData[uitmp + txCounter] == DLE) || (pData[uitmp + txCounter] == NAK)) { + ++dxCounter; + } + } + + for (uitmp2 = 1; uitmp2 < dxLength + dxCounter; ++uitmp2) { + if ((txAsynchData[uitmp2] >= STX && txAsynchData[uitmp2] <= ACK2) + || (txAsynchData[uitmp2] == DLE) || (txAsynchData[uitmp2] == NAK)) { + for (uitmp3 = dxLength + dxCounter; uitmp3 > uitmp2; --uitmp3) { + txAsynchData[uitmp3] = txAsynchData[uitmp3 - 1]; + } + txAsynchData[uitmp2 + 1] = (txAsynchData[uitmp2 + 1] + 0x30); + txAsynchData[uitmp2] = DLE; + } + } + + /*if (dxLength < IUC_ASYNCHPOS_MIN_PACKET_SIZE && txAsynchData[txCounter + dxCounter] != 0x00) { + ++dxCounter; + }*/ + + for (uitmp2 = 1; uitmp2 <= (txCounter + dxCounter); ++uitmp2) { + chksum ^= txAsynchData[uitmp2]; + } + + if (!iucAsynchpoxDataContext) { + txAsynchData[1 + txCounter + dxCounter] = ETX1; + chksum ^= ETX1; + } else { + txAsynchData[1 + txCounter + dxCounter] = ETX2; + chksum ^= ETX2; + } + + txAsynchData[2 + txCounter + dxCounter] = chksum; + + //Check if the terminal has decided, that our gateway is gone and is frantically sending us EOTs all the time + //iuc_asynchpos_cts(); + + //send packet + biox_Usart3_ClearRecBuffer(); + biox_Usart3_SendBlock(txAsynchData,3 + txCounter + dxCounter); + biox_delay_ms(1); + + iuc_asynchpos_sub_initArray(rxBuf,8); + biox_itoa(3 + txCounter + dxCounter,rxBuf); + + if (GWstate.DebugLevel & 0x10) + { + brd_SendDiagStr("->IUC ASYNCHPOS Packetlength: ",0); + brd_SendDiagBlock(rxBuf,1,8); + brd_SendDiagStr("->IUC ASYNCHPOS send package: ",0); + brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter); + } + //brd_SendDiagStr("->IUC ASYNCHPOS Send: ",0); + //brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter); + + //wait for ACK + uctmp = 0x00; + lastRetry = 0; + retryCount = 0; + + brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1); + do { + uctmp = iuc_asynchpos_waitforACK(); + //uctmp2 = uctmp; + uctmp &= 0x0F; + //if (!(lastRetry % 10)) { + //} + + if ((uctmp == NAK) || ((lastRetry >= 100) && (uctmp == 0x00))) { + brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1); + if (uctmp == NAK) + brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1); + biox_Usart3_SendBlock(txAsynchData,3 + txCounter + dxCounter); + biox_delay_ms(1); + ++retryCount; + uctmp = 0x00; + lastRetry = 0; + } else { + ++lastRetry; + biox_delay_ms(1); + } + } while (retryCount < 25 && uctmp == 0x00); //Entweder Timeout, keine neuen Versuche oder ein ACK1/ACK2 holen uns hier raus + + /*while (retryCount < 5 && (uctmp == 0x00 || uctmp == NAK)) { + uctmp = iuc_asynchpos_waitforACK(); + ++lastRetry; + +// if (uitmp == 0) +// biox_delay_ms(100); + + if ((uctmp == NAK) || (uctmp == 0x00 && (lastRetry % 10 == 0x00))) { + biox_Usart2_ClearRecBuffer(); + brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1); + biox_Usart2_SendBlock(txAsynchData,3 + txCounter + dxCounter); + biox_delay_ms(10); + brd_SendDiagStr("->IUC ASYNCHPOS resend: ",0); + brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter); + ++retryCount; + } else if (uctmp == ETX1 || uctmp == ETX2) { + biox_Usart2_ClearRecBuffer(); + uctmp = NAK; + biox_Usart2_SendBlock(&uctmp,1); + } + }*/ + + if (!uctmp) { + brd_SendDiagStr("->IUC ASYNCHPOS Terminal did not reply.",1); + return 1; //sending failed + } + + //iuc_asynchpos_sub_initArray(txAsynchData, 3 + txCounter + dxCounter); + + if (uctmp == ACK1) { + brd_SendDiagStr("->IUC ASYNCHPOS ACK 1 (serial)",1); + //dataContext = 0x01; + iucAsynchpoxDataContext = 0x01; + } + + if (uctmp == ACK2) { + brd_SendDiagStr("->IUC ASYNCHPOS ACK 2 (serial)",1); + //dataContext = 0x00; + iucAsynchpoxDataContext = 0x00; + } + + if (retryCount >= 5) { + brd_SendDiagStr("->IUC ASYNCHPOS Too much NACKs, giving up.",1); + return 2; //too much NACKs, giving up + } + } + + /*uctmp2 &= 0xF0; + + if (uctmp2 == 0xA0) { + retVal = 1; + } + + if (uctmp2 == 0xF0) { + retVal = 0; + }*/ + + /*if (!overrideACK) { + brd_SendDiagStr("->IUC ASYNCHPOS Retrieving.",1); + retVal = 0x01; + uitmp = 0x01; + while(uitmp > 0 && loopCount > 0) { + uitmp = iuc_asynchpos_recieve_serial(0x01); + biox_delay_ms(1); + --loopCount; + biox_Usart2_ClearRecBuffer(); + } + + if (loopCount == 0) { + brd_SendDiagStr("->IUC ASYNCHPOS Retrieving timeout!",1); + retVal = 0x00; + } + brd_SendDiagStr("->IUC ASYNCHPOS Retrieving ended.",1); + }*/ + + return 1;//retVal;//(UCHAR) uitmp; + } else { + brd_SendDiagStr("->IUC ASYNCHPOS Not ready to send to POS, giving up.",1); + } + + return 2; +} + +unsigned int iuc_asynchpos_send(unsigned char packetType, unsigned char* pData, unsigned int length, unsigned char needRTS) { + unsigned char txData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; + unsigned char tempID [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE]; + unsigned char tempID_ [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE]; + unsigned char tempAPAK [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE]; + unsigned long uitmp = 0; + unsigned int posID = 0; + unsigned long chksum = 0; + unsigned int messageLength = length + 1; + unsigned int length_ = length + 1; + unsigned char pData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; + unsigned char uctemp = 0; +// unsigned char retries = 4; + unsigned char rxBuf[8]; + + iuc_asynchpos_crc_old = 0; + iuc_asynchpos_sub_initArray(rxBuf, 8); + iuc_asynchpos_sub_initArray(pData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + biox_CopyBlock(pData,0,pData_,0,length_); + + iuc_asynchpos_sub_initArray(txData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynchpos_sub_initArray(tempID, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE); + iuc_asynchpos_sub_initArray(tempID_, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE); + iuc_asynchpos_sub_initArray(tempAPAK, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE); + + //header + /* + The header of the message is composed of: + ? 1 byte packet Type, which indicates the type of the packet; + ? 8 bytes Packet ID, a unique ID to achieve maximum security (for information on forming + Packet ID see chapter 3.4 Communication security); + ? 1 byte P.O.S. ID length; + ? ASCII encoded P.O.S. ID (up to 255 bytes); ((gemeint ist Terminal ID) + */ + + txData_[2] = packetType; + + //1 byte P.O.S. ID length + /*for (uitmp = 0; uitmp < 32 && terminalID[uitmp] != 0x00; ++uitmp) { + ++posID; // -= uitmp; + }*/ + + posID = biox_StrLen(terminalID)/* + 1*/; + + //++posID; + txData_[11] = (UCHAR) posID; + + messageLength += (10 + posID); //Added header + txData_[0] = (messageLength) & 0xFF00; //high byte + txData_[1] = (messageLength) & 0x00FF; //low byte + + //8 byte Packet ID + /* + Apak: 9D547268976ADE1BBB39DE90F3A449E5 + Terminal id: T-LT-OPT-01 + */ + + //calculate CRC32 + uctemp = (UCHAR) posID; + chksum = IUC_ASYNCHPOS_POLYNOME_INITIAL; + chksum = iuc_asynchpos_sub_updateCRC(chksum,&uctemp,1); + chksum = iuc_asynchpos_sub_updateCRC(chksum,terminalID,posID); + //for (uitmp = 0; uitmp < length_; ++uitmp) { + chksum = iuc_asynchpos_sub_updateCRC(chksum,pData_/*[uitmp]*/,length_); + //} + + //XOR crc value with APAK + //chksum = 2502456899; //HACK FOR TESTING, REMOVE LATER! + for(uitmp = 0; uitmp < IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE; ++uitmp) { + tempAPAK[uitmp] |= biox_ah2ui_char(terminalAPAK[uitmp * 2]) << 4; + tempAPAK[uitmp] |= biox_ah2ui_char(terminalAPAK[(uitmp * 2) + 1]); + //tempAPAK[uitmp] = (terminalAPAK[uitmp * 2] << 8) | (terminalAPAK[(uitmp * 2) + 1]); + } + + tempID[0] = (chksum >> 24) & 0xFF; + tempID[1] = (chksum >> 16) & 0xFF; + tempID[2] = (chksum >> 8) & 0xFF; + tempID[3] = chksum & 0xFF; + + for (uitmp = 0; uitmp < 4; ++uitmp) { + tempID[uitmp] ^= tempAPAK[uitmp]; //terminalAPAK[uitmp]; + } + + for (uitmp = 4; uitmp < IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE; ++uitmp) { + tempID[uitmp] = tempAPAK[uitmp]; //terminalAPAK[uitmp]; + } + + //Eyncrypt result with APAK, according to AES128 + aes_encrypt(tempID,tempID_,tempAPAK); + + //get the leftmost 8 byte of that value and set then as Packet ID + for (uitmp = 0; uitmp < 8; ++uitmp) + txData_[3 + uitmp] = tempID_[uitmp]; + + //P.O.S.ID + for (uitmp = 0; uitmp < posID; ++uitmp) { + txData_[12 + uitmp] = terminalID[uitmp]; + } + + //Message + //1 byte - marker + //0 . 7F bytes - tag name + //2 + N bytes - data + for (uitmp = 0; uitmp < length_; ++uitmp) { + txData_[12 + posID + uitmp] = pData_[uitmp]; + } + + brd_SendDiagStr("->IUC ASYNCHPOS send message: ",0); + brd_SendDiagBlock(txData_,1,messageLength); + + //Message compiled, now send it via serial + uitmp = 1; + //while (retries > 0 && uitmp > 0) { + //uitmp = iuc_asynchpos_send_serial(txData_, (messageLength + 1)); + //--retries; + if (iuc_asynchpos_send_serial(txData_, (messageLength/* + 1*/),needRTS,0x00)) { + //brd_SendDiagStr("->IUC ASYNCHPOS Message failed!",1); + //TODO Message sending failed -> Error handling here + //return 1; + uitmp = 0x00; + brd_SendDiagStr("->IUC ASYNCHPOS Message NOT send",1); + } else { + brd_SendDiagStr("->IUC ASYNCHPOS Message send",1); + } /*else { + --retries; + } + }*/ + + //if (!uitmp) + //return 1; + + /*if (retries == 0) { + brd_SendDiagStr("->IUC ASYNCHPOS Message failed!",1); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0xFF; + vmc_SendWithBuffer(rxBuf,20,0x69,0); + return 1; + } + + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,20,0x69,0);*/ + + //brd_SendDiagStr("->IUC ASYNCHPOS Message send",1); + //while(iuc_asynchpos_recieve_serial()); + + return 0; +} + +/* +Let us assume that a client wants to purchase items and he wants to pay for these items with his +bank card. When the client is ready to authorize the transaction, the ECR needs to send [Authorize] +request for the operations to start. Within the request, the ECR must include: +? An [Amount] sub tag with the tender amount in minor currency; +? A [Currency] sub tag with a three digit currency code; +? A [DocNr] sub tag with the number referencing the current receipt; +? [Time] – the time of the transaction; +? A [Lang] sub tag specifying a language code; +As a result, the P.O.S. will reply by an [AuthorizationResult] device event with an [ID], [DocNr], +[Result] sub tags. When ECR closes/finalizes its receipt, ECR must send [DocClosed] event to +finalize bank operation of in this receipt. A successful authorization Id from [AuthorizationResult] +must be included in [DocClosed] message. Only Id of successful authorization has to be included, +other Ids has to be omitted from message. +Depending on the configuration, and requirements, the ECR may receive a [PrintReceipt] event +(though some models of P.O.S. could as well print the receipt itself), with an [ID], [DocNr], and the +[ReceiptText], to be printed out. The [PrintReceipt] event may occur at any time of the operation, +whenever the P.O.S. needs to print something, and it should be printed as soon as possible. ECR +may be occupied during the event, so it may start printing when no more operations are waiting to +be processed. After the receipt has been printed, the ECR has to send a [PrintResult] to P.O.S. to +confirm the successful action. P.O.S. may send [GetMessageBoxInput] message to ECR if signature +of Client needed. ECR must send [InputResult] message to POS. This message informs about sign +status. +During bank card authorization [PrintReceipt] messages usually are sent before +[AuthorizationResult] event. +POS could send additional [DisplayText] message(s) to ECR to inform about process steps. +*/ + +void iuc_asynchpos_sub_initZero(unsigned char* pArray, int length) { + unsigned int uitemp = 0; + + for (uitemp = 0; uitemp < (length - 1); ++uitemp) + pArray[uitemp] = 0x30; + + pArray[length - 1] = 0x00; +} + +void iuc_asynchpos_sub_clear_message(unsigned char fillwithZero) { + if (fillwithZero) { + iuc_asynchpos_sub_initZero(asynchBill.id,37); + iuc_asynchpos_sub_initZero(asynchBill.docNr,33); + /*iuc_asynchpos_sub_initZero(asynchBill.token,25); + iuc_asynchpos_sub_initZero(asynchBill.result,8); + iuc_asynchpos_sub_initZero(asynchBill.amount,10); + iuc_asynchpos_sub_initZero(asynchBill.authCode,7); + iuc_asynchpos_sub_initZero(asynchBill.rrn,13); + iuc_asynchpos_sub_initZero(asynchBill.stan,7); + iuc_asynchpos_sub_initZero(asynchBill.cardtype,33);*/ + //iuc_asynchpos_sub_initZero(asynchBill.errCode,17); + } else { + iuc_asynchpos_sub_initArray(asynchBill.id,37); + iuc_asynchpos_sub_initArray(asynchBill.docNr,33); + /*iuc_asynchpos_sub_initArray(asynchBill.token,25); + iuc_asynchpos_sub_initArray(asynchBill.result,8); + iuc_asynchpos_sub_initArray(asynchBill.amount,10); + iuc_asynchpos_sub_initArray(asynchBill.authCode,7); + iuc_asynchpos_sub_initArray(asynchBill.rrn,13); + iuc_asynchpos_sub_initArray(asynchBill.stan,7); + iuc_asynchpos_sub_initArray(asynchBill.cardtype,33);*/ + //iuc_asynchpos_sub_initArray(asynchBill.errCode,17); + } +} + +void iuc_asynchpos_sub_sendACK(unsigned char switchPrint) { + unsigned char messageReturnData[100]; + unsigned int uitemp = 0; + unsigned int uitemp2 = 0; + unsigned int uitemp3 = 0; + unsigned char uctmp = 0; + unsigned int lastRetry = 0; + unsigned int retryCount = 0; + + iuc_asynchpos_sub_initArray(messageReturnData, 100); //iuc_asynchpos_sub_initArray(messageData, messageLength + 1);//iuc_asynchpos_sub_initArray(messageReturnData, IUC_ASYNCHPOS_MAX_MESSAGE_SIZE); + switch (switchPrint) { + case 1: + for (uitemp = 0; uitemp < 8; ++uitemp) { + messageReturnData[uitemp + 3] = terminalSignature[uitemp]; + } + messageReturnData[uitemp + 3] = (UCHAR) biox_StrLen(terminalID); + + for (uitemp = 0; uitemp < biox_StrLen(terminalID); ++uitemp) { + messageReturnData[uitemp + 12] = terminalID[uitemp]; + } + uitemp += 10; + break; + case 2: + for (uitemp = 0; uitemp < 8; ++uitemp) { + messageReturnData[uitemp + 3] = terminalSignature[uitemp + 8]; + } + messageReturnData[uitemp + 3] = biox_StrLen(terminalID); + + for (uitemp = 0; uitemp < biox_StrLen(terminalID); ++uitemp) { + messageReturnData[uitemp + 12] = terminalID[uitemp]; + } + uitemp += 10; + break; + case 0: + default: + for (uitemp = 0; uitemp < rxAsynchData[11] + 9; ++uitemp) { + messageReturnData[uitemp + 3] = rxAsynchData[uitemp + 3]; + } + ++uitemp; + break; + } + + messageReturnData[0] = uitemp & (0xFF00); + messageReturnData[1] = uitemp & (0x00FF); + messageReturnData[2] = 0x0A; + //iuc_asynchpos_send_serial(messageReturnData,uitemp/* + 1*/,0x00,0x01); + + for (uitemp2 = uitemp + 2; uitemp2 > 0; --uitemp2) { + messageReturnData[uitemp2] = messageReturnData[uitemp2 - 1]; + } + uitemp += 2; + + messageReturnData[0] = 0x01; + + //convert characters + for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) { + if ((messageReturnData[uitemp2] >= STX && messageReturnData[uitemp2] <= ACK2) + || (messageReturnData[uitemp2] == DLE) || (messageReturnData[uitemp2] == NAK)) { + ++uitemp; + for (uitemp3 = uitemp + 1; uitemp3 > uitemp2; --uitemp3) { + messageReturnData[uitemp3] = messageReturnData[uitemp3 - 1]; + } + messageReturnData[uitemp2 + 1] = messageReturnData[uitemp2 + 1] + 0x30; + messageReturnData[uitemp2] = DLE; + } + } + + messageReturnData[uitemp + 1] = ETX1; + + //calculate chksum + for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) { + messageReturnData[uitemp + 2] ^= messageReturnData[uitemp2]; + } + + biox_Usart3_SendBlock(messageReturnData,uitemp2+1); + + //wait for ACK + uctmp = 0x00; + lastRetry = 1; + retryCount = 0; + + brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1); + do { + uctmp = iuc_asynchpos_waitforACK(); + //if (!(lastRetry % 10)) { + //} + + if (uctmp == NAK || ((lastRetry % 500 == 0) && (uctmp == 0x00))) { + brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1); + if (uctmp == NAK) + brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1); + biox_Usart3_SendBlock(messageReturnData,uitemp2+1); + biox_delay_ms(1); + ++retryCount; + uctmp = 0x00; + lastRetry = 1; + } else { + ++lastRetry; + biox_delay_ms(1); + } + } while (retryCount < 5 && uctmp == 0x00); //Entweder Timeout, keine neuen Versuche oder ein ACK1/ACK2 holen uns hier raus + + if (!uctmp) { + brd_SendDiagStr("->IUC ASYNCHPOS Terminal did not reply.",1); + //return 1; //sending failed + } + + if (uctmp == ACK1) { + brd_SendDiagStr("->IUC ASYNCHPOS ACK 1 (ACK serial)",1); + //dataContext = 0x01; + iucAsynchpoxDataContext = 0x01; + } + + if (uctmp == ACK2) { + brd_SendDiagStr("->IUC ASYNCHPOS ACK 2 (ACK serial)",1); + //dataContext = 0x00; + iucAsynchpoxDataContext = 0x00; + } + + if (retryCount >= 5) { + brd_SendDiagStr("->IUC ASYNCHPOS (ACK serial) Too much NACKs, giving up.",1); + //return 2; //too much NACKs, giving up + } +} + +void iuc_asynchpos_resetBuffers(unsigned char sendENQ) { + unsigned char uctmp = ENQ; + unsigned char rxBuf[8]; + + if (sendENQ != 0x02) { + rxCounter = 0; + messageLength = 0; + iuc_asynchpos_sub_initArray(rxAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynchpos_sub_initArray(txAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + } + + if (sendENQ) { + iucAsynchpoxDataContext = 0x00; + ENQrecieved = 1; + brd_SendDiagStr("->IUC ASYNCHPOS 0x04 (EOT) received.",1); + brd_switch_RS3(RS3SW2IUC); + biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none); + biox_delay_ms(1); + biox_Usart3_ClearRecBuffer(); + brd_SendDiagStr("->IUC ASYNCHPOS send 0x05 (ENQ). CTS",1); + biox_Usart3_SendBlock(&uctmp,1); + + if (asynchState <= 0x03) + { + brd_SendDiagStr("->IUC ASYNCHPOS sending an error to the VMC",1); + iuc_asynchpos_sub_initArray(rxBuf,8); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0xFF; + vmc_SendWithBuffer(rxBuf,8,0x69,0); + } + } +} + +//46 +void iuc_asynchpos_command_print_Result(unsigned char status) { //Finalize sale + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "PrintResult"; + UCHAR tagName[] = "DocNr"; + UCHAR tag2Name[] = "Result"; + UCHAR tag3Name[] = "ID"; + UCHAR tag2ValueO[] = "OK"; + UCHAR tag2ValueE[] = "ERROR"; + unsigned char uctmp = status; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + + uitemp = biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + //ID + message[uitemp] = (UCHAR) biox_StrLen(tag3Name); + ++uitemp; + biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name)); + uitemp += (1 + biox_StrLen(tag3Name)); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.printId);//value length + ++uitemp; + biox_CopyBlock(asynchBill.printId,0,message,uitemp, biox_StrLen(asynchBill.printId));//value + uitemp += biox_StrLen(asynchBill.printId); + + //DocNr + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length + ++uitemp; + biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value + uitemp += biox_StrLen(asynchBill.docNr); + + //Result + message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name + uitemp += (1 + biox_StrLen(tag2Name)); + + if (!uctmp) { + message[uitemp] = (UCHAR) biox_StrLen(tag2ValueE);//value length + ++uitemp; + biox_CopyBlock(tag2ValueE,0,message,uitemp, biox_StrLen(tag2ValueE));//value + uitemp += biox_StrLen(tag2ValueE)/* + 1*/; + } else { + message[uitemp] = (UCHAR) biox_StrLen(tag2ValueO);//value length + ++uitemp; + biox_CopyBlock(tag2ValueO,0,message,uitemp, biox_StrLen(tag2ValueO));//value + uitemp += biox_StrLen(tag2ValueO)/* + 1*/; + } + + iuc_asynchpos_send(packetType,message,uitemp,0x00); +} + +void iuc_asynchpos_handleMessage(unsigned char* pData) { + //unsigned char marker = pData[0]; +// unsigned int tagNameLength = pData[1]; + unsigned char tagName[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; +// unsigned int curElementLength = 0; + //unsigned char curElement[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; + //unsigned char receiptData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1]; + unsigned char rxBuf[20]; +// unsigned char flags[129]; +// unsigned char docNr[32]; + //unsigned char messageType = pData[1]; + + unsigned int uitmp = 0; + unsigned int uitmp2 = 0; + + iuc_asynchpos_sub_initArray(tagName, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + //iuc_asynchpos_sub_initArray(curElement, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + + uitmp = biox_FindStrInBufferInt("LoginResult",pData) | biox_FindStrInBuffer("LOGINRESULT",pData); + if (uitmp) { + asynchState = 0x02; //eingeloggt + /*rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,40,0x69,0);*/ + } + + uitmp = biox_FindStrInBufferInt("AuthorizationStarted",pData) | biox_FindStrInBuffer("AUTHORIZATIONSTARTED",pData); + if (uitmp) { + iuc_asynchpos_sub_initArray(rxBuf,5); + rxBuf[0] = 0x53; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,5,0x69,0); + } + + uitmp = biox_FindStrInBufferInt("AuthorizationResult",pData) | biox_FindStrInBuffer("AUTHORIZATIONRESULT",pData); + if (uitmp) { + asynchState = 0x03; //successfully authorized + iuc_asynchpos_sub_clear_message(0x00); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]); + //uitmp = biox_FindStrInBuffer("Result",pData) | biox_FindStrInBuffer("RESULT",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.result, 0, pData[uitmp + 1]); + + brd_SendDiagStr("->IUC ASYNCHPOS message ID: ",0); + brd_SendDiagBlock(asynchBill.id,1,36); + + /*if (iuc_asynch_PrintControl) { + brd_SendDiagStr("->IUC ASYNCHPOS print data send AUTH: ",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + iuc_asynch_PrintControl = 0x00; + //biox_delay_ms(750); + } else { + brd_SendDiagStr("->IUC ASYNCHPOS sending authorization: ",1); + iuc_asynch_PrintControl = 0x01; + }*/ + + uitmp = biox_FindStrInBufferInt("ERROR",pData); + if (!uitmp/*biox_FindStrInBuffer("OK",pData) | biox_FindStrInBuffer("Approved",pData) | biox_FindStrInBuffer("APPROVED",asynchBill.result)*/) { + iuc_asynch_PrintControl |= 0xF0; + /*uitmp = biox_FindStrInBufferInt("Amount",pData) | biox_FindStrInBufferInt("AMOUNT",pData); + //if (pData[uitmp + 1] <= 10) { + biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, pData[uitmp + 1]); + //} else { + //biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, 10); + //}*/ + + //uitmp = biox_FindStrInBuffer("Token",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.token, 0, pData[uitmp + 1]); + /*uitmp = biox_FindStrInBufferInt("Authcode",pData) | biox_FindStrInBufferInt("AUTHCODE",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.authCode, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("RRN",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.rrn, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("STAN",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.stan, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("CardType",pData) | biox_FindStrInBufferInt("CARDTYPE",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.cardtype, 0, pData[uitmp + 1]);*/ + asynchState = 0x04; + + brd_SendDiagStr("->IUC ASYNCHPOS authorization confirmed.",1); + + /*iuc_asynchpos_sub_initArray(rxBuf,20); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,20,0x69,0);*/ + + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_command_close_Document(); + } else { + iuc_asynch_PrintControl |= 0xF0; + //uitmp = biox_FindStrInBufferInt("ErrCode",pData) | biox_FindStrInBufferInt("ERRCODE",pData); + //biox_CopyBlock(pData, uitmp + 2, asynchBill.errCode, 0, pData[uitmp + 1]); + + brd_SendDiagStr("->IUC ASYNCHPOS authorization failed.",1); + + /*iuc_asynchpos_sub_initArray(rxBuf,20); + rxBuf[0] = 0x45; + rxBuf[1] = 0xFF; + biox_CopyBlock(pData, uitmp + 2, rxBuf, 2, pData[uitmp + 1]); + vmc_SendWithBuffer(rxBuf,20,0x69,0);*/ + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + } + } + + uitmp = biox_FindStrInBufferInt("PrintReceipt",pData) | biox_FindStrInBufferInt("PRINTRECEIPT",pData); + if (uitmp) { + asynchState = 0x03; //Customer receipt recieved + //iuc_asynchpos_sub_initArray(flags,129); + //uitmp = biox_FindStrInBufferInt("Flag",pData) | biox_FindStrInBufferInt("FLAG",pData) | biox_FindStrInBufferInt("Flags",pData) | biox_FindStrInBufferInt("FLAGS",pData); + /*if (uitmp) { + biox_CopyBlock(pData, uitmp + 2, flags, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("CD",flags) | biox_FindStrInBufferInt("LR",flags); + }*/ + + /*iuc_asynchpos_sub_clear_message(0x00); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]); + uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]);*/ + iuc_asynchpos_sub_initArray(asynchBill.printId,129); + uitmp = biox_FindStrInBufferInt("ID",pData); + biox_CopyBlock(pData, uitmp + 2, asynchBill.printId, 0, pData[uitmp + 1]); + + //if(asynchState == 0x02/* && uitmp biox_FindStrInBufferInt("CD",flags) || biox_FindStrInBufferInt("LR",flags)*/) { + if((!iuc_asynch_PRNrecieved) && (biox_FindStrInBufferInt("CD",pData) || biox_FindStrInBufferInt("LR",pData)) ) { + iuc_asynch_PRNrecieved = 0x01; + iuc_asynchpos_sub_initArray(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1); + uitmp = /*biox_FindStrInBuffer("ReceiptText",pData) | */biox_FindStrInBufferInt("RECEIPTTEXT",pData); + uitmp2 = (pData[uitmp] * 256) + pData[uitmp + 1]; + + //if (uitmp2 <= IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + if (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + uitmp2 = IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large! Cutting off.",1); + /*receiptData[0] = 0x50; + biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*); + //uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + //uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0); + brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynch_PrintControl |= 0x0F;*/ + + /*if (iuc_asynch_PrintControl) { + brd_SendDiagStr("->IUC ASYNCHPOS print data send: ",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + iuc_asynch_PrintControl = 0x00; + } else { + brd_SendDiagStr("->IUC ASYNCHPOS print data stored: ",1); + iuc_asynch_PrintControl = 0x01; + }*/ + //biox_delay_ms(750); + + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_command_close_Document(); + + //iuc_asynchpos_resetBuffers(0x02); + //iuc_asynchpos_command_print_Result(0x01); + } + + receiptData[0] = 0x50; + biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*/); + + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0); + brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynch_PrintControl |= 0x0F; + + /* else { + //receiptData[0] = 0x50; + //iuc_asynchpos_sub_initZero(receiptData,1); + brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large!",1); + iuc_asynch_PrintControl |= 0x0E; + } */ + /* else { + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x00); + }*/ + } + + //++iuc_print_counter; + + //if(asynchState == 0x04 && iuc_asynch_PrintControl == 0) { + //iuc_asynchpos_resetBuffers(0x01); + //iuc_asynchpos_resetBuffers(0x00); + //iuc_asynchpos_command_print_Result(0x01); + /*} /else { + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x01); + }*/ + //iuc_asynchpos_command_print_Result(0x01); + + /*while (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + biox_CopyBlock(pData, uitmp + 2, receiptData, 0, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE; + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0); + } + + //Rest des Packets + biox_CopyBlock(pData, uitmp + 2, receiptData, 0, uitmp2); + vmc_SendWithBuffer(receiptData,uitmp2,0x69,0); + + //iuc_asynchpos_resetBuffers(0x02); + iuc_asynchpos_command_print_Result(0x01);*/ + } + + uitmp = biox_FindStrInBufferInt("VoidResult",pData) | biox_FindStrInBufferInt("VOIDRESULT",pData); + if (uitmp) { + asynchState = 0x01; //There was a cancel. Relogin and try again. + uitmp = biox_FindStrInBufferInt("ERROR",pData); + if (uitmp) { + rxBuf[0] = 0x45; + rxBuf[1] = 0x56; + rxBuf[2] = 0x45; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + } + + uitmp = biox_FindStrInBufferInt("REFUND",pData); + if (uitmp) { + rxBuf[0] = 0x45; + rxBuf[1] = 0x56; + rxBuf[2] = 0x52; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + //TODO refund bill here. Should not trigger, but it might. + } + } + + uitmp = biox_FindStrInBufferInt("DocClosed",pData); + if (uitmp) { + asynchState = 0x01; //Transaction successful + + //if (VendRequest) + GWstate.VendRequest=0; + } + + + /*while (pData[uitmp] != 0x00) { //0x00 is the end marker + if (tagNameLength > 0x7F) { + //tagNameLength -= 0x80; + + for (uitmp2 = 0; uitmp2 < (tagNameLength - 0x80); ++uitmp2) { + tagName[uitmp2] = pData[uitmp + 1 + uitmp2]; + } + + //TODO Do something with the name here + + uitmp = uitmp2 + 1; + tagNameLength = pData[uitmp]; + + } else { + for (uitmp2 = 0; uitmp2 < tagNameLength; ++uitmp2) { + tagName[uitmp2] = pData[uitmp + 1 + uitmp2]; + } + + //TODO Do something with the name here + + uitmp = uitmp2 + 1; + + curElementLength = ((UINT) pData[uitmp] << 8) | pData[uitmp]; + + for (uitmp2 = 0; uitmp2 < curElementLength; ++uitmp2) { + curElement[uitmp2] = pData[uitmp + 1 + uitmp2]; + } + + //TODO Do something with the data here + + uitmp = uitmp2 + 1; + tagNameLength = pData[uitmp]; + } + }*/ + +} + +void iuc_asynchpos_startCommunication() { + unsigned char uctmp = EOT; + + biox_Usart3_ClearRecBuffer(); + biox_Usart3_SendBlock(&uctmp,1); +} + +void iuc_asynchpos_init() { + //TODO: CHANGE THIS LATER ON! TEST ONLY! + #ifdef IUC_ASYCHNPOS_TESTMODE + unsigned char APAK[] = "9D547268976ADE1BBB39DE90F3A449E5"; //9D547268976ADE1BBB39DE90F3A449E5 + unsigned char TID[] = "T-LT-OPT-01"; + #endif + unsigned char timeStart[] = "2018-01-01 00:00:00"; + unsigned int uitmp = 0; + + iuc_asynchpos_sub_initArray(asynchBill.time,20); + biox_CopyBlock(timeStart,0,asynchBill.time,0,biox_StrLen(timeStart)); + //iuc_asynchpos_sub_initArray(asynchBill.id,20); + //iuc_asynchpos_sub_initArray(asynchBill.docNr,32); + iuc_asynchpos_sub_clear_message(0x01); + asynchState = 0; + iuc_asynch_keepAlive = 0x00; + iuc_asynch_PrintControl = 0x00; + + tableCreated = 0x00; + + #ifdef IUC_ASYCHNPOS_TESTMODE + iuc_asynchpos_setTerminalAPAK(APAK, biox_StrLen(APAK)); + iuc_asynchpos_setTerminalID(TID, biox_StrLen(TID)); + #endif + + ENQrecieved = 0x00; + timeInitalized = GWglobTime.SecOfDay; + asynchSessionClosed = 0x00; + iuc_asynch_PRNrecieved = 0x00; + iuc_asynchpos_crc_old = 0; + iucAsynchpoxDataContext = 0x00; + iuc_asynch_printTimeout = IUC_ASYNCHPOS_PRINTTIMOUT; + + brd_switch_RS3(RS3SW2IUC); + biox_Usart3_ClearRecBuffer(); + biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none); + biox_delay_ms(1); + + /* + Apak: 9D547268976ADE1BBB39DE90F3A449E5 + Terminal id: T-LT-OPT-01 + */ + + for (uitmp = 0; uitmp < IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE; ++uitmp) + terminalAPAK[uitmp] = Conf.APAK_backup[uitmp]; + + //biox_CopyBlock(Conf.APAK_backup,0,terminalAPAK,0,IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + + iuc_asynchpos_resetBuffers(0x00); + iuc_asynchpos_startCommunication(); +} + +unsigned char iuc_asynchpos_recieve_serial(unsigned char waitforACK) { + unsigned int rxLength = 0; + unsigned int uitemp = 0; + unsigned int uitemp2 = 0; + unsigned char rxData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; +// unsigned char messageReturnData[100]; + unsigned char messageLength_[8]; + unsigned char messageCounter_[8]; + unsigned char chksum = 0x00; + unsigned char uctmp = 0x00; + unsigned char resetBuffers = 0x00; + //unsigned int rxCounter = messageLength; + unsigned char fullPackage = 0x00; + unsigned char rxBuf[8]; + + //if (biox_Usart2_NewTelegram()) { + //brd_SendDiagStr("<----- IUC ASYNCHPOS",1); + //get datastream from buffer + //iuc_asynchpos_sub_initArray(rxData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + rxLength = biox_Usart3BuffSize(); + + rxData_[0] = 0xFF; + + if (rxLength > 0) { + brd_SendDiagStr("<----- IUC ASYNCHPOS",1); + + if (rxLength >= IUC_ASYNCHPOS_MAX_ARRAY_SIZE) { + brd_SendDiagStr("->IUC ASYNCHPOS rx buffer overflow!",1); + biox_Usart3_ClearRecBuffer(); + return 8; + } + + brd_SendDiagStr("->IUC ASYNCHPOS Data recieved, ISMAS locked!",1); + ism_lock(); + timeHoldISMAS = GWglobTime.SecOfDay; + + //iuc_asynchpos_sub_initArray(rxData_, rxLength); + biox_Usart3_GetRecBuffer(rxData_,rxLength); + + if (GWstate.DebugLevel & 0x10) + { + biox_itoa(rxLength,messageLength_); + brd_SendDiagStr("->IUC ASYNCHPOS recieved: ",0); + brd_SendDiagBlock(messageLength_,1,8); + brd_SendDiagStr("->IUC ASYNCHPOS rx data: ",0); + brd_SendDiagBlock(rxData_,1,rxLength); + + if (rxLength <= 1) + brd_SendDiagStr("->IUC ASYNCHPOS Single Byte recieved.",1); + } + + for (uitemp = 0; uitemp < rxLength/* && resetBuffers == 0x00*/; ++uitemp) { + if (rxData_[uitemp] == EOT || (!ENQrecieved && rxData_[uitemp] == ENQ)) {//Either we did not initialize everysthing yet OR the PT wants to send something. + if (uitemp == 0 || (uitemp > 0 && (rxData_[uitemp-1] != ETX1 || rxData_[uitemp-1] != ETX2))) { + if (rxData_[uitemp] != ENQ) { + resetBuffers = 0x01; + } else { + resetBuffers = 0x02; + + brd_SendDiagStr("->IUC ASYNCHPOS ENQ recieved, ISMAS unlocked!",1); + ism_unlock(); + } + } + } + + if (rxData_[uitemp] == ETX1 || (rxData_[uitemp] == ETX2)) + fullPackage = 0x01; + } + + if (resetBuffers) { //Does the terminal want to send? / Did we receive an EOT? + /*ENQrecieved = 0x01; + rxCounter = 0; + messageLength = 0; + iuc_asynchpos_sub_initArray(rxData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);*/ + /*if (ENQrecieved == 0) { + brd_SendDiagStr("-> IUC ANSNYCHPOS initialized",1); + } else { + brd_SendDiagStr("->IUC ASYNCHPOS listening to terminal",1); + }*/ + + if (resetBuffers >= 0x01) { + iuc_asynchpos_resetBuffers(0x01); + } else { + iuc_asynchpos_resetBuffers(0x00); + } + + if (rxLength > 1) { + //biox_Usart2_ClearRecBuffer(); + uctmp = NAK; + biox_Usart3_SendBlock(&uctmp,1); + } + + //iuc_asynchpos_sub_initArray(messageData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + return 2; //Yes, it does. / Yes, we did. + } else + + if (ENQrecieved && fullPackage/* && biox_Usart2_NewTelegram()*/) { + + brd_SendDiagStr("->IUC ASYNCHPOS Full packet recieved, ISMAS unlocked!",1); + ism_unlock(); + + //brd_SendDiagStr("->IUC ASYNCHPOS Data recieved.",1); + //calculate chksum + for (uitemp = 1; uitemp < (rxLength - 1) && (rxData_[uitemp - 1] != ACK1 || rxData_[uitemp - 1] != ACK2); ++uitemp) { + chksum ^= rxData_[uitemp]; + } + + if (chksum != rxData_[uitemp]) { + biox_Usart3_ClearRecBuffer(); + uctmp = NAK; + biox_Usart3_SendBlock(&uctmp,1); + brd_SendDiagStr("->IUC ASYNCHPOS Sending NACK (Checksum mismatch).",1); + return 3; //checksum mismatch + } else { + biox_Usart3_ClearRecBuffer(); + if (rxData_[rxLength - 2] == ETX1) { + uctmp = ACK1; + biox_Usart3_SendBlock(&uctmp,1); + brd_SendDiagStr("->IUC ASYNCHPOS Sending ACK1.",1); + //iucAsynchpoxDataContext = 0x01; + } else if (rxData_[rxLength - 2] == ETX2) { + uctmp = ACK2; + biox_Usart3_SendBlock(&uctmp,1); + brd_SendDiagStr("->IUC ASYNCHPOS Sending ACK2.",1); + //iucAsynchpoxDataContext = 0x00; + } else { + uctmp = NAK; + biox_Usart3_SendBlock(&uctmp,1); + brd_SendDiagStr("->IUC ASYNCHPOS Sending NACK (Wrong Byte).",1); + return 4; //We got something wrong and it's causing an error + } + } + + /*if (iuc_asynchpos_crc_old == rxData_[rxLength - 2]) { //We recieved that package already + iuc_asynchpos_crc_old = 0; + brd_SendDiagStr("->IUC ASYNCHPOS EXCEPTION: double package!",1); + + brd_SendDiagStr("->IUC ASYNCHPOS rx data: ",0); + brd_SendDiagBlock(rxData_,1,rxLength); + return 5; + } + + iuc_asynchpos_crc_old = rxData_[rxLength - 2];*/ + + //reformatting according to specs + for (uitemp = 0; uitemp < rxLength; ++uitemp) { + if (rxData_[uitemp] == DLE) { + rxData_[uitemp] = rxData_[uitemp + 1] - 0x30; + for (uitemp2 = uitemp + 2; uitemp2 < rxLength; ++uitemp2) { + rxData_[uitemp2 - 1] = rxData_[uitemp2]; + } + --rxLength; + } + } + + //Check if we received a logical ACK or NACK + if (rxCounter == 0) { + if (rxData_[3] == 0x0F) { + //NACK recieved, resend message + brd_SendDiagStr("-> IUC ANSNYCHPOS Message NOT ackknowledged",1); + if (asynchState < 0x02) { + iuc_asynchpos_sub_initArray(rxBuf,8); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0xFF; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + } + return 0; + } + + if (rxData_[3] == 0x0A) { + //ACK recieved, do nothing + brd_SendDiagStr("-> IUC ANSNYCHPOS Message acknowledged",1); + if (asynchState < 0x02) { + asynchState = 0x02; + iuc_asynchpos_sub_initArray(rxBuf,8); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + } + return 0; + } + } + + if (rxCounter == 0) { + messageLength = ((UINT) rxData_[1] << 8) | rxData_[2]; + + if (GWstate.DebugLevel & 0x10) + { + biox_itoa(messageLength,messageLength_); + brd_SendDiagStr("->IUC ASYNCHPOS message length: ",0); + brd_SendDiagBlock(messageLength_,1,8); + } + + if (messageLength + 1 < IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE) { + iuc_asynchpos_sub_initArray(messageData, /*messageLength + 1*/ IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE); + } else { + messageLength = 0; + brd_SendDiagStr("->IUC ASYNCHPOS message too long!",0); + //iuc_asynchpos_sub_initArray(messageData, IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE); + iuc_asynchpos_sub_initArray(rxBuf,8); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0xFF; + vmc_SendWithBuffer(rxBuf,3,0x69,0); + iuc_asynchpos_resetBuffers(0x00); + return 6; + } + } + + if (messageLength > 0) { + //add to rxData + uitemp = 1; + //while (rxData_[uitemp] != ETX1 && rxData_[uitemp] != ETX2 && rxData_[uitemp] != STX) { + while (/*rxData_[uitemp] != 0x02 && rxData_[uitemp] != 0x03*/uitemp < (rxLength - 2)) { //removing the STX, ETX, the checksum and additional zero at the end + rxAsynchData[(uitemp - 1) + rxCounter] = rxData_[uitemp]; + ++uitemp; + } + + rxCounter += uitemp - 1; + + if (GWstate.DebugLevel & 0x10) + { + biox_itoa(rxCounter,messageCounter_); + brd_SendDiagStr("->IUC ASYNCHPOS message counter: ",0); + brd_SendDiagBlock(messageCounter_,1,8); + + brd_SendDiagStr("->IUC ASYNCHPOS recieve buffer: ",0); + brd_SendDiagBlock(rxAsynchData,1,rxCounter); + } + + //NEXT Telegram + if (/*messageLength != 0 && messageLength <= (rxCounter + 5)*/ rxCounter >= (messageLength - 1)) { + if (GWstate.DebugLevel & 0x10) + { + biox_itoa(messageLength,messageLength_); + brd_SendDiagStr("->IUC ASYNCHPOS message length FINAL: ",0); + brd_SendDiagBlock(messageLength_,1,8); + + biox_itoa(rxCounter,messageCounter_); + brd_SendDiagStr("->IUC ASYNCHPOS message counter FINAL: ",0); + brd_SendDiagBlock(messageCounter_,1,8); + } + + if (rxAsynchData[2] != 0x0A) { + //iuc_asynchpos_sub_initArray(messageReturnData, 100);; //iuc_asynchpos_sub_initArray(messageData, messageLength + 1);//iuc_asynchpos_sub_initArray(messageReturnData, IUC_ASYNCHPOS_MAX_MESSAGE_SIZE); + + //if (!iuc_asynchpos_sub_confirm_message(messageData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE))) { + //Send ACK to terminal + //iuc_asynchpos_resetBuffers(0x02); + + /*for (uitemp = 0; uitemp < rxAsynchData[11] + 9; ++uitemp) { + messageReturnData[uitemp + 3] = rxAsynchData[uitemp + 3]; + } + ++uitemp; + + //messageReturnData[0] = 0x02; + messageReturnData[0] = uitemp & (0xFF00); + messageReturnData[1] = uitemp & (0x00FF); + messageReturnData[2] = 0x0A;*/ + //messageReturnData[uitemp + 2] = ETX1; + + //calculate chksum + /*for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) { + messageReturnData[uitemp + 3] ^= messageReturnData[uitemp]; + }*/ + + //biox_Usart2_SendBlock(messageReturnData,uitemp + 4); + + //brd_SendDiagStr("->IUC ASYNCHPOS message ACKNOWLEDGE: ",0); + //brd_SendDiagBlock(messageReturnData,1,uitemp + 1); + //iuc_asynchpos_send_serial(messageReturnData,uitemp + 1,0x01,0x01); + + for (uitemp = 0; uitemp < rxCounter - (12 + rxAsynchData[11]); ++uitemp) { + messageData[uitemp] = rxAsynchData[uitemp + (12 + (UINT) rxAsynchData[11])]; + + if (messageData[uitemp] == 0x00) + messageData[uitemp] = 0x30; + } + + uitemp = biox_FindStrInBufferInt("PrintReceipt",messageData) | biox_FindStrInBufferInt("PRINTRECEIPT",messageData) + | biox_FindStrInBufferInt("AuthorizationResult",messageData) | biox_FindStrInBuffer("AUTHORIZATIONRESULT",messageData); + + if (uitemp) { + if (biox_FindStrInBufferInt("PrintReceipt",messageData) | biox_FindStrInBufferInt("PRINTRECEIPT",messageData)) { + biox_CopyBlock(rxAsynchData,3,terminalSignature,0,8); + } else { + biox_CopyBlock(rxAsynchData,3,terminalSignature,8,8); + } + } else { + iuc_asynchpos_sub_sendACK(0); + } + + if (GWstate.DebugLevel & 0x10) + { + brd_SendDiagStr("->IUC ASYNCHPOS full message: ",0); + brd_SendDiagBlock(messageData,1,rxCounter - (12 + ((UINT) rxAsynchData[11]))); + } + + iuc_asynchpos_handleMessage(messageData); + brd_SendDiagStr("-> IUC ANSNYCHPOS Data handled",1); + } + + /*brd_SendDiagStr("->IUC ASYNCHPOS full message: ",0); + brd_SendDiagBlock(messageData,1,rxCounter - (12 + rxAsynchData[11])); + + iuc_asynchpos_handleMessage(messageData); + brd_SendDiagStr("-> IUC ANSNYCHPOS Data handled",1);*/ + iuc_asynchpos_resetBuffers(0x00); + } + } + + return 1; //Still busy + } + } //else { + + if (ENQrecieved == 0 && (timeInitalized + 10) < GWglobTime.SecOfDay) { + brd_SendDiagStr("->IUC ASYNCHPOS waiting for initialization",1); + biox_Usart3_ClearRecBuffer(); + iuc_asynchpos_init(); + return 1; + } + + if (ism_islocked() && (timeHoldISMAS - GWglobTime.SecOfDay >= 1800)) + { + brd_SendDiagStr("->IUC ASYNCHPOS ISMAS holding timeout, ISMAS unlocked!",1); + ism_unlock(); + } + + if (iuc_asynch_PrintControl == 0xFF) { + iuc_asynch_keepAlive = 0x00; + iuc_asynchpos_sub_sendACK(1); + biox_delay_ms(2); + iuc_asynchpos_sub_sendACK(2); + biox_delay_ms(2); + iuc_asynchpos_command_print_Result(0x01); + biox_delay_ms(2); + if (0x04 == asynchState) { //Was the authorization successful? + brd_SendDiagStr("->IUC ASYNCHPOS Sending YES receipt to VMC.",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x10); //Yes + } else { + brd_SendDiagStr("->IUC ASYNCHPOS Sending NO receipt to VMC.",1); + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x20); //No + } + iuc_asynch_PrintControl = 0; + + //VendRequest=0; + return 1; + } + + /*if (iuc_asynch_PrintControl == 0xFE) { + iuc_asynch_keepAlive = 0x00; + iuc_asynchpos_sub_initArray(rxBuf,8); + rxBuf[0] = 0x45; + rxBuf[1] = 0x00; + rxBuf[2] = 0x00; + vmc_SendWithBuffer(rxBuf,8,0x69,0); + iuc_asynch_PrintControl = 0; + return 1; + }*/ + + if (rxData_[0] != STX/* && rxLength > 0 && rxData_[0] != 0xFF*/) { + //brd_SendDiagStr("->IUC ASYNCHPOS No STX recieved, ISMAS unlocked, sending NACK!",1); + if (rxData_[0] != 0xFF) { + brd_SendDiagStr("->IUC ASYNCHPOS No STX recieved, ISMAS unlocked!",1); + ism_unlock(); + } + biox_Usart3_ClearRecBuffer(); + //uctmp = NAK; + //biox_Usart3_SendBlock(&uctmp,1); + } + + //Workaround for our terminal problem, which, sometimes, fails to send a Print Result + /*if (0xF0 == iuc_asynch_PrintControl) { + if (0x00 == iuc_asynch_printTimeout) { + iuc_asynchpos_sub_initArray(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + receiptData[0] = 0x50; + if (0x04 == asynchState) { //Was the authorization successful? + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x10); //Yes + } else { + vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x20); //No + } + iuc_asynch_printTimeout = IUC_ASYNCHPOS_PRINTTIMOUT; + iuc_asynch_PrintControl = 0; + } else { + --iuc_asynch_printTimeout; + biox_delay_ms(1); + } + }*/ + //} + + if (waitforACK) + return 8; + return 0; +} + +//messagees + +void iuc_asynchpos_sub_synchTime() { + UINT uitemp = 0; + + //unsigned char timeStart[] = "2017-12-19 13:40:00"; + //biox_CopyBlock(timeStart,0,asynchBill.time,0,biox_StrLen(timeStart)); + + for (uitemp = 0; uitemp < 6; ++uitemp) { + switch (uitemp) { + case 0: //year + asynchBill.time[2] = (GWglobTime.year / 10) + 0x30;; + asynchBill.time[3] = (GWglobTime.year % 10) + 0x30; + + /*#ifdef IUC_ASYCHNPOS_TESTMODE + asynchBill.time[2] = 0x31; + asynchBill.time[3] = 0x39; + #endif*/ + break; + case 1: //month + asynchBill.time[5] = (GWglobTime.month / 10) + 0x30;; + asynchBill.time[6] = (GWglobTime.month % 10) + 0x30; + + /*#ifdef IUC_ASYCHNPOS_TESTMODE + asynchBill.time[5] = 0x31; + asynchBill.time[6] = 0x32; + #endif*/ + break; + case 2: //day + asynchBill.time[8] = (GWglobTime.dayOfMon / 10) + 0x30;; + asynchBill.time[9] = (GWglobTime.dayOfMon % 10) + 0x30; + + /*#ifdef IUC_ASYCHNPOS_TESTMODE + asynchBill.time[8] = 0x30; + asynchBill.time[9] = 0x32; + #endif*/ + break; + case 3: //hours + asynchBill.time[11] = (GWglobTime.hour / 10) + 0x30;; + asynchBill.time[12] = (GWglobTime.hour % 10) + 0x30; + + /*#ifdef IUC_ASYCHNPOS_TESTMODE + asynchBill.time[11] = 0x31; + asynchBill.time[12] = 0x32; + #endif*/ + break; + + case 4: //minutes + asynchBill.time[14] = (GWglobTime.min / 10) + 0x30;; + asynchBill.time[15] = (GWglobTime.min % 10) + 0x30; + + /*#ifdef IUC_ASYCHNPOS_TESTMODE + asynchBill.time[14] = 0x30; + asynchBill.time[15] = 0x30; + #endif*/ + break; + case 5: //seconds + asynchBill.time[17] = (GWglobTime.sec / 10) + 0x30;; + asynchBill.time[18] = (GWglobTime.sec % 10) + 0x30; + break; + } + } +} + +void iuc_asynchpos_command_ping_terminal() { + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "Ping"; + UCHAR tagName[] = "Time"; +// UCHAR tagValue[] = "2017-12-19 13:40:00"; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE); + + //biox_CopyBlock(UCHAR *src, UINT srcPos, UCHAR *dest, UINT destPos, UINT len); + uitemp = (UCHAR) biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + iuc_asynchpos_sub_synchTime(); + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length + ++uitemp; + biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value + + uitemp += biox_StrLen(asynchBill.time)/* + 1*/; + + iuc_asynchpos_send(packetType,message,uitemp,0x00); +} + +//80 - d +void iuc_asynchpos_command_Login() { //Kasse registrieren + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "Login"; + UCHAR tagName[] = "Time"; + //UCHAR tag2Name[] = "IdleText"; + UCHAR tag3Name[] = "Flags"; + UCHAR tag3Value[] = "AP3"; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE); + + uitemp = (UCHAR) biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + //Time + iuc_asynchpos_sub_synchTime(); + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length + ++uitemp; + biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value + uitemp += biox_StrLen(asynchBill.time); + + //Flags + message[uitemp] = (UCHAR) biox_StrLen(tag3Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name));// tag name + uitemp += (1 + biox_StrLen(tag3Name)); + + message[uitemp] = (UCHAR) biox_StrLen(tag3Value);//value length + ++uitemp; + biox_CopyBlock(tag3Value,0,message,uitemp, biox_StrLen(tag3Value));//value + + uitemp += biox_StrLen(tag3Value)/* + 1*/; + + iuc_asynchpos_send(packetType,message,uitemp,0x01); +} + +//81 - d +void iuc_asynchpos_command_Logout () { //Kassenschluss + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "Logout"; + UCHAR tagName[] = "Time"; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE); + + uitemp = (UCHAR) biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + iuc_asynchpos_sub_synchTime(); + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length + ++uitemp; + biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value + + uitemp += biox_StrLen(asynchBill.time)/* + 1*/; + + iuc_asynchpos_send(packetType,message,uitemp,0x01); + asynchState = 0x00; +} + +//54 - d +void iuc_asynchpos_command_authorize(unsigned int vkPreis) { + UCHAR message[IUC_ASYNCHPOS_MAX_ARRAY_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "Authorize"; + UCHAR tag1Name[] = "Amount"; + UCHAR tag2Name[] = "Cash"; + UCHAR tag3Name[] = "Currency"; + UCHAR tag4Name[] = "DocNr"; + UCHAR tag5Name[] = "Time"; + UCHAR tag6Name[] = "Lang"; + UCHAR tag1Value[10]; + UCHAR tag2Value[] = "0"; + UCHAR tag3Value[] = "978"; + UCHAR tag6Value[] = "lt"; + UINT vkPreis_ = vkPreis; + + iuc_asynch_PRNrecieved = 0; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_ARRAY_SIZE); + iuc_asynchpos_sub_initArray(tag1Value,10); + + uitemp = (UCHAR) biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + //Amount + message[uitemp] = (UCHAR) biox_StrLen(tag1Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag1Name,0,message,uitemp, biox_StrLen(tag1Name));// tag name + uitemp += (1 + biox_StrLen(tag1Name)); + + biox_itoa(vkPreis_,tag1Value); + message[uitemp] = (UCHAR) biox_StrLen(tag1Value);//value length + ++uitemp; + biox_CopyBlock(tag1Value,0,message,uitemp, biox_StrLen(tag1Value));//value + uitemp += (/*1 + */biox_StrLen(tag1Value)); + + //Cash + message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name + uitemp += (1 + biox_StrLen(tag2Name)); + + message[uitemp] = (UCHAR) biox_StrLen(tag2Value);//value length + ++uitemp; + biox_CopyBlock(tag2Value,0,message,uitemp, biox_StrLen(tag2Value));//value + uitemp += (/*1 + */biox_StrLen(tag2Value)); + + //Currency + message[uitemp] = (UCHAR) biox_StrLen(tag3Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name));// tag name + uitemp += (1 + biox_StrLen(tag3Name)); + + message[uitemp] = (UCHAR) biox_StrLen(tag3Value);//value length + ++uitemp; + biox_CopyBlock(tag3Value,0,message,uitemp, biox_StrLen(tag3Value));//value + uitemp += (/*1 + */biox_StrLen(tag3Value)); + + //DocNr + message[uitemp] = (UCHAR) biox_StrLen(tag4Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag4Name,0,message,uitemp, biox_StrLen(tag4Name));// tag name + uitemp += (1 + biox_StrLen(tag4Name)); + + //biox_ltoa(asynchBill.docuNr,asynchBill.docNr); + //++asynchBill.docuNr; + + generate_UniqueTransNr(asynchBill.docNr); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length + ++uitemp; + biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value + + uitemp += biox_StrLen(asynchBill.docNr)/* + 1*/; + + //Time + message[uitemp] = (UCHAR) biox_StrLen(tag5Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag5Name,0,message,uitemp, biox_StrLen(tag5Name));// tag name + uitemp += (1 + biox_StrLen(tag5Name)); + + iuc_asynchpos_sub_synchTime(); + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length + ++uitemp; + biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value + + uitemp += biox_StrLen(asynchBill.time)/* + 1*/; + + //Language + message[uitemp] = (UCHAR) biox_StrLen(tag6Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag6Name,0,message,uitemp, biox_StrLen(tag6Name));// tag name + uitemp += (1 + biox_StrLen(tag6Name)); + + message[uitemp] = (UCHAR) biox_StrLen(tag6Value);//value length + ++uitemp; + biox_CopyBlock(tag6Value,0,message,uitemp, biox_StrLen(tag6Value));//value + uitemp += biox_StrLen(tag6Value)/* + 1*/; + + iuc_asynchpos_send(packetType,message,uitemp,0x00); +} + +//73 - d +void iuc_asynchpos_command_cancel_authorize() { + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "AuthorizationCancelled"; + UCHAR tagName[] = "ID"; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE); + + uitemp = biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + + if (asynchBill.id[0] != 0x00) { + ++uitemp; + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.id);//value length + ++uitemp; + biox_CopyBlock(asynchBill.id,0,message,uitemp, biox_StrLen(asynchBill.id));//value + + uitemp += biox_StrLen(asynchBill.id)/* + 1*/; + } + + iuc_asynchpos_send(packetType,message,uitemp,0x00); +} + +//77 - d +void iuc_asynchpos_command_close_Document(unsigned char isStorno) { //Finalize sale + UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE]; + UCHAR packetType = 0x00; + UINT uitemp = 0; + UCHAR command[] = "DocClosed"; + UCHAR tagName[] = "DocNr"; + UCHAR tag2Name[] = "AuthID"; + + //Constructing the message + iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE); + + uitemp = biox_StrLen(command); + message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length + biox_CopyBlock(command,0,message,1,uitemp); //tag name + ++uitemp; + + //DocNr + message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length + ++uitemp; + biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name + uitemp += (1 + biox_StrLen(tagName)); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length + ++uitemp; + biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value + uitemp += biox_StrLen(asynchBill.docNr); + + //AuthID + if (!isStorno) { + message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length + ++uitemp; + biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name + uitemp += (1 + biox_StrLen(tag2Name)); + + message[uitemp] = (UCHAR) biox_StrLen(asynchBill.id);//value length + ++uitemp; + biox_CopyBlock(asynchBill.id,0,message,uitemp, biox_StrLen(asynchBill.id));//value + uitemp += biox_StrLen(asynchBill.id)/* + 1*/; + } + + iuc_asynchpos_send(packetType,message,uitemp,0x00); +} + +void iuc_asynchpos_handleCommand(unsigned char command, unsigned char status) { + //r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt + UCHAR tempBuf[3]; + UCHAR rxBuf[8]; +// UINT uitemp = 0; +UINT uitmp= 700; + + tempBuf[0] = 0x00; + tempBuf[1] = 0x00; + tempBuf[2] = 0x00; + + timeHoldISMAS = GWglobTime.SecOfDay; + + iuc_asynchpos_sub_initArray(rxBuf,8); + //iuc_asynchpos_resetBuffers(0x00); + + switch (command) { + case 0x72: //registration + //iuc_asynchpos_init(); + asynchState = 0x01; + iuc_asynchpos_command_Login(); + GWstate.VendRequest=1; + break; + case 0x61: //authorisation + iuc_asynch_keepAlive = 0x01; + iuc_asynch_PrintControl = 0; + iuc_asynchpos_sub_clear_message(0x01); + //VendRequest=1; + iuc_asynchpos_resetBuffers(0x00); + ///#ifdef IUC_ASYCHNPOS_TESTMODE + //iuc_asynchpos_command_authorize(uitmp); + //#else + iuc_asynchpos_command_authorize(Vend.Amount); + //#endif + break; + case 0x63: //cancel + case 0x73: //storno + /*if (asynchState <= 0x02 != 0) { //Authorization result recieved? + iuc_asynchpos_command_cancel_authorize(); + } else {*/ + iuc_asynchpos_command_close_Document(0x01); + //} + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + break; + case 0x6B: //kassenschnitt + iuc_asynchpos_command_Logout(); + break; + case 0x62: //get last bill + //iuc_zvt_getLastBill(tempBuf); + break; + case 0x01: iuc_asynchpos_command_close_Document(0x00); + iuc_asynch_keepAlive = 0x00; + //VendRequest=0; + break; + case 0x70: iuc_asynchpos_command_ping_terminal(); + break; + default: + break; + } +} + +int iuc_asynchpos_checkTime() { + int retVal = 0; + + if ((GWglobTime.hour == 0) && asynchSessionClosed != 0x00) { + asynchSessionClosed = 0x00; + retVal = 1; + } else if ((GWglobTime.hour == 1) && asynchSessionClosed == 0x00) { + iuc_asynchpos_command_Logout(); + retVal = 1; + asynchSessionClosed = 0x01; + } else if ((GWglobTime.hour == 2) && asynchSessionClosed == 0x01) { + iuc_asynchpos_command_Login(); + retVal = 1; + asynchSessionClosed = 0x02; + } + + return retVal; +} + +unsigned char iuc_asynchpos_getIsSaleRunning() { + + //Print, when idle + /*if (iuc_print_counter && asynchState == 0x01) { + iuc_asynchpos_command_print_Result(0x01); + --iuc_print_counter; + return 1; + }*/ + + return iuc_asynch_keepAlive; +} + + +#endif diff --git a/main/main.cpp b/main/main.cpp index b315a34..cfefe7f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -27,140 +27,3694 @@ extern "C" char* strptime(const char* s, #include #include #include +#include +#include +#include #include #include #include "calculator_functions.h" -#include +#include "calculate_price.h" +#include + +#define SZEGED (0) +#define SCHOENAU_KOENIGSEE (0) +#define NEUHAUSER_KORNEUBURG (1) +#define NEUHAUSER_LINSINGER_MASCHINENBAU (0) +#define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0) +#define NEUHAUSER_BILEXA_GALTUER (0) +#define BAD_NEUENAHR_AHRWEILER (0) +#define NEUHAUSER_CHRISTOPH_REISEN (0) +#define NEUHAUSER_PERNEGG_AN_DER_MUR (0) +#define NEUHAUSER_STOCKERAU (0) +#define KLEIPEDA_LITAUEN (0) +#define SEXTEN (0) +#define SCHNALS_LEITER_KIRCHL (0) +#define SCHNALS_STAUMAUER (SCHNALS_LEITER_KIRCHL) +#define VALSER_ALM (0) +#define NEUHAUSER_FORCHACH (0) + +#if NEUHAUSER_KIRCHDORF==1 +static bool test_neuhauser_kirchdorf(int step, double cost) { + return true; + + + switch (step) { + case 30: + if (cost != 30) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 30; + return false; + } + break; + case 35: + if (cost != 40) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 40; + return false; + } + break; + case 40: + if (cost != 50) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 50; + return false; + } + break; + case 45: + if (cost != 60) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 60; + return false; + } + break; + case 50: + if (cost != 70) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 70; + return false; + } + break; + case 55: + if (cost != 80) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 80; + return false; + } + break; + case 60: + if (cost != 90) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 90; + return false; + } + break; + case 65: + if (cost != 100) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 100; + return false; + } + break; + case 70: + if (cost != 110) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 110; + return false; + } + break; + case 75: + if (cost != 120) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 120; + return false; + } + break; + case 80: + if (cost != 130) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 130; + return false; + } + break; + case 85: + if (cost != 140) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 140; + return false; + } + break; + case 90: + if (cost != 150) { + qCritical() << "ERROR COMPUTING COST" + << "HAVE" << cost + << "SHOULD" << 150; + return false; + } + break; + default: + break; + } + + return true; +} +#endif + +#include +#include +#include +#include +#include + +/* + QJsonObject root; + QJsonArray PaymentRate; + QJsonArray Duration; + + for (int i = 1; i <= 15*15; ++i) { + QJsonObject o; + o["pra_payment_option_id"] = 1049; + o["pra_payment_unit_id"] = i; + if (i <= 15) { + o["pra_price"] = 0; + } else { + o["pra_price"] = (i-15)*10; + } + + PaymentRate.push_back(o); + } + for (int i = 1; i <= 15*15; ++i) { + QJsonObject o; + o["pun_duration"] = i*4; + o["pun_id"] = i; + o["pun_label"] = QString("%1 min").arg(i*4); + Duration.push_back(o); + } + + root["PaymentRate"] = PaymentRate; + root["Duration"] = Duration; + + qCritical().noquote() << QJsonDocument(root).toJson(); + + return 0; +*/ int main() { - std::ifstream input(QDir::homePath().append("/tariff01.json").toStdString()); + + //487 { + // 488 "pra_payment_option_id": 1049, + // 489 "pra_payment_unit_id": 84, + // 490 "pra_price":"840" + //>>491 } + + //for (int i = 1; i < 85; ++i) { + //printf("{\n \"\pra_payment_option_id\": 1049,\n \"\pra_payment_unit_id\": %d,\n \"pra_price\": %d\n},\n", + // i, i*10); + //} + //return 0; +#if 0 + MessageHelper msgHelp; + // msgHelp.createLoginMessageChunksToSend(0x02); + msgHelp.createAuthorizeMessageChunksToSend(0x02); + + + qCritical() << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl; + + // unsigned static char terminalID[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; + // unsigned static char terminalAPAK[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE]; + strncpy((char *)&terminalID[0], "T-TPS-SELF2002in", IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + strncpy((char *)&terminalAPAK[0], "8AC304380E0E476BA2558B75DB9E2516", IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE); + + //iuc_asynchpos_command_Login(); + iuc_asynchpos_command_authorize(1000); + + qCritical() << "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; + return 0; + + // test aes + aes_init(); + + uint32_t crc = 0; + + QByteArray a("T-TPS-SELF2002"); + qCritical() << a.toHex(' '); + + //QByteArray xx("\x0D\x54\x2D\x54\x50\x53\x2D\x53\x45\x4C\x46\x32\x30\x30\x32\x85\x4C\x6F\x67\x69\x6E\x04\x54\x69\x6D\x65\x00\x13\x32\x30\x32\x34\x2d\x30\x36\x2d\x31\x31\x20\x31\x33\x3a\x34\x34\x3a\x33\x35\x00\x02", + // 48); + + //QByteArray xx("123456789", 9); + + QByteArray xx("2E5450532D53454C4632303032854C6F67696E0454696D650013323032342d30362d31312031333a34343a333505466C616773000341505300", + 114); + unsigned char bb = 0; + //32:4b:e7:4e:1d:d7:b5:ae + QByteArray b("\x00\x46\x00\x32\x4b\xe7\x4e\x1d\xd7\xb5\xae\x0E\x54\x2D\x54\x50\x53\x2D\x53\x45\x4C\x46\x32\x30\x30\x32\x85\x4C\x6F\x67\x69\x6E\x04\x54\x69\x6D\x65\x00\x13\x32\x30\x32\x34\x2d\x30\x36\x2d\x31\x31\x20\x31\x33\x3a\x34\x34\x3a\x33\x35\x05\x46\x6C\x61\x67\x73\x00\x03\x41\x50\x53\x00\x02", + 71); + qCritical() << "B" << b.toHex(':'); + + for (int i=0; i < b.size(); ++i) { + //printf("%d %02x\n", i, (unsigned char)b.at(i)); + bb = bb ^ b.at(i); + } + printf("bb=%02x\n", bb); + + + + qCritical() << xx.size() << "xx" << xx.toHex(' '); + + crc = iuc_asynchpos_sub_updateCRC(crc, xx.data(), xx.size()); + + printf("111 crc=%04x\n", crc); + + crc = crc32(xx.data(), xx.size()); + printf("222 crc=%04x\n", crc); + + QByteArray ba("TEST\x0E\x0E\x47\x6B\xA2\x55\x8B\x75\xDB\x9E\x25\x16"); + + ba[0] = (crc >> 24); + ba[1] = (crc >> 16); + ba[2] = (crc >> 8); + ba[3] = (crc); + + qCritical() << ba.toHex(' '); + + QDateTime current = QDateTime::currentDateTime(); + QString const &s = current.toString(Qt::ISODate); + QByteArray time(s.toStdString().c_str()); + time[10] = ' '; + + qCritical() << time.toHex(' '); + + + + //unsigned char in[] = "TESTTESTTESTTEST"; + //unsigned char in[] = ba.data(); + unsigned char key[] = "8AC304380E0E476BA2558B75DB9E2516"; + //unsigned char key[] = "\x8A\xC3\x04\x38\x0E\x0E\x47\x6B\xA2\x55\x8B\x75\xDB\x9E\x25\x16"; + unsigned char output[256]; + + memset(output, 0, sizeof(output)); + + aes_encrypt((unsigned char*)ba.data(), output, key); + + qCritical() << ba.toHex(':') << endl; + qCritical() << QByteArray((char*)key).toHex(':') << endl; + qCritical() << QByteArray((char*)output).toHex(':') << endl; + + return 0; +#endif + +//char aes_encrypt(unsigned char *input,unsigned char *output,unsigned char *key); + +#if KLEIPEDA_LITAUEN==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + input.open("/opt/ptu5/opt/customer_335/etc/psa_tariff/tariff01.json"); + std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); - Calculator calculator; Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; - char const *startDate = ""; + if (isParsed) { + //pop_min_time = get_minimal_parkingtime(&cfg); + //pop_max_time = get_maximal_parkingtime(&cfg); + //pop_min_price = get_minimal_parkingprice(&cfg); + //pop_max_price = get_maximal_parkingprice(&cfg); + //pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; - if (isParsed) - { - startDate = "2023-05-10T13:52:18.665Z"; - std::string duration = calculator.GetDurationFromCost(&cfg, 3, (char *)startDate, 33, false, true); - cout << "---> startDate " << startDate << " _price_ = " << 33 - << " Total duration is: " << duration << endl; + //qCritical() << " pop_min_time: " << pop_min_time; + //qCritical() << " pop_max_time: " << pop_max_time; + //qCritical() << " pop_min_price: " << pop_min_price; + //qCritical() << " pop_max_price: " << pop_max_price; + + + //QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + //qCritical() << "TimeSteps" << timeSteps; + + // return 0; + + CalcState cs; + double cost; + int durationInMinutes = 0; + int offsetInMinutes = 0; + + // for (int day = Qt::Monday; day <= Qt::Sunday; ++day) { + for (int day = Qt::Monday; day <= Qt::Monday; ++day) { + QDateTime s(QDate(2024, 8, 19 + day), QTime()); // 20: (whit) monday,..., 26: sunday + + switch (day) { + case (int)Qt::Monday: + qCritical() << "Monday"; + break; + case (int)Qt::Tuesday: + qCritical() << "Tuesday"; + break; + case (int)Qt::Wednesday: + qCritical() << "Wednesday"; + break; + case (int)Qt::Thursday: + qCritical() << "Thursday"; + break; + case (int)Qt::Friday: + qCritical() << "Friday"; + break; + case (int)Qt::Saturday: + qCritical() << "Saturday"; + break; + case (int)Qt::Sunday: + qCritical() << "Sunday"; + break; + } + + QDateTime start(s); + start.setTime(QTime(21, 30, 0)); + + QDateTime end; + int netto_parking_time = 14 * 60; + struct price_t costs; + PermitType pt(PERMIT_TYPE::SHORT_TERM_PARKING); + + double cost = 150; + + //cs = compute_price_for_parking_ticket(&cfg, start, netto_parking_time, + // end, &costs, pt); + + + + //qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << costs.netto + // << "> end" << end.toString(Qt::ISODate); + + cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << cost + << "> end" << end.toString(Qt::ISODate); + //} + + exit(0); + + /* + CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time, + int netto_parking_time, + QDateTime &end_parking_time, // return value + struct price_t *price, // return value + bool prepaid = true); + */ + + //for (int minutes = 0; minutes < 1440; ++minutes) { + for (int minutes = 540; minutes <= 540; ++minutes) { + // QDateTime start = s.addSecs(minutes * 60); + QDateTime start(QDateTime::currentDateTime()); + QDateTime effectiveStart(QDateTime::currentDateTime()); + + if (start.time() < QTime(8, 0, 0)) { + effectiveStart.setTime(QTime(8, 0, 0)); + } else + if (start.time() <= QTime(22, 0, 0)) { + effectiveStart = start; + } else { + effectiveStart = start.addDays(1); + effectiveStart.setTime(QTime(8, 0, 0)); // next day + } + + for (int i = 30; i <= 30; i += 10) { + //for (int i = 2100; i <= 2100; i += 10) { + cost = i; + + if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { // return value + qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << cost + << "> end" << end.toString(Qt::ISODate); + } + + if (!cs) { + qCritical() << "ERROR CalcState" << cs.toString() << endl; + } + } + } + } + } +#endif + +#if SEXTEN==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + input.open("/opt/ptu5/opt/customer_501/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + + QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + // return 0; + + CalcState cs; + double cost; + int durationInMinutes = 0; + int offsetInMinutes = 0; + + // for (int day = Qt::Monday; day <= Qt::Sunday; ++day) { + for (int day = Qt::Monday; day <= Qt::Monday; ++day) { + QDateTime s(QDate(2024, 7, 14 + day), QTime()); // 20: (whit) monday,..., 26: sunday + QDateTime end; + + switch (day) { + case (int)Qt::Monday: + qCritical() << "Monday"; + break; + case (int)Qt::Tuesday: + qCritical() << "Tuesday"; + break; + case (int)Qt::Wednesday: + qCritical() << "Wednesday"; + break; + case (int)Qt::Thursday: + qCritical() << "Thursday"; + break; + case (int)Qt::Friday: + qCritical() << "Friday"; + break; + case (int)Qt::Saturday: + qCritical() << "Saturday"; + break; + case (int)Qt::Sunday: + qCritical() << "Sunday"; + break; + } + + + /* + CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + QDateTime &start_parking_time, + int netto_parking_time, + QDateTime &end_parking_time, // return value + struct price_t *price, // return value + bool prepaid = true); + */ + + //for (int minutes = 0; minutes < 1440; ++minutes) { + for (int minutes = 480; minutes <= 480; minutes += 1) { + QDateTime start = s.addSecs(minutes * 60); + + // qCritical() << "start" << start.toString(Qt::ISODate); + + QDateTime effectiveStart = start; + + if (start.time() < QTime(8, 0, 0)) { + effectiveStart.setTime(QTime(8, 0, 0)); + } else + if (start.time() <= QTime(19, 0, 0)) { + effectiveStart = start; + } else { + effectiveStart = start.addDays(1); + effectiveStart.setTime(QTime(8, 0, 0)); // next day + } + +/* + for (int i = 10; i <= 400; i += 10) { + cost = i; + + if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { // return value + qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << cost + << "> end" << end.toString(Qt::ISODate); + } + + if (!cs) { + qCritical() << "ERROR CalcState" << cs.toString() << endl; + } + } +*/ + int netto_parking_time = 60; + struct price_t price; + + qCritical() << "start" << start.toString(Qt::ISODate); + + QDateTime const s = start; + + if ((cs = compute_price_for_parking_ticket(&cfg, start, netto_parking_time, end, &price, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { + qCritical() << "start" << s.toString(Qt::ISODate) + << "netto_parking_time" << netto_parking_time + << "< price" << price.netto + << "> end" << end.toString(Qt::ISODate); + } + } + } } - return 0; +#endif + +#if (SCHNALS_LEITER_KIRCHL==1 || SCHNALS_STAUMAUER==1) + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + //input.open("/home/linux/customer_505/etc/psa_tariff/tariff01.json"); + input.open("/opt/ptu5/opt/customer_505/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + + //QDateTime s = QDateTime::currentDateTime(); + //s.setTime(QTime(13, 30, 0)); + //std::optional e = cfg.getInterpolationEnd(s, 0); + //if (e) { + // qCritical() << " endtime: " << e.value().toString(Qt::ISODate); + //} + //return 0; + + //QDateTime start = QDateTime::currentDateTime(); + //start.setTime(QTime(18, 0, 0)); + //QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, 0, start); + //qCritical() << "TimeSteps" << timeSteps; + + //return 0; + + CalcState cs; + double cost; + int durationInMinutes = 0; + int offsetInMinutes = 0; + + // for (int day = Qt::Monday; day <= Qt::Sunday; ++day) { + for (int day = Qt::Monday; day <= Qt::Monday; ++day) { + QDateTime s(QDate(2024, 7, 21 + day), QTime(0, 0, 0)); + QDateTime end; + + switch (day) { + case (int)Qt::Monday: + qCritical() << "Monday"; + break; + case (int)Qt::Tuesday: + qCritical() << "Tuesday"; + break; + case (int)Qt::Wednesday: + qCritical() << "Wednesday"; + break; + case (int)Qt::Thursday: + qCritical() << "Thursday"; + break; + case (int)Qt::Friday: + qCritical() << "Friday"; + break; + case (int)Qt::Saturday: + qCritical() << "Saturday"; + break; + case (int)Qt::Sunday: + qCritical() << "Sunday"; + break; + } + + //for (int minutes = 0; minutes < 1440; ++minutes) { + for (int minutes = 1020; minutes <= 1020; minutes += 1) { + QDateTime start = s.addSecs(minutes * 60); + + qCritical() << "start" << start.toString(Qt::ISODate); + + QDateTime effectiveStart = start; + + // hier sollte man auch testen was passiert, falls man ausserhalb + // der verkaufsdaten steht + if (start.time() < QTime(7, 0, 0)) { + effectiveStart.setTime(QTime(7, 0, 0)); + } else + if (start.time() <= QTime(20, 0, 0)) { + effectiveStart = start; + } else { + effectiveStart = start.addDays(1); + effectiveStart.setTime(QTime(7, 0, 0)); // next day + } + +#if 0 + PermitType permitType(PERMIT_TYPE::SHORT_TERM_PARKING); + for (int i = 200; i <= 200; i += 10) { + cost = i; + + if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, permitType))) { // return value + } + + if (!cs) { + qCritical() << "ERROR CalcState" << cs.toString() << endl; + } else { +// qCritical() << cs.toString(); + } + + qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << cost + << "> end" << end.toString(Qt::ISODate); + + } +#else + for (int i = 700; i <= 1400; i += 700) { + //for (int i = 2100; i <= 2100; i += 10) { + cost = i; + + if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW)))) { // return value + } + + if (!cs) { + qCritical() << "ERROR CalcState" << cs.toString() << endl; + } else { +// qCritical() << cs.toString(); + } + + qCritical() << "start" << start.toString(Qt::ISODate) << "< cost" << cost + << "> end" << end.toString(Qt::ISODate); + } +#endif +#if 0 + + start = QDateTime::currentDateTime(); + start.setTime(QTime(9, 57, 0)); + + for (int i = 66; i <= 66; i += 6) { + + QDateTime end; + struct price_t price; + cs = compute_price_for_parking_ticket(&cfg, start, i, end, &price); + + qCritical() << "start" << start.toString(Qt::ISODate) << "end" << end.toString(Qt::ISODate) + << "price" << price.netto; + } +#endif + } + } + } +#endif + +#if VALSER_ALM==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + int zone = 1; + + if (zone == 1) { + input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff01.json"); + } + if (zone == 2) { + input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff02.json"); + } + if (zone == 3) { + input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff03.json"); + } + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + + if (zone == 1 || zone == 3) { +/* + pop_min_time = get_minimal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + pop_max_time = get_maximal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + pop_min_price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + pop_max_price = get_maximal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time_pkw: " << pop_min_time; + qCritical() << " pop_max_time_pkw: " << pop_max_time; + qCritical() << " pop_min_price_pkw: " << pop_min_price; + qCritical() << " pop_max_price_pkw: " << pop_max_price; + + pop_min_time = get_minimal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_BUS); + pop_max_time = get_maximal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_BUS); + pop_min_price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_BUS); + pop_max_price = get_maximal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING_BUS); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time_bus: " << pop_min_time; + qCritical() << " pop_max_time_bus: " << pop_max_time; + qCritical() << " pop_min_price_bus: " << pop_min_price; + qCritical() << " pop_max_price_bus: " << pop_max_price; +*/ + } + if (zone == 2) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + } + + //QDateTime start = QDateTime::currentDateTime(); + //start.setTime(QTime(12, 0, 0)); + //QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, 0, start); + //qCritical() << "TimeSteps" << timeSteps; + //return 0; + if (zone == 1) { + //int minParkingTime = get_minimal_parkingtime(&cfg); + QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << timeSteps; + int Down = 0; + int Up = 1; + + QDateTime const start = QDateTime::currentDateTime(); + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + + if (paymentOptionIndex < 0) { + qCritical() << "ERROR paymentOptionIndex" << paymentOptionIndex + << "< 0 for start" << start.toString(Qt::ISODate); + exit(-1); + } + + QSet const prices_pkw{600, 1200, 1800, 2400, 3000, 3600, 4200}; + QSet const prices_bus{3000, 6000, 9000, 12000, 15000, 18000, 21000}; + + QDateTime end; + CalcState calcState; + QDateTime s(QDateTime::currentDateTime()); + + // s.setTime(QTime(12, 0, 0)); + + //calcState = compute_duration_for_parking_ticket(&cfg, s, + // (double)1200, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW)); + //qCritical() << end.toString(Qt::ISODate); + //qCritical() << calcState.toString(); + + calcState = compute_duration_for_parking_ticket(&cfg, s, + (double)9000, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_BUS)); + qCritical() << end.toString(Qt::ISODate); + qCritical() << calcState.toString(); + + struct price_t costs; + + CalcState cs; + + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + qCritical() << "XXXXX end" << end.toString(Qt::ISODate); + + cs = compute_price_for_parking_ticket(&cfg, s, timeSteps.at(i), end, &costs, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + if (cs.getStatus() != CalcState::State::SUCCESS) { + qCritical() << "ERROR STATUS" << costs.netto; + exit(-1); + } + } + } + + if (zone == 2) { + //int minParkingTime = get_minimal_parkingtime(&cfg); + QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << timeSteps; + int Down = 0; + int Up = 1; + + QDateTime const start = QDateTime::currentDateTime(); + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + + if (paymentOptionIndex < 0) { + qCritical() << "ERROR paymentOptionIndex" << paymentOptionIndex + << "< 0 for start" << start.toString(Qt::ISODate); + exit(-1); + } + + QSet const prices{600, 1200, 1800, 2400, 3000, 3600, 4200}; + + QDateTime end; + CalcState calcState; + QDateTime s(QDateTime::currentDateTime()); + + s.setTime(QTime(18, 0, 0)); + calcState = compute_duration_for_parking_ticket(&cfg, s, + (double)600, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << end.toString(Qt::ISODate); + qCritical() << calcState.toString(); +#if 0 + + for (int i=0; i "2024-07-30T23:59:00" + //qCritical() << xx.toString(Qt::ISODate); + + //QDateTime s(QDateTime::currentDateTime()); + //s.setTime(QTime(12, 0, 0)); + //QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, 0, s); + //qCritical() << timeSteps; + int Down = 0; + int Up = 1; + + QDateTime const start = QDateTime::currentDateTime(); + int paymentOptionIndex = cfg.getPaymentOptionIndex(PERMIT_TYPE::SHORT_TERM_PARKING_PKW); + + if (paymentOptionIndex != 0) { + qCritical() << "ERROR paymentOptionIndex" << paymentOptionIndex + << "< 0 for start" << start.toString(Qt::ISODate); + exit(-1); + } + + //QSet const prices1{800, 1600, 2400, 3200, 4000, 4800, 5600}; + //QSet const prices2{500, 1600, 2400, 3200, 4000, 4800, 5600}; + + QDateTime end; + CalcState calcState; + + QDateTime s(QDateTime::currentDateTime()); + s.setTime(QTime(12, 0, 0)); + + int minimal_parking_price = get_minimal_parkingprice(&cfg, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW), + paymentOptionIndex, s); + +#if 0 + qCritical() << "minimal parking price" << minimal_parking_price; + + for (int i = 0; i < 8; ++i) { + calcState = compute_duration_for_parking_ticket(&cfg, s, + (double)minimal_parking_price + i*800, + end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW)); + qCritical() << "RUN" << i << end.toString(Qt::ISODate) << calcState.toString(); + } + +#else + s.setTime(QTime(15, 0, 0)); + + minimal_parking_price = get_minimal_parkingprice(&cfg, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW), + paymentOptionIndex, s); + + qCritical() << "minimal parking price" << minimal_parking_price; + + for (int i = 0; i < 8; ++i) { + calcState = compute_duration_for_parking_ticket(&cfg, s, + (double)minimal_parking_price + i*800, + end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW)); + qCritical() << "RUN" << i << end.toString(Qt::ISODate) << calcState.toString(); + } +#endif + } + } +#endif + +#if NEUHAUSER_STOCKERAU==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + input.open("/opt/ptu5/opt/customer_748/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + + CalcState cs; + double const x = 30.0/7.0; + double cost; + int durationInMinutes; + int offsetInMinutes = 0; + + //for (int day = Qt::Monday; day <= Qt::Sunday; ++day) { + for (int day = Qt::Tuesday; day <= Qt::Tuesday; ++day) { + QDateTime s(QDate(2024, 6, 9 + day), QTime()); // 20: (whit) monday,..., 26: sunday + QDateTime end; + + for (int minutes = 660; minutes <= 660; ++minutes) { + //for (int minutes = 0; minutes < 1440; ++minutes) { + QDateTime start = s.addSecs(minutes * 60); + QDateTime effectiveStart = start; + + if (day >= Qt::Monday && day <= Qt::Friday) { + if (start.time() < QTime(8,0,0)) { + effectiveStart.setTime(QTime(8,0,0)); + } else + if (start.time() <= QTime(12,0,0)) { + effectiveStart = start; + } else + if (start.time() < QTime(13,30,0)) { + effectiveStart.setTime(QTime(13,30,0)); + } else + if (start.time() <= QTime(18,0,0)) { + effectiveStart = start; + } else { + effectiveStart = start.addDays(1); + effectiveStart.setTime(QTime(8,0,0)); // saturday + } + } else + if (day == Qt::Saturday) { + if (start.time() < QTime(8,0,0)) { + effectiveStart.setTime(QTime(8,0,0)); + } else + if (start.time() <= QTime(12,0,0)) { + effectiveStart = start; + } else { + effectiveStart = start.addDays(2); + effectiveStart.setTime(QTime(8,0,0)); // monday + } + } else + if (day == Qt::Sunday) { + effectiveStart = start.addDays(1); + effectiveStart.setTime(QTime(8,0,0)); // monday + } + + for (int i = 700; i <= 700; i += 10) { + cost = i; + if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end))) { // return value + durationInMinutes = truncf(x * (i/10)); + offsetInMinutes = 0; + if (day >= Qt::Monday && day <= Qt::Friday) { + if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) { + if (effectiveStart.date().dayOfWeek() == start.date().dayOfWeek()) { + if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) { + offsetInMinutes = 90; // 12:00 - 13:30 + } + } else { + offsetInMinutes = 14 * 60; // 18:00 -> next day, 8:00 + if (effectiveStart.time().addSecs(durationInMinutes * 60) <= QTime(12, 0, 0)) { + offsetInMinutes = 0; + } else { + if (effectiveStart.date().dayOfWeek() == Qt::Saturday) { + offsetInMinutes = (12 + 24 + 8) * 60; + } else { + offsetInMinutes = 90; + } + } + } + } else + if (effectiveStart.time() >= QTime(13, 30, 0)) { + if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(18, 0, 0)) { + offsetInMinutes = 14 * 60; // 18:00 -> next day, 8:00 + } + } + } else + if (day == Qt::Saturday) { + if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) { + if (effectiveStart.date().dayOfWeek() == start.date().dayOfWeek()) { + if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) { + offsetInMinutes = (12 + 24 + 8) * 60; // monday, 8:00 + } + } else { + offsetInMinutes = (12 + 24 + 8) * 60; // monday, 8:00 + if (effectiveStart.time().addSecs(durationInMinutes * 60) <= QTime(12, 0, 0)) { + offsetInMinutes = 0; + } else { + offsetInMinutes = 90; + } + } + } + } else + if (day == Qt::Sunday) { + if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) { + if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) { + offsetInMinutes = 90; + } + } + } + + if ((durationInMinutes + offsetInMinutes) == (effectiveStart.secsTo(end) / 60)) { + qCritical() << "| start ............................" << start.toString(Qt::ISODate); + qCritical() << "| effectiveStart ..................." << effectiveStart.toString(Qt::ISODate); + qCritical() << "| cost ............................." << cost; + qCritical() << "| durationMinutes .................." << durationInMinutes; + qCritical() << "| offsetInMinutes .................." << offsetInMinutes; + qCritical() << "| effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60; + qCritical() << "| end .............................." << end.toString(Qt::ISODate) << endl; + continue; + } + } + + if (!cs) { + qCritical() << "ERROR CalcState" << cs.toString() << endl; + } else { + qCritical() << "SUCCESS"; + } + qCritical() << "start ............................" << cs.toString(); + qCritical() << "start ............................" << start.toString(Qt::ISODate); + qCritical() << "effectiveStart ..................." << effectiveStart.toString(Qt::ISODate); + qCritical() << "cost ............................." << cost; + qCritical() << "durationMinutes .................." << durationInMinutes; + qCritical() << "offsetInMinutes .................." << offsetInMinutes; + qCritical() << "effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60; + qCritical() << "end .............................." << end.toString(Qt::ISODate) << endl; + exit(-1); + } + } + } + } + +#endif + +#if NEUHAUSER_PERNEGG_AN_DER_MUR==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + input.open("/opt/ptu5/opt/customer_747/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + int price; + QDateTime productStart; + QDateTime productEnd; + QDateTime start = QDateTime::currentDateTime(); + start.setTime(QTime(0, 0, 0)); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start); + qCritical() << QString("line=%1 price (%2) :") + .arg(__LINE__) + .arg(start.time().toString(Qt::ISODate)) << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET, 0, start); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) << price; + + start.setTime(QTime(6, 0, 0)); + productStart = productEnd = QDateTime(); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start, &productStart, &productEnd); + qCritical() << QString("line=%1 price (%2-%3) :") + .arg(__LINE__) + .arg(productStart.time().toString(Qt::ISODate)) + .arg(productEnd.time().toString(Qt::ISODate)) + << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET, 0, start); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) + << price; + + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start); + qCritical() << QString("line=%1 price:").arg(__LINE__) << price; + + start.setTime(QTime(15, 0, 0)); + productStart = productEnd = QDateTime(); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start, &productStart, &productEnd); + qCritical() << QString("line=%1 price (%2-%3) :") + .arg(__LINE__) + .arg(productStart.time().toString(Qt::ISODate)) + .arg(productEnd.time().toString(Qt::ISODate)) + << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET, 0, start); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) << price; + + start.setTime(QTime(16, 0, 0)); + productStart = productEnd = QDateTime(); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start, &productStart, &productEnd); + qCritical() << QString("line=%1 price (%2-%3) :") + .arg(__LINE__) + .arg(productStart.time().toString(Qt::ISODate)) + .arg(productEnd.time().toString(Qt::ISODate)) + << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET, 0, start); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) << price; + + start.setTime(QTime(17, 0, 0)); + productStart = productEnd = QDateTime(); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start, &productStart, &productEnd); + qCritical() << QString("line=%1 price (%2-%3) :") + .arg(__LINE__) + .arg(productStart.time().toString(Qt::ISODate)) + .arg(productEnd.time().toString(Qt::ISODate)) + << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET, 0, start); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) << price; + + price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::DAY_TICKET); + qCritical() << QString("line=%1 get_minimal_parkingprice:").arg(__LINE__) << price; + + for (int h = 0; h < 24; ++h) { + start.setTime(QTime(h, 0, 0)); + productStart = productEnd = QDateTime(); + price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET, start, &productStart, &productEnd); + qCritical() << QString("line=%1 %2 price (%3-%4) :") + .arg(__LINE__) + .arg(start.time().toString(Qt::ISODate)) + .arg(productStart.time().toString(Qt::ISODate)) + .arg(productEnd.time().toString(Qt::ISODate)) + << price; + } + } +#endif + +#if NEUHAUSER_CHRISTOPH_REISEN==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + input.open("/opt/ptu5/opt/customer_746/etc/psa_tariff/tariff01.json"); + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + static QList stepsConfigured + = QList(std::initializer_list{ + 360, 420, 1440, 2880, 4320, 5400, 7440}); + + QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + if (stepsConfigured != timeSteps) { + qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + return -1; + } + + stepsConfigured.push_front(360); // for test run + stepsConfigured.push_back(7440); + +#if 0 + static const int Down = 0; + static const int Up = 1; + + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up); + if (nextTimeStep != stepsConfigured.at(i+2)) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") ERROR" + << nextTimeStep << stepsConfigured.at(i+2); + return -1; + } + qCritical() << "curTimeStep" << timeSteps.at(i) << ", nextTimeStep" << nextTimeStep; + int prevTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Down); + if (prevTimeStep != stepsConfigured.at(i)) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") ERROR" + << prevTimeStep << stepsConfigured.at(i); + return -1; + } + qCritical() << "curTimeStep" << timeSteps.at(i) << ", prevTimeStep" << prevTimeStep; + } +#endif + + QDateTime start = QDateTime::currentDateTime(); + start.setTime(QTime(10, 2, 30)); + start.setDate(QDate(2024, 5, 5)); + + // 2024-05-05 10:02:30 + + struct price_t costs; + double const cost[] = {600, 700, 800, 1600, 2400, 3200, 4000}; + double price1 = 0; + double price2 = 0; + + CalcState cs; + + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs); + if (cs.getStatus() != CalcState::State::SUCCESS) { + qCritical() << "ERROR STATUS" << costs.netto; + exit(-1); + } + price1 = costs.netto; + price2 = Calculator::GetInstance().GetCostFromDuration(&cfg, start, timeSteps.at(i)); + + if (price1 != price2) { + qCritical() << "ERROR DIFFERENT PRICES" << price1 << price2; + exit(-1); + } + + qCritical() << "compute_price_for_parking_ticket()/GetCostFromDuration() TIME: " + << timeSteps.at(i) << "(" << timeSteps.at(i)/60 << "h)" << "PRICE=" << price1; + std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 4, + start.toString(Qt::ISODate).toStdString().c_str(), + cost[i], false, true); + QDateTime d(QDateTime::fromString(QString(duration.c_str()), Qt::ISODate)); + + qCritical() << "start" << start.toString(Qt::ISODate) + << "cost[" << i << "]" << cost[i] << "duration" << d.toString(Qt::ISODate) << (start.secsTo(d) + 59) / 60; + } + } + +#endif +#if NEUHAUSER_FORCHACH==1 + std::ifstream input; + input.open("/opt/ptu5/opt/customer_749/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + compute_product_price(&cfg, PermitType(PERMIT_TYPE::DAY_TICKET_PKW)); + compute_product_price(&cfg, PermitType(PERMIT_TYPE::DAY_TICKET_CAMPER)); + + QDateTime start = QDateTime::currentDateTime(); + QDateTime ticketEndTime; + compute_duration_for_daily_ticket(&cfg, start, ticketEndTime, PermitType(PERMIT_TYPE::DAY_TICKET)); + } + +#endif +#if BAD_NEUENAHR_AHRWEILER==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + int pop_carry_over; + int pop_carry_over_time_range_id; + + for (int zone=2; zone < 3; ++zone) { + //for (int t=6; t < 7; t+=20) { + switch (zone) { + case 1: { + // standard-tarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff01.json"); + //pop_max_time = 6*60; + } break; + case 2: { + qCritical() << " ZONE 2: KURZZEIT 1"; + // kuzzeit-1-tarif + //input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json"); + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json"); + //pop_max_time = 5*60; + } break; + case 3: { + // kuzzeit-2-tarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff03.json"); + //pop_max_time = 6*60; + } break; + case 4: { + // kuzzeit-3-tarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff04.json"); + //pop_max_time = 4*60; + } break; + case 5: { + // langzeit-tarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json"); + //pop_max_time = 6*60; + } break; + case 6: { + // sondertarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff06.json"); + //pop_max_time = 4*60; + } break; + case 7: { + // wochenend-tarif + input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff07.json"); + //pop_max_time = 4*60; + } break; + default: + continue; + } + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + + // test library functions + + if (zone == 1) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + static QList const stepsConfigured + = QList(std::initializer_list{ + 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 1440}); + + //static QList const cost + // = QList(std::initializer_list{ + // 0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 500}); + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + //if (stepsConfigured != timeSteps) { + // qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + // return -1; + //} + + QDateTime start = QDateTime::currentDateTime(); + + struct price_t costs; + double price1 = 0; + double price2 = 0; + + //for (int m=0; m < 1440; ++m) { + for (int m=480; m < 481; ++m) { + start.setTime(QTime(0, 0, 0)); + start = start.addSecs(m*60); + + qCritical() << "START" << start.toString(Qt::ISODate); + + //int Down = 0; + //int Up = 1; + // for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + // int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up); + // qCritical() << "nextTimeStep" << nextTimeStep; + // + // int prevTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Down); + // qCritical() << "prevTimeStep" << prevTimeStep; + //} + + CalcState cs; +#if 1 + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + if (cs.getStatus() != CalcState::State::SUCCESS) { + if (start.time().hour() >= 8 && start.time().hour() < 18) { + qCritical() << "ERROR CALC-STATE-1=" << QString(cs); + exit(-1); + } else { + if (cs.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "CALC-STATE=" << QString(cs); + continue; + } + qCritical() << "ERROR CALC-STATE-2=" << QString(cs); + exit(-1); + } + } + price1 = costs.netto; + price2 = Calculator::GetInstance().GetCostFromDuration(&cfg, start, timeSteps.at(i)); + + if (price1 != price2) { + qCritical() << "ERROR DIFFERENT PRICES" << price1 << price2; + exit(-1); + } + + qCritical() << "compute_price_for_parking_ticket()/GetCostFromDuration() TIME: " + << timeSteps.at(i) << "PRICE=" << price1 << "end=" << end.toString(Qt::ISODate); + //std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 4, + // start.toString(Qt::ISODate).toStdString().c_str(), + // cost[i], false, true); + //qCritical() << "duration" << duration.c_str(); + } +#else - parking_tariff_t *tariff = 0; - if (init_tariff(&tariff, "/etc/psa_tariff/")) { + double cost = 80; + qCritical() << "START" << start.toString(Qt::ISODate) << "cost" << cost; + QDateTime end; + + cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << __LINE__ << cs.toString() + << "START" << start.toString(Qt::ISODate) + << " end" << end.toString(Qt::ISODate); + //} +#endif + } + } // zone == 1 + if (zone == 2) { + int const numOptions = cfg.getAllPaymentOptions().size(); + +#if 0 + for (int payOpt=0; payOpt < numOptions; ++payOpt) { + pop_min_time = get_minimal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING, payOpt); + pop_max_time = get_maximal_parkingtime(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING, payOpt); + pop_min_price = get_minimal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING, payOpt); + pop_max_price = get_maximal_parkingprice(&cfg, PERMIT_TYPE::SHORT_TERM_PARKING, payOpt); + pop_daily_card_price = cfg.getPaymentOptions(payOpt).pop_daily_card_price; + + pop_carry_over = cfg.getPaymentOptions(payOpt).pop_carry_over; + pop_carry_over_time_range_id = cfg.getPaymentOptions(payOpt).pop_carry_over_time_range_id; + + qCritical() << QString(" pop_min_time[%1]: %2").arg(payOpt).arg(pop_min_time); + qCritical() << QString(" pop_max_time[%1]: %2").arg(payOpt).arg(pop_max_time); + qCritical() << QString(" pop_min_price[%1]: %2").arg(payOpt).arg(pop_min_price); + qCritical() << QString(" pop_max_price[%1]: %2").arg(payOpt).arg(pop_max_price); + qCritical() << QString(" pop_daily_card_price[%1]: %2").arg(payOpt).arg(pop_daily_card_price); + qCritical() << QString(" pop_carry_over[%1]: %2").arg(payOpt).arg(pop_carry_over); + qCritical() << QString("pop_carry_over_time_range_id[%1]: %2").arg(payOpt).arg(pop_carry_over_time_range_id); + + if (pop_carry_over_time_range_id != -1) { + QTime const carryOverTimeRangeFrom = cfg.TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from; + QTime const carryOverTimeRangeTo = cfg.TimeRange.find(pop_carry_over_time_range_id)->second.time_range_to; + qCritical() << QString(" timeRangeFrom[%1]: %2").arg(payOpt).arg(carryOverTimeRangeFrom.toString(Qt::ISODate)); + qCritical() << QString(" timeRangeTo[%1]: %2").arg(payOpt).arg(carryOverTimeRangeTo.toString(Qt::ISODate)); + + } + + } +#endif + bool fail; + QDateTime start; + + for (int i=1; i < 2; ++i) { + switch (i) { + case 0: + start = QDateTime(QDate(2024, 5, 1), QTime(16, 0, 0)); // holiday + fail = false; + break; + case 1: + //start = QDateTime(QDate(2024, 10, 3), QTime(17, 0, 0)); // sunday + //start = QDateTime(QDate(2025, 4, 20), QTime(18, 0, 0)); // sunday + start = QDateTime(QDate(2024, 9, 27), QTime(17, 0, 0)); // friday + fail = false; + break; + case 2: + start = QDateTime(QDate(2024, 4, 22), QTime(17, 30, 0)); // monday + fail = false; + break; + case 3: + start = QDateTime(QDate(2024, 4, 22), QTime(17, 30, 0)); // monday + fail = true; + break; + default:; + } + + QDateTime end; + struct price_t price; + + //start = QDateTime::currentDateTime(); + QList timeSteps; + + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + if (paymentOptionIndex != -1) { + qCritical() << "paymentOptionIndex" << paymentOptionIndex; + timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, paymentOptionIndex); + qCritical() << "TimeSteps" << timeSteps; + + QList::const_iterator step; + for (step = timeSteps.cbegin(); step != timeSteps.cend(); ++step) { + //qCritical() << __LINE__ + // << "START" << start.toString(Qt::ISODate) + // << " end" << end.toString(Qt::ISODate); + } else { + if (fail == false) { + qCritical() << "<<>> cs =" << QString(cs); + } + } +#else + cost = 200; + qCritical() << "START" << start.toString(Qt::ISODate) << "cost" << cost; + + cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << __LINE__ << cs.toString() + << "START" << start.toString(Qt::ISODate) + << " end" << end.toString(Qt::ISODate); + break; + //} +#endif + + } + } else { + qCritical() << "ERROR paymentOptionIndex =" << paymentOptionIndex; + } + } + } + if (zone == 3) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + static QList const stepsConfigured + = QList(std::initializer_list{20, 40, 60, 80, 100, 120}); + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + if (stepsConfigured != timeSteps) { + qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + return -1; + } + + bool fail; + QDateTime start; + + for (int i=0; i < 5; ++i) { + switch (i) { + case 0: + start = QDateTime(QDate(2024, 5, 1), QTime(16, 0, 0)); // holiday + fail = false; + break; + case 1: + start = QDateTime(QDate(2024, 4, 21), QTime(16, 0, 0)); // sunday + fail = false; + break; + case 2: + start = QDateTime(QDate(2024, 4, 22), QTime(8, 0, 0)); // monday + fail = false; + break; + case 3: + start = QDateTime(QDate(2024, 4, 23), QTime(17, 30, 0)); // tuesday + fail = true; + break; + case 4: + start = QDateTime(QDate(2024, 4, 24), QTime(7, 30, 0)); // wednesday + fail = true; + break; + default:; + } + + QDateTime end; + struct price_t price; + + //start = QDateTime::currentDateTime(); + QList timeSteps; + + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + if (paymentOptionIndex != -1) { + qCritical() << "paymentOptionIndex" << paymentOptionIndex; + timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, paymentOptionIndex); + qCritical() << "TimeSteps" << timeSteps; + + QList::const_iterator step; + for (step = timeSteps.cbegin(); step != timeSteps.cend(); ++step) { + + double cost = 0; + CalcState cs; + + if ((cs = compute_price_for_parking_ticket(&cfg, start, *step, end, &price, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { + cost = price.netto; + qCritical() << "step" << *step << ": cost" << cost; + } else { + if (fail == false) { + qCritical() << "<<>> cs =" << QString(cs); + } + } + } + } else { + qCritical() << "ERROR paymentOptionIndex =" << paymentOptionIndex; + } + } + + } + if (zone == 4) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + static QList const stepsConfigured + = QList(std::initializer_list{20, 40, 60, 80, 100, 120}); + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + if (stepsConfigured != timeSteps) { + qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + return -1; + } + + bool fail; + QDateTime start; + + for (int i=4; i < 5; ++i) { + switch (i) { + case 0: + start = QDateTime(QDate(2024, 5, 1), QTime(16, 0, 0)); // holiday + fail = false; + break; + case 1: + start = QDateTime(QDate(2024, 4, 21), QTime(16, 0, 0)); // sunday + fail = false; + break; + case 2: + start = QDateTime(QDate(2024, 4, 22), QTime(8, 0, 0)); // monday + fail = false; + break; + case 3: + start = QDateTime(QDate(2024, 4, 23), QTime(17, 30, 0)); // tuesday + fail = true; + break; + case 4: + start = QDateTime(QDate(2024, 4, 24), QTime(7, 30, 0)); // wednesday + fail = true; + break; + default:; + } + + QDateTime end; + struct price_t price; + + //start = QDateTime::currentDateTime(); + QList timeSteps; + + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + if (paymentOptionIndex != -1) { + qCritical() << "paymentOptionIndex" << paymentOptionIndex; + timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg, paymentOptionIndex); + qCritical() << "TimeSteps" << timeSteps; + + QList::const_iterator step; + for (step = timeSteps.cbegin(); step != timeSteps.cend(); ++step) { + + double cost = 0; + CalcState cs; + + if ((cs = compute_price_for_parking_ticket(&cfg, start, *step, end, &price, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { + cost = price.netto; + qCritical() << "step" << *step << ": cost" << cost; + } else { + if (fail == false) { + qCritical() << "<<>> cs =" << QString(cs); + } + } + } + } else { + qCritical() << "ERROR paymentOptionIndex =" << paymentOptionIndex; + } + } + } + if (zone == 5) { // langzeit-tarif + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << zone << " pop_min_time: " << pop_min_time; + qCritical() << zone << " pop_max_time: " << pop_max_time; + qCritical() << zone << " pop_min_price: " << pop_min_price; + qCritical() << zone << " pop_max_price: " << pop_max_price; + qCritical() << zone << "pop_daily_card_price: " << pop_daily_card_price; + + static QList const stepsConfigured + = QList(std::initializer_list{ + 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 1440, 4320, 10080 + }); + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "( TimeSteps :" << __LINE__ << ")" << timeSteps; + + if (stepsConfigured != timeSteps) { + qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + return -1; + } + + bool fail; + QDateTime start = QDateTime::currentDateTime(); + + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + if (paymentOptionIndex != -1) { + QDateTime end; + struct price_t price; + + qCritical() << "paymentOptionIndex" << paymentOptionIndex; + + QList::const_iterator step; + int i = 0; + for (step = timeSteps.cbegin(); step != timeSteps.cend(); ++step) { + if (++i < 16) continue; + + double cost = 0; + CalcState cs; + + if ((cs = compute_price_for_parking_ticket(&cfg, start, *step, end, &price, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)))) { + cost = price.netto; + qCritical() << "step" << *step << ": cost" << cost; + } else { + if (fail == false) { + qCritical() << "<<>> cs =" << QString(cs); + } + } + exit(0); + } + } else { + qCritical() << "ERROR paymentOptionIndex =" << paymentOptionIndex; + } + + } + if (zone == 6) { // sondertarif: 24h ticket wohnmobile + // 8 euro; hoechstparkdauer 24h + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << zone << " pop_min_time: " << pop_min_time; + qCritical() << zone << " pop_max_time: " << pop_max_time; + qCritical() << zone << " pop_min_price: " << pop_min_price; + qCritical() << zone << " pop_max_price: " << pop_max_price; + qCritical() << zone << "pop_daily_card_price: " << pop_daily_card_price; + + QDateTime start = QDateTime::currentDateTime(); + start.setTime(QTime(0, 0, 0)); + + for (int i=0; i<1440; ++i) { + + QDateTime productStart; + QDateTime productEnd; + + int v = compute_product_price(&cfg, PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET, start, &productStart, &productEnd); + if (v != 800) { + qCritical() << "ERROR [" << i << "]" << "price 24h-ticket" + << v << productStart.toString(Qt::ISODate) + << productEnd.toString(Qt::ISODate); + exit(-1); + } else { + + int const secs = productStart.secsTo(productEnd); + if (secs != 86400) { + qCritical() << "ERROR" << i << secs << v + << productStart.toString(Qt::ISODate) + << productEnd.toString(Qt::ISODate); + exit(-1); + } else { + qCritical() << i << secs << v + << productStart.toString(Qt::ISODate) + << productEnd.toString(Qt::ISODate); + } + + } + start = start.addSecs(60); + } + } + if (zone == 7) { + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << zone << " pop_min_time: " << pop_min_time; + qCritical() << zone << " pop_max_time: " << pop_max_time; + qCritical() << zone << " pop_min_price: " << pop_min_price; + qCritical() << zone << " pop_max_price: " << pop_max_price; + qCritical() << zone << "pop_daily_card_price: " << pop_daily_card_price; + + static QList const stepsConfigured + = QList(std::initializer_list{ + 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 1440}); + + //static QList const cost + // = QList(std::initializer_list{ + // 0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 500}); + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "( TimeSteps :" << __LINE__ << ")" << timeSteps; + + if (stepsConfigured != timeSteps) { + qCritical() << "TIME-STEPS SHOULD BE" << stepsConfigured; + return -1; + } + + QDateTime start = QDateTime::currentDateTime(); + + // testing + start.setDate(QDate(2024, 5, 5)); + start.setTime(QTime(16, 0, 0)); + + struct price_t costs; + double price1 = 0; + double price2 = 0; + + CalcState cs; + for (int i = 13, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << endl; + } + + exit(0); + + for (int m=0; m < 1440; ++m) { + start.setTime(QTime(0, 0, 0)); + start = start.addSecs(m*60); + + qCritical() << "START" << start.toString(Qt::ISODate); + + //int Down = 0; + //int Up = 1; + // for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + // int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up); + // qCritical() << "nextTimeStep" << nextTimeStep; + // + // int prevTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Down); + // qCritical() << "prevTimeStep" << prevTimeStep; + //} + + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + if (cs.getStatus() != CalcState::State::SUCCESS) { + if (start.time().hour() >= 8 && start.time().hour() < 18) { + qCritical() << "ERROR CALC-STATE-1=" << QString(cs); + exit(-1); + } else { + if (cs.getStatus() == CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME) { + qCritical() << "CALC-STATE=" << QString(cs); + continue; + } + qCritical() << "ERROR CALC-STATE-2=" << QString(cs); + exit(-1); + } + } + price1 = costs.netto; + price2 = Calculator::GetInstance().GetCostFromDuration(&cfg, start, timeSteps.at(i)); + + if (price1 != price2) { + qCritical() << "ERROR DIFFERENT PRICES" << price1 << price2; + exit(-1); + } + + qCritical() << "compute_price_for_parking_ticket()/GetCostFromDuration() TIME: " + << timeSteps.at(i) << "PRICE=" << price1; + + + //std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 4, + // start.toString(Qt::ISODate).toStdString().c_str(), + // cost[i], false, true); + //qCritical() << "duration" << duration.c_str(); + } + } + } + } + } +#endif + +#if SCHOENAU_KOENIGSEE==1 + for (int zone=1; zone < 3; ++zone) { + std::ifstream input; + + if (zone == 1) { + input.open("/opt/ptu5/opt/customer_332/etc/psa_tariff/tariff01.json"); + } + if (zone == 2) { + input.open("/opt/ptu5/opt/customer_332/etc/psa_tariff/tariff02.json"); + } + + qCritical() << "--------------------"; + qCritical() << " ZONE" << zone; + qCritical() << "--------------------"; + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + // qCritical() << "parsed zone" << zone << "file"; + + int minParkingTime = get_minimal_parkingtime(&cfg); + qCritical() << "minimal_parking_time" << minParkingTime; + + QDateTime start = QDateTime::currentDateTime(); + + // zone 1 + //int timeSteps[] = {60, 180, 1440, 2880, 4320, 5670, 7200, 8640, 10080, 11520, 12960, 14400}; + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + for (int i = 0 ; i < timeSteps.size(); ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + double price = Calculator::GetInstance().GetCostFromDuration( + &cfg, + start, + timeSteps.at(i)); + qCritical() << "zone" << zone + << "GetCostFromDuration() time: " << timeSteps.at(i) + << "(" << timeSteps.at(i)/60 << "h)" + << "price=" << price; + + switch(timeSteps.at(i)) { + case 60: + if (zone == 1) { + if (price == 300.0) { + continue; + } + } + if (zone == 2) { + if (price == 300.0) { + continue; + } + } + if (zone == 3) { + if (price == 200.0) { + continue; + } + } + break; + case 180: + if (zone == 1) { + if (price == 700.0) { + continue; + } + } + if (zone == 2) { + if (price == 500.0) { + continue; + } + } + if (zone == 3) { + if (price == 400.0) { + continue; + } + } + break; + case 1440: + if (zone == 1) { + if (price == 900.0) { + continue; + } + } + if (zone == 2) { + if (price == 600.0) { + continue; + } + } + if (zone == 3) { + if (price == 500.0) { + continue; + } + } + break; + case 2880: + if (zone == 1) { + if (price == 1800.0) { + continue; + } + } + if (zone == 2) { + if (price == 1200.0) { + continue; + } + } + break; + case 4320: + if (zone == 1) { + if (price == 2700.0) { + continue; + } + } + if (zone == 2) { + if (price == 1800.0) { + continue; + } + } + break; + case 5760: + if (zone == 1) { + if (price == 3600.0) { + continue; + } + } + if (zone == 2) { + if (price == 2400.0) { + continue; + } + } + break; + case 7200: + if (zone == 1) { + if (price == 4500.0) { + continue; + } + } + if (zone == 2) { + if (price == 3000.0) { + continue; + } + } + break; + case 8640: + if (zone == 1) { + if (price == 5400.0) { + continue; + } + } + if (zone == 2) { + if (price == 3600.0) { + continue; + } + } + break; + case 10080: + if (zone == 1) { + if (price == 6300.0) { + continue; + } + } + if (zone == 2) { + if (price == 4200.0) { + continue; + } + } + break; + case 11520: + if (zone == 1) { + if (price == 7200.0) { + continue; + } + } + if (zone == 2) { + if (price == 4800.0) { + continue; + } + } + break; + case 12960: + if (zone == 1) { + if (price == 8100.0) { + continue; + } + } + if (zone == 2) { + if (price == 5400.0) { + continue; + } + } + break; + case 14400: + if (zone == 1) { + if (price == 9000.0) { + continue; + } + } + if (zone == 2) { + if (price == 6000.0) { + continue; + } + } + break; + default: + qCritical() << "ERROR zone" << zone + << "GetCostFromDuration() time: " << timeSteps.at(i) + << "(" << timeSteps.at(i)/60 << "h)" + << "price=" << price; + exit(-1); + } + + } + } + } +#endif + + +#if NEUHAUSER_KIRCHDORF==1 + //if (QDir("/opt/app/tools/atbupdate/customer_743").exists()) { + // if(QFileInfo::exists("/etc/psa_tariff/tariff01.json")) { + if (true) { + if(true) { + // const char *f = "/etc/psa_tariff/tariff01.json"; + const char *f = "/opt/ptu5/opt/customer_743/etc/psa_tariff/tariff01.json"; + std::ifstream input(f); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + + if (!isParsed) { + qCritical() << "ERROR: CANNOT PARSE" << f; + return -1; + } + qCritical() << "Successfully parsed" << f; + + int const minParkingTime = get_minimal_parkingtime(&cfg); + int const maxParkingTime = get_maximal_parkingtime(&cfg); + int const minParkingPrice = get_minimal_parkingprice(&cfg); + + if (minParkingTime != 30) { + qCritical() << "ERROR: WRONG MIN_PARKING_TIME" << minParkingTime; + return -1; + } + qCritical() << "min_parking_time " << minParkingTime; + + if (maxParkingTime != 90) { + qCritical() << "ERROR: WRONG MAX_PARKING_TIME" << maxParkingTime; + return -1; + } + qCritical() << "max_parking_time " << maxParkingTime; + + + if (minParkingPrice != 30) { + qCritical() << "ERROR: WRONG MIN_PARKING_PRICE" << minParkingPrice; + return -1; + } + qCritical() << "min_parking_price" << minParkingPrice; + + QList const stepsConfigured + = QList(std::initializer_list{ + 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90}); + + QList const steps = Calculator::GetInstance().GetTimeSteps(&cfg); + + if (stepsConfigured != steps) { + qCritical() << "ERROR: WRONG TIME-STEP-LIST" << steps; + qCritical() << "SHOULD BE" << stepsConfigured; + return -1; + } + qCritical() << "time steps" << steps; + + QDateTime s(QDate(2024, 2, 21), QTime()); + QDateTime end; + struct price_t price; + + QList::const_iterator step; + for (step = steps.cbegin(); step != steps.cend(); ++step) { + qCritical() << QString("*** NEXT STEP: %1 ***").arg(*step); + //for (int offset = 691; offset < 692; ++offset) { + for (int offset = 480; offset < 1080; ++offset) { + //for (int offset = 7*60; offset < (18*60)-90; ++offset) { + //for (int offset = (18*60)-90; offset < 18*60; ++offset) { + //for (int offset = 1046; offset < 1047; ++offset) { + QDateTime start = s.addSecs(offset * 60); + QDateTime const firstStart = start; + + //if (*step != 30) continue; + + double cost = 0; + + if (compute_price_for_parking_ticket(&cfg, start, *step, end, &price)) { + cost = price.netto; + + qCritical() << "****" << offset << *step << "****"; + qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate); + qCritical() << " start :" << start.toString(Qt::ISODate); + qCritical() << " end :" << end.toString(Qt::ISODate); + qCritical() << " cost :" << cost; + + if (offset < 8*60) { // [7:00 - 8:00[ + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 9*60) { // [8:00 - 9:00[ + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 10*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 11*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 12*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 13*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 14*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 15*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 16*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + new_cost += ((*step-30)/5)*10; + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 17*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + double const f = ((*step-30)/5)*10; + new_cost += f; + new_cost = std::min(new_cost, f+30); + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + //return -1; + } + } else + if (offset < 18*60) { + double new_cost = cost; + if (offset > (18*60)-(*step)) { + double const f = ((*step-30)/5)*10; + new_cost += f; + new_cost = std::min(new_cost, f+30); + qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; + } + if (!test_neuhauser_kirchdorf(*step, new_cost)) { + qCritical() << "ERROR AT OFFSET" << offset; + // return -1; + } + } else { + qCritical() << "ERROR OFFSET TOO HIGH" << offset; + return -1; + } + + } else { + qCritical() << "ERROR COMPUTING PRICE FOR" + << "start" << start.toString(Qt::ISODate) + << "step" << *step + << "end" << end.toString(Qt::ISODate); + return -1; + } + + QDateTime end2 = QDateTime(); + if (compute_duration_for_parking_ticket(&cfg, start, cost, end2)) { // return value + qCritical() << "start" << start.toString(Qt::ISODate) + << "offset" << offset + << "cost" << cost + << "end" << end2.toString(Qt::ISODate); + if (end != end2) { + qCritical() << end.toString(Qt::ISODate) + << end2.toString(Qt::ISODate); + } + } + } + } + } + return 0; + } + +#if 0 + const char *f = "/opt/ptu5/opt/customer_743/etc/psa_tariff/tariff01.json"; + std::ifstream input(f); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + if (isParsed) { + qCritical() << "Parsed" << f; + + int minParkingTime = get_minimal_parkingtime(&cfg); + int maxParkingTime = get_maximal_parkingtime(&cfg); + int minParkingPrice = get_minimal_parkingprice(&cfg); + + qCritical() << "min_parking_time " << minParkingTime; + qCritical() << "max_parking_time " << maxParkingTime; + qCritical() << "min_parking_price" << minParkingPrice; + + bool nextDay = false; + bool prePaid = true; + // bool carryOver = false; + + //QDateTime s = QDateTime::currentDateTime(); + QDateTime s(QDate(2024, 2, 21), QTime()); + QDateTime end; + for (int duration = 30; duration <= 90; duration += 5) { + // for (int duration = 30; duration <= maxParkingTime; duration += 5) { + qCritical() << ""; + for (int offset = 420; offset <= 1080; ++offset) { + //for (int offset = 0; offset <= 0; ++offset) { + //for (int offset = 420; offset <= 1080; ++offset) { + //if (offset > 720 && offset < 840) { + // continue; + //} + QDateTime start = s.addSecs(offset * 60); + QDateTime const firstStart = start; + // qCritical() << "start" << start.toString(Qt::ISODate); + + // double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 1, start, end, duration, nextDay, prePaid); + + struct price_t price; + compute_price_for_parking_ticket(&cfg, start, duration, end, &price); + + double cost = price.netto; + +//#if COST_FROM_DURATION==0 + double cost_soll = 30 + ((duration-30)/5 * 10); + uint32_t duration_ist = start.secsTo(end) / 60; + + if (duration_ist >= 120) { + duration_ist = duration_ist - 120; + } + + qCritical() << "****" << offset << duration << "****"; + qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate); + qCritical() << " start :" << start.toString(Qt::ISODate); + qCritical() << " end :" << end.toString(Qt::ISODate); + //qCritical() << "duration (soll):" << duration; + //qCritical() << "duration (ist) :" << duration_ist; + //qCritical() << " cost (soll):" << cost_soll; + //qCritical() << " cost (ist) :" << cost; + + // if (cost_soll != cost) { + //qCritical() << "ERROR" << __func__ << ":" << __LINE__ + // << "cost_soll" << cost_soll << "cost_ist" << cost; + //break; + // } + // if (duration != duration_ist) { + //qCritical() << "ERROR" << __func__ << ":" << __LINE__ + // << "duration_soll" << duration << "duration_ist" << duration_ist; + //break; + // } + +//#else + //start = s.addSecs(offset * 60); + //std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 1, + // start.toString(Qt::ISODate).toStdString().c_str(), + // cost, false, true); + + + //if (end.toString(Qt::ISODate) != QString(duration.c_str())) { + //qCritical() << "ERROR" << end.toString(Qt::ISODate) + // << QString(duration.c_str()); + //break; + + //} + + //qCritical() << "start" << start.toString(Qt::ISODate) + // << "cost" << cost + // << "until" << duration.c_str() + // << "end" << end.toString(Qt::ISODate) + // << ":" << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60 + // << (end.toString(Qt::ISODate) == QString(duration.c_str())); + +//#endif // COST_FROM_DURATION + + } + } +#endif // 0 +#endif + +#if NEUHAUSER_BILEXA_GALTUER==1 + std::ifstream input("/opt/ptu5/opt/customer_745/etc/psa_tariff/tariff01.json"); + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + //int minParkingTime = get_minimal_parkingtime(&cfg); + QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << timeSteps; + int Down = 0; + int Up = 1; + //compute_next_timestep(&cfg, ) + + QDateTime const start = QDateTime::currentDateTime(); + int paymentOptionIndex = cfg.getPaymentOptionIndex(start); + + if (paymentOptionIndex < 0) { + qCritical() << "ERROR paymentOptionIndex" << paymentOptionIndex + << "< 0 for start" << start.toString(Qt::ISODate); + exit(-1); + } + + QSet const prices{700, 1400, 2100, 2800, 3500, 4200, 4900}; + + for (int i=0; i> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + + int v = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_ADULT); + qCritical() << "price adult" << v; + + int w = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_TEEN); + qCritical() << "price teen" << w; + + + QDateTime s(QDate(2023, 11, 30), QTime()); + QDateTime end; struct price_t price; - memset(&price, 0x00, sizeof(price)); - QDateTime start = QDateTime::fromString("2023-05-11T07:50:00",Qt::ISODate); //QDateTime::currentDateTime(); - time_t start_parking_time = start.toSecsSinceEpoch() / 60; - time_t end_parking_time = start_parking_time + 615; - if (compute_price_for_parking_ticket(tariff, - start_parking_time, - end_parking_time, - &price)) - { - qDebug() << "GetCostFromDuration() => price=" << price.netto; + for (int offset = 480; offset < 1200; ++offset) { + QDateTime start = s.addSecs(offset * 60); + CalcState cs = compute_price_for_daily_ticket(&cfg, start, end, + PERMIT_TYPE::DAY_TICKET_ADULT, + &price); + if (price.netto != 800) { + qCritical() << "ERROR(ADULT) start=" << start.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) << "price (ADULT)" << price.netto; + exit(-1); + } + qCritical() << "start=" << start.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) << "price (ADULT)" << price.netto; } - QString duration; - if(compute_duration_for_parking_ticket(tariff,start_parking_time,3090,duration)) - { - qDebug() << "GetDurationFromCost() => duration=" << duration; + for (int offset = 480; offset < 1200; ++offset) { + QDateTime start = s.addSecs(offset * 60); + CalcState cs = compute_price_for_daily_ticket(&cfg, start, end, + PERMIT_TYPE::DAY_TICKET_TEEN, + &price); + if (price.netto != 400) { + qCritical() << "ERROR(TEEN) start=" << start.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) << "price (TEEN)" << price.netto; + exit(-1); + } + qCritical() << "start=" << start.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) << "price (TEEN)" << price.netto; } + } +#undef ADULT +#undef TEEN +#endif - // Daily ticket - //compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3); +#if NEUHAUSER_LINSINGER_MASCHINENBAU==1 + std::ifstream input("/opt/ptu5/opt/customer_741/etc/psa_tariff/tariff01.json"); - //Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over - // // tests - // struct tm now; - // memset(&now, 0, sizeof(now)); + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); - // // 3.Jan 2023 -> Tuesday - // strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now); - // for (int i = 0; i < 600; ++i) { - // start_parking_time = mktime(&now); - // end_parking_time = start_parking_time + 240; // duration == 240 + Configuration cfg; - // if (compute_price_for_parking_ticket(tariff, - // start_parking_time, - // end_parking_time, - // &price)) { - // int const zone = get_zone_nr(1); - // switch (zone) { - // case 1: - // assert(price.netto == 879); // expected value: 880 - // break; - // case 2: - // /* fall through */ - // case 3: - // assert(price.netto == 1920); - // break; - // } - // } - // time_t t = start_parking_time + 60; - // now = *localtime(&t); - // } - // // - // // test May 1st 2023 - // // - // memset(&now, 0, sizeof(now)); - // strptime("2023-04-30T06:00:00", "%Y-%m-%dT%H:%M:%S", &now); - // now.tm_hour -= 1; // for ctime - // // for (int i=0; i<6*24; ++i) { - // for (int i=0; i<1; ++i) { - // int const duration = 120; - // time_t t = mktime(&now); - // start_parking_time = t / 60; - // end_parking_time = start_parking_time + duration; + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; - // if (compute_price_for_parking_ticket(tariff, - // start_parking_time, - // end_parking_time, - // &price)) { - // int const zone = get_zone_nr(); - // switch (zone) { - // case 1: - // qDebug() << i << zone << ctime(&t) << price.netto << " FT"; - // assert(price.netto == 440); - // break; - // case 2: - // /* fall through */ - // case 3: - // qDebug() << i << zone << ctime(&t) << price.netto << " FT"; - // assert(price.netto == 960); - // break; - // } - // } + if (isParsed) { + int const price = compute_product_price(&cfg, PERMIT_TYPE::FOOD_STAMP); + if (price != 300) { + qCritical() << "ERROR price food stamp" << price; + exit(-1); - // t = (start_parking_time + 60)*60; - // now = *localtime(&t); - // } + } + qCritical() << "price food stamp" << price; + } +#endif - free_tariff(tariff); +#if NEUHAUSER_KORNEUBURG==1 + std::ifstream input("/opt/ptu5/opt/customer_714/etc/psa_tariff/tariff01.json"); + int pop_max_time; + + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + { + pop_max_time = 3*60; + bool nextDay = false; + bool prePaid = true; + // zone 1 (lila) + QDateTime s(QDate(2024, 10, 8), QTime()); + QDateTime end; + + static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); + qCritical() << "TimeSteps" << timeSteps; + + for (int duration = 30; duration <= pop_max_time; duration += 5) { + int offset = 600; + //for (int offset = 720; offset < 601; ++offset) { + //if (offset > 720 && offset < 840) { + // continue; + //} + QDateTime start = s.addSecs(offset * 60); + //qCritical() << "start" << start.toString(Qt::ISODate); + + CalcState cs; +#if 1 + struct price_t costs; + for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) { + QDateTime end = start.addSecs(timeSteps.at(i)*60); + + // if (i != 2) continue; + + cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + int price1 = costs.netto; + + qCritical() << "compute_price_for_parking_ticket()/GetCostFromDuration() TIME: " + << timeSteps.at(i) << "ZZZZZZZZZZZZZ PRICE=" << price1 << "end=" << end.toString(Qt::ISODate); + } + exit(0); +#else + + double cost = 360; + qCritical() << "XXXXXXXX START" << start.toString(Qt::ISODate) << "cost" << cost; + QDateTime end; + + cs = compute_duration_for_parking_ticket(&cfg, start, cost, end, + PermitType(PERMIT_TYPE::SHORT_TERM_PARKING)); + qCritical() << __LINE__ << cs.toString() + << "START" << start.toString(Qt::ISODate) + << " end" << end.toString(Qt::ISODate); + //} + + exit(0); +#endif + + //double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid); + //Q_ASSERT(cost == duration*2.5); + //qCritical() << ""; + //qCritical() << "start" << start.toString(Qt::ISODate) + // << "end" << end.toString(Qt::ISODate) + // << "duration" << duration + // << "cost" << cost; +#if 0 + switch(duration) { + case 30: + if (cost == 60.0) { + continue; + } + break; + case 35: + if (cost == 70.0) { + continue; + } + break; + case 40: + if (cost == 80.0) { + continue; + } + break; + case 45: + if (cost == 90.0) { + continue; + } + break; + case 50: + if (cost == 100.0) { + continue; + } + break; + case 55: + if (cost == 110.0) { + continue; + } + break; + case 60: + if (cost == 120.0) { + continue; + } + break; + case 65: + if (cost == 130.0) { + continue; + } + break; + case 70: + if (cost == 140.0) { + continue; + } + break; + case 75: + if (cost == 150.0) { + continue; + } + break; + case 80: + if (cost == 160.0) { + continue; + } + break; + case 85: + if (cost == 170.0) { + continue; + } + break; + case 90: + if (cost == 180.0) { + continue; + } + break; + case 95: + if (cost == 190.0) { + continue; + } + break; + case 100: + if (cost == 200.0) { + continue; + } + break; + case 105: + if (cost == 210.0) { + continue; + } + break; + case 110: + if (cost == 220.0) { + continue; + } + break; + case 115: + if (cost == 230.0) { + continue; + } + break; + case 120: + if (cost == 240.0) { + continue; + } + break; + case 125: + if (cost == 250.0) { + continue; + } + break; + case 130: + if (cost == 260.0) { + continue; + } + break; + case 135: + if (cost == 270.0) { + continue; + } + break; + case 140: + if (cost == 280.0) { + continue; + } + break; + case 145: + if (cost == 290.0) { + continue; + } + break; + case 150: + if (cost == 300.0) { + continue; + } + break; + case 155: + if (cost == 310.0) { + continue; + } + break; + case 160: + if (cost == 320.0) { + continue; + } + break; + case 165: + if (cost == 330.0) { + continue; + } + break; + case 170: + if (cost == 340.0) { + continue; + } + break; + case 175: + if (cost == 350.0) { + continue; + } + break; + case 180: + if (cost == 360.0) { + continue; + } + break; + default: + qCritical() << "ERROR(1) start" << start.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) + << "duration" << duration + << "cost" << cost; + exit(-1); + } +#endif + + //std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost); + //Q_ASSERT(cost == duration*2.5); + //qCritical() << "start" << start.toString(Qt::ISODate) + // << "cost" << cost + // << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60; + //} + } + +#if 0 + Configuration::SpecialDaysType specialDays = cfg.SpecialDays; + for (Configuration::SpecialDaysType::const_iterator it = specialDays.cbegin(); + it != specialDays.cend(); ++it) { + QDate d = QDate::fromString(QString::fromStdString(it->second.ped_date_start), Qt::ISODate); + s.setDate(d); + s.setTime(QTime(12, 0, 0)); + int duration = 30; + double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 3, s, end, duration, nextDay, prePaid); + if (cost != 60.0) { + qCritical() << "ERROR(2) start" << s.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) + << "duration" << duration + << "cost" << cost; + exit(-1); + } + qCritical() << "start" << s.toString(Qt::ISODate) + << "end" << end.toString(Qt::ISODate) + << "duration" << duration + << "cost" << cost; + } +#endif + } + } + return 0; + +#endif + +#if SZEGED==1 + std::ifstream input; + int pop_min_time; + int pop_max_time; + int pop_min_price; + int pop_max_price; + int pop_daily_card_price; + + for (int zone = 1; zone < 2; ++zone) { + //for (int t=6; t < 7; t+=20) { + switch (zone) { + case 1: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff01.json"); + //pop_max_time = 6*60; + } break; + case 2: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff02.json"); + //pop_max_time = 5*60; + } break; + case 3: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff03.json"); + //pop_max_time = 6*60; + } break; + case 4: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff04.json"); + //pop_max_time = 4*60; + } break; + case 5: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff05.json"); + //pop_max_time = 6*60; + } break; + case 6: { + input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff06.json"); + //pop_max_time = 4*60; + } break; + default: + continue; + } + std::stringstream sstr; + while(input >> sstr.rdbuf()); + std::string json(sstr.str()); + + Configuration cfg; + + bool isParsed = cfg.ParseJson(&cfg, json.c_str()); + cout << endl; + + if (isParsed) { + // test library functions + + pop_min_time = get_minimal_parkingtime(&cfg); + pop_max_time = get_maximal_parkingtime(&cfg); + pop_min_price = get_minimal_parkingprice(&cfg); + pop_max_price = get_maximal_parkingprice(&cfg); + pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; + + qCritical() << " pop_min_time: " << pop_min_time; + qCritical() << " pop_max_time: " << pop_max_time; + qCritical() << " pop_min_price: " << pop_min_price; + qCritical() << " pop_max_price: " << pop_max_price; + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + + pop_daily_card_price = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET); + qCritical() << "pop_daily_card_price: " << pop_daily_card_price; + + if (pop_min_time > pop_max_time) { + qCritical() << "ERROR pop_min_time > pop_max_time" + << pop_min_time << pop_max_time; + return -1; + } + + if (pop_min_price > pop_max_price) { + qCritical() << "ERROR pop_min_price > pop_max_price" + << pop_min_price << pop_max_price; + return -1; + } + + if (pop_daily_card_price < pop_max_price) { + qCritical() << "ERROR pop_daily_card_price < pop_max_price" + << pop_daily_card_price << pop_max_price; + return -1; + } + + QMap m; + + { + // zone 1 (lila) + QDateTime s(QDate(2024, 3, 26), QTime()); + QDateTime end; + int cnt = 1; + if (zone == 1) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 42 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 55); + m.insert(25, 69); + m.insert(30, 83); + m.insert(35, 97); + m.insert(40, 110); + m.insert(45, 124); + m.insert(50, 138); + m.insert(55, 152); + m.insert(60, 165); + + m.insert(65, 179); + m.insert(70, 193); + m.insert(75, 207); + m.insert(80, 220); + m.insert(85, 234); + m.insert(90, 248); + m.insert(95, 262); + m.insert(100, 275); + m.insert(105, 289); + m.insert(110, 303); + m.insert(115, 317); + m.insert(120, 330); + + m.insert(125, 344); + m.insert(130, 358); + m.insert(135, 372); + m.insert(140, 385); + m.insert(145, 399); + m.insert(150, 413); + m.insert(155, 427); + m.insert(160, 440); + m.insert(165, 454); + m.insert(170, 468); + m.insert(175, 482); + m.insert(180, 495); + + m.insert(185, 509); + m.insert(190, 523); + m.insert(195, 537); + m.insert(200, 550); + m.insert(205, 564); + m.insert(210, 578); + m.insert(215, 592); + m.insert(220, 605); + m.insert(225, 619); + m.insert(230, 633); + m.insert(235, 647); + m.insert(240, 660); + + m.insert(245, 674); + m.insert(250, 688); + m.insert(255, 702); + m.insert(260, 715); + m.insert(265, 729); + m.insert(270, 743); + m.insert(275, 757); + m.insert(280, 770); + m.insert(285, 784); + m.insert(290, 798); + m.insert(295, 812); + m.insert(300, 825); + + m.insert(305, 839); + m.insert(310, 853); + m.insert(315, 867); + m.insert(320, 880); + m.insert(325, 894); + m.insert(330, 908); + m.insert(335, 922); + m.insert(340, 935); + m.insert(345, 949); + m.insert(350, 963); + m.insert(355, 977); + m.insert(360, pop_max_price); // 990 + + m.insert(365, pop_max_price); + m.insert(370, pop_max_price); + m.insert(375, pop_max_price); + m.insert(380, pop_max_price); + m.insert(385, pop_max_price); + m.insert(390, pop_max_price); + m.insert(395, pop_max_price); + m.insert(400, pop_max_price); + m.insert(405, pop_max_price); + m.insert(410, pop_max_price); + m.insert(415, pop_max_price); + m.insert(420, pop_max_price); + } else + if (zone == 2) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 65 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 87); + m.insert(25, 109); + m.insert(30, 130); + m.insert(35, 152); + m.insert(40, 174); + m.insert(45, 195); + m.insert(50, 217); + m.insert(55, 239); + m.insert(60, 260); + + m.insert(65, 282); + m.insert(70, 304); + m.insert(75, 325); + m.insert(80, 347); + m.insert(85, 369); + m.insert(90, 390); + m.insert(95, 412); + m.insert(100, 434); + m.insert(105, 455); + m.insert(110, 477); + m.insert(115, 499); + m.insert(120, 520); + + m.insert(125, 542); + m.insert(130, 564); + m.insert(135, 585); + m.insert(140, 607); + m.insert(145, 629); + m.insert(150, 650); + m.insert(155, 672); + m.insert(160, 694); + m.insert(165, 715); + m.insert(170, 737); + m.insert(175, 759); + m.insert(180, 780); + + m.insert(185, 802); + m.insert(190, 824); + m.insert(195, 845); + m.insert(200, 867); + m.insert(205, 889); + m.insert(210, 910); + m.insert(215, 932); + m.insert(220, 954); + m.insert(225, 975); + m.insert(230, 997); + m.insert(235, 1019); + m.insert(240, 1040); + + m.insert(245, 1062); + m.insert(250, 1084); + m.insert(255, 1105); + m.insert(260, 1127); + m.insert(265, 1149); + m.insert(270, 1170); + m.insert(275, 1192); + m.insert(280, 1214); + m.insert(285, 1235); + m.insert(290, 1257); + m.insert(295, 1279); + m.insert(300, 1300); + + m.insert(305, 1322); + m.insert(310, 1344); + m.insert(315, 1365); + m.insert(320, 1387); + m.insert(325, 1409); + m.insert(330, 1430); + m.insert(335, 1452); + m.insert(340, 1474); + m.insert(345, 1495); + m.insert(350, 1517); + m.insert(355, 1539); + m.insert(360, pop_max_price); // 1560 + + m.insert(365, pop_max_price); + m.insert(370, pop_max_price); + m.insert(375, pop_max_price); + m.insert(380, pop_max_price); + m.insert(385, pop_max_price); + m.insert(390, pop_max_price); + m.insert(395, pop_max_price); + m.insert(400, pop_max_price); + m.insert(405, pop_max_price); + m.insert(410, pop_max_price); + m.insert(415, pop_max_price); + m.insert(420, pop_max_price); + } else + if (zone == 3) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 90 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 120); + m.insert(25, 150); + m.insert(30, 180); + m.insert(35, 210); + m.insert(40, 240); + m.insert(45, 270); + m.insert(50, 300); + m.insert(55, 330); + m.insert(60, 360); + m.insert(65, 390); + m.insert(70, 420); + m.insert(75, 450); + m.insert(80, 480); + m.insert(85, 510); + m.insert(90, 540); + m.insert(95, 570); + m.insert(100, 600); + m.insert(105, 630); + m.insert(110, 660); + m.insert(115, 690); + m.insert(120, 720); + + m.insert(125, 750); + m.insert(130, 780); + m.insert(135, 810); + m.insert(140, 840); + m.insert(145, 870); + m.insert(150, 900); + m.insert(155, 930); + m.insert(160, 960); + m.insert(165, 990); + m.insert(170, 1020); + m.insert(175, 1050); + m.insert(180, 1080); + + m.insert(185, 1110); + m.insert(190, 1140); + m.insert(195, 1170); + m.insert(200, 1200); + m.insert(205, 1230); + m.insert(210, 1260); + m.insert(215, 1290); + m.insert(220, 1320); + m.insert(225, 1350); + m.insert(230, 1380); + m.insert(235, 1410); + m.insert(240, 1440); + + m.insert(245, 1470); + m.insert(250, 1500); + m.insert(255, 1530); + m.insert(260, 1560); + m.insert(265, 1590); + m.insert(270, 1620); + m.insert(275, 1650); + m.insert(280, 1680); + m.insert(285, 1710); + m.insert(290, 1740); + m.insert(295, 1770); + m.insert(300, 1800); + + m.insert(305, 1830); + m.insert(310, 1860); + m.insert(315, 1890); + m.insert(320, 1920); + m.insert(325, 1950); + m.insert(330, 1980); + m.insert(335, 2010); + m.insert(340, 2040); + m.insert(345, 2070); + m.insert(350, 2100); + m.insert(355, 2130); + m.insert(360, pop_max_price); // 2160 + + m.insert(365, pop_max_price); + m.insert(370, pop_max_price); + m.insert(375, pop_max_price); + m.insert(380, pop_max_price); + m.insert(385, pop_max_price); + m.insert(390, pop_max_price); + m.insert(395, pop_max_price); + m.insert(400, pop_max_price); + m.insert(405, pop_max_price); + m.insert(410, pop_max_price); + m.insert(415, pop_max_price); + m.insert(420, pop_max_price); + } else + if (zone == 4) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 163 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 217); + m.insert(25, 271); + m.insert(30, 325); + m.insert(35, 380); + m.insert(40, 434); + m.insert(45, 488); + m.insert(50, 542); + m.insert(55, 596); + m.insert(60, 650); + + m.insert(65, 705); + m.insert(70, 759); + m.insert(75, 813); + m.insert(80, 867); + m.insert(85, 921); + m.insert(90, 975); + m.insert(95, 1030); + m.insert(100, 1084); + m.insert(105, 1138); + m.insert(110, 1192); + m.insert(115, 1246); + m.insert(120, 1300); + + m.insert(125, 1355); + m.insert(130, 1409); + m.insert(135, 1463); + m.insert(140, 1517); + m.insert(145, 1571); + m.insert(150, 1625); + m.insert(155, 1680); + m.insert(160, 1734); + m.insert(165, 1788); + m.insert(170, 1842); + m.insert(175, 1896); + m.insert(180, 1950); + + m.insert(185, 2005); + m.insert(190, 2059); + m.insert(195, 2113); + m.insert(200, 2167); + m.insert(205, 2221); + m.insert(210, 2275); + m.insert(215, 2330); + m.insert(220, 2384); + m.insert(225, 2438); + m.insert(230, 2492); + m.insert(235, 2546); + m.insert(240, pop_max_price); // 2600 + + m.insert(245, pop_max_price); + m.insert(250, pop_max_price); + m.insert(255, pop_max_price); + m.insert(260, pop_max_price); + m.insert(270, pop_max_price); + m.insert(280, pop_max_price); + m.insert(290, pop_max_price); + m.insert(300, pop_max_price); + } else + if (zone == 5) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 90 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 120); + m.insert(25, 150); + m.insert(30, 180); + m.insert(35, 210); + m.insert(40, 240); + m.insert(45, 270); + m.insert(50, 300); + m.insert(55, 330); + m.insert(60, 360); + m.insert(65, 390); + m.insert(70, 420); + m.insert(75, 450); + m.insert(80, 480); + m.insert(85, 510); + m.insert(90, 540); + m.insert(95, 570); + m.insert(100, 600); + m.insert(105, 630); + m.insert(110, 660); + m.insert(115, 690); + m.insert(120, 720); + + m.insert(125, 750); + m.insert(130, 780); + m.insert(135, 810); + m.insert(140, 840); + m.insert(145, 870); + m.insert(150, 900); + m.insert(155, 930); + m.insert(160, 960); + m.insert(165, 990); + m.insert(170, 1020); + m.insert(175, 1050); + m.insert(180, 1080); + + m.insert(185, 1110); + m.insert(190, 1140); + m.insert(195, 1170); + m.insert(200, 1200); + m.insert(205, 1230); + m.insert(210, 1260); + m.insert(215, 1290); + m.insert(220, 1320); + m.insert(225, 1350); + m.insert(230, 1380); + m.insert(235, 1410); + m.insert(240, 1440); + + m.insert(245, 1470); + m.insert(250, 1500); + m.insert(255, 1530); + m.insert(260, 1560); + m.insert(265, 1590); + m.insert(270, 1620); + m.insert(275, 1650); + m.insert(280, 1680); + m.insert(285, 1710); + m.insert(290, 1740); + m.insert(295, 1770); + m.insert(300, 1800); + + m.insert(305, 1830); + m.insert(310, 1860); + m.insert(315, 1890); + m.insert(320, 1920); + m.insert(325, 1950); + m.insert(330, 1980); + m.insert(335, 2010); + m.insert(340, 2040); + m.insert(345, 2070); + m.insert(350, 2100); + m.insert(355, 2130); + m.insert(360, pop_max_price); // 2160 + + m.insert(365, pop_max_price); + m.insert(370, pop_max_price); + m.insert(375, pop_max_price); + m.insert(380, pop_max_price); + m.insert(385, pop_max_price); + m.insert(390, pop_max_price); + m.insert(395, pop_max_price); + m.insert(400, pop_max_price); + m.insert(405, pop_max_price); + m.insert(410, pop_max_price); + m.insert(415, pop_max_price); + m.insert(420, pop_max_price); + } else + if (zone == 6) { + m.insert(5, pop_min_price); + m.insert(10, pop_min_price); // 163 + + m.insert(pop_min_time, pop_min_price); + m.insert(20, 217); + m.insert(25, 271); + m.insert(30, 325); + m.insert(35, 380); + m.insert(40, 434); + m.insert(45, 488); + m.insert(50, 542); + m.insert(55, 596); + m.insert(60, 650); + + m.insert(65, 705); + m.insert(70, 759); + m.insert(75, 813); + m.insert(80, 867); + m.insert(85, 921); + m.insert(90, 975); + m.insert(95, 1030); + m.insert(100, 1084); + m.insert(105, 1138); + m.insert(110, 1192); + m.insert(115, 1246); + m.insert(120, 1300); + + m.insert(125, 1355); + m.insert(130, 1409); + m.insert(135, 1463); + m.insert(140, 1517); + m.insert(145, 1571); + m.insert(150, 1625); + m.insert(155, 1680); + m.insert(160, 1734); + m.insert(165, 1788); + m.insert(170, 1842); + m.insert(175, 1896); + m.insert(180, 1950); + + m.insert(185, 2005); + m.insert(190, 2059); + m.insert(195, 2113); + m.insert(200, 2167); + m.insert(205, 2221); + m.insert(210, 2275); + m.insert(215, 2330); + m.insert(220, 2384); + m.insert(225, 2438); + m.insert(230, 2492); + m.insert(235, 2546); + m.insert(240, pop_max_price); // 2600 + + m.insert(245, pop_max_price); + m.insert(250, pop_max_price); + m.insert(255, pop_max_price); + m.insert(260, pop_max_price); + m.insert(270, pop_max_price); + m.insert(280, pop_max_price); + m.insert(290, pop_max_price); + m.insert(300, pop_max_price); + } + + struct price_t price; + for (int duration = pop_min_time; duration <= pop_max_time; duration += 5) { + for (int offset = 480; offset < 1080; ++offset) { + QDateTime start = s.addSecs(offset * 60); + end = QDateTime(); + price.netto = 0; + if (compute_price_for_parking_ticket(&cfg, start, duration, end, &price)) { + double cost = price.netto; + + //qCritical() << start.toString(Qt::ISODate) << end.toString(Qt::ISODate) + // << duration << cost; + + if (cost != m[duration]) { + qCritical() << "ERROR computing_price_for_parking_ticket" + << "duration" << duration + << "HAVE cost" << cost + << "SHOULD HAVE cost" << m[duration]; + return -1; + } + } else { + qCritical() << "ERROR computing_price_for_parking_ticket AT" + << cnt << "duration" << duration + << "start" << start.toString(Qt::ISODate); + return -1; + } + start = s.addSecs(offset * 60); + end = QDateTime(); + price.netto = 0; + + if (compute_price_for_daily_ticket(&cfg, start, end, PERMIT_TYPE::DAY_TICKET, &price)) { + if (price.netto != pop_daily_card_price) { + qCritical() << "ERROR computing_price_for_daily_ticket" + << "duration" << duration + << "HAVE cost" << price.netto + << "SHOULD HAVE cost" << pop_daily_card_price; + return -1; + } + } else { + qCritical() << "ERROR computing_price_for_daily_ticket AT" + << "start" << start.toString(Qt::ISODate); + return -1; + } + + // this->getDayTicketPrice(PERMIT_TYPE::DAY_TICKET) + + // start = s.addSecs(offset * 60); + // end = QDateTime(); + // if (compute_duration_for_daily_ticket(&cfg, start, end)) { + // + // } else { + // qCritical() << "ERROR computing_duration_for_daily_ticket AT" + // << "start" << start.toString(Qt::ISODate); + // return -1; + // } + + // ++cnt; + } + } + } + } } return 0; +#endif + #if 0 //std::string json = "{\"Currency\":[{\"pcu_id\":2,\"pcu_sign\":\"Ft\",\"pcu_major\":\"HUF\",\"pcu_minor\":\"\",\"pcu_active\":true}],\"PaymentMethod\":[{\"pme_id\":1,\"pme_label\":\"progressive\"},{\"pme_id\":2,\"pme_label\":\"degressive\"},{\"pme_id\":3,\"pme_label\":\"linear\"},{\"pme_id\":4,\"pme_label\":\"steps\"}],\"PaymentOption\":[{\"pop_id\":17,\"pop_label\":\"Zone 1\",\"pop_payment_method_id\":3,\"pop_day_end_time\":\"00:00:00\",\"pop_day_night_end_time\":\"00:00:00\",\"pop_price_night\":0,\"pop_min_time\":15,\"pop_max_time\":240,\"pop_min_price\":120,\"pop_carry_over\":1}],\"PaymentRate\":[{\"pra_payment_option_id\":17,\"pra_payment_unit_id\":3,\"pra_price\":480}],\"Duration\":[{\"pun_id\":1,\"pun_label\":\"1h\",\"pun_duration\":60},{\"pun_id\":2,\"pun_label\":\"1 min\",\"pun_duration\":1},{\"pun_id\":3,\"pun_label\":\"15 min\",\"pun_duration\":15},{\"pun_id\":4,\"pun_label\":\"1d\",\"pun_duration\":1440},{\"pun_id\":6,\"pun_label\":\"2h\",\"pun_duration\":120},{\"pun_id\":7,\"pun_label\":\"3h\",\"pun_duration\":180},{\"pun_id\":11,\"pun_label\":\"4h\",\"pun_duration\":240},{\"pun_id\":17,\"pun_label\":\"30 min\",\"pun_duration\":30},{\"pun_id\":18,\"pun_label\":\"1.5h\",\"pun_duration\":90},{\"pun_id\":20,\"pun_label\":\"10min\",\"pun_duration\":10}],\"WeekDaysWorktime\":[{\"pwd_id\":540,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":1,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":541,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":2,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":542,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":3,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":543,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":4,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":544,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":5,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"}],\"PeriodYear\":[{\"pye_id\":1,\"pye_label\":\"Summer\",\"pye_start_month\":6,\"pye_start_day\":1,\"pye_end_month\":9,\"pye_end_day\":30},{\"pye_id\":2,\"pye_label\":\"Winter\",\"pye_start_month\":10,\"pye_start_day\":1,\"pye_end_month\":5,\"pye_end_day\":31},{\"pye_id\":8,\"pye_label\":\"Whole year\",\"pye_start_month\":1,\"pye_start_day\":1,\"pye_end_month\":12,\"pye_end_day\":31}],\"SpecialDaysWorktime\":[{\"pedwt_id\":2156,\"pedwt_period_exc_day_id\":2024,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2158,\"pedwt_period_exc_day_id\":2025,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2160,\"pedwt_period_exc_day_id\":2026,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2162,\"pedwt_period_exc_day_id\":2027,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2164,\"pedwt_period_exc_day_id\":2028,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2170,\"pedwt_period_exc_day_id\":2030,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2172,\"pedwt_period_exc_day_id\":2032,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2174,\"pedwt_period_exc_day_id\":11,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2175,\"pedwt_period_exc_day_id\":13,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2178,\"pedwt_period_exc_day_id\":2022,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2179,\"pedwt_period_exc_day_id\":14,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2180,\"pedwt_period_exc_day_id\":2017,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2181,\"pedwt_period_exc_day_id\":2018,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2182,\"pedwt_period_exc_day_id\":2019,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2183,\"pedwt_period_exc_day_id\":2020,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2184,\"pedwt_period_exc_day_id\":2021,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2185,\"pedwt_period_exc_day_id\":2023,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2188,\"pedwt_period_exc_day_id\":2031,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2189,\"pedwt_period_exc_day_id\":2029,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2191,\"pedwt_period_exc_day_id\":2016,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2192,\"pedwt_period_exc_day_id\":2033,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2194,\"pedwt_period_exc_day_id\":2034,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2196,\"pedwt_period_exc_day_id\":2035,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2198,\"pedwt_period_exc_day_id\":2036,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2200,\"pedwt_period_exc_day_id\":2037,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2202,\"pedwt_period_exc_day_id\":2038,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2204,\"pedwt_period_exc_day_id\":2039,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2206,\"pedwt_period_exc_day_id\":2040,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2219,\"pedwt_period_exc_day_id\":2041,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2220,\"pedwt_period_exc_day_id\":2042,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2221,\"pedwt_period_exc_day_id\":2043,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2222,\"pedwt_period_exc_day_id\":2044,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2223,\"pedwt_period_exc_day_id\":2045,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"01:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2224,\"pedwt_period_exc_day_id\":2046,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0}],\"SpecialDays\":[{\"ped_id\":11,\"ped_label\":\"Christmas 1st day\",\"ped_date_start\":\"2022-12-25\",\"ped_date_end\":\"2022-12-25\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":13,\"ped_label\":\"Christmas 2nd day\",\"ped_date_start\":\"2022-12-26\",\"ped_date_end\":\"2022-12-26\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":14,\"ped_label\":\"Republic Day (Hungary)\",\"ped_date_start\":\"2022-10-23\",\"ped_date_end\":\"2022-10-23\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2016,\"ped_label\":\"Christmas (Sunday)\",\"ped_date_start\":\"2022-12-24\",\"ped_date_end\":\"2022-12-24\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2017,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-27\",\"ped_date_end\":\"2022-12-27\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2018,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-28\",\"ped_date_end\":\"2022-12-28\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2019,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-29\",\"ped_date_end\":\"2022-12-29\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2020,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-30\",\"ped_date_end\":\"2022-12-30\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2021,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-31\",\"ped_date_end\":\"2022-12-31\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2022,\"ped_label\":\"NewYear\",\"ped_date_start\":\"2023-01-01\",\"ped_date_end\":\"2023-01-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2023,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2023-01-02\",\"ped_date_end\":\"2023-01-02\",\"ped_period_special_day_id\":1,\"ped_year\":2024},{\"ped_id\":2024,\"ped_label\":\"Good Friday\",\"ped_date_start\":\"2023-04-07\",\"ped_date_end\":\"2023-04-07\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2025,\"ped_label\":\"Easter Sunday\",\"ped_date_start\":\"2023-04-09\",\"ped_date_end\":\"2023-04-09\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2026,\"ped_label\":\"Easter Monday\",\"ped_date_start\":\"2023-04-10\",\"ped_date_end\":\"2023-04-10\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2027,\"ped_label\":\"Whit Sunday\",\"ped_date_start\":\"2023-05-28\",\"ped_date_end\":\"2023-05-28\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2028,\"ped_label\":\"Whit Monday\",\"ped_date_start\":\"2023-05-29\",\"ped_date_end\":\"2023-05-29\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2029,\"ped_label\":\"Revolution Day (Hungary)\",\"ped_date_start\":\"2023-03-15\",\"ped_date_end\":\"2023-03-15\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2030,\"ped_label\":\"Labour Day\",\"ped_date_start\":\"2023-05-01\",\"ped_date_end\":\"2023-05-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2031,\"ped_label\":\"Saint Stephens Day (Hungary)\",\"ped_date_start\":\"2023-08-20\",\"ped_date_end\":\"2023-08-20\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2032,\"ped_label\":\"All Saints Day\",\"ped_date_start\":\"2023-11-01\",\"ped_date_end\":\"2023-11-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2033,\"ped_label\":\"Christmas (Tuesday)\",\"ped_date_start\":\"2024-12-24\",\"ped_date_end\":\"2024-12-24\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2034,\"ped_label\":\"Good Friday\",\"ped_date_start\":\"2024-03-29\",\"ped_date_end\":\"2024-03-29\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2035,\"ped_label\":\"Easter\",\"ped_date_start\":\"2024-03-31\",\"ped_date_end\":\"2024-03-31\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2036,\"ped_label\":\"Easter Monday\",\"ped_date_start\":\"2024-04-01\",\"ped_date_end\":\"2024-04-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2037,\"ped_label\":\"Whit Monday\",\"ped_date_start\":\"2024-05-20\",\"ped_date_end\":\"2024-05-20\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2038,\"ped_label\":\"Whit Sunday\",\"ped_date_start\":\"2024-05-19\",\"ped_date_end\":\"2024-05-19\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2039,\"ped_label\":\"Christmas 1st Day\",\"ped_date_start\":\"2024-12-25\",\"ped_date_end\":\"2024-12-25\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2040,\"ped_label\":\"Christmas 2nd Day\",\"ped_date_start\":\"2024-12-26\",\"ped_date_end\":\"2024-12-26\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2041,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-27\",\"ped_date_end\":\"2024-12-27\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2042,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-28\",\"ped_date_end\":\"2024-12-28\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2043,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-29\",\"ped_date_end\":\"2024-12-29\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2044,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-30\",\"ped_date_end\":\"2024-12-30\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2045,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-31\",\"ped_date_end\":\"2024-12-31\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2046,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2025-01-02\",\"ped_date_end\":\"2025-01-02\",\"ped_period_special_day_id\":1,\"ped_year\":2025}]}"; @@ -354,6 +3908,6 @@ int main() { } } } + #endif - return 0; } diff --git a/main/main.cpp.bck.23112023 b/main/main.cpp.bck.23112023 new file mode 100644 index 0000000..ca7015a --- /dev/null +++ b/main/main.cpp.bck.23112023 @@ -0,0 +1,75 @@ +#ifdef WIN32 +#include +#include +#include + + +extern "C" char* strptime(const char* s, + const char* f, + struct tm* tm) { + // Isn't the C++ standard lib nice? std::get_time is defined such that its + // format parameters are the exact same as strptime. Of course, we have to + // create a string stream first, and imbue it with the current C locale, and + // we also have to make sure we return the right things if it fails, or + // if it succeeds, but this is still far simpler an implementation than any + // of the versions in any of the C standard libraries. + std::istringstream input(s); + input.imbue(std::locale(setlocale(LC_ALL, nullptr))); + input >> std::get_time(tm, f); + if (input.fail()) { + return nullptr; + } + return (char*)(s + input.tellg()); +} +#endif + +#include "calculate_price.h" +#include "calculator_functions.h" +#include "payment_method.h" +#include "payment_option.h" + + +#include +#include + + +static Calculator calculator; +int main() { + + parking_tariff_t *tariff = 0; + if (init_tariff(&tariff, "/tmp")) + { + + + for(auto itr = tariff->WeekDaysWorktime.begin(); itr != tariff->WeekDaysWorktime.end(); ++itr) + { + qCritical() << itr->first << "TO " << itr->second.pwd_time_from.c_str(); + qCritical() << itr->first << "FROM" << itr->second.pwd_time_from.c_str(); + } + + for (auto[itr, rangeEnd] = tariff->WeekDaysWorktime.equal_range(36); itr != rangeEnd; ++itr) + { + qCritical() << itr->first << itr->second.pwd_time_from.c_str(); + } + +#if 0 + struct price_t price; + memset(&price, 0x00, sizeof(price)); + QDateTime start = QDateTime::fromString("2023-11-22T14:00:00.000Z",Qt::ISODate); //QDateTime::currentDateTime(); + //QDateTime start = QDateTime::currentDateTime(); + for (int j=30; j <=180; j+=5) { + QDateTime s = start.addSecs(j*60); + for (int i = 60; i <= 360; i+=10) { + std::string a = calculator.GetDurationFromCost(tariff, PaymentOption::Option1, + s.toString(Qt::ISODate).toStdString().c_str(), + i); + + //qCritical() << "cost=" << i << ", duration=" << QString(a.c_str()); + } + } +#endif + free_tariff(tariff); + } + + return 0; +} diff --git a/main/main.pro b/main/main.pro index cb88c34..912d6ec 100644 --- a/main/main.pro +++ b/main/main.pro @@ -3,8 +3,8 @@ TARGET = main CONFIG += -std=c++11 -QMAKE_CFLAGS = -c -pipe -std=c11 -g -O0 -Wall -Wno-attributes -W -DDEBUG -D_REENTRANT -fPIC -QMAKE_CXX_FLAGS += -std=c11 +QMAKE_CFLAGS = -c -pipe -std=c11 -g -O -Wall -Wno-attributes -W -DDEBUG -D_REENTRANT -fPIC +QMAKE_CXXFLAGS += -std=c++17 -g -O INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/mobilisis/ INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/rapidjson/ @@ -27,11 +27,19 @@ CONFIG(debug, debug|release) { SOURCES += main.cpp +# HEADERS += -# HEADERS += \ - -# OTHER_FILES += \ - +OTHER_FILES += \ + /opt/ptu5/opt/customer_335/etc/psa_tariff/tariff01.json \ + /opt/ptu5/opt/customer_335/etc/psa_tariff/tariff02.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff01.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff03.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff04.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff06.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff07.json \ + /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff08.json diff --git a/main/terminal_utils.cpp b/main/terminal_utils.cpp new file mode 100644 index 0000000..8b1d71f --- /dev/null +++ b/main/terminal_utils.cpp @@ -0,0 +1,96 @@ +#include "terminal_utils.h" + +#include +#include +#include +#include +#include +#include + +namespace TU { + char const *terminalStatus(uint8_t status) { + switch (status) { + case TERMINAL_CB2_KEYS_NOT_PRESENT: + return "CB2 KEYS NOT PRESENT"; + case TERMINAL_NO_BANKING_PARAMETERS_PRESENT: + return "NO BANKING PARAMETERS PRESENT"; + case TERMINAL_IS_BLOCKED: + return "TERMINAL IS BLOCKED"; + case TERMINAL_NOT_OPERATIVE: + return "TERMINAL NOT OPERATIVE"; + case TERMINAL_IS_READY_AND_ACTIVE: + return "TERMINAL IS READY AND ACTIVE"; + case TERMINAL_IS_READY_AND_NOT_ACTIVE: + return "TERMINAL IS READY AND *NOT* ACTIVE"; + case TERMINAL_LOG_FULL: + return "TERMINAL LOG IS FULL"; + default: + return ""; + } + } + + QByteArray int2Hex(int i) { + return QByteArray::fromHex( + QString().setNum(i, 16).toLocal8Bit().constData()).toHex(); + } + + uint16_t getNextTransactionId() { + static std::atomic i{0}; + int j = 0; + + while ((j = (++i % 100)) == 0); // 1 <= j <= 99 + + return htobe16(((j / 10) + 0x30) << 8) | ((j % 10) + 0x30); + } + + uint32_t crc32(uint32_t crc, unsigned char* pData, size_t len) { + + qCritical() << "updateCRC" << QByteArray((char *)pData, len).toHex(); + + int i = 0; + int j = 0; + unsigned char ucCarry = 0x00; + + crc = ~crc; + while (len > 0) { + uint32_t const c = pData[i]; + crc ^= c; + ++i; + + for (j = 0; j < 8; ++j) { + ucCarry = crc & 1; + crc >>= 1; + + if (ucCarry) { + crc ^= 0xedb88320; + } + } + --len; + } + + return ~crc; + + } + + uint32_t crc32(QByteArray const &ba) { + uint32_t crc = 0; + return crc32(crc, (uint8_t *)ba.data(), ba.size()); + } + + char lrc(QByteArray const &ba) { + char crc = 0; + for (int i = 0; i < ba.size(); ++i) { + crc ^= ba[i]; + } + return crc; + } + + bool isBigEndian() { + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + + return bint.c[0] == 1; + } +} diff --git a/main/terminal_utils.h b/main/terminal_utils.h new file mode 100644 index 0000000..7cd1db6 --- /dev/null +++ b/main/terminal_utils.h @@ -0,0 +1,31 @@ +#ifndef TERMINAL_UTILS_H_INCLUDED +#define TERMINAL_UTILS_H_INCLUDED + +#include +#include + +namespace TU { + + enum STATUS : uint8_t { + TERMINAL_CB2_KEYS_NOT_PRESENT = 0x30, + TERMINAL_NO_BANKING_PARAMETERS_PRESENT = 0x31, + TERMINAL_IS_BLOCKED = 0x32, + TERMINAL_NOT_OPERATIVE = 0x33, + TERMINAL_IS_READY_AND_ACTIVE = 0x34, + TERMINAL_IS_READY_AND_NOT_ACTIVE = 0x35, + TERMINAL_LOG_FULL = 0x36 + }; + + char const *terminalStatus(uint8_t status); + QByteArray int2Hex(int i); + uint16_t getNextTransactionId(); + + //uint32_t crc32(const char *s, size_t n); + //uint32_t crc32(QByteArray const &ba); + uint32_t crc32(QByteArray const &ba); + uint32_t crc32(uint32_t crc, unsigned char* pData, size_t len); + + char lrc(QByteArray const &ba); + bool isBigEndian(); +} +#endif // TERMINAL_UTILS_H_INCLUDED diff --git a/out.txt b/out.txt new file mode 100644 index 0000000..4a08fde --- /dev/null +++ b/out.txt @@ -0,0 +1,1529 @@ +-- Logs begin at Thu 2024-09-12 09:01:22 CEST, end at Thu 2024-09-12 09:05:50 CEST. -- +Sep 12 09:02:03 ATB_PTU5 systemd[1]: Starting ATB update tool... +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: hwapi::hwapi() APP_VERSION: 1.0.1 +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: hwapi::hwapi() APP_BUILD_DATE: 27-07-24 +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: hwapi::hwapi() APP_BUILD_TIME: 07:44:09 +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: hwapi::hwapi() APP_EXTENDED_VERSION: 1.0.1-433af98de7803738ec21a9bc743213f1975b56ca +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: hwapi::hwapi() APP_EXTENDED_VERSION_LIB: +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: Shared memory ( 24848 bytes) created and attached +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: ATBDeviceControllerPlugin: instantiate CashAgentLib: "/usr/lib/libCAslave.so" +Sep 12 09:02:04 ATB_PTU5 atbAccountingTool[347]: DeviceControllerAbstraction: loaded CashAgentLib +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: xkbcommon: ERROR: couldn't find a Compose file for locale "C" +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: Get account numbers: +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: nrOfVals = 8 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 0 ] = 1 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 1 ] = 2 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 2 ] = 3 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 3 ] = 0 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 4 ] = 0 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 5 ] = 0 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 6 ] = 0 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: backupedAccNumbers[ 7 ] = 0 +Sep 12 09:02:05 ATB_PTU5 atbAccountingTool[347]: onShowAvailableAccounts() currentSelectedAccountNumber = "3" +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 0 +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2000-00-00T00:00:00" +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":0,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_6\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"feece6bd-47a1-4d67-8c33-e2b54ffa47c9\"}" +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:07 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 0 +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2000-00-00T00:00:00" +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":0,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_6\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"9ec195d2-0989-4e98-9cae-71c63c833e26\"}" +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:09 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 0 +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2000-00-00T00:00:00" +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":0,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_6\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"84ecf604-c353-4523-948c-b3a1461574a0\"}" +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:11 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 0 +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2000-00-00T00:00:00" +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":0,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_6\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"fce5e5f6-559d-4e62-a280-bea676a18bc4\"}" +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:13 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 0 +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2000-00-00T00:00:00" +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":0,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_6\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"775f8df2-226a-476a-a776-a2500dd646e2\"}" +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:15 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 1 +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2024-07-31T08:12:04" +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 5) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 10) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 20) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 50) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 100) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 1) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 200) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 255) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 500) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 1000) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 2000) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 5000) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 10000) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":1,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":5},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":10},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":20},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":50},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":100},\"COIN_6\":{\"QUANTITY\":1,\"VALUE\":200},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":255},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"2024-07-31T08:12:04.000+02:00\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":500},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":1000},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":2000},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":5000},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":10000},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"cd6dac0a-141b-4bb0-abde-49862bc8c451\"}" +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:17 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 2 +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2024-09-11T07:22:04" +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 5) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 10) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 20) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 50) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 100) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 13) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 200) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 255) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 500) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 1000) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 2000) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 5000) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 10000) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":2,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":5},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":10},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":20},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":50},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":100},\"COIN_6\":{\"QUANTITY\":13,\"VALUE\":200},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":255},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"2024-09-11T07:22:04.000+02:00\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":500},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":1000},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":2000},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":5000},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":10000},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"8c9ef432-b24e-4bc5-9180-7870b6ad80e5\"}" +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:19 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: --> private_checkAccountData() +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: --> private_getAccountData() +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: AccountingNumber: ----------------------- +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: AccountingNumber = 3 +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: NumberOfCoinVariants = 16 +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: startDateTimeString = "2024-09-11T17:15:24" +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_1_Value = " QVariant(int, 5) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_2_Value = " QVariant(int, 10) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_3_Value = " QVariant(int, 20) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_4_Value = " QVariant(int, 50) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_5_Value = " QVariant(int, 100) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Quantity = " QVariant(int, 13) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_6_Value = " QVariant(int, 200) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_7_Value = " QVariant(int, 255) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_8_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_9_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_10_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_11_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_12_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_13_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_14_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_15_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "COIN_16_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: numberOfBillVariants = 8 +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_1_Value = " QVariant(int, 500) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_2_Value = " QVariant(int, 1000) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_3_Value = " QVariant(int, 2000) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_4_Value = " QVariant(int, 5000) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_5_Value = " QVariant(int, 10000) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_6_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_7_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Quantity = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: "NOTE_8_Value = " QVariant(int, 0) +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Connected! +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient::send: "#M=APISM#C=CMD_CashboxChange#J={\"COINBOX_CHANGE_NUMBER\":3,\"COIN_1\":{\"QUANTITY\":0,\"VALUE\":5},\"COIN_10\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_11\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_12\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_13\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_14\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_15\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_16\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_2\":{\"QUANTITY\":0,\"VALUE\":10},\"COIN_3\":{\"QUANTITY\":0,\"VALUE\":20},\"COIN_4\":{\"QUANTITY\":0,\"VALUE\":50},\"COIN_5\":{\"QUANTITY\":0,\"VALUE\":100},\"COIN_6\":{\"QUANTITY\":13,\"VALUE\":200},\"COIN_7\":{\"QUANTITY\":0,\"VALUE\":255},\"COIN_8\":{\"QUANTITY\":0,\"VALUE\":0},\"COIN_9\":{\"QUANTITY\":0,\"VALUE\":0},\"EndHash\":\"\",\"EndTime\":\"2024-09-11T17:15:24.000+02:00\",\"NOTE_1\":{\"QUANTITY\":0,\"VALUE\":500},\"NOTE_2\":{\"QUANTITY\":0,\"VALUE\":1000},\"NOTE_3\":{\"QUANTITY\":0,\"VALUE\":2000},\"NOTE_4\":{\"QUANTITY\":0,\"VALUE\":5000},\"NOTE_5\":{\"QUANTITY\":0,\"VALUE\":10000},\"NOTE_6\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_7\":{\"QUANTITY\":0,\"VALUE\":0},\"NOTE_8\":{\"QUANTITY\":0,\"VALUE\":0},\"PROCESS\":\"INFO\",\"StartHash\":\"\",\"StartTime\":\"\",\"UID\":\"92ff1ab5-91df-4912-98af-a47ff9093d68\"}" +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: ISMAS received: "RECORD SAVED\r" +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: ApismClient::onReceivedResponse() response is no json data: +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: Error: "illegal value" +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: ApismTcpClient: Disconnected! +Sep 12 09:02:21 ATB_PTU5 atbAccountingTool[347]: -> SocketErrorString: "Unknown error" +Sep 12 09:02:22 ATB_PTU5 systemd[1]: Started ATB update tool. +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() iniFileDir "/opt/app/tools/atbupdate" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() iniFileName "/opt/app/tools/atbupdate/ATBUpdateTool.ini" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "DIRECTORIES/plugin-directory" -> "/usr/lib/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "DIRECTORIES/psa-config-directory" -> "etc/psa_config/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "DIRECTORIES/psa-tariff-directory" -> "etc/psa_tariff/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "DIRECTORIES/working-directory" -> "/opt/app/tools/atbupdate/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/always-download-config" -> "true" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/always-download-dc" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/dry-run" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/extended-version" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/no-psa-hardware-update" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/yocto-install" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "FLAGS/yocto-version" -> "false" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "PLUGINS/plugin-name" -> "libCAslave.so" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: void CommandLineParser::readSettings() "REPOSITORY_URL/repository-url" -> "gitea@ptu-config.atb-comm.de:ATB" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: m_alwaysDownloadConfig "true" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: pwd ...................... "/opt/app/tools/atbupdate" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: repositoryUrl ............ "gitea@ptu-config.atb-comm.de:ATB" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: GIT_SSH_COMMAND .......... "ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: plugInDir ................ "/usr/lib/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: plugInName ............... "libCAslave.so" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: workingDir ............... "/opt/app/tools/atbupdate/" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: dryRun ................... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: noUpdatePsaHardware ...... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: alwaysDownloadConfig ..... true +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: alwaysDownloadDC ......... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: showYoctoVersion ......... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: showYoctoInstallStatus ... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: showExtendedVersion ...... false +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: iniFileName .............. "/opt/app/tools/atbupdate/ATBUpdateTool.ini" +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: extended-version ......... 1.5.1-0d00faf493047c773864055bbd11b402b74f9f59 +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: machineNr ................ 44 +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: customerNr ............... 249 +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: zoneNr ................... 2 +Sep 12 09:02:22 ATB_PTU5 ATBUpdateTool[360]: Main thread 0xb6fb4010 +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 41ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 118ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 41ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 72ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 116ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 101ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 96ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 146ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 106ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 116ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: loadDCPlugin() plugin directory: "/usr/lib" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: loadDCPlugin() plugin file name: "/usr/lib/libCAslave.so" +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: hwapi::hwapi() APP_VERSION: 1.0.1 +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: hwapi::hwapi() APP_BUILD_DATE: 27-07-24 +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: hwapi::hwapi() APP_BUILD_TIME: 07:44:09 +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: hwapi::hwapi() APP_EXTENDED_VERSION: 1.0.1-433af98de7803738ec21a9bc743213f1975b56ca +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: hwapi::hwapi() APP_EXTENDED_VERSION_LIB: +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: Shared memory ( 24848 bytes) created and attached +Sep 12 09:02:23 ATB_PTU5 ATBUpdateTool[360]: ( Update : 134 ) m_sys_areDCDataValid ... true +Sep 12 09:02:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 98ms)" with code 0 IN "/tmp" +Sep 12 09:02:24 ATB_PTU5 ATBUpdateTool[360]: Using Wayland-EGL +Sep 12 09:02:24 ATB_PTU5 ATBUpdateTool[360]: Using the 'xdg-shell-v6' shell integration +Sep 12 09:02:24 ATB_PTU5 ATBUpdateTool[360]: xkbcommon: ERROR: couldn't find a Compose file for locale "C" +Sep 12 09:02:24 ATB_PTU5 ATBUpdateTool[360]: qt.qpa.wayland: Wayland does not support QWindow::requestActivate() +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::STARTED" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CURRENT TIME ...............2024-09-12T09:02:25" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "OS VERSION .................i.MX6-thud-PCM058-KSP30-ATB-PTU5-2024-08-23" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "ATBQT VERSION ..............6.5.3-2-gc20e9fad_00249_20240911-1219" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CPU SERIAL .................da2cc15d130541d4" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CUSTOMER_NR ................249" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CUSTOMER_NR_STR ............customer_249" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CUSTOMER_REPOSITORY_PATH ...gitea@ptu-config.atb-comm.de:ATB/customer_249.git" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CUSTOMER_REPOSITORY ......../opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "MACHINE_NR .................44" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "ZONE_NR ....................2" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "BRANCH_NAME ................zg1/zone2" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "PLUGIN_NAME ................libCAslave.so" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "WORKING_DIRECTORY ........../opt/app/tools/atbupdate/" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "APISM VERSION ..............1.5.1-r0" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "ATB UPDATE TOOL VERSION ....1.5.1-0d00faf493047c773864055bbd11b402b74f9f59" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::CHECK_SANITY" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "CHECK SANITY OF CUSTOMER REPOSITORY /opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:25.198+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 5,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::CHECK_SANITY\",\"STEP_RESULT\" : \"SANITY OF /opt/app/tools/atbupdate/customer_249 (BRANCH zg1/zone2) OK\",\"VERSION\" : \"N/A\"}}" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59400 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59400 +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:25.198+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 5,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::CHECK_SANITY","STEP_RESULT" : "SANITY OF /opt/app/tools/atbupdate/customer_249 (BRANCH zg1/zone2) OK","VERSION" : "N/A"}}>>> +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::CHECK_SANITY_SUCCESS" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: "SANITY OF CUSTOMER REPOSITORY /opt/app/tools/atbupdate/customer_249 OK" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: CLONE "gitea@ptu-config.atb-comm.de:ATB/customer_249.git" AND CHECKOUT "zg1/zone2" +Sep 12 09:02:25 ATB_PTU5 ATBUpdateTool[360]: IN CURRENT WD "/opt/app/tools/atbupdate/" CLONE VIA COMMAND "git clone --progress -vvv --filter=blob:none gitea@ptu-config.atb-comm.de:ATB/customer_249.git" +Sep 12 09:02:34 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git clone --progress -vvv --filter=blob:none gitea@ptu-config.atb-comm.de:ATB/customer_249.git" "(runtime 9177ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:02:34 ATB_PTU5 ATBUpdateTool[360]: CLONING "gitea@ptu-config.atb-comm.de:ATB/customer_249.git" OK +Sep 12 09:02:34 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git checkout zg1/zone2" "(runtime 185ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git fsck" "(runtime 79ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git show origin/zg1/zone2 -s --format=\"c=%h m=%s d=%cI\"" "(runtime 20ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:35.075+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 13,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::CLONE_REPOSITORY\",\"STEP_RESULT\" : \"CLONED REPOSITORY /opt/app/tools/atbupdate/customer_249 AND CHECKED OUT BRANCH zg1/zone2\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59404 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59404 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:35.075+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 13,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::CLONE_REPOSITORY","STEP_RESULT" : "CLONED REPOSITORY /opt/app/tools/atbupdate/customer_249 AND CHECKED OUT BRANCH zg1/zone2","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git show origin/zg1/zone2 -s --format=\"c=%h m=%s d=%cI\"" "(runtime 27ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:35.483+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 17,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER\",\"STEP_RESULT\" : \"\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59406 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59406 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:35.483+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 17,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER","STEP_RESULT" : "","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::CHECKOUT_BRANCH" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:35.868+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 27,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::CHECKOUT_BRANCH\",\"STEP_RESULT\" : \"\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59408 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59408 +Sep 12 09:02:35 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:35.868+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 27,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::CHECKOUT_BRANCH","STEP_RESULT" : "","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git checkout zg1/zone2" "(runtime 154ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git show origin/zg1/zone2 -s --format=\"c=%h m=%s d=%cI\"" "(runtime 21ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::CHECKOUT_BRANCH" +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS" +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:36.427+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 27,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::CHECKOUT_BRANCH\",\"STEP_RESULT\" : \"UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59410 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59410 +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:36.427+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 27,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::CHECKOUT_BRANCH","STEP_RESULT" : "UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:36 ATB_PTU5 ATBUpdateTool[360]: BRANCH NAME "zg1/zone2" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git pull" "(runtime 2206ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: ( filesToUpdate : 836 ) FILES-TO-UPDATE ("etc/psa_update/opkg_commands", "etc/psa_config/DC2C_cash.json", "etc/psa_config/DC2C_device.json", "etc/psa_config/DC2C_print01.json", "etc/psa_config/DC2C_print02.json", "etc/psa_config/DC2C_print03.json", "etc/psa_config/DC2C_print04.json", "etc/psa_config/DC2C_print05.json", "etc/psa_config/DC2C_print06.json", "etc/psa_config/DC2C_print07.json", "etc/psa_config/DC2C_print08.json", "etc/psa_config/DC2C_print31.json", "etc/psa_config/DC2C_print32.json") +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::FILES_TO_UPDATE" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_update/opkg_commands" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_cash.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_device.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print01.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print02.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print03.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print04.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print05.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print06.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print07.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print08.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print31.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "etc/psa_config/DC2C_print32.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: FILES_TO_UPDATE ("etc/psa_update/opkg_commands", "etc/psa_config/DC2C_cash.json", "etc/psa_config/DC2C_device.json", "etc/psa_config/DC2C_print01.json", "etc/psa_config/DC2C_print02.json", "etc/psa_config/DC2C_print03.json", "etc/psa_config/DC2C_print04.json", "etc/psa_config/DC2C_print05.json", "etc/psa_config/DC2C_print06.json", "etc/psa_config/DC2C_print07.json", "etc/psa_config/DC2C_print08.json", "etc/psa_config/DC2C_print31.json", "etc/psa_config/DC2C_print32.json") +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git show origin/zg1/zone2 -s --format=\"c=%h m=%s d=%cI\"" "(runtime 50ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:39.097+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 33,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY\",\"STEP_RESULT\" : \"START\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59414 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59414 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:39.097+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 33,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY","STEP_RESULT" : "START","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 15ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "CONFIGURED SYNCING TO /ETC" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTING CMD... "rsync -v --recursive --progress --checksum --exclude=.* --include=*.bin --include=*.json --include=*.ini etc/ /etc" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "EXECUTING CMD rsync -v --recursive --progress --checksum --exclude=.* --include=*.bin --include=*.json --include=*.ini etc/ /etc..." +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 160ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "sending incremental file list" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "atbapp/ATBAPP.ini" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 1,684 100% 0.00kB/s 0:00:00 \r 1,684 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=23/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff02.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 14.64MB/s 0:00:00 \r 15,346 100% 14.64MB/s 0:00:00 (xfr#2, to-chk=6/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff03.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 14.64MB/s 0:00:00 \r 15,346 100% 14.64MB/s 0:00:00 (xfr#3, to-chk=5/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff04.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 14.64MB/s 0:00:00 \r 15,346 100% 14.64MB/s 0:00:00 (xfr#4, to-chk=4/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff05.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 14.64MB/s 0:00:00 \r 15,346 100% 14.64MB/s 0:00:00 (xfr#5, to-chk=3/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff06.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 999.09kB/s 0:00:00 \r 15,346 100% 936.65kB/s 0:00:00 (xfr#6, to-chk=2/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "psa_tariff/tariff07.json" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "\r 15,346 100% 881.55kB/s 0:00:00 \r 15,346 100% 881.55kB/s 0:00:00 (xfr#7, to-chk=1/29)" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "sent 94,957 bytes received 158 bytes 190,230.00 bytes/sec" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "total size is 178,934 speedup is 1.88" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: "" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:39.698+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 33,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY\",\"STEP_RESULT\" : \"SUCCESS rsync -v --recursive --progress --checksum --exclude=.* --include=*.bin --include=*.json --include=*.ini etc/ /etc\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59416 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59416 +Sep 12 09:02:39 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:39.698+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 33,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY","STEP_RESULT" : "SUCCESS rsync -v --recursive --progress --checksum --exclude=.* --include=*.bin --include=*.json --include=*.ini etc/ /etc","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: "/opt/app/tools/atbupdate/customer_249/etc/psa_tariff AND /etc/psa_tariff ARE EQUAL: [tariff01.json,tariff02.json,tariff03.json,tariff04.json,tariff05.json,tariff06.json,tariff07.json]" +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: "/opt/app/tools/atbupdate/customer_249/etc/psa_tariff AND /etc/psa_tariff CONTAIN SAME GIT-BLOBS FOR FILES: [tariff01.json,tariff02.json,tariff03.json,tariff04.json,tariff05.json,tariff06.json,tariff07.json]" +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS" +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS" +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:02:40.071+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 35,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS\",\"STEP_RESULT\" : \"UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59418 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59418 +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:02:40.071+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 35,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS","STEP_RESULT" : "UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS","VERSION" : "c2c872a"}}>>> +Sep 12 09:02:40 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg update" +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg update" "(runtime 29833ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg update OK: Downloading https://firmware.ptu5.atb-comm.de/testing/all/Packages.gz.\nUpdated source 'uri-all-0'.\nDownloading https://firmware.ptu5.atb-comm.de/testing/cortexa9t2hf-neon/Packages.gz.\nUpdated source 'uri-cortexa9t2hf-neon-0'.\nDownloading https://firmware.ptu5.atb-comm.de/testing/cortexa9t2hf-neon-mx6qdl/Packages.gz.\nUpdated source 'uri-cortexa9t2hf-neon-mx6qdl-0'.\nDownloading https://firmware.ptu5.atb-comm.de/testing/pcm058_ksp30_atb_ptu5_solo/Packages.gz.\nUpdated source 'uri-pcm058_ksp30_atb_ptu5_solo-0'.\nDownloading https://firmware.ptu5.atb-comm.de/testing/00249/Packages.gz.\nUpdated source 'uri-00249-0'.\n" +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_1" +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:10.267+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 40,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_1\",\"STEP_RESULT\" : \"opkg update\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59430 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59430 +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:10.267+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 40,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_1","STEP_RESULT" : "opkg update","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:10 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg install prepare-update" +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg install prepare-update" "(runtime 12234ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg install prepare-update OK: No packages installed or removed.\n" +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_2" +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:22.877+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 41,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_2\",\"STEP_RESULT\" : \"opkg install prepare-update\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59432 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59432 +Sep 12 09:03:22 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:22.877+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 41,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_2","STEP_RESULT" : "opkg install prepare-update","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:23 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-calculateprice-mobilisis" +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-calculateprice-mobilisis" "(runtime 2811ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-calculateprice-mobilisis OK: No packages installed or removed.\n" +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_3" +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:26.083+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 42,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_3\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-calculateprice-mobilisis\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59434 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59434 +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:26.083+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 42,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_3","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-calculateprice-mobilisis","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:26 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade libmobilisis-calc" +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade libmobilisis-calc" "(runtime 2905ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade libmobilisis-calc OK: No packages installed or removed.\n" +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_4" +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:29.366+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 43,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_4\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade libmobilisis-calc\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59436 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59436 +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:29.366+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 43,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_4","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade libmobilisis-calc","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:29 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade atb-dc-libraries" +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade atb-dc-libraries" "(runtime 2768ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade atb-dc-libraries OK: No packages installed or removed.\n" +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_5" +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:32.507+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 44,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_5\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade atb-dc-libraries\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59438 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59438 +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:32.507+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 44,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_5","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade atb-dc-libraries","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:32 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-dc" +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-dc" "(runtime 2775ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-dc OK: No packages installed or removed.\n" +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_6" +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:35.656+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 45,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_6\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-dc\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59440 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59440 +Sep 12 09:03:35 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:35.656+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 45,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_6","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-dc","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:36 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-cc-tcpzvt" +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-cc-tcpzvt" "(runtime 3081ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-cc-tcpzvt OK: No packages installed or removed.\n" +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_7" +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:39.134+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 46,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_7\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-cc-tcpzvt\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59442 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59442 +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:39.134+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 46,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_7","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade atb-plugin-cc-tcpzvt","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:39 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg --download-only upgrade atbqt" +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg --download-only upgrade atbqt" "(runtime 2794ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg --download-only upgrade atbqt OK: No packages installed or removed.\n" +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_8" +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:42.295+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 47,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_8\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg --download-only upgrade atbqt\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59444 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59444 +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:42.295+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 47,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_8","STEP_RESULT" : "opkg --cache /var/cache/opkg --download-only upgrade atbqt","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:42 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade atb-plugin-calculateprice-mobilisis" +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade atb-plugin-calculateprice-mobilisis" "(runtime 2810ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade atb-plugin-calculateprice-mobilisis OK: No packages installed or removed.\n" +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_9" +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:45.525+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 48,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_9\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade atb-plugin-calculateprice-mobilisis\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59446 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59446 +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:45.525+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 48,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_9","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade atb-plugin-calculateprice-mobilisis","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:45 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade libmobilisis-calc" +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade libmobilisis-calc" "(runtime 2766ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade libmobilisis-calc OK: No packages installed or removed.\n" +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST" +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:48.747+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 49,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_LAST\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade libmobilisis-calc\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59448 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59448 +Sep 12 09:03:48 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:48.747+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 49,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade libmobilisis-calc","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:49 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade atb-dc-libraries" +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade atb-dc-libraries" "(runtime 2769ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade atb-dc-libraries OK: No packages installed or removed.\n" +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST" +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:51.877+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 49,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_LAST\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade atb-dc-libraries\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59450 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59450 +Sep 12 09:03:51 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:51.877+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 49,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade atb-dc-libraries","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:52 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade atb-plugin-dc" +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade atb-plugin-dc" "(runtime 2692ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade atb-plugin-dc OK: No packages installed or removed.\n" +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST" +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:54.941+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 49,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_LAST\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade atb-plugin-dc\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59452 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59452 +Sep 12 09:03:54 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:54.941+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 49,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade atb-plugin-dc","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:55 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade atb-plugin-cc-tcpzvt" +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade atb-plugin-cc-tcpzvt" "(runtime 2682ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade atb-plugin-cc-tcpzvt OK: No packages installed or removed.\n" +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST" +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:03:58.015+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 49,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_LAST\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade atb-plugin-cc-tcpzvt\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59454 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59454 +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:03:58.015+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 49,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade atb-plugin-cc-tcpzvt","VERSION" : "c2c872a"}}>>> +Sep 12 09:03:58 ATB_PTU5 ATBUpdateTool[360]: Found opkg-command "opkg --cache /var/cache/opkg upgrade atbqt" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "opkg --cache /var/cache/opkg upgrade atbqt" "(runtime 2760ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: "EXECUTE OPKG COMMAND opkg --cache /var/cache/opkg upgrade atbqt OK: No packages installed or removed.\n" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:01.146+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 49,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMAND_LAST\",\"STEP_RESULT\" : \"opkg --cache /var/cache/opkg upgrade atbqt\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59456 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59456 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:01.146+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 49,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMAND_LAST","STEP_RESULT" : "opkg --cache /var/cache/opkg upgrade atbqt","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:01.506+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 51,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::EXEC_OPKG_COMMANDS\",\"STEP_RESULT\" : \"\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59458 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59458 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:01.506+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 51,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::EXEC_OPKG_COMMANDS","STEP_RESULT" : "","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:01.874+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 59,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE\",\"STEP_RESULT\" : \"START\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59460 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59460 +Sep 12 09:04:01 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:01.874+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 59,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE","STEP_RESULT" : "START","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:02.246+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 60,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"DC2C_cash.json DC2C_device.json DC2C_print01.json DC2C_print02.json DC2C_print03.json DC2C_print04.json DC2C_print05.json DC2C_print06.json DC2C_print07.json DC2C_print08.json DC2C_print31.json DC2C_print32.json\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59462 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59462 +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:02.246+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 60,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "DC2C_cash.json DC2C_device.json DC2C_print01.json DC2C_print02.json DC2C_print03.json DC2C_print04.json DC2C_print05.json DC2C_print06.json DC2C_print07.json DC2C_print08.json DC2C_print31.json DC2C_print32.json","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:02 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:03.611+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_cash.json (3) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59464 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59464 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:03.611+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_cash.json (3) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:03.962+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_cash.json\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59466 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59466 +Sep 12 09:04:03 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:03.962+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_cash.json","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:04 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:05.333+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_device.json (2) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59468 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59468 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:05.333+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_device.json (2) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:05.704+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_device.json\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59470 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59470 +Sep 12 09:04:05 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:05.704+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_device.json","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:06 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:07.078+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print01.json (1) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59472 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59472 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:07.078+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print01.json (1) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:07.438+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print01.json (1)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59474 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59474 +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:07.438+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print01.json (1)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:07 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:08.809+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print02.json (2) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59476 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59476 +Sep 12 09:04:08 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:08.809+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print02.json (2) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:09.182+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print02.json (2)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59478 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59478 +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:09.182+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print02.json (2)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:09 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:10.546+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print03.json (3) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59480 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59480 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:10.546+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print03.json (3) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:10.925+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print03.json (3)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59482 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59482 +Sep 12 09:04:10 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:10.925+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print03.json (3)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:11 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:12.291+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print04.json (4) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59484 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59484 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:12.291+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print04.json (4) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:12.649+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print04.json (4)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59486 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59486 +Sep 12 09:04:12 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:12.649+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print04.json (4)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:13 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:14.037+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print05.json (5) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59488 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59488 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:14.037+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print05.json (5) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:14.416+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print05.json (5)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59490 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59490 +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:14.416+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print05.json (5)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:14 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:15.791+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print06.json (6) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59492 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59492 +Sep 12 09:04:15 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:15.791+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print06.json (6) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:16.155+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print06.json (6)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59494 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59494 +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:16.155+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print06.json (6)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:16 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:17.512+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print07.json (7) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59496 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59496 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:17.512+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print07.json (7) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:17.889+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print07.json (7)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59498 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59498 +Sep 12 09:04:17 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:17.889+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print07.json (7)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:18 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:19.258+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print08.json (8) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59500 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59500 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:19.258+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print08.json (8) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:19.628+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print08.json (8)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59502 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59502 +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:19.628+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print08.json (8)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:19 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:20 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:20.993+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print31.json (31) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59504 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59504 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:20.993+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print31.json (31) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:21.366+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print31.json (31)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59506 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59506 +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:21.366+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print31.json (31)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:21 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:22.740+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE\",\"STEP_RESULT\" : \"LOADED DC2C_print32.json (32) TO DC\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59508 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59508 +Sep 12 09:04:22 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:22.740+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE","STEP_RESULT" : "LOADED DC2C_print32.json (32) TO DC","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:23.103+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 70,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS\",\"STEP_RESULT\" : \"DL:DC2C_print32.json (32)\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59510 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59510 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:23.103+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 70,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS","STEP_RESULT" : "DL:DC2C_print32.json (32)","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SET AUTO-REQUEST=TRUE +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: "DONE" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:23.471+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0010\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 88,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE\",\"STEP_RESULT\" : \"DONE\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59512 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59512 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:23.471+02:00","EVENT_ID":"0","EVENT":"U0010","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 88,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE","STEP_RESULT" : "DONE","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::UPDATE_SUCCEEDED" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:23.848+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0001\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 100,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::UPDATE_FINALIZE\",\"STEP_RESULT\" : \"UPDATE_STEP::UPDATE_SUCCEEDED\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59514 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59514 +Sep 12 09:04:23 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:23.848+02:00","EVENT_ID":"0","EVENT":"U0001","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 100,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::UPDATE_FINALIZE","STEP_RESULT" : "UPDATE_STEP::UPDATE_SUCCEEDED","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::UPDATE_ACTIVATED" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_EVENT#J={\"REASON\":\"SW_UP\",\"TIMESTAMP\":\"2024-09-12T09:04:24.223+02:00\",\"EVENT_ID\":\"0\",\"EVENT\":\"U0002\",\"EVENTSTATE\":1,\"PARAMETER\": {\"PERCENT\" : 100,\"RESULTCODE\" : 0,\"STEP\" : \"UPDATE_STEP::UPDATE_FINALIZE\",\"STEP_RESULT\" : \"UPDATE_STEP::UPDATE_ACTIVATED\",\"VERSION\" : \"c2c872a\"}}" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59516 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59516 +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_EVENT#J={"REASON":"SW_UP","TIMESTAMP":"2024-09-12T09:04:24.223+02:00","EVENT_ID":"0","EVENT":"U0002","EVENTSTATE":1,"PARAMETER": {"PERCENT" : 100,"RESULTCODE" : 0,"STEP" : "UPDATE_STEP::UPDATE_FINALIZE","STEP_RESULT" : "UPDATE_STEP::UPDATE_ACTIVATED","VERSION" : "c2c872a"}}>>> +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: "UPDATE_STEP::FINISHED" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: "DC2c_oct2022 PO2e_nov2022\x00" "DC2c.7.26 09.09.2024\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: CURRENT DC-HW-VERSION: "DC2c_oct2022 PO2e_nov2022" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: CURRENT DC-SW-VERSION: "DC2c.7.26 09.09.2024" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_tariff/tariff02.json" "(runtime 25ms)" with code 0 IN "/tmp" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 54ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 69ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 40ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_249" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 70ms)" with code 0 IN "/tmp" +Sep 12 09:04:24 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "bash" "(runtime 119ms)" with code 0 IN "/opt/app/tools/atbupdate/" +Sep 12 09:04:25 ATB_PTU5 ATBUpdateTool[360]: json request nr: 1 +Sep 12 09:04:25 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_conf.json" +Sep 12 09:04:25 ATB_PTU5 ATBUpdateTool[360]: json request nr: 3 +Sep 12 09:04:25 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_cash.json" +Sep 12 09:04:25 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: json request nr: 2 +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_device.json" +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.2-2024-07-24" +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: json request nr: 6 +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print01.json" +Sep 12 09:04:26 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: json request nr: 7 +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print02.json" +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: json request nr: 8 +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print03.json" +Sep 12 09:04:27 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:28 ATB_PTU5 ATBUpdateTool[360]: json request nr: 9 +Sep 12 09:04:28 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print04.json" +Sep 12 09:04:28 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: json request nr: 10 +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print05.json" +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: json request nr: 11 +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print06.json" +Sep 12 09:04:29 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: json request nr: 12 +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print07.json" +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: json request nr: 13 +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print08.json" +Sep 12 09:04:30 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:31 ATB_PTU5 ATBUpdateTool[360]: json request nr: 14 +Sep 12 09:04:31 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print09.json" +Sep 12 09:04:31 ATB_PTU5 ATBUpdateTool[360]: json request nr: 15 +Sep 12 09:04:31 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print10.json" +Sep 12 09:04:32 ATB_PTU5 ATBUpdateTool[360]: json request nr: 16 +Sep 12 09:04:32 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print11.json" +Sep 12 09:04:32 ATB_PTU5 ATBUpdateTool[360]: json request nr: 17 +Sep 12 09:04:32 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print12.json" +Sep 12 09:04:33 ATB_PTU5 ATBUpdateTool[360]: json request nr: 18 +Sep 12 09:04:33 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print13.json" +Sep 12 09:04:33 ATB_PTU5 ATBUpdateTool[360]: json request nr: 19 +Sep 12 09:04:33 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print14.json" +Sep 12 09:04:34 ATB_PTU5 ATBUpdateTool[360]: json request nr: 20 +Sep 12 09:04:34 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print15.json" +Sep 12 09:04:34 ATB_PTU5 ATBUpdateTool[360]: json request nr: 21 +Sep 12 09:04:34 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print16.json" +Sep 12 09:04:35 ATB_PTU5 ATBUpdateTool[360]: json request nr: 22 +Sep 12 09:04:35 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print17.json" +Sep 12 09:04:35 ATB_PTU5 ATBUpdateTool[360]: json request nr: 23 +Sep 12 09:04:35 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print18.json" +Sep 12 09:04:36 ATB_PTU5 ATBUpdateTool[360]: json request nr: 24 +Sep 12 09:04:36 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print19.json" +Sep 12 09:04:36 ATB_PTU5 ATBUpdateTool[360]: json request nr: 25 +Sep 12 09:04:36 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print20.json" +Sep 12 09:04:37 ATB_PTU5 ATBUpdateTool[360]: json request nr: 26 +Sep 12 09:04:37 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print21.json" +Sep 12 09:04:37 ATB_PTU5 ATBUpdateTool[360]: json request nr: 27 +Sep 12 09:04:37 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print22.json" +Sep 12 09:04:38 ATB_PTU5 ATBUpdateTool[360]: json request nr: 28 +Sep 12 09:04:38 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print23.json" +Sep 12 09:04:38 ATB_PTU5 ATBUpdateTool[360]: json request nr: 29 +Sep 12 09:04:38 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print24.json" +Sep 12 09:04:39 ATB_PTU5 ATBUpdateTool[360]: json request nr: 30 +Sep 12 09:04:39 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print25.json" +Sep 12 09:04:39 ATB_PTU5 ATBUpdateTool[360]: json request nr: 31 +Sep 12 09:04:39 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print26.json" +Sep 12 09:04:40 ATB_PTU5 ATBUpdateTool[360]: json request nr: 32 +Sep 12 09:04:40 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print27.json" +Sep 12 09:04:40 ATB_PTU5 ATBUpdateTool[360]: json request nr: 33 +Sep 12 09:04:40 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print28.json" +Sep 12 09:04:41 ATB_PTU5 ATBUpdateTool[360]: json request nr: 34 +Sep 12 09:04:41 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print29.json" +Sep 12 09:04:41 ATB_PTU5 ATBUpdateTool[360]: json request nr: 35 +Sep 12 09:04:41 ATB_PTU5 ATBUpdateTool[360]: unknown json file (repo and DC): "DC2C_print30.json" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: json request nr: 36 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print31.json" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "6.7.1-2024-07-24" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: json request nr: 37 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: json file: "DC2C_print32.json" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: installed version in DC: "" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: file version in repository: "6.7.1-2024-07-24" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_cash.json" "(runtime 21ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_device.json" "(runtime 8ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print01.json" "(runtime 22ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print02.json" "(runtime 18ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print03.json" "(runtime 17ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print04.json" "(runtime 9ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print05.json" "(runtime 8ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print06.json" "(runtime 17ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print07.json" "(runtime 9ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print08.json" "(runtime 8ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print31.json" "(runtime 9ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: EXECUTED "git hash-object /etc/psa_config/DC2C_print32.json" "(runtime 9ms)" with code 0 IN "/tmp" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: {"VERSION_INFO" : {"REASON":"Add application config ATBAPP.ini","CREATED":"2024-09-11T18:05:46+02:00","HASH":"c2c872a"},"TARIFF" : {"VERSION" : "1.0.4","PROJECT" : "SV Bad Neuenahr","ZONE" : 2,"INFO" : "Standard","BLOB" : "879a4f6dce8d2c0d016af011213840dda105a78a","LAST-COMMIT" : "9e27cfe163b5a19acb38798ca24ab50e2a27e2a","SIZE" : 15346,"LOADED" : "2024-09-12T09:02:39.000"},"OPKG_COMMANDS" : {"BLOB" : "N/A","LAST-COMMIT" : "c2c4a686905ba6cfa7c16ecc11d5c2f378f94c4","SIZE" : -1,"LOADED" : "N/A"},"JSON" : {"DC2C_CASH" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 514},"DC2C_CONF" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_DEVICE" : {"BLOB" : "6.7.2-2024-07-24","SIZE" : 559},"DC2C_PRINT_01" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 662},"DC2C_PRINT_02" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 369},"DC2C_PRINT_03" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 509},"DC2C_PRINT_04" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 101},"DC2C_PRINT_05" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 660},"DC2C_PRINT_06" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 371},"DC2C_PRINT_07" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 509},"DC2C_PRINT_08" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 101},"DC2C_PRINT_09" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_10" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_11" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_12" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_13" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_14" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_15" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_16" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_17" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_18" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_19" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_20" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_21" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_22" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_23" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_24" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_25" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_26" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_27" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_28" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_29" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_30" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_31" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 719},"DC2C_PRINT_32" : {"BLOB" : "","SIZE" : 733}},"HARDWARE" : {"DEVICES" : ["PTU5", "DC", "PRINTER", "BNA"]},"OS" : {"Linux": "i.MX6-thud-PCM058-KSP30-ATB-PTU5-2024-08-23"},"CONFIG" : {"PTU5" : {"CPU_SERIAL" : "da2cc15d130541d4"},"DC" : {"HW-VERSION" : "DC2c_oct2022 PO2e_nov2022","SW-VERSION" : "DC2c.7.26 09.09.2024","SIZE" : -1,"GITBLOB" : "N/A","GITLASTCOMMIT" : "N/A"},"PRINTER" : {},"BNA" : {}},"SOFTWARE": {"APISM" : {"VERSION" : "1.5.1-r0"},"ATBQT" : {"VERSION" : "6.5.3-2-gc20e9fad_00249_20240911-1219"},"ATB-UPDATE-TOOL" : {"VERSION" : "1.5.1-0d00faf493047c773864055bbd11b402b74f9f59"}},"PLUGINS" : {"libATBDeviceControllerPlugin.so" : {"VERSION" : "20240823_0644"},"libIngenicoISelf_CCPlugin.so" : {"VERSION" : "20240729_1246"},"libMOBILISIS_CalculatePricePlugin.so" : {"VERSION" : "20240906_1011"},"libMOBILISIS_CalculatePricePlugin_ConfigUi.so" : {"VERSION" : "20240906_1011"},"libPRM_CalculatePricePlugin.so" : {"VERSION" : "20240702_1450"},"libPRM_CalculatePricePlugin_ConfigUi.so" : {"VERSION" : "20240702_1450"},"libTCP_ZVT_CCPlugin.so" : {"VERSION" : "20240805_1418"}}} +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: REQUEST "#M=APISM#C=CMD_SENDVERSION#J={\"VERSION_INFO\" : {\"REASON\":\"Add application config ATBAPP.ini\",\"CREATED\":\"2024-09-11T18:05:46+02:00\",\"HASH\":\"c2c872a\"},\"TARIFF\" : {\"VERSION\" : \"1.0.4\",\"PROJECT\" : \"SV Bad Neuenahr\",\"ZONE\" : 2,\"INFO\" : \"Standard\",\"BLOB\" : \"879a4f6dce8d2c0d016af011213840dda105a78a\",\"LAST-COMMIT\" : \"9e27cfe163b5a19acb38798ca24ab50e2a27e2a\",\"SIZE\" : 15346,\"LOADED\" : \"2024-09-12T09:02:39.000\"},\"OPKG_COMMANDS\" : {\"BLOB\" : \"N/A\",\"LAST-COMMIT\" : \"c2c4a686905ba6cfa7c16ecc11d5c2f378f94c4\",\"SIZE\" : -1,\"LOADED\" : \"N/A\"},\"JSON\" : {\"DC2C_CASH\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 514},\"DC2C_CONF\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_DEVICE\" : {\"BLOB\" : \"6.7.2-2024-07-24\",\"SIZE\" : 559},\"DC2C_PRINT_01\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 662},\"DC2C_PRINT_02\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 369},\"DC2C_PRINT_03\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 509},\"DC2C_PRINT_04\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 101},\"DC2C_PRINT_05\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 660},\"DC2C_PRINT_06\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 371},\"DC2C_PRINT_07\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 509},\"DC2C_PRINT_08\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 101},\"DC2C_PRINT_09\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_10\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_11\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_12\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_13\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_14\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_15\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_16\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_17\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_18\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_19\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_20\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_21\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_22\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_23\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_24\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_25\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_26\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_27\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_28\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_29\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_30\" : {\"BLOB\" : \"inst.vers.not.avail\",\"SIZE\" : -1},\"DC2C_PRINT_31\" : {\"BLOB\" : \"6.7.1-2024-07-24\",\"SIZE\" : 719},\"DC2C_PRINT_32\" : {\"BLOB\" : \"\",\"SIZE\" : 733}},\"HARDWARE\" : {\"DEVICES\" : [\"PTU5\", \"DC\", \"PRINTER\", \"BNA\"]},\"OS\" : {\"Linux\": \"i.MX6-thud-PCM058-KSP30-ATB-PTU5-2024-08-23\"},\"CONFIG\" : {\"PTU5\" : {\"CPU_SERIAL\" : \"da2cc15d130541d4\"},\"DC\" : {\"HW-VERSION\" : \"DC2c_oct2022 PO2e_nov2022\",\"SW-VERSION\" : \"DC2c.7.26 09.09.2024\",\"SIZE\" : -1,\"GITBLOB\" : \"N/A\",\"GITLASTCOMMIT\" : \"N/A\"},\"PRINTER\" : {},\"BNA\" : {}},\"SOFTWARE\": {\"APISM\" : {\"VERSION\" : \"1.5.1-r0\"},\"ATBQT\" : {\"VERSION\" : \"6.5.3-2-gc20e9fad_00249_20240911-1219\"},\"ATB-UPDATE-TOOL\" : {\"VERSION\" : \"1.5.1-0d00faf493047c773864055bbd11b402b74f9f59\"}},\"PLUGINS\" : {\"libATBDeviceControllerPlugin.so\" : {\"VERSION\" : \"20240823_0644\"},\"libIngenicoISelf_CCPlugin.so\" : {\"VERSION\" : \"20240729_1246\"},\"libMOBILISIS_CalculatePricePlugin.so\" : {\"VERSION\" : \"20240906_1011\"},\"libMOBILISIS_CalculatePricePlugin_ConfigUi.so\" : {\"VERSION\" : \"20240906_1011\"},\"libPRM_CalculatePricePlugin.so\" : {\"VERSION\" : \"20240702_1450\"},\"libPRM_CalculatePricePlugin_ConfigUi.so\" : {\"VERSION\" : \"20240702_1450\"},\"libTCP_ZVT_CCPlugin.so\" : {\"VERSION\" : \"20240805_1418\"}}}" +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59518 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: CONNECTED TO SERVER +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: SEND-REQUEST-RECEIVE-RESPONSE ... +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: hostname ........ 127.0.0.1 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: port ............ 7777 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: local address ... 127.0.0.1 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: local port ...... 59518 +Sep 12 09:04:42 ATB_PTU5 ATBUpdateTool[360]: MESSAGE SENT <<<#M=APISM#C=CMD_SENDVERSION#J={"VERSION_INFO" : {"REASON":"Add application config ATBAPP.ini","CREATED":"2024-09-11T18:05:46+02:00","HASH":"c2c872a"},"TARIFF" : {"VERSION" : "1.0.4","PROJECT" : "SV Bad Neuenahr","ZONE" : 2,"INFO" : "Standard","BLOB" : "879a4f6dce8d2c0d016af011213840dda105a78a","LAST-COMMIT" : "9e27cfe163b5a19acb38798ca24ab50e2a27e2a","SIZE" : 15346,"LOADED" : "2024-09-12T09:02:39.000"},"OPKG_COMMANDS" : {"BLOB" : "N/A","LAST-COMMIT" : "c2c4a686905ba6cfa7c16ecc11d5c2f378f94c4","SIZE" : -1,"LOADED" : "N/A"},"JSON" : {"DC2C_CASH" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 514},"DC2C_CONF" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_DEVICE" : {"BLOB" : "6.7.2-2024-07-24","SIZE" : 559},"DC2C_PRINT_01" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 662},"DC2C_PRINT_02" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 369},"DC2C_PRINT_03" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 509},"DC2C_PRINT_04" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 101},"DC2C_PRINT_05" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 660},"DC2C_PRINT_06" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 371},"DC2C_PRINT_07" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 509},"DC2C_PRINT_08" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 101},"DC2C_PRINT_09" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_10" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_11" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_12" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_13" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_14" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_15" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_16" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_17" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_18" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_19" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_20" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_21" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_22" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_23" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_24" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_25" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_26" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_27" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_28" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_29" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_30" : {"BLOB" : "inst.vers.not.avail","SIZE" : -1},"DC2C_PRINT_31" : {"BLOB" : "6.7.1-2024-07-24","SIZE" : 719},"DC2C_PRINT_32" : {"BLOB" : "","SIZE" : 733}},"HARDWARE" : {"DEVICES" : ["PTU5", "DC", "PRINTER", "BNA"]},"OS" : {"Linux": "i.MX6-thud-PCM058-KSP30-ATB-PTU5-2024-08-23"},"CONFIG" : {"PTU5" : {"CPU_SERIAL" : "da2cc15d130541d4"},"DC" : {"HW-VERSION" : "DC2c_oct2022 PO2e_nov2022","SW-VERSION" : "DC2c.7.26 09.09.2024","SIZE" : -1,"GITBLOB" : "N/A","GITLASTCOMMIT" : "N/A"},"PRINTER" : {},"BNA" : {}},"SOFTWARE": {"APISM" : {"VERSION" : "1.5.1-r0"},"ATBQT" : {"VERSION" : "6.5.3-2-gc20e9fad_00249_20240911-1219"},"ATB-UPDATE-TOOL" : {"VERSION" : "1.5.1-0d00faf493047c773864055bbd11b402b74f9f59"}},"PLUGINS" : {"libATBDeviceControllerPlugin.so" : {"VERSION" : "20240823_0644"},"libIngenicoISelf_CCPlugin.so" : {"VERSION" : "20240729_1246"},"libMOBILISIS_CalculatePricePlugin.so" : {"VERSION" : "20240906_1011"},"libMOBILISIS_CalculatePricePlugin_ConfigUi.so" : {"VERSION" : "20240906_1011"},"libPRM_CalculatePricePlugin.so" : {"VERSION" : "20240702_1450"},"libPRM_CalculatePricePlugin_ConfigUi.so" : {"VERSION" : "20240702_1450"},"libTCP_ZVT_CCPlugin.so" : {"VERSION" : "20240805_1418"}}}>>> +Sep 12 09:04:45 ATB_PTU5 ATBUpdateTool[360]: "ON QUIT: CURRENT STEP UPDATE_STEP::UPDATE_FINALIZE" +Sep 12 09:04:45 ATB_PTU5 ATBUpdateTool[360]: "ON QUIT: EXIT CODE 0" diff --git a/script.sql b/script.sql new file mode 100644 index 0000000..75f20ac --- /dev/null +++ b/script.sql @@ -0,0 +1,296 @@ +/****** Object: User [atb_tariff_api] Script Date: 11.12.2023. 14:30:40 ******/ +CREATE USER [atb_tariff_api] FOR LOGIN [atb_tariff_api] WITH DEFAULT_SCHEMA=[dbo] +GO +ALTER ROLE [db_owner] ADD MEMBER [atb_tariff_api] +GO +ALTER ROLE [db_datareader] ADD MEMBER [atb_tariff_api] +GO +ALTER ROLE [db_datawriter] ADD MEMBER [atb_tariff_api] +GO +/****** Object: Table [dbo].[city] Script Date: 11.12.2023. 14:30:40 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[city]( + [cty_id] [int] IDENTITY(1,1) NOT NULL, + [cty_label] [nvarchar](50) NOT NULL, + [cty_delete_date] [datetimeoffset](7) NULL, + CONSTRAINT [PK_city] PRIMARY KEY CLUSTERED +( + [cty_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[payment_currency] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[payment_currency]( + [pcu_id] [int] IDENTITY(1,1) NOT NULL, + [pcu_sign] [nvarchar](50) NOT NULL, + [pcu_major] [nvarchar](50) NOT NULL, + [pcu_minor] [nvarchar](50) NULL, + [pcu_active] [bit] NOT NULL, + CONSTRAINT [PK_payment_currency] PRIMARY KEY CLUSTERED +( + [pcu_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[payment_method] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[payment_method]( + [pme_id] [int] IDENTITY(1,1) NOT NULL, + [pme_label] [nvarchar](50) NOT NULL, + CONSTRAINT [PK_payment_method] PRIMARY KEY CLUSTERED +( + [pme_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[payment_option] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[payment_option]( + [pop_id] [int] IDENTITY(1,1) NOT NULL, + [pop_label] [nvarchar](50) NOT NULL, + [pop_payment_method_id] [int] NOT NULL, + [pop_day_end_time] [time](7) NOT NULL, + [pop_day_night_end_time] [time](7) NOT NULL, + [pop_price_night] [float] NULL, + [pop_min_time] [int] NULL, + [pop_max_time] [int] NULL, + [pop_min_price] [decimal](18, 0) NULL, + [pop_carry_over] [bit] NULL, + [pop_period_week_id] [int] NULL, + [pop_currency_id] [int] NULL, + [pop_daily_card_price] [int] NULL, + [pop_city_id] [int] NULL, + [pop_multi_hour_price] [float] NULL, + CONSTRAINT [PK_payment_option] PRIMARY KEY CLUSTERED +( + [pop_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[payment_rate] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[payment_rate]( + [pra_id] [int] IDENTITY(1,1) NOT NULL, + [pra_payment_option_id] [int] NOT NULL, + [pra_payment_unit_id] [int] NOT NULL, + [pra_price] [float] NOT NULL, + [pra_currency_id] [int] NULL, + CONSTRAINT [PK_payment_rate_1] PRIMARY KEY CLUSTERED +( + [pra_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[payment_unit] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[payment_unit]( + [pun_id] [int] IDENTITY(1,1) NOT NULL, + [pun_label] [nvarchar](50) NOT NULL, + [pun_duration] [int] NOT NULL, + CONSTRAINT [PK_payment_unit] PRIMARY KEY CLUSTERED +( + [pun_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_day_in_week] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_day_in_week]( + [pdiw_id] [tinyint] IDENTITY(1,1) NOT NULL, + [pdiw_label] [nvarchar](50) NOT NULL, + [pdiw_index] [tinyint] NOT NULL, + [pdiw_index_device] [tinyint] NOT NULL, + CONSTRAINT [PK_period_day_in_week] PRIMARY KEY CLUSTERED +( + [pdiw_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_exceptional_day_work_time] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_exceptional_day_work_time]( + [pedwt_id] [int] IDENTITY(1,1) NOT NULL, + [pedwt_period_exc_day_id] [int] NOT NULL, + [pedwt_time_from] [time](7) NOT NULL, + [pedwt_time_to] [time](7) NOT NULL, + [pedwt_price] [float] NOT NULL, + [pedwt_currency_id] [int] NULL, + CONSTRAINT [PK_period_exceptional_day_work_time] PRIMARY KEY CLUSTERED +( + [pedwt_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_exceptional_days] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_exceptional_days]( + [ped_id] [int] IDENTITY(1,1) NOT NULL, + [ped_label] [nvarchar](50) NOT NULL, + [ped_date_start] [date] NOT NULL, + [ped_date_end] [date] NOT NULL, + [ped_period_special_day_id] [int] NOT NULL, + [ped_year] [int] NULL, + [ped_city_id] [int] NULL, + CONSTRAINT [PK_period_exceptional_days] PRIMARY KEY CLUSTERED +( + [ped_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_special_days] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_special_days]( + [psd_id] [int] IDENTITY(1,1) NOT NULL, + [psd_label] [nvarchar](50) NOT NULL, + [psd_chargeable] [bit] NOT NULL, + [psd_priority] [tinyint] NOT NULL, + CONSTRAINT [PK_period_special_days] PRIMARY KEY CLUSTERED +( + [psd_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_week] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_week]( + [pwe_id] [int] IDENTITY(1,1) NOT NULL, + [pwe_label] [nvarchar](150) NOT NULL, + [pwe_period_year_id] [int] NOT NULL, + [pwe_city_id] [int] NULL, + CONSTRAINT [PK_period_week] PRIMARY KEY CLUSTERED +( + [pwe_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_week_day] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_week_day]( + [pwd_id] [int] IDENTITY(1,1) NOT NULL, + [pwd_period_week_day_id] [int] NOT NULL, + [pwd_period_day_in_week_id] [tinyint] NOT NULL, + [pwd_time_from] [time](7) NOT NULL, + [pwd_time_to] [time](7) NOT NULL, + [pwd_ui_group] [int] NULL, + CONSTRAINT [PK_period_week_day] PRIMARY KEY CLUSTERED +( + [pwd_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +/****** Object: Table [dbo].[period_year] Script Date: 11.12.2023. 14:30:41 ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE TABLE [dbo].[period_year]( + [pye_id] [int] IDENTITY(1,1) NOT NULL, + [pye_label] [nvarchar](50) NOT NULL, + [pye_start_month] [int] NOT NULL, + [pye_start_day] [int] NOT NULL, + [pye_end_month] [int] NOT NULL, + [pye_end_day] [int] NOT NULL, + [pye_city_id] [int] NULL, + CONSTRAINT [PK_period_year] PRIMARY KEY CLUSTERED +( + [pye_id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +GO +ALTER TABLE [dbo].[payment_option] WITH CHECK ADD CONSTRAINT [FK_payment_option_payment_currency] FOREIGN KEY([pop_currency_id]) +REFERENCES [dbo].[payment_currency] ([pcu_id]) +GO +ALTER TABLE [dbo].[payment_option] CHECK CONSTRAINT [FK_payment_option_payment_currency] +GO +ALTER TABLE [dbo].[payment_option] WITH CHECK ADD CONSTRAINT [FK_payment_option_payment_method] FOREIGN KEY([pop_payment_method_id]) +REFERENCES [dbo].[payment_method] ([pme_id]) +GO +ALTER TABLE [dbo].[payment_option] CHECK CONSTRAINT [FK_payment_option_payment_method] +GO +ALTER TABLE [dbo].[payment_option] WITH CHECK ADD CONSTRAINT [FK_payment_option_period_week] FOREIGN KEY([pop_period_week_id]) +REFERENCES [dbo].[period_week] ([pwe_id]) +GO +ALTER TABLE [dbo].[payment_option] CHECK CONSTRAINT [FK_payment_option_period_week] +GO +ALTER TABLE [dbo].[payment_rate] WITH CHECK ADD CONSTRAINT [FK_payment_rate_payment_currency] FOREIGN KEY([pra_currency_id]) +REFERENCES [dbo].[payment_currency] ([pcu_id]) +GO +ALTER TABLE [dbo].[payment_rate] CHECK CONSTRAINT [FK_payment_rate_payment_currency] +GO +ALTER TABLE [dbo].[payment_rate] WITH CHECK ADD CONSTRAINT [FK_payment_rate_payment_option] FOREIGN KEY([pra_payment_option_id]) +REFERENCES [dbo].[payment_option] ([pop_id]) +GO +ALTER TABLE [dbo].[payment_rate] CHECK CONSTRAINT [FK_payment_rate_payment_option] +GO +ALTER TABLE [dbo].[payment_rate] WITH CHECK ADD CONSTRAINT [FK_payment_rate_payment_unit] FOREIGN KEY([pra_payment_unit_id]) +REFERENCES [dbo].[payment_unit] ([pun_id]) +GO +ALTER TABLE [dbo].[payment_rate] CHECK CONSTRAINT [FK_payment_rate_payment_unit] +GO +ALTER TABLE [dbo].[period_exceptional_day_work_time] WITH CHECK ADD CONSTRAINT [FK_period_exceptional_day_work_time_payment_currency] FOREIGN KEY([pedwt_currency_id]) +REFERENCES [dbo].[payment_currency] ([pcu_id]) +GO +ALTER TABLE [dbo].[period_exceptional_day_work_time] CHECK CONSTRAINT [FK_period_exceptional_day_work_time_payment_currency] +GO +ALTER TABLE [dbo].[period_exceptional_day_work_time] WITH CHECK ADD CONSTRAINT [FK_period_exceptional_day_work_time_period_exceptional_days] FOREIGN KEY([pedwt_period_exc_day_id]) +REFERENCES [dbo].[period_exceptional_days] ([ped_id]) +GO +ALTER TABLE [dbo].[period_exceptional_day_work_time] CHECK CONSTRAINT [FK_period_exceptional_day_work_time_period_exceptional_days] +GO +ALTER TABLE [dbo].[period_exceptional_days] WITH CHECK ADD CONSTRAINT [FK_period_exceptional_days_period_special_days] FOREIGN KEY([ped_period_special_day_id]) +REFERENCES [dbo].[period_special_days] ([psd_id]) +GO +ALTER TABLE [dbo].[period_exceptional_days] CHECK CONSTRAINT [FK_period_exceptional_days_period_special_days] +GO +ALTER TABLE [dbo].[period_week] WITH CHECK ADD CONSTRAINT [FK_period_week_period_year] FOREIGN KEY([pwe_period_year_id]) +REFERENCES [dbo].[period_year] ([pye_id]) +GO +ALTER TABLE [dbo].[period_week] CHECK CONSTRAINT [FK_period_week_period_year] +GO +ALTER TABLE [dbo].[period_week_day] WITH CHECK ADD CONSTRAINT [FK_period_week_day_period_day_in_week] FOREIGN KEY([pwd_period_day_in_week_id]) +REFERENCES [dbo].[period_day_in_week] ([pdiw_id]) +GO +ALTER TABLE [dbo].[period_week_day] CHECK CONSTRAINT [FK_period_week_day_period_day_in_week] +GO +ALTER TABLE [dbo].[period_week_day] WITH CHECK ADD CONSTRAINT [FK_period_week_day_period_week] FOREIGN KEY([pwd_period_week_day_id]) +REFERENCES [dbo].[period_week] ([pwe_id]) +GO +ALTER TABLE [dbo].[period_week_day] CHECK CONSTRAINT [FK_period_week_day_period_week] +GO diff --git a/script_data.sql b/script_data.sql new file mode 100644 index 0000000..9b8765a --- /dev/null +++ b/script_data.sql @@ -0,0 +1,760 @@ +SET IDENTITY_INSERT [dbo].[payment_currency] ON + +INSERT [dbo].[payment_currency] ([pcu_id], [pcu_sign], [pcu_major], [pcu_minor], [pcu_active]) VALUES (1, N'€', N'Euro', N'Cent', 1) +INSERT [dbo].[payment_currency] ([pcu_id], [pcu_sign], [pcu_major], [pcu_minor], [pcu_active]) VALUES (2, N'Ft', N'HUF', NULL, 1) +SET IDENTITY_INSERT [dbo].[payment_currency] OFF +SET IDENTITY_INSERT [dbo].[payment_method] ON + +INSERT [dbo].[payment_method] ([pme_id], [pme_label]) VALUES (1, N'progressive') +INSERT [dbo].[payment_method] ([pme_id], [pme_label]) VALUES (2, N'degressive') +INSERT [dbo].[payment_method] ([pme_id], [pme_label]) VALUES (3, N'linear') +INSERT [dbo].[payment_method] ([pme_id], [pme_label]) VALUES (4, N'steps') +SET IDENTITY_INSERT [dbo].[payment_method] OFF +SET IDENTITY_INSERT [dbo].[period_year] ON + +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (8, N'Whole year', 1, 1, 12, 31, 2) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (9, N'Whole year', 1, 1, 12, 31, 1) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (10, N'Whole year', 1, 1, 12, 31, 3) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (11, N'Whole Year', 1, 1, 12, 31, 4) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (12, N'Whole Year', 1, 1, 12, 31, 5) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (13, N'Whole Year', 1, 1, 12, 31, 2) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (14, N'Whole Year', 1, 1, 12, 31, 1) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (15, N'Whole year', 1, 1, 12, 31, 6) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (17, N'Whole year', 1, 1, 12, 31, 7) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (18, N'Whole Year', 1, 1, 12, 31, 7) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (19, N'Whole year', 1, 1, 12, 31, 9) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (20, N'Whole Year', 1, 1, 12, 31, 9) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (21, N'Whole year', 1, 1, 12, 31, 9) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (22, N'Whole Year', 1, 1, 12, 31, 9) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (23, N'Whole year', 1, 1, 12, 31, 10) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (24, N'Whole Year', 1, 1, 12, 31, 10) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (25, N'Whole year', 1, 1, 12, 31, 11) +INSERT [dbo].[period_year] ([pye_id], [pye_label], [pye_start_month], [pye_start_day], [pye_end_month], [pye_end_day], [pye_city_id]) VALUES (26, N'Whole Year', 1, 1, 12, 31, 11) +SET IDENTITY_INSERT [dbo].[period_year] OFF +SET IDENTITY_INSERT [dbo].[period_week] ON + +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (16, N'HU Mon Fri 8-18, Sat 8-14', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (17, N'HU Mon Wed Fri 6:30-18, Tue, Thu 13-18 Sat 13-14', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (18, N'Mo. - Fr. 8-18, Sa. 8-12', 9, 1) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (19, N'Montag-Freitag: 6:30-18:00, Samstag: 6:30-14:00 ', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (31, N'Monday - Friday: 08:00-18:00, Saturday: 14:00 - Monday 8:00', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (32, N'Szeged, Mon-Fri: 8:00-18:00', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (33, N'Szeged, Mon-Fri 8:00-18:00, Sat 8:00-12:00', 8, 2) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (34, N'Pon-pet 8-18, Sub 8-12', 10, 3) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (35, N'24/7', 11, 4) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (36, N'Mon-Fri 8:00 - 18:00 ', 12, 5) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (37, N'Mon - Fri 8:00 18:00; Sat 8:00 - 12:00', 12, 5) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (39, N'24/7', 14, 1) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (40, N'HU Mon Fri 8-18, Sat 8-14', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (41, N'HU Mon Wed Fri 6:30-18, Tue, Thu 13-18 Sat 13-14', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (42, N'Montag-Freitag: 6:30-18:00, Samstag: 6:30-14:00 ', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (43, N'Monday - Friday: 08:00-18:00, Saturday: 14:00 - Monday 8:00', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (44, N'Szeged, Mon-Fri: 8:00-18:00', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (45, N'Szeged, Mon-Fri 8:00-18:00, Sat 8:00-12:00', 15, 6) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (46, N'HU Mon Fri 8-18, Sat 8-14', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (47, N'HU Mon Wed Fri 6:30-18, Tue, Thu 13-18 Sat 13-14', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (48, N'Montag-Freitag: 6:30-18:00, Samstag: 6:30-14:00 ', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (49, N'Monday - Friday: 08:00-18:00, Saturday: 14:00 - Monday 8:00', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (50, N'Szeged, Mon-Fri: 8:00-18:00', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (51, N'Szeged, Mon-Fri 8:00-18:00, Sat 8:00-12:00', 17, 7) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (52, N'HU Mon Fri 8-18, Sat 8-14', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (53, N'HU Mon Wed Fri 6:30-18, Tue, Thu 13-18 Sat 13-14', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (54, N'Montag-Freitag: 6:30-18:00, Samstag: 6:30-14:00 ', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (55, N'Monday - Friday: 08:00-18:00, Saturday: 14:00 - Monday 8:00', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (56, N'Szeged, Mon-Fri: 8:00-18:00', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (57, N'Szeged, Mon-Fri 8:00-18:00, Sat 8:00-12:00', 19, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (58, N'Mo. - Fr. 8-18, Sa. 8-12', 21, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (59, N'24/7', 22, 9) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (60, N'Mo. - Fr. 8-18, Sa. 8-12', 23, 10) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (61, N'24/7', 24, 10) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (62, N'HU Mon Fri 8-18, Sat 8-14', 25, 11) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (63, N'HU Mon Wed Fri 6:30-18, Tue, Thu 13-18 Sat 13-14', 25, 11) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (64, N'Montag-Freitag: 6:30-18:00, Samstag: 6:30-14:00 ', 25, 11) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (65, N'Monday - Friday: 08:00-18:00, Saturday: 14:00 - Monday 8:00', 25, 11) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (66, N'Szeged, Mon-Fri: 8:00-18:00', 25, 11) +INSERT [dbo].[period_week] ([pwe_id], [pwe_label], [pwe_period_year_id], [pwe_city_id]) VALUES (67, N'Szeged, Mon-Fri 8:00-18:00, Sat 8:00-12:00', 25, 11) +SET IDENTITY_INSERT [dbo].[period_week] OFF +SET IDENTITY_INSERT [dbo].[payment_option] ON + +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (17, N'Zone 1', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, 900, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (22, N'Zone 2', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (23, N'Zone 3', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, 0, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (24, N'Zone 4 - Marketplace ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (26, N'Zone 4', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (27, N'Zone 4 - Südstr.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 120, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (28, N'Zone 4- Zárda 2.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (29, N'Garage Parking - Day', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), NULL, 15, 0, CAST(75 AS Decimal(18, 0)), 1, 16, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (30, N'Garage Parking -Night ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(25 AS Decimal(18, 0)), NULL, 31, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1041, N'Szeged Test', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), NULL, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, NULL, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1045, N'Zone 1', 3, CAST(N'15:20:00' AS Time), CAST(N'15:20:00' AS Time), NULL, 0, 10080, CAST(3 AS Decimal(18, 0)), 1, 39, 1, 0, 1, 8) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1046, N'pojer teeest', 3, CAST(N'16:03:00' AS Time), CAST(N'16:03:00' AS Time), NULL, 0, 0, CAST(0 AS Decimal(18, 0)), 0, 18, 2, NULL, 3, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1047, N'VŽ Zone I', 3, CAST(N'15:20:00' AS Time), CAST(N'15:20:00' AS Time), NULL, 60, 0, CAST(0 AS Decimal(18, 0)), NULL, 32, 1, NULL, 3, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1048, N'Day Ticket', 3, CAST(N'16:01:00' AS Time), CAST(N'16:01:00' AS Time), NULL, 180, 0, CAST(1 AS Decimal(18, 0)), NULL, 35, 1, 12, 4, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1049, N'Zone Lila 1', 3, CAST(N'16:25:00' AS Time), CAST(N'16:25:00' AS Time), NULL, 15, 300, CAST(0 AS Decimal(18, 0)), 1, 36, 2, 900, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1050, N'Zone Blau 2', 3, CAST(N'16:27:00' AS Time), CAST(N'16:27:00' AS Time), NULL, 15, 300, CAST(0 AS Decimal(18, 0)), 1, 36, 2, 1320, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1051, N'Zone Gelb 3', 3, CAST(N'16:29:00' AS Time), CAST(N'16:29:00' AS Time), NULL, 15, 300, CAST(0 AS Decimal(18, 0)), 1, 36, 2, 1980, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1052, N'Zone Grün 4', 3, CAST(N'16:30:00' AS Time), CAST(N'16:30:00' AS Time), NULL, 15, 240, CAST(0 AS Decimal(18, 0)), 1, 36, 2, 2400, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1055, N'Zone 1', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, 900, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1056, N'Zone 2', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1057, N'Zone 3', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 33, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1058, N'Zone 4 - Marketplace ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1059, N'Zone 4', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1060, N'Zone 4 - Südstr.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 120, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1061, N'Zone 4- Zárda 2.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1062, N'Garage Parking - Day', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), NULL, 15, 0, CAST(75 AS Decimal(18, 0)), 1, 16, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1063, N'Garage Parking -Night ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(25 AS Decimal(18, 0)), NULL, 31, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1064, N'Szeged Test', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), NULL, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, NULL, 6, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1065, N'Kék (blau)', 3, CAST(N'12:52:00' AS Time), CAST(N'12:52:00' AS Time), NULL, 15, 360, CAST(58 AS Decimal(18, 0)), 1, 32, 2, 1320, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1066, N'Lila', 3, CAST(N'12:59:00' AS Time), CAST(N'12:59:00' AS Time), NULL, 15, 360, CAST(38 AS Decimal(18, 0)), 1, 32, 2, 900, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1067, N'Sárga (gelb)', 3, CAST(N'13:00:00' AS Time), CAST(N'13:00:00' AS Time), NULL, 15, 360, CAST(83 AS Decimal(18, 0)), 1, 33, 2, 900, 2, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1068, N'Zone 1', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, 900, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1069, N'Zone 2', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1070, N'Zone 3', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 33, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1071, N'Zone 4 - Marketplace ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1072, N'Zone 4', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1073, N'Zone 4 - Südstr.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 120, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1074, N'Zone 4- Zárda 2.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1075, N'Garage Parking - Day', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), NULL, 15, 0, CAST(75 AS Decimal(18, 0)), 1, 16, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1076, N'Garage Parking -Night ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(25 AS Decimal(18, 0)), NULL, 31, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1077, N'Szeged Test', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), NULL, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, NULL, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1078, N'Kék (blau)', 3, CAST(N'12:52:00' AS Time), CAST(N'12:52:00' AS Time), NULL, 15, 360, CAST(58 AS Decimal(18, 0)), 1, 32, 2, 1320, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1079, N'Lila', 3, CAST(N'12:59:00' AS Time), CAST(N'12:59:00' AS Time), NULL, 15, 360, CAST(38 AS Decimal(18, 0)), 1, 32, 2, 900, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1080, N'Sárga (gelb)', 3, CAST(N'13:00:00' AS Time), CAST(N'13:00:00' AS Time), NULL, 15, 360, CAST(83 AS Decimal(18, 0)), 1, 33, 2, 900, 7, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1081, N'Zone Gelb Mars 5', 3, CAST(N'15:08:00' AS Time), CAST(N'15:08:00' AS Time), NULL, 15, 360, CAST(83 AS Decimal(18, 0)), 1, 37, 2, 1980, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1082, N'Zone Grün Mars 6', 3, CAST(N'15:13:00' AS Time), CAST(N'15:13:00' AS Time), NULL, 15, 240, CAST(150 AS Decimal(18, 0)), 1, 37, 2, 2400, 5, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1083, N'Zone 1', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, 900, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1084, N'Zone 2', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1085, N'Zone 3', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, 0, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1086, N'Zone 4 - Marketplace ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1087, N'Zone 4', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 17, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1088, N'Zone 4 - Südstr.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 120, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1089, N'Zone 4- Zárda 2.', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(45 AS Decimal(18, 0)), 1, 19, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1090, N'Garage Parking - Day', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), NULL, 15, 0, CAST(75 AS Decimal(18, 0)), 1, 16, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1091, N'Garage Parking -Night ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(25 AS Decimal(18, 0)), NULL, 31, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1092, N'Szeged Test', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), NULL, 15, 10000, CAST(0 AS Decimal(18, 0)), 1, 32, 2, NULL, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1093, N'Kék (blau)', 3, CAST(N'12:52:00' AS Time), CAST(N'12:52:00' AS Time), NULL, 15, 360, CAST(58 AS Decimal(18, 0)), 1, 32, 2, 1320, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1094, N'Lila', 3, CAST(N'12:59:00' AS Time), CAST(N'12:59:00' AS Time), NULL, 15, 360, CAST(38 AS Decimal(18, 0)), 1, 32, 2, 900, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1095, N'Sárga (gelb)', 3, CAST(N'13:00:00' AS Time), CAST(N'13:00:00' AS Time), NULL, 15, 360, CAST(83 AS Decimal(18, 0)), 1, 33, 2, 900, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1096, N'Zone 2', 3, CAST(N'15:07:00' AS Time), CAST(N'15:07:00' AS Time), NULL, 60, 1440, CAST(0 AS Decimal(18, 0)), 1, 39, 1, 0, 1, 8) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1097, N'Zone 1', 3, CAST(N'15:20:00' AS Time), CAST(N'15:20:00' AS Time), NULL, 0, 10080, CAST(3 AS Decimal(18, 0)), 1, 39, 1, 0, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1098, N'Zone 2', 3, CAST(N'15:07:00' AS Time), CAST(N'15:07:00' AS Time), NULL, 60, 1440, CAST(0 AS Decimal(18, 0)), 1, 39, 1, 0, 9, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1099, N'Zone 1', 3, CAST(N'15:20:00' AS Time), CAST(N'15:20:00' AS Time), NULL, 60, 10080, CAST(3 AS Decimal(18, 0)), 1, 61, 1, 0, 10, 8) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1100, N'Zone 2', 3, CAST(N'15:07:00' AS Time), CAST(N'15:07:00' AS Time), NULL, 60, 1440, CAST(2 AS Decimal(18, 0)), 1, 61, 1, 0, 10, 5) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1101, N'Zone 3', 3, CAST(N'08:34:00' AS Time), CAST(N'08:34:00' AS Time), NULL, 60, 10080, CAST(3 AS Decimal(18, 0)), 1, 39, 1, 0, 1, 8) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1103, N'Zone 2', 3, CAST(N'18:00:00' AS Time), CAST(N'08:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, NULL, 11, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1104, N'Zone 3', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 240, CAST(120 AS Decimal(18, 0)), 1, 32, 2, 0, 11, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1109, N'Garage Parking - Day', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), NULL, 15, 0, CAST(75 AS Decimal(18, 0)), 1, 16, 2, NULL, 11, NULL) +INSERT [dbo].[payment_option] ([pop_id], [pop_label], [pop_payment_method_id], [pop_day_end_time], [pop_day_night_end_time], [pop_price_night], [pop_min_time], [pop_max_time], [pop_min_price], [pop_carry_over], [pop_period_week_id], [pop_currency_id], [pop_daily_card_price], [pop_city_id], [pop_multi_hour_price]) VALUES (1110, N'Garage Parking -Night ', 3, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, 15, 0, CAST(25 AS Decimal(18, 0)), NULL, 31, 2, NULL, 11, NULL) +SET IDENTITY_INSERT [dbo].[payment_option] OFF +SET IDENTITY_INSERT [dbo].[payment_unit] ON + +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (1, N'1h', 60) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (3, N'15 min', 15) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (5, N'24h', 1440) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (6, N'3h', 180) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (7, N'48h', 2880) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (8, N'72h', 4320) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (9, N'96h', 5670) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (10, N'120h', 7200) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (11, N'144h', 8640) +INSERT [dbo].[payment_unit] ([pun_id], [pun_label], [pun_duration]) VALUES (12, N'168h', 10080) +SET IDENTITY_INSERT [dbo].[payment_unit] OFF +SET IDENTITY_INSERT [dbo].[payment_rate] ON + +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (1, 17, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (2, 22, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (4, 24, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (5, 26, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (6, 27, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (7, 28, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (8, 29, 1, 300, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (9, 30, 1, 100, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (10, 1041, 3, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (27, 1047, 1, 5, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (28, 1046, 1, 0.6, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (31, 1048, 1, 1, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (32, 1048, 3, 2, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (45, 1055, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (46, 1056, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (47, 1057, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (48, 1058, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (49, 1059, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (50, 1060, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (51, 1061, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (52, 1062, 1, 300, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (53, 1063, 1, 100, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (54, 1064, 3, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (60, 1065, 1, 230, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (61, 1066, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (62, 1067, 1, 330, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (75, 1068, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (76, 1069, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (77, 1070, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (78, 1071, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (79, 1072, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (80, 1073, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (81, 1074, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (82, 1075, 1, 300, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (83, 1076, 1, 100, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (84, 1077, 3, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (85, 1078, 1, 230, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (86, 1079, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (87, 1080, 1, 330, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (88, 23, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (109, 1049, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (110, 1050, 1, 230, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (111, 1051, 1, 330, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (112, 1052, 1, 600, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (114, 1081, 1, 330, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (115, 1082, 1, 600, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (117, 1083, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (118, 1084, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (119, 1085, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (120, 1086, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (121, 1087, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (122, 1088, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (123, 1089, 1, 180, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (124, 1090, 1, 300, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (125, 1091, 1, 100, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (126, 1092, 3, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (127, 1093, 1, 230, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (128, 1094, 1, 150, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (129, 1095, 1, 330, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (144, 1096, 1, 2, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (145, 1096, 6, 4, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (146, 1045, 1, 3, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (147, 1045, 6, 7, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (148, 1097, 1, 3, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (149, 1097, 6, 7, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (150, 1098, 1, 2, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (151, 1098, 6, 4, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (180, 1101, 1, 3, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (181, 1101, 6, 7, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (182, 1101, 5, 8, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (186, 1099, 1, 3, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (187, 1099, 6, 7, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (188, 1099, 5, 8, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (189, 1099, 7, 16, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (190, 1099, 8, 24, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (191, 1099, 9, 32, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (192, 1099, 10, 40, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (193, 1099, 11, 48, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (194, 1099, 12, 56, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (195, 1100, 1, 2, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (196, 1100, 6, 4, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (197, 1100, 5, 5, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (199, 1103, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (200, 1104, 3, 480, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (205, 1109, 1, 300, NULL) +INSERT [dbo].[payment_rate] ([pra_id], [pra_payment_option_id], [pra_payment_unit_id], [pra_price], [pra_currency_id]) VALUES (206, 1110, 1, 100, NULL) +SET IDENTITY_INSERT [dbo].[payment_rate] OFF +SET IDENTITY_INSERT [dbo].[period_special_days] ON + +INSERT [dbo].[period_special_days] ([psd_id], [psd_label], [psd_chargeable], [psd_priority]) VALUES (1, N'Holiday', 0, 3) +INSERT [dbo].[period_special_days] ([psd_id], [psd_label], [psd_chargeable], [psd_priority]) VALUES (2, N'Special', 1, 1) +INSERT [dbo].[period_special_days] ([psd_id], [psd_label], [psd_chargeable], [psd_priority]) VALUES (3, N'Shop', 1, 1) +INSERT [dbo].[period_special_days] ([psd_id], [psd_label], [psd_chargeable], [psd_priority]) VALUES (4, N'Free', 0, 4) +SET IDENTITY_INSERT [dbo].[period_special_days] OFF +SET IDENTITY_INSERT [dbo].[period_exceptional_days] ON + +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (11, N'Christmas 1st day', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-25' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (13, N'Christmas 2nd day', CAST(N'2022-12-26' AS Date), CAST(N'2022-12-26' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (14, N'Republic Day (Hungary)', CAST(N'2022-10-23' AS Date), CAST(N'2022-10-23' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2016, N'Christmas (Sunday)', CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2021, N'Holiday (Hungary)', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), 1, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2022, N'NewYear', CAST(N'2023-01-01' AS Date), CAST(N'2023-01-01' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2024, N'Good Friday', CAST(N'2023-04-07' AS Date), CAST(N'2023-04-07' AS Date), 2, 2023, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2025, N'Easter Sunday', CAST(N'2023-04-09' AS Date), CAST(N'2023-04-09' AS Date), 2, 2023, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2026, N'Easter Monday', CAST(N'2023-04-10' AS Date), CAST(N'2023-04-10' AS Date), 2, 2023, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2027, N'Whit Sunday', CAST(N'2023-05-28' AS Date), CAST(N'2023-05-28' AS Date), 2, 2023, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2028, N'Whit Monday', CAST(N'2023-05-29' AS Date), CAST(N'2023-05-29' AS Date), 2, 2023, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2029, N'Revolution Day (Hungary)', CAST(N'2023-03-15' AS Date), CAST(N'2023-03-15' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2030, N'Labour Day', CAST(N'2023-05-01' AS Date), CAST(N'2023-05-01' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2031, N'Saint Stephens Day (Hungary)', CAST(N'2023-08-20' AS Date), CAST(N'2023-08-20' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2032, N'All Saints Day', CAST(N'2023-11-01' AS Date), CAST(N'2023-11-01' AS Date), 2, NULL, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2034, N'Good Friday', CAST(N'2024-03-29' AS Date), CAST(N'2024-03-29' AS Date), 2, 2024, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2035, N'Easter', CAST(N'2024-03-31' AS Date), CAST(N'2024-03-31' AS Date), 2, 2024, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2036, N'Easter Monday', CAST(N'2024-04-01' AS Date), CAST(N'2024-04-01' AS Date), 2, 2024, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2037, N'Whit Monday', CAST(N'2024-05-20' AS Date), CAST(N'2024-05-20' AS Date), 2, 2024, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2038, N'Whit Sunday', CAST(N'2024-05-19' AS Date), CAST(N'2024-05-19' AS Date), 2, 2024, 2) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2050, N'Weihnachten', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-26' AS Date), 1, NULL, 1) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2051, N'Uskrs', CAST(N'2023-04-16' AS Date), CAST(N'2023-04-16' AS Date), 1, NULL, 3) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2052, N'Christmas 1st day', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-25' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2053, N'Christmas 2nd day', CAST(N'2022-12-26' AS Date), CAST(N'2022-12-26' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2054, N'Republic Day (Hungary)', CAST(N'2022-10-23' AS Date), CAST(N'2022-10-23' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2055, N'Christmas (Sunday)', CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2056, N'Holiday (Hungary)', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), 1, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2057, N'NewYear', CAST(N'2023-01-01' AS Date), CAST(N'2023-01-01' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2058, N'Good Friday', CAST(N'2023-04-07' AS Date), CAST(N'2023-04-07' AS Date), 2, 2023, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2059, N'Easter Sunday', CAST(N'2023-04-09' AS Date), CAST(N'2023-04-09' AS Date), 2, 2023, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2060, N'Easter Monday', CAST(N'2023-04-10' AS Date), CAST(N'2023-04-10' AS Date), 2, 2023, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2061, N'Whit Sunday', CAST(N'2023-05-28' AS Date), CAST(N'2023-05-28' AS Date), 2, 2023, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2062, N'Whit Monday', CAST(N'2023-05-29' AS Date), CAST(N'2023-05-29' AS Date), 2, 2023, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2063, N'Revolution Day (Hungary)', CAST(N'2023-03-15' AS Date), CAST(N'2023-03-15' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2064, N'Labour Day', CAST(N'2023-05-01' AS Date), CAST(N'2023-05-01' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2065, N'Saint Stephens Day (Hungary)', CAST(N'2023-08-20' AS Date), CAST(N'2023-08-20' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2066, N'All Saints Day', CAST(N'2023-11-01' AS Date), CAST(N'2023-11-01' AS Date), 2, NULL, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2067, N'Good Friday', CAST(N'2024-03-29' AS Date), CAST(N'2024-03-29' AS Date), 2, 2024, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2068, N'Easter', CAST(N'2024-03-31' AS Date), CAST(N'2024-03-31' AS Date), 2, 2024, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2069, N'Easter Monday', CAST(N'2024-04-01' AS Date), CAST(N'2024-04-01' AS Date), 2, 2024, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2070, N'Whit Monday', CAST(N'2024-05-20' AS Date), CAST(N'2024-05-20' AS Date), 2, 2024, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2071, N'Whit Sunday', CAST(N'2024-05-19' AS Date), CAST(N'2024-05-19' AS Date), 2, 2024, 6) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2072, N'Christmas 1st day', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-25' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2073, N'Christmas 2nd day', CAST(N'2022-12-26' AS Date), CAST(N'2022-12-26' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2074, N'Republic Day (Hungary)', CAST(N'2022-10-23' AS Date), CAST(N'2022-10-23' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2075, N'Christmas (Sunday)', CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2076, N'Holiday (Hungary)', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), 1, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2077, N'NewYear', CAST(N'2023-01-01' AS Date), CAST(N'2023-01-01' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2078, N'Good Friday', CAST(N'2023-04-07' AS Date), CAST(N'2023-04-07' AS Date), 2, 2023, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2079, N'Easter Sunday', CAST(N'2023-04-09' AS Date), CAST(N'2023-04-09' AS Date), 2, 2023, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2080, N'Easter Monday', CAST(N'2023-04-10' AS Date), CAST(N'2023-04-10' AS Date), 2, 2023, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2081, N'Whit Sunday', CAST(N'2023-05-28' AS Date), CAST(N'2023-05-28' AS Date), 2, 2023, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2082, N'Whit Monday', CAST(N'2023-05-29' AS Date), CAST(N'2023-05-29' AS Date), 2, 2023, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2083, N'Revolution Day (Hungary)', CAST(N'2023-03-15' AS Date), CAST(N'2023-03-15' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2084, N'Labour Day', CAST(N'2023-05-01' AS Date), CAST(N'2023-05-01' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2085, N'Saint Stephens Day (Hungary)', CAST(N'2023-08-20' AS Date), CAST(N'2023-08-20' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2086, N'All Saints Day', CAST(N'2023-11-01' AS Date), CAST(N'2023-11-01' AS Date), 2, NULL, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2087, N'Good Friday', CAST(N'2024-03-29' AS Date), CAST(N'2024-03-29' AS Date), 2, 2024, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2088, N'Easter', CAST(N'2024-03-31' AS Date), CAST(N'2024-03-31' AS Date), 2, 2024, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2089, N'Easter Monday', CAST(N'2024-04-01' AS Date), CAST(N'2024-04-01' AS Date), 2, 2024, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2090, N'Whit Monday', CAST(N'2024-05-20' AS Date), CAST(N'2024-05-20' AS Date), 2, 2024, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2091, N'Whit Sunday', CAST(N'2024-05-19' AS Date), CAST(N'2024-05-19' AS Date), 2, 2024, 7) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2092, N'Christmas 1st day', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-25' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2093, N'Christmas 2nd day', CAST(N'2022-12-26' AS Date), CAST(N'2022-12-26' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2094, N'Republic Day (Hungary)', CAST(N'2022-10-23' AS Date), CAST(N'2022-10-23' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2095, N'Christmas (Sunday)', CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2096, N'Holiday (Hungary)', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), 1, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2097, N'NewYear', CAST(N'2023-01-01' AS Date), CAST(N'2023-01-01' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2098, N'Good Friday', CAST(N'2023-04-07' AS Date), CAST(N'2023-04-07' AS Date), 2, 2023, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2099, N'Easter Sunday', CAST(N'2023-04-09' AS Date), CAST(N'2023-04-09' AS Date), 2, 2023, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2100, N'Easter Monday', CAST(N'2023-04-10' AS Date), CAST(N'2023-04-10' AS Date), 2, 2023, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2101, N'Whit Sunday', CAST(N'2023-05-28' AS Date), CAST(N'2023-05-28' AS Date), 2, 2023, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2102, N'Whit Monday', CAST(N'2023-05-29' AS Date), CAST(N'2023-05-29' AS Date), 2, 2023, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2103, N'Revolution Day (Hungary)', CAST(N'2023-03-15' AS Date), CAST(N'2023-03-15' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2104, N'Labour Day', CAST(N'2023-05-01' AS Date), CAST(N'2023-05-01' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2105, N'Saint Stephens Day (Hungary)', CAST(N'2023-08-20' AS Date), CAST(N'2023-08-20' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2106, N'All Saints Day', CAST(N'2023-11-01' AS Date), CAST(N'2023-11-01' AS Date), 2, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2107, N'Good Friday', CAST(N'2024-03-29' AS Date), CAST(N'2024-03-29' AS Date), 2, 2024, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2108, N'Easter', CAST(N'2024-03-31' AS Date), CAST(N'2024-03-31' AS Date), 2, 2024, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2109, N'Easter Monday', CAST(N'2024-04-01' AS Date), CAST(N'2024-04-01' AS Date), 2, 2024, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2110, N'Whit Monday', CAST(N'2024-05-20' AS Date), CAST(N'2024-05-20' AS Date), 2, 2024, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2111, N'Whit Sunday', CAST(N'2024-05-19' AS Date), CAST(N'2024-05-19' AS Date), 2, 2024, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2112, N'Weihnachten', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-26' AS Date), 1, NULL, 9) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2113, N'Weihnachten', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-26' AS Date), 1, NULL, 10) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2114, N'Christmas 1st day', CAST(N'2022-12-25' AS Date), CAST(N'2022-12-25' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2115, N'Christmas 2nd day', CAST(N'2022-12-26' AS Date), CAST(N'2022-12-26' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2116, N'Republic Day (Hungary)', CAST(N'2022-10-23' AS Date), CAST(N'2022-10-23' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2117, N'Christmas (Sunday)', CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2118, N'Holiday (Hungary)', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), 1, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2119, N'NewYear', CAST(N'2023-01-01' AS Date), CAST(N'2023-01-01' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2120, N'Good Friday', CAST(N'2023-04-07' AS Date), CAST(N'2023-04-07' AS Date), 2, 2023, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2121, N'Easter Sunday', CAST(N'2023-04-09' AS Date), CAST(N'2023-04-09' AS Date), 2, 2023, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2122, N'Easter Monday', CAST(N'2023-04-10' AS Date), CAST(N'2023-04-10' AS Date), 2, 2023, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2123, N'Whit Sunday', CAST(N'2023-05-28' AS Date), CAST(N'2023-05-28' AS Date), 2, 2023, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2124, N'Whit Monday', CAST(N'2023-05-29' AS Date), CAST(N'2023-05-29' AS Date), 2, 2023, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2125, N'Revolution Day (Hungary)', CAST(N'2023-03-15' AS Date), CAST(N'2023-03-15' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2126, N'Labour Day', CAST(N'2023-05-01' AS Date), CAST(N'2023-05-01' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2127, N'Saint Stephens Day (Hungary)', CAST(N'2023-08-20' AS Date), CAST(N'2023-08-20' AS Date), 2, NULL, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2128, N'All Saints Day', CAST(N'2023-11-01' AS Date), CAST(N'2023-11-01' AS Date), 2, NULL, 11) +GO +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2129, N'Good Friday', CAST(N'2024-03-29' AS Date), CAST(N'2024-03-29' AS Date), 2, 2024, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2130, N'Easter', CAST(N'2024-03-31' AS Date), CAST(N'2024-03-31' AS Date), 2, 2024, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2131, N'Easter Monday', CAST(N'2024-04-01' AS Date), CAST(N'2024-04-01' AS Date), 2, 2024, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2132, N'Whit Monday', CAST(N'2024-05-20' AS Date), CAST(N'2024-05-20' AS Date), 2, 2024, 11) +INSERT [dbo].[period_exceptional_days] ([ped_id], [ped_label], [ped_date_start], [ped_date_end], [ped_period_special_day_id], [ped_year], [ped_city_id]) VALUES (2133, N'Whit Sunday', CAST(N'2024-05-19' AS Date), CAST(N'2024-05-19' AS Date), 2, 2024, 11) +SET IDENTITY_INSERT [dbo].[period_exceptional_days] OFF +SET IDENTITY_INSERT [dbo].[period_exceptional_day_work_time] ON + +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2156, 2024, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2158, 2025, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2160, 2026, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2162, 2027, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2164, 2028, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2170, 2030, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2172, 2032, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2174, 11, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2175, 13, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2178, 2022, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2179, 14, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2184, 2021, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2188, 2031, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2189, 2029, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2194, 2034, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2200, 2037, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2202, 2038, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2226, 2016, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2245, 2035, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2246, 2036, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2250, 2051, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2251, 2052, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2252, 2053, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2253, 2054, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2254, 2055, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2255, 2056, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2256, 2057, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2257, 2058, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2258, 2059, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2259, 2060, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2260, 2061, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2261, 2062, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2262, 2063, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2263, 2064, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2264, 2065, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2265, 2066, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2266, 2067, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2267, 2068, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2268, 2069, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2269, 2070, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2270, 2071, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2271, 2072, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2272, 2073, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2273, 2074, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2274, 2075, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2275, 2076, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2276, 2077, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2277, 2078, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2278, 2079, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2279, 2080, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2280, 2081, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2281, 2082, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2282, 2083, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2283, 2084, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2284, 2085, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2285, 2086, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2286, 2087, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2287, 2088, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2288, 2089, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2289, 2090, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2290, 2091, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2291, 2092, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2292, 2093, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2293, 2094, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2294, 2095, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2295, 2096, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2296, 2097, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2297, 2098, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2298, 2099, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2299, 2100, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2300, 2101, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2301, 2102, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2302, 2103, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2303, 2104, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2304, 2105, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2305, 2106, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2306, 2107, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2307, 2108, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2308, 2109, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2309, 2110, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2310, 2111, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2312, 2050, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2313, 2112, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2314, 2113, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2315, 2114, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2316, 2115, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2317, 2116, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2318, 2117, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2319, 2118, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2320, 2119, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2321, 2120, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2322, 2121, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2323, 2122, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2324, 2123, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2325, 2124, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2326, 2125, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2327, 2126, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2328, 2127, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2329, 2128, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +GO +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2330, 2129, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2331, 2130, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2332, 2131, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2333, 2132, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +INSERT [dbo].[period_exceptional_day_work_time] ([pedwt_id], [pedwt_period_exc_day_id], [pedwt_time_from], [pedwt_time_to], [pedwt_price], [pedwt_currency_id]) VALUES (2334, 2133, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 0, NULL) +SET IDENTITY_INSERT [dbo].[period_exceptional_day_work_time] OFF +SET IDENTITY_INSERT [dbo].[period_day_in_week] ON + +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (1, N'Monday', 1, 1) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (2, N'Tuesday', 2, 2) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (3, N'Wednesday', 3, 3) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (4, N'Thursday', 4, 4) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (5, N'Friday', 5, 5) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (6, N'Saturday', 6, 6) +INSERT [dbo].[period_day_in_week] ([pdiw_id], [pdiw_label], [pdiw_index], [pdiw_index_device]) VALUES (7, N'Sunday', 0, 7) +SET IDENTITY_INSERT [dbo].[period_day_in_week] OFF +SET IDENTITY_INSERT [dbo].[period_week_day] ON + +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (433, 17, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (434, 17, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (435, 17, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (436, 17, 2, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (437, 17, 4, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (438, 17, 6, CAST(N'13:00:00' AS Time), CAST(N'14:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (455, 19, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (456, 19, 2, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (457, 19, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (458, 19, 4, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (459, 19, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (460, 19, 6, CAST(N'06:30:00' AS Time), CAST(N'14:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (499, 31, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (500, 31, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (501, 31, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (502, 31, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (503, 31, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (504, 31, 6, CAST(N'14:00:00' AS Time), CAST(N'00:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (505, 31, 7, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (506, 31, 1, CAST(N'00:00:00' AS Time), CAST(N'08:00:00' AS Time), 4) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (513, 16, 6, CAST(N'08:00:00' AS Time), CAST(N'14:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (514, 16, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (515, 16, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (516, 16, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (517, 16, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (518, 16, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (519, 16, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (520, 16, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (570, 33, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (571, 33, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (572, 33, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (573, 33, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (574, 33, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (575, 33, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (581, 32, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (582, 32, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (583, 32, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (584, 32, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (585, 32, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (592, 34, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (593, 34, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (594, 34, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (595, 34, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (596, 34, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (597, 34, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (598, 35, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (599, 35, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (600, 35, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (601, 35, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (602, 35, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (603, 35, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (604, 35, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (621, 36, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (622, 36, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (623, 36, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (624, 36, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (625, 36, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (632, 37, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (633, 37, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (634, 37, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (635, 37, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (636, 37, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (637, 37, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (652, 40, 6, CAST(N'08:00:00' AS Time), CAST(N'14:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (653, 40, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (654, 40, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (655, 40, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (656, 40, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (657, 40, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (658, 40, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (659, 40, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (660, 41, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (661, 41, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (662, 41, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (663, 41, 2, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (664, 41, 4, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (665, 41, 6, CAST(N'13:00:00' AS Time), CAST(N'14:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (666, 42, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (667, 42, 2, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (668, 42, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (669, 42, 4, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (670, 42, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (671, 42, 6, CAST(N'06:30:00' AS Time), CAST(N'14:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (672, 43, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (673, 43, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (674, 43, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (675, 43, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (676, 43, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (677, 43, 6, CAST(N'14:00:00' AS Time), CAST(N'00:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (678, 43, 7, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (679, 43, 1, CAST(N'00:00:00' AS Time), CAST(N'08:00:00' AS Time), 4) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (680, 44, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (681, 44, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (682, 44, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (683, 44, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (684, 44, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (685, 45, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (686, 45, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (687, 45, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +GO +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (688, 45, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (689, 45, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (690, 45, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (733, 46, 6, CAST(N'08:00:00' AS Time), CAST(N'14:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (734, 46, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (735, 46, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (736, 46, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (737, 46, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (738, 46, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (739, 46, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (740, 46, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (741, 47, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (742, 47, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (743, 47, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (744, 47, 2, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (745, 47, 4, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (746, 47, 6, CAST(N'13:00:00' AS Time), CAST(N'14:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (747, 48, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (748, 48, 2, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (749, 48, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (750, 48, 4, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (751, 48, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (752, 48, 6, CAST(N'06:30:00' AS Time), CAST(N'14:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (753, 49, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (754, 49, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (755, 49, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (756, 49, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (757, 49, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (758, 49, 6, CAST(N'14:00:00' AS Time), CAST(N'00:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (759, 49, 7, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (760, 49, 1, CAST(N'00:00:00' AS Time), CAST(N'08:00:00' AS Time), 4) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (761, 50, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (762, 50, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (763, 50, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (764, 50, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (765, 50, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (766, 51, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (767, 51, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (768, 51, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (769, 51, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (770, 51, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (771, 51, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (772, 52, 6, CAST(N'08:00:00' AS Time), CAST(N'14:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (773, 52, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (774, 52, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (775, 52, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (776, 52, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (777, 52, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (778, 52, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (779, 52, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (780, 53, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (781, 53, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (782, 53, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (783, 53, 2, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (784, 53, 4, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (785, 53, 6, CAST(N'13:00:00' AS Time), CAST(N'14:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (786, 54, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (787, 54, 2, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (788, 54, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (789, 54, 4, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (790, 54, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (791, 54, 6, CAST(N'06:30:00' AS Time), CAST(N'14:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (792, 55, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (793, 55, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (794, 55, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (795, 55, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (796, 55, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (797, 55, 6, CAST(N'14:00:00' AS Time), CAST(N'00:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (798, 55, 7, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (799, 55, 1, CAST(N'00:00:00' AS Time), CAST(N'08:00:00' AS Time), 4) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (800, 56, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (801, 56, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (802, 56, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (803, 56, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (804, 56, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (805, 57, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (806, 57, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (807, 57, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (808, 57, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (809, 57, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (810, 57, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (811, 39, 1, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (812, 39, 2, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (813, 39, 3, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (814, 39, 4, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (815, 39, 5, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (816, 39, 6, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (817, 39, 7, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (824, 18, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (825, 18, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (826, 18, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (827, 18, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (828, 18, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (829, 18, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (830, 58, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (831, 58, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (832, 58, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (833, 58, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (834, 58, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (835, 58, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +GO +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (836, 59, 1, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (837, 59, 2, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (838, 59, 3, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (839, 59, 4, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (840, 59, 5, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (841, 59, 6, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (842, 59, 7, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (843, 60, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (844, 60, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (845, 60, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (846, 60, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (847, 60, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (848, 60, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (863, 61, 1, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (864, 61, 2, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (865, 61, 3, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (866, 61, 4, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (867, 61, 5, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (868, 61, 6, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (869, 61, 7, CAST(N'00:00:00' AS Time), CAST(N'23:59:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (870, 62, 6, CAST(N'08:00:00' AS Time), CAST(N'14:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (871, 62, 1, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (872, 62, 2, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (873, 62, 3, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (874, 62, 4, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (875, 62, 5, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (876, 62, 6, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (877, 62, 7, CAST(N'08:00:00' AS Time), CAST(N'16:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (878, 63, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (879, 63, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (880, 63, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (881, 63, 2, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (882, 63, 4, CAST(N'13:00:00' AS Time), CAST(N'18:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (883, 63, 6, CAST(N'13:00:00' AS Time), CAST(N'14:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (884, 64, 1, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (885, 64, 2, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (886, 64, 3, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (887, 64, 4, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (888, 64, 5, CAST(N'06:30:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (889, 64, 6, CAST(N'06:30:00' AS Time), CAST(N'14:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (890, 65, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (891, 65, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (892, 65, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (893, 65, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (894, 65, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (895, 65, 6, CAST(N'14:00:00' AS Time), CAST(N'00:00:00' AS Time), 2) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (896, 65, 7, CAST(N'00:00:00' AS Time), CAST(N'00:00:00' AS Time), 3) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (897, 65, 1, CAST(N'00:00:00' AS Time), CAST(N'08:00:00' AS Time), 4) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (898, 66, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (899, 66, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (900, 66, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (901, 66, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (902, 66, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (903, 67, 1, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (904, 67, 2, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (905, 67, 3, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (906, 67, 4, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (907, 67, 5, CAST(N'08:00:00' AS Time), CAST(N'18:00:00' AS Time), 1) +INSERT [dbo].[period_week_day] ([pwd_id], [pwd_period_week_day_id], [pwd_period_day_in_week_id], [pwd_time_from], [pwd_time_to], [pwd_ui_group]) VALUES (908, 67, 6, CAST(N'08:00:00' AS Time), CAST(N'12:00:00' AS Time), 2) +SET IDENTITY_INSERT [dbo].[period_week_day] OFF +SET IDENTITY_INSERT [dbo].[city] ON + +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (1, N'Varaždinci', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (2, N'Szeged', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (3, N'Test', CAST(N'2023-06-01T09:23:45.7126694+02:00' AS DateTimeOffset)) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (4, N'Berlin Trewpto', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (5, N'Szeged Start Juni 2023', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (6, N'Szeged copy', CAST(N'2023-06-06T10:45:53.9298634+02:00' AS DateTimeOffset)) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (7, N'Szeged Versuch ', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (8, N'Schönau', CAST(N'2023-08-31T14:41:04.2730562+02:00' AS DateTimeOffset)) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (9, N'Schönau Königssee', CAST(N'2023-08-31T15:50:29.5479445+02:00' AS DateTimeOffset)) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (10, N'Schönau', NULL) +INSERT [dbo].[city] ([cty_id], [cty_label], [cty_delete_date]) VALUES (11, N'NVT Korneuburg ', NULL) +SET IDENTITY_INSERT [dbo].[city] OFF diff --git a/tariff_korneuburg.json b/tariff_korneuburg.json new file mode 100644 index 0000000..8662012 --- /dev/null +++ b/tariff_korneuburg.json @@ -0,0 +1,629 @@ +{ + "Project" : "Korneuburg", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 2, + "pcu_sign": "€", + "pcu_major": "EUR", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone 1", + "pop_payment_method_id": 3, + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", + "pop_price_night": 0, + "pop_min_time": 30, + "pop_max_time": 180, + "pop_min_price": 60, + "pop_carry_over": 1, + "pop_daily_card_price": 0 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 10 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "5 min", + "pun_duration": 5 + }, + { + "pun_id": 3, + "pun_label": "15 min", + "pun_duration": 15 + }, + { + "pun_id": 4, + "pun_label": "1 min", + "pun_duration": 1 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 626, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 6, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + } + ], + "SpecialDaysWorktime": [ + { + "pedwt_id": 2156, + "pedwt_period_exc_day_id": 2024, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2158, + "pedwt_period_exc_day_id": 2025, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2160, + "pedwt_period_exc_day_id": 2026, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2162, + "pedwt_period_exc_day_id": 2027, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2164, + "pedwt_period_exc_day_id": 2028, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2170, + "pedwt_period_exc_day_id": 2030, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2172, + "pedwt_period_exc_day_id": 2032, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2174, + "pedwt_period_exc_day_id": 11, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2175, + "pedwt_period_exc_day_id": 13, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2178, + "pedwt_period_exc_day_id": 2022, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2179, + "pedwt_period_exc_day_id": 14, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2184, + "pedwt_period_exc_day_id": 2021, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2188, + "pedwt_period_exc_day_id": 2031, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2189, + "pedwt_period_exc_day_id": 2029, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2194, + "pedwt_period_exc_day_id": 2034, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2200, + "pedwt_period_exc_day_id": 2037, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2202, + "pedwt_period_exc_day_id": 2038, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2226, + "pedwt_period_exc_day_id": 2016, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2245, + "pedwt_period_exc_day_id": 2035, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2246, + "pedwt_period_exc_day_id": 2036, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2249, + "pedwt_period_exc_day_id": 2050, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2250, + "pedwt_period_exc_day_id": 2051, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2251, + "pedwt_period_exc_day_id": 2052, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2252, + "pedwt_period_exc_day_id": 2053, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2253, + "pedwt_period_exc_day_id": 2054, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2254, + "pedwt_period_exc_day_id": 2055, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2255, + "pedwt_period_exc_day_id": 2056, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2256, + "pedwt_period_exc_day_id": 2057, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2257, + "pedwt_period_exc_day_id": 2058, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2258, + "pedwt_period_exc_day_id": 2059, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2259, + "pedwt_period_exc_day_id": 2060, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + } + ], + "SpecialDays": [ + { + "ped_id": 11, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2023-12-08", + "ped_date_end": "2023-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 13, + "ped_label": "Christtag", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 14, + "ped_label": "Stefanitag", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2016, + "ped_label": "Neujahr", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2021, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2024-01-06", + "ped_date_end": "2024-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2022, + "ped_label": "Ostermontag", + "ped_date_start": "2024-01-04", + "ped_date_end": "2024-01-04", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2024, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2025, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2024-05-09", + "ped_date_end": "2024-05-09", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2026, + "ped_label": "Pfingst Montag", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2027, + "ped_label": "Fronleichnam", + "ped_date_start": "2024-05-30", + "ped_date_end": "2024-05-30", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2028, + "ped_label": "Maria Himmelfahrt", + "ped_date_start": "2024-08-15", + "ped_date_end": "2024-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2029, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2024-10-26", + "ped_date_end": "2024-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2030, + "ped_label": "Allerheiligen", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2031, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2024-08-12", + "ped_date_end": "2024-08-12", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2032, + "ped_label": "Christtag", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2034, + "ped_label": "Stefanitag", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2035, + "ped_label": "Neujahr", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2036, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2025-06-01", + "ped_date_end": "2025-06-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2037, + "ped_label": "Ostermontag", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2038, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2050, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2025-05-29", + "ped_date_end": "2025-05-29", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2051, + "ped_label": "Pfingstmontag", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2052, + "ped_label": "Fronlaeichnam", + "ped_date_start": "2025-06-19", + "ped_date_end": "2025-06-19", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2053, + "ped_label": "Mariae Himmelfahrt", + "ped_date_start": "2025-08-15", + "ped_date_end": "2025-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2054, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2025-10-26", + "ped_date_end": "2025-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2055, + "ped_label": "Allerheiligen", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2056, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2025-12-08", + "ped_date_end": "2025-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2057, + "ped_label": "Christtag", + "ped_date_start": "2025-12-25", + "ped_date_end": "2025-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2058, + "ped_label": "Stefanitag", + "ped_date_start": "2025-12-26", + "ped_date_end": "2025-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2059, + "ped_label": "Neujahr", + "ped_date_start": "2026-01-01", + "ped_date_end": "2026-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2060, + "ped_label": "Heilige Drei Koenige", + "ped_date_start": "2026-01-06", + "ped_date_end": "2026-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ] +} diff --git a/tariffs/tariff01.json b/tariffs/tariff01.json index b3155a3..8662012 100644 --- a/tariffs/tariff01.json +++ b/tariffs/tariff01.json @@ -1,9 +1,12 @@ { + "Project" : "Korneuburg", + "Version" : "1.0.0", + "Info" : "", "Currency": [ { "pcu_id": 2, - "pcu_sign": "Ft", - "pcu_major": "HUF", + "pcu_sign": "€", + "pcu_major": "EUR", "pcu_minor": "", "pcu_active": true } @@ -29,30 +32,30 @@ "PaymentOption": [ { "pop_id": 1049, - "pop_label": "Zone Lila", + "pop_label": "Zone 1", "pop_payment_method_id": 3, - "pop_day_end_time": "16:25:00", - "pop_day_night_end_time": "16:25:00", + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", "pop_price_night": 0, - "pop_min_time": 15, - "pop_max_time": 300, - "pop_min_price": 0, + "pop_min_time": 30, + "pop_max_time": 180, + "pop_min_price": 60, "pop_carry_over": 1, - "pop_daily_card_price": 900 + "pop_daily_card_price": 0 } ], "PaymentRate": [ { "pra_payment_option_id": 1049, "pra_payment_unit_id": 1, - "pra_price": 150 + "pra_price": 10 } ], "Duration": [ { "pun_id": 1, - "pun_label": "1h", - "pun_duration": 60 + "pun_label": "5 min", + "pun_duration": 5 }, { "pun_id": 3, @@ -71,6 +74,13 @@ "pwd_period_week_day_id": 36, "pwd_period_day_in_week_id": 1, "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "14:00:00", "pwd_time_to": "18:00:00" }, { @@ -78,6 +88,13 @@ "pwd_period_week_day_id": 36, "pwd_period_day_in_week_id": 2, "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "14:00:00", "pwd_time_to": "18:00:00" }, { @@ -85,6 +102,13 @@ "pwd_period_week_day_id": 36, "pwd_period_day_in_week_id": 3, "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "14:00:00", "pwd_time_to": "18:00:00" }, { @@ -92,6 +116,13 @@ "pwd_period_week_day_id": 36, "pwd_period_day_in_week_id": 4, "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "14:00:00", "pwd_time_to": "18:00:00" }, { @@ -99,73 +130,21 @@ "pwd_period_week_day_id": 36, "pwd_period_day_in_week_id": 5, "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "14:00:00", "pwd_time_to": "18:00:00" - } - ], - "PeriodYear": [ - { - "pye_id": 8, - "pye_label": "Whole year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 }, { - "pye_id": 9, - "pye_label": "Whole year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 10, - "pye_label": "Whole year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 11, - "pye_label": "Whole Year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 12, - "pye_label": "Whole Year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 13, - "pye_label": "Whole Year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 14, - "pye_label": "Whole Year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 - }, - { - "pye_id": 15, - "pye_label": "Whole year", - "pye_start_month": 1, - "pye_start_day": 1, - "pye_end_month": 12, - "pye_end_day": 31 + "pwd_id": 626, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 6, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" } ], "SpecialDaysWorktime": [ @@ -385,421 +364,266 @@ "pedwt_time_from": "00:00:00", "pedwt_time_to": "00:00:00", "pedwt_price": 0 - }, - { - "pedwt_id": 2260, - "pedwt_period_exc_day_id": 2061, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2261, - "pedwt_period_exc_day_id": 2062, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2262, - "pedwt_period_exc_day_id": 2063, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2263, - "pedwt_period_exc_day_id": 2064, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2264, - "pedwt_period_exc_day_id": 2065, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2265, - "pedwt_period_exc_day_id": 2066, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2266, - "pedwt_period_exc_day_id": 2067, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2267, - "pedwt_period_exc_day_id": 2068, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2268, - "pedwt_period_exc_day_id": 2069, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2269, - "pedwt_period_exc_day_id": 2070, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 - }, - { - "pedwt_id": 2270, - "pedwt_period_exc_day_id": 2071, - "pedwt_time_from": "00:00:00", - "pedwt_time_to": "00:00:00", - "pedwt_price": 0 } ], "SpecialDays": [ { "ped_id": 11, - "ped_label": "Christmas 1st day", - "ped_date_start": "2022-12-25", - "ped_date_end": "2022-12-25", - "ped_period_special_day_id": 2, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2023-12-08", + "ped_date_end": "2023-12-08", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 13, - "ped_label": "Christmas 2nd day", - "ped_date_start": "2022-12-26", - "ped_date_end": "2022-12-26", - "ped_period_special_day_id": 2, + "ped_label": "Christtag", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 14, - "ped_label": "Republic Day (Hungary)", - "ped_date_start": "2022-10-23", - "ped_date_end": "2022-10-23", - "ped_period_special_day_id": 2, + "ped_label": "Stefanitag", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2016, - "ped_label": "Christmas (Sunday)", - "ped_date_start": "2022-12-24", - "ped_date_end": "2022-12-24", - "ped_period_special_day_id": 2, + "ped_label": "Neujahr", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2021, - "ped_label": "Holiday (Hungary)", - "ped_date_start": "2022-12-31", - "ped_date_end": "2022-12-31", + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2024-01-06", + "ped_date_end": "2024-01-06", "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2022, - "ped_label": "NewYear", - "ped_date_start": "2023-01-01", - "ped_date_end": "2023-01-01", - "ped_period_special_day_id": 2, - "ped_year": 0 + "ped_label": "Ostermontag", + "ped_date_start": "2024-01-04", + "ped_date_end": "2024-01-04", + "ped_period_special_day_id": 1, + "ped_year": 2024 }, { "ped_id": 2024, - "ped_label": "Good Friday", - "ped_date_start": "2023-04-07", - "ped_date_end": "2023-04-07", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Staatsfeiertag", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2025, - "ped_label": "Easter Sunday", - "ped_date_start": "2023-04-09", - "ped_date_end": "2023-04-09", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2024-05-09", + "ped_date_end": "2024-05-09", + "ped_period_special_day_id": 1, + "ped_year": 2024 }, { "ped_id": 2026, - "ped_label": "Easter Monday", - "ped_date_start": "2023-04-10", - "ped_date_end": "2023-04-10", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Pfingst Montag", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 1, + "ped_year": 2024 }, { "ped_id": 2027, - "ped_label": "Whit Sunday", - "ped_date_start": "2023-05-28", - "ped_date_end": "2023-05-28", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Fronleichnam", + "ped_date_start": "2024-05-30", + "ped_date_end": "2024-05-30", + "ped_period_special_day_id": 1, + "ped_year": 2024 }, { "ped_id": 2028, - "ped_label": "Whit Monday", - "ped_date_start": "2023-05-29", - "ped_date_end": "2023-05-29", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Maria Himmelfahrt", + "ped_date_start": "2024-08-15", + "ped_date_end": "2024-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2029, - "ped_label": "Revolution Day (Hungary)", - "ped_date_start": "2023-03-15", - "ped_date_end": "2023-03-15", - "ped_period_special_day_id": 2, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2024-10-26", + "ped_date_end": "2024-10-26", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2030, - "ped_label": "Labour Day", - "ped_date_start": "2023-05-01", - "ped_date_end": "2023-05-01", - "ped_period_special_day_id": 2, + "ped_label": "Allerheiligen", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2031, - "ped_label": "Saint Stephens Day (Hungary)", - "ped_date_start": "2023-08-20", - "ped_date_end": "2023-08-20", - "ped_period_special_day_id": 2, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2024-08-12", + "ped_date_end": "2024-08-12", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2032, - "ped_label": "All Saints Day", - "ped_date_start": "2023-11-01", - "ped_date_end": "2023-11-01", - "ped_period_special_day_id": 2, + "ped_label": "Christtag", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2034, - "ped_label": "Good Friday", - "ped_date_start": "2024-03-29", - "ped_date_end": "2024-03-29", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "ped_label": "Stefanitag", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2035, - "ped_label": "Easter", - "ped_date_start": "2024-03-31", - "ped_date_end": "2024-03-31", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "ped_label": "Neujahr", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2036, - "ped_label": "Easter Monday", - "ped_date_start": "2024-04-01", - "ped_date_end": "2024-04-01", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2025-06-01", + "ped_date_end": "2025-06-01", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2037, - "ped_label": "Whit Monday", - "ped_date_start": "2024-05-20", - "ped_date_end": "2024-05-20", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "ped_label": "Ostermontag", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 1, + "ped_year": 2025 }, { "ped_id": 2038, - "ped_label": "Whit Sunday", - "ped_date_start": "2024-05-19", - "ped_date_end": "2024-05-19", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "ped_label": "Staatsfeiertag", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 1, + "ped_year": 2025 }, { "ped_id": 2050, - "ped_label": "Uskrs", - "ped_date_start": "2023-04-16", - "ped_date_end": "2023-04-16", + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2025-05-29", + "ped_date_end": "2025-05-29", "ped_period_special_day_id": 1, - "ped_year": 0 + "ped_year": 2025 }, { "ped_id": 2051, - "ped_label": "Uskrs", - "ped_date_start": "2023-04-16", - "ped_date_end": "2023-04-16", + "ped_label": "Pfingstmontag", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", "ped_period_special_day_id": 1, - "ped_year": 0 + "ped_year": 2025 }, { "ped_id": 2052, - "ped_label": "Christmas 1st day", - "ped_date_start": "2022-12-25", - "ped_date_end": "2022-12-25", - "ped_period_special_day_id": 2, - "ped_year": 0 + "ped_label": "Fronlaeichnam", + "ped_date_start": "2025-06-19", + "ped_date_end": "2025-06-19", + "ped_period_special_day_id": 1, + "ped_year": 2025 }, { "ped_id": 2053, - "ped_label": "Christmas 2nd day", - "ped_date_start": "2022-12-26", - "ped_date_end": "2022-12-26", - "ped_period_special_day_id": 2, + "ped_label": "Mariae Himmelfahrt", + "ped_date_start": "2025-08-15", + "ped_date_end": "2025-08-15", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2054, - "ped_label": "Republic Day (Hungary)", - "ped_date_start": "2022-10-23", - "ped_date_end": "2022-10-23", - "ped_period_special_day_id": 2, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2025-10-26", + "ped_date_end": "2025-10-26", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2055, - "ped_label": "Christmas (Sunday)", - "ped_date_start": "2022-12-24", - "ped_date_end": "2022-12-24", - "ped_period_special_day_id": 2, + "ped_label": "Allerheiligen", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2056, - "ped_label": "Holiday (Hungary)", - "ped_date_start": "2022-12-31", - "ped_date_end": "2022-12-31", + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2025-12-08", + "ped_date_end": "2025-12-08", "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2057, - "ped_label": "NewYear", - "ped_date_start": "2023-01-01", - "ped_date_end": "2023-01-01", - "ped_period_special_day_id": 2, + "ped_label": "Christtag", + "ped_date_start": "2025-12-25", + "ped_date_end": "2025-12-25", + "ped_period_special_day_id": 1, "ped_year": 0 }, { "ped_id": 2058, - "ped_label": "Good Friday", - "ped_date_start": "2023-04-07", - "ped_date_end": "2023-04-07", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Stefanitag", + "ped_date_start": "2025-12-26", + "ped_date_end": "2025-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2059, - "ped_label": "Easter Sunday", - "ped_date_start": "2023-04-09", - "ped_date_end": "2023-04-09", - "ped_period_special_day_id": 2, - "ped_year": 2023 + "ped_label": "Neujahr", + "ped_date_start": "2026-01-01", + "ped_date_end": "2026-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 }, { "ped_id": 2060, - "ped_label": "Easter Monday", - "ped_date_start": "2023-04-10", - "ped_date_end": "2023-04-10", - "ped_period_special_day_id": 2, - "ped_year": 2023 - }, - { - "ped_id": 2061, - "ped_label": "Whit Sunday", - "ped_date_start": "2023-05-28", - "ped_date_end": "2023-05-28", - "ped_period_special_day_id": 2, - "ped_year": 2023 - }, - { - "ped_id": 2062, - "ped_label": "Whit Monday", - "ped_date_start": "2023-05-29", - "ped_date_end": "2023-05-29", - "ped_period_special_day_id": 2, - "ped_year": 2023 - }, - { - "ped_id": 2063, - "ped_label": "Revolution Day (Hungary)", - "ped_date_start": "2023-03-15", - "ped_date_end": "2023-03-15", - "ped_period_special_day_id": 2, + "ped_label": "Heilige Drei Koenige", + "ped_date_start": "2026-01-06", + "ped_date_end": "2026-01-06", + "ped_period_special_day_id": 1, "ped_year": 0 - }, + } + ], + "PeriodYear": [ { - "ped_id": 2064, - "ped_label": "Labour Day", - "ped_date_start": "2023-05-01", - "ped_date_end": "2023-05-01", - "ped_period_special_day_id": 2, - "ped_year": 0 - }, - { - "ped_id": 2065, - "ped_label": "Saint Stephens Day (Hungary)", - "ped_date_start": "2023-08-20", - "ped_date_end": "2023-08-20", - "ped_period_special_day_id": 2, - "ped_year": 0 - }, - { - "ped_id": 2066, - "ped_label": "All Saints Day", - "ped_date_start": "2023-11-01", - "ped_date_end": "2023-11-01", - "ped_period_special_day_id": 2, - "ped_year": 0 - }, - { - "ped_id": 2067, - "ped_label": "Good Friday", - "ped_date_start": "2024-03-29", - "ped_date_end": "2024-03-29", - "ped_period_special_day_id": 2, - "ped_year": 2024 - }, - { - "ped_id": 2068, - "ped_label": "Easter", - "ped_date_start": "2024-03-31", - "ped_date_end": "2024-03-31", - "ped_period_special_day_id": 2, - "ped_year": 2024 - }, - { - "ped_id": 2069, - "ped_label": "Easter Monday", - "ped_date_start": "2024-04-01", - "ped_date_end": "2024-04-01", - "ped_period_special_day_id": 2, - "ped_year": 2024 - }, - { - "ped_id": 2070, - "ped_label": "Whit Monday", - "ped_date_start": "2024-05-20", - "ped_date_end": "2024-05-20", - "ped_period_special_day_id": 2, - "ped_year": 2024 - }, - { - "ped_id": 2071, - "ped_label": "Whit Sunday", - "ped_date_start": "2024-05-19", - "ped_date_end": "2024-05-19", - "ped_period_special_day_id": 2, - "ped_year": 2024 + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 } ] } diff --git a/tariffs/tariff_bilexa_galtuer.json b/tariffs/tariff_bilexa_galtuer.json new file mode 100644 index 0000000..88a4669 --- /dev/null +++ b/tariffs/tariff_bilexa_galtuer.json @@ -0,0 +1,172 @@ +{ + "Project" : "Bilexa Galtuer", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 1, + "pcu_sign": "€", + "pcu_major": "Euro", + "pcu_minor": "Cent", + "pcu_active": true + } + ], + "TimeStepConfig" : [ + { + "tsconfig_id" : 1, + "tsconfig_label" : "static", + "tsconfig_comment" : "read time steps as given in jsonfiles" + }, + { + "tsconfig_id" : 2, + "tsconfig_label" : "dynamic", + "tsconfig_comment" : "determine timesteps at runtime" + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1099, + "pop_label": "Zone 1", + "pop_payment_method_id": 4, + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", + "pop_price_night": 0, + "pop_min_time": 1, + "pop_max_time": 10080, + "pop_min_price": 700, + "pop_carry_over": 1, + "pop_carry_over_time_range_id": 1, + "pop_daily_card_price": 0, + "pop_business_hours": 0, + "pop_time_step_config": 2 + } + ], + "TimeBase": [ + { + "tbase_id": 0, + "tbase_type": 0, + "tbase_type_comment": "time is given as starting from some wall-clock-time", + "tbase_label": "absolute time" + }, + { + "tbase_id": 1, + "tbase_type": 1, + "tbase_type_comment": "time is given as starting from 0 minutes", + "tbase_label": "relative time" + } + ], + "TimeRange" : [ + { + "time_range_id": 1, + "time_range_from": "00:00:00", + "time_range_to": "00:01:00", + "time_range_comment": "- <= 60secs -> time range is time point " + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 1, + "pra_price": 700 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 2, + "pra_price": 1400 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 3, + "pra_price": 2100 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 4, + "pra_price": 2800 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 5, + "pra_price": 3500 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 6, + "pra_price": 4200 + }, + { + "pra_payment_option_id": 1099, + "pra_payment_unit_id": 7, + "pra_price": 4900 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "Day 1", + "pun_duration_min": 1, + "pun_duration_max": 1440, + "pun_duration": 0 + }, + { + "pun_id": 2, + "pun_label": "Day 2", + "pun_duration_min": 2880, + "pun_duration_max": 2880, + "pun_duration": 2880 + }, + { + "pun_id": 3, + "pun_label": "Day 3", + "pun_duration_min": 4320, + "pun_duration_max": 4320, + "pun_duration": 4320 + }, + { + "pun_id": 4, + "pun_label": "Day 4", + "pun_duration_min": 5760, + "pun_duration_max": 5760, + "pun_duration": 5760 + }, + { + "pun_id": 5, + "pun_label": "Day 5", + "pun_duration_min": 7200, + "pun_duration_max": 7200, + "pun_duration": 7200 + }, + { + "pun_id": 6, + "pun_label": "Day 6", + "pun_duration_min": 8640, + "pun_duration_max": 8640, + "pun_duration": 8640 + }, + { + "pun_id": 7, + "pun_label": "Day 7", + "pun_duration_min": 10080, + "pun_duration_max": 10080, + "pun_duration": 10080 + } + ] +} diff --git a/tariffs/tariff_korneuburg.json b/tariffs/tariff_korneuburg.json new file mode 100644 index 0000000..8662012 --- /dev/null +++ b/tariffs/tariff_korneuburg.json @@ -0,0 +1,629 @@ +{ + "Project" : "Korneuburg", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 2, + "pcu_sign": "€", + "pcu_major": "EUR", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone 1", + "pop_payment_method_id": 3, + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", + "pop_price_night": 0, + "pop_min_time": 30, + "pop_max_time": 180, + "pop_min_price": 60, + "pop_carry_over": 1, + "pop_daily_card_price": 0 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 10 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "5 min", + "pun_duration": 5 + }, + { + "pun_id": 3, + "pun_label": "15 min", + "pun_duration": 15 + }, + { + "pun_id": 4, + "pun_label": "1 min", + "pun_duration": 1 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 626, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 6, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + } + ], + "SpecialDaysWorktime": [ + { + "pedwt_id": 2156, + "pedwt_period_exc_day_id": 2024, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2158, + "pedwt_period_exc_day_id": 2025, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2160, + "pedwt_period_exc_day_id": 2026, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2162, + "pedwt_period_exc_day_id": 2027, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2164, + "pedwt_period_exc_day_id": 2028, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2170, + "pedwt_period_exc_day_id": 2030, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2172, + "pedwt_period_exc_day_id": 2032, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2174, + "pedwt_period_exc_day_id": 11, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2175, + "pedwt_period_exc_day_id": 13, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2178, + "pedwt_period_exc_day_id": 2022, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2179, + "pedwt_period_exc_day_id": 14, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2184, + "pedwt_period_exc_day_id": 2021, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2188, + "pedwt_period_exc_day_id": 2031, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2189, + "pedwt_period_exc_day_id": 2029, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2194, + "pedwt_period_exc_day_id": 2034, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2200, + "pedwt_period_exc_day_id": 2037, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2202, + "pedwt_period_exc_day_id": 2038, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2226, + "pedwt_period_exc_day_id": 2016, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2245, + "pedwt_period_exc_day_id": 2035, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2246, + "pedwt_period_exc_day_id": 2036, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2249, + "pedwt_period_exc_day_id": 2050, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2250, + "pedwt_period_exc_day_id": 2051, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2251, + "pedwt_period_exc_day_id": 2052, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2252, + "pedwt_period_exc_day_id": 2053, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2253, + "pedwt_period_exc_day_id": 2054, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2254, + "pedwt_period_exc_day_id": 2055, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2255, + "pedwt_period_exc_day_id": 2056, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2256, + "pedwt_period_exc_day_id": 2057, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2257, + "pedwt_period_exc_day_id": 2058, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2258, + "pedwt_period_exc_day_id": 2059, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2259, + "pedwt_period_exc_day_id": 2060, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + } + ], + "SpecialDays": [ + { + "ped_id": 11, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2023-12-08", + "ped_date_end": "2023-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 13, + "ped_label": "Christtag", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 14, + "ped_label": "Stefanitag", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2016, + "ped_label": "Neujahr", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2021, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2024-01-06", + "ped_date_end": "2024-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2022, + "ped_label": "Ostermontag", + "ped_date_start": "2024-01-04", + "ped_date_end": "2024-01-04", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2024, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2025, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2024-05-09", + "ped_date_end": "2024-05-09", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2026, + "ped_label": "Pfingst Montag", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2027, + "ped_label": "Fronleichnam", + "ped_date_start": "2024-05-30", + "ped_date_end": "2024-05-30", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2028, + "ped_label": "Maria Himmelfahrt", + "ped_date_start": "2024-08-15", + "ped_date_end": "2024-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2029, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2024-10-26", + "ped_date_end": "2024-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2030, + "ped_label": "Allerheiligen", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2031, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2024-08-12", + "ped_date_end": "2024-08-12", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2032, + "ped_label": "Christtag", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2034, + "ped_label": "Stefanitag", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2035, + "ped_label": "Neujahr", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2036, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2025-06-01", + "ped_date_end": "2025-06-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2037, + "ped_label": "Ostermontag", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2038, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2050, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2025-05-29", + "ped_date_end": "2025-05-29", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2051, + "ped_label": "Pfingstmontag", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2052, + "ped_label": "Fronlaeichnam", + "ped_date_start": "2025-06-19", + "ped_date_end": "2025-06-19", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2053, + "ped_label": "Mariae Himmelfahrt", + "ped_date_start": "2025-08-15", + "ped_date_end": "2025-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2054, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2025-10-26", + "ped_date_end": "2025-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2055, + "ped_label": "Allerheiligen", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2056, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2025-12-08", + "ped_date_end": "2025-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2057, + "ped_label": "Christtag", + "ped_date_start": "2025-12-25", + "ped_date_end": "2025-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2058, + "ped_label": "Stefanitag", + "ped_date_start": "2025-12-26", + "ped_date_end": "2025-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2059, + "ped_label": "Neujahr", + "ped_date_start": "2026-01-01", + "ped_date_end": "2026-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2060, + "ped_label": "Heilige Drei Koenige", + "ped_date_start": "2026-01-06", + "ped_date_end": "2026-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ] +} diff --git a/tariffs/tariff_linsinger_maschinenbau.json b/tariffs/tariff_linsinger_maschinenbau.json new file mode 100644 index 0000000..5773c8c --- /dev/null +++ b/tariffs/tariff_linsinger_maschinenbau.json @@ -0,0 +1,598 @@ +{ + "Project" : "Linsinger Maschinenbau", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 1, + "pcu_sign": "€", + "pcu_major": "EUR", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone 1", + "pop_payment_method_id": 4, + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", + "pop_price_night": 0, + "pop_min_time": 1, + "pop_max_time": 2, + "pop_min_price": 900, + "pop_carry_over": 0, + "pop_daily_card_price": 0, + "pop_business_hours": 2 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 900 + }, + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 2, + "pra_price": 1500 + }, + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 3, + "pra_price": 3000 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "3 Marken", + "pun_duration": 180 + }, + { + "pun_id": 2, + "pun_label": "5 Marken", + "pun_duration": 300 + }, + { + "pun_id": 3, + "pun_label": "10 Marken", + "pun_duration": 600 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "06:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "06:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "06:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "06:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "06:00:00", + "pwd_time_to": "12:00:00" + } + ], + "SpecialDaysWorktime": [ + { + "pedwt_id": 2156, + "pedwt_period_exc_day_id": 2024, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2158, + "pedwt_period_exc_day_id": 2025, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2160, + "pedwt_period_exc_day_id": 2026, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2162, + "pedwt_period_exc_day_id": 2027, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2164, + "pedwt_period_exc_day_id": 2028, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2170, + "pedwt_period_exc_day_id": 2030, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2172, + "pedwt_period_exc_day_id": 2032, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2174, + "pedwt_period_exc_day_id": 11, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2175, + "pedwt_period_exc_day_id": 13, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2178, + "pedwt_period_exc_day_id": 2022, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2179, + "pedwt_period_exc_day_id": 14, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2184, + "pedwt_period_exc_day_id": 2021, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2188, + "pedwt_period_exc_day_id": 2031, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2189, + "pedwt_period_exc_day_id": 2029, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2194, + "pedwt_period_exc_day_id": 2034, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2200, + "pedwt_period_exc_day_id": 2037, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2202, + "pedwt_period_exc_day_id": 2038, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2226, + "pedwt_period_exc_day_id": 2016, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2245, + "pedwt_period_exc_day_id": 2035, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2246, + "pedwt_period_exc_day_id": 2036, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2249, + "pedwt_period_exc_day_id": 2050, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2250, + "pedwt_period_exc_day_id": 2051, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2251, + "pedwt_period_exc_day_id": 2052, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2252, + "pedwt_period_exc_day_id": 2053, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2253, + "pedwt_period_exc_day_id": 2054, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2254, + "pedwt_period_exc_day_id": 2055, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2255, + "pedwt_period_exc_day_id": 2056, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2256, + "pedwt_period_exc_day_id": 2057, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2257, + "pedwt_period_exc_day_id": 2058, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2258, + "pedwt_period_exc_day_id": 2059, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2259, + "pedwt_period_exc_day_id": 2060, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + } + ], + "SpecialDays": [ + { + "ped_id": 11, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2023-12-08", + "ped_date_end": "2023-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 13, + "ped_label": "Christtag", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 14, + "ped_label": "Stefanitag", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2016, + "ped_label": "Neujahr", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2021, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2024-01-06", + "ped_date_end": "2024-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2022, + "ped_label": "Ostermontag", + "ped_date_start": "2024-01-04", + "ped_date_end": "2024-01-04", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2024, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2025, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2024-05-09", + "ped_date_end": "2024-05-09", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2026, + "ped_label": "Pfingst Montag", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2027, + "ped_label": "Fronleichnam", + "ped_date_start": "2024-05-30", + "ped_date_end": "2024-05-30", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2028, + "ped_label": "Maria Himmelfahrt", + "ped_date_start": "2024-08-15", + "ped_date_end": "2024-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2029, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2024-10-26", + "ped_date_end": "2024-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2030, + "ped_label": "Allerheiligen", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2031, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2024-08-12", + "ped_date_end": "2024-08-12", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2032, + "ped_label": "Christtag", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2034, + "ped_label": "Stefanitag", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2035, + "ped_label": "Neujahr", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2036, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2025-06-01", + "ped_date_end": "2025-06-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2037, + "ped_label": "Ostermontag", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2038, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2050, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2025-05-29", + "ped_date_end": "2025-05-29", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2051, + "ped_label": "Pfingstmontag", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2052, + "ped_label": "Fronlaeichnam", + "ped_date_start": "2025-06-19", + "ped_date_end": "2025-06-19", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2053, + "ped_label": "Mariae Himmelfahrt", + "ped_date_start": "2025-08-15", + "ped_date_end": "2025-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2054, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2025-10-26", + "ped_date_end": "2025-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2055, + "ped_label": "Allerheiligen", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2056, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2025-12-08", + "ped_date_end": "2025-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2057, + "ped_label": "Christtag", + "ped_date_start": "2025-12-25", + "ped_date_end": "2025-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2058, + "ped_label": "Stefanitag", + "ped_date_start": "2025-12-26", + "ped_date_end": "2025-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2059, + "ped_label": "Neujahr", + "ped_date_start": "2026-01-01", + "ped_date_end": "2026-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2060, + "ped_label": "Heilige Drei Koenige", + "ped_date_start": "2026-01-06", + "ped_date_end": "2026-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ] +} diff --git a/tariffs/tariff_naz.json b/tariffs/tariff_naz.json new file mode 100644 index 0000000..53d5b36 --- /dev/null +++ b/tariffs/tariff_naz.json @@ -0,0 +1,217 @@ +{ + "Project" : "Nordisches Ausbildungszentrum", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 1, + "pcu_sign": "€", + "pcu_major": "EUR", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "TimeBase": [ + { + "tbase_id": 0, + "tbase_type": 0, + "tbase_type_comment": "time is given as starting from some wall-clock-time", + "tbase_label": "absolute time" + }, + { + "tbase_id": 1, + "tbase_type": 1, + "tbase_type_comment": "time is given as starting from 0 minutes", + "tbase_label": "relative time" + } + ], + "TimeRange" : [ + { + "time_range_id": 1, + "time_range_from": "00:00:00", + "time_range_to": "00:01:00", + "time_range_comment": "- <= 60secs -> time range is time point " + } + ], + "TimeStepConfig" : [ + { + "tsconfig_id" : 1, + "tsconfig_label" : "static", + "tsconfig_comment" : "read time steps as given in jsonfiles" + }, + { + "tsconfig_id" : 2, + "tsconfig_label" : "dynamic", + "tsconfig_comment" : "determine timesteps at runtime" + } + ], + "Customer": [ + { + "cust_id": 1, + "cust_type": 1000, + "cust_label": "Adult" + }, + { + "cust_id": 2, + "cust_type": 1001, + "cust_label": "Child" + }, + { + "cust_id": 3, + "cust_type": 1002, + "cust_label": "Teen" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone 1", + "pop_payment_method_id": 4, + "pop_day_end_time": "08:00:00", + "pop_day_night_end_time": "20:00:00", + "pop_price_night": 0, + "pop_min_time": 1, + "pop_max_time": 720, + "pop_min_price": 400, + "pop_carry_over": 0, + "pop_daily_card_price": 0, + "pop_business_hours": 128 + }, + { + "pop_id": 1050, + "pop_label": "Zone 1", + "pop_payment_method_id": 4, + "pop_day_end_time": "08:00:00", + "pop_day_night_end_time": "20:00:00", + "pop_price_night": 0, + "pop_min_time": 1, + "pop_max_time": 720, + "pop_min_price": 800, + "pop_carry_over": 0, + "pop_daily_card_price": 0, + "pop_business_hours": 128 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 400 + }, + { + "pra_payment_option_id": 1050, + "pra_payment_unit_id": 2, + "pra_price": 800 + } + ], + "DailyTicket": [ + { + "daily_ticket_payment_option_id": 1049, + "daily_ticket_id": 1, + "daily_ticket_price_id": 1, + "daily_ticket_tb_id": 1, + "daily_ticket_clearance_customer_ids": [3], + "daily_ticket_from_min": "08:00:00", + "daily_ticket_to_max": "20:00:00", + "daily_ticket_from_offset_min": 0, + "daily_ticket_to_offset_max": 0 + }, + { + "daily_ticket_payment_option_id": 1050, + "daily_ticket_id": 2, + "daily_ticket_price_id": 2, + "daily_ticket_tb_id": 1, + "daily_ticket_clearance_customer_ids": [1], + "daily_ticket_from_min": "08:00:00", + "daily_ticket_to_max": "20:00:00", + "daily_ticket_from_offset_min": 0, + "daily_ticket_to_offset_max": 0 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "Tagesticket", + "pun_duration": 720 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 626, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 6, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + }, + { + "pwd_id": 627, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 7, + "pwd_time_from": "08:00:00", + "pwd_time_to": "20:00:00" + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ] +} diff --git a/tariffs/tariff_new_01.json b/tariffs/tariff_new_01.json new file mode 100644 index 0000000..debedfa --- /dev/null +++ b/tariffs/tariff_new_01.json @@ -0,0 +1,805 @@ +{ + "Currency": [ + { + "pcu_id": 2, + "pcu_sign": "Ft", + "pcu_major": "HUF", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone Lila", + "pop_payment_method_id": 3, + "pop_day_end_time": "16:25:00", + "pop_day_night_end_time": "16:25:00", + "pop_price_night": 0, + "pop_min_time": 15, + "pop_max_time": 300, + "pop_min_price": 0, + "pop_carry_over": 1, + "pop_daily_card_price": 900 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 150 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "1h", + "pun_duration": 60 + }, + { + "pun_id": 3, + "pun_label": "15 min", + "pun_duration": 15 + }, + { + "pun_id": 4, + "pun_label": "1 min", + "pun_duration": 1 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "08:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "08:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "08:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "08:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "08:00:00", + "pwd_time_to": "18:00:00" + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 9, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 10, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 11, + "pye_label": "Whole Year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 12, + "pye_label": "Whole Year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 13, + "pye_label": "Whole Year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 14, + "pye_label": "Whole Year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + }, + { + "pye_id": 15, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ], + "SpecialDaysWorktime": [ + { + "pedwt_id": 2156, + "pedwt_period_exc_day_id": 2024, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2158, + "pedwt_period_exc_day_id": 2025, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2160, + "pedwt_period_exc_day_id": 2026, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2162, + "pedwt_period_exc_day_id": 2027, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2164, + "pedwt_period_exc_day_id": 2028, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2170, + "pedwt_period_exc_day_id": 2030, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2172, + "pedwt_period_exc_day_id": 2032, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2174, + "pedwt_period_exc_day_id": 11, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2175, + "pedwt_period_exc_day_id": 13, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2178, + "pedwt_period_exc_day_id": 2022, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2179, + "pedwt_period_exc_day_id": 14, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2184, + "pedwt_period_exc_day_id": 2021, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2188, + "pedwt_period_exc_day_id": 2031, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2189, + "pedwt_period_exc_day_id": 2029, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2194, + "pedwt_period_exc_day_id": 2034, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2200, + "pedwt_period_exc_day_id": 2037, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2202, + "pedwt_period_exc_day_id": 2038, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2226, + "pedwt_period_exc_day_id": 2016, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2245, + "pedwt_period_exc_day_id": 2035, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2246, + "pedwt_period_exc_day_id": 2036, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2249, + "pedwt_period_exc_day_id": 2050, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2250, + "pedwt_period_exc_day_id": 2051, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2251, + "pedwt_period_exc_day_id": 2052, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2252, + "pedwt_period_exc_day_id": 2053, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2253, + "pedwt_period_exc_day_id": 2054, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2254, + "pedwt_period_exc_day_id": 2055, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2255, + "pedwt_period_exc_day_id": 2056, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2256, + "pedwt_period_exc_day_id": 2057, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2257, + "pedwt_period_exc_day_id": 2058, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2258, + "pedwt_period_exc_day_id": 2059, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2259, + "pedwt_period_exc_day_id": 2060, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2260, + "pedwt_period_exc_day_id": 2061, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2261, + "pedwt_period_exc_day_id": 2062, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2262, + "pedwt_period_exc_day_id": 2063, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2263, + "pedwt_period_exc_day_id": 2064, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2264, + "pedwt_period_exc_day_id": 2065, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2265, + "pedwt_period_exc_day_id": 2066, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2266, + "pedwt_period_exc_day_id": 2067, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2267, + "pedwt_period_exc_day_id": 2068, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2268, + "pedwt_period_exc_day_id": 2069, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2269, + "pedwt_period_exc_day_id": 2070, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2270, + "pedwt_period_exc_day_id": 2071, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + } + ], + "SpecialDays": [ + { + "ped_id": 2016, + "ped_label": "Christmas", + "ped_date_start": "2023-12-24", + "ped_date_end": "2023-12-24", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 11, + "ped_label": "Christmas 1st day", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 13, + "ped_label": "Christmas 2nd day", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2022, + "ped_label": "NewYear", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 14, + "ped_label": "1848 Revolution Memorial Day", + "ped_date_start": "2024-03-15", + "ped_date_end": "2024-03-15", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2024, + "ped_label": "Good Friday", + "ped_date_start": "2024-03-29", + "ped_date_end": "2024-03-29", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2025, + "ped_label": "Easter Sunday", + "ped_date_start": "2024-03-31", + "ped_date_end": "2024-03-31", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2026, + "ped_label": "Easter Monday", + "ped_date_start": "2024-04-01", + "ped_date_end": "2024-04-01", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2030, + "ped_label": "Labour Day", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2027, + "ped_label": "Whit Sunday", + "ped_date_start": "2024-05-19", + "ped_date_end": "2024-05-19", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2028, + "ped_label": "Whit Monday", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2031, + "ped_label": "National Day", + "ped_date_start": "2024-08-20", + "ped_date_end": "2024-08-20", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2054, + "ped_label": "1956 Revolution Memorial Day", + "ped_date_start": "2024-10-23", + "ped_date_end": "2024-10-23", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2032, + "ped_label": "All Saints Day", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2055, + "ped_label": "Christmas", + "ped_date_start": "2024-12-24", + "ped_date_end": "2024-12-24", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2052, + "ped_label": "Christmas 1st day", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2053, + "ped_label": "Christmas 2nd day", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2057, + "ped_label": "NewYear", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2029, + "ped_label": "1848 Revolution Memorial Day", + "ped_date_start": "2025-03-15", + "ped_date_end": "2025-03-15", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2034, + "ped_label": "Good Friday", + "ped_date_start": "2025-04-18", + "ped_date_end": "2025-04-18", + "ped_period_special_day_id": 2, + "ped_year": 2025 + }, + { + "ped_id": 2035, + "ped_label": "Easter", + "ped_date_start": "2025-04-20", + "ped_date_end": "2025-04-20", + "ped_period_special_day_id": 2, + "ped_year": 2025 + }, + { + "ped_id": 2036, + "ped_label": "Easter Monday", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 2, + "ped_year": 2025 + }, + { + "ped_id": 2064, + "ped_label": "Labour Day", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2038, + "ped_label": "Whit Sunday", + "ped_date_start": "2024-06-08", + "ped_date_end": "2024-06-08", + "ped_period_special_day_id": 2, + "ped_year": 2025 + }, + { + "ped_id": 2037, + "ped_label": "Whit Monday", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", + "ped_period_special_day_id": 2, + "ped_year": 2025 + }, + { + "ped_id": 2065, + "ped_label": "<<<<< Hungary National Day >>>>>", + "ped_date_start": "2025-08-20", + "ped_date_end": "2025-08-20", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2021, + "ped_label": "Holiday (Hungary)", + "ped_date_start": "2023-12-31", + "ped_date_end": "2023-12-31", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2050, + "ped_label": "Uskrs", + "ped_date_start": "2023-04-16", + "ped_date_end": "2023-04-16", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2051, + "ped_label": "Uskrs", + "ped_date_start": "2023-04-16", + "ped_date_end": "2023-04-16", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2056, + "ped_label": "Holiday (Hungary)", + "ped_date_start": "2022-12-31", + "ped_date_end": "2022-12-31", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2058, + "ped_label": "Good Friday", + "ped_date_start": "2023-04-07", + "ped_date_end": "2023-04-07", + "ped_period_special_day_id": 2, + "ped_year": 2023 + }, + { + "ped_id": 2059, + "ped_label": "Easter Sunday", + "ped_date_start": "2023-04-09", + "ped_date_end": "2023-04-09", + "ped_period_special_day_id": 2, + "ped_year": 2023 + }, + { + "ped_id": 2060, + "ped_label": "Easter Monday", + "ped_date_start": "2023-04-10", + "ped_date_end": "2023-04-10", + "ped_period_special_day_id": 2, + "ped_year": 2023 + }, + { + "ped_id": 2061, + "ped_label": "Whit Sunday", + "ped_date_start": "2023-05-28", + "ped_date_end": "2023-05-28", + "ped_period_special_day_id": 2, + "ped_year": 2023 + }, + { + "ped_id": 2062, + "ped_label": "Whit Monday", + "ped_date_start": "2023-05-29", + "ped_date_end": "2023-05-29", + "ped_period_special_day_id": 2, + "ped_year": 2023 + }, + { + "ped_id": 2063, + "ped_label": "Revolution Day (Hungary)", + "ped_date_start": "2023-03-15", + "ped_date_end": "2023-03-15", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2066, + "ped_label": "All Saints Day", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 2, + "ped_year": 0 + }, + { + "ped_id": 2067, + "ped_label": "Good Friday", + "ped_date_start": "2024-03-29", + "ped_date_end": "2024-03-29", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2068, + "ped_label": "Easter", + "ped_date_start": "2024-03-31", + "ped_date_end": "2024-03-31", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2069, + "ped_label": "Easter Monday", + "ped_date_start": "2024-04-01", + "ped_date_end": "2024-04-01", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2070, + "ped_label": "Whit Monday", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 2, + "ped_year": 2024 + }, + { + "ped_id": 2071, + "ped_label": "Whit Sunday", + "ped_date_start": "2024-05-19", + "ped_date_end": "2024-05-19", + "ped_period_special_day_id": 2, + "ped_year": 2024 + } + ] +} diff --git a/test-files/tariff_korneuburg.json b/test-files/tariff_korneuburg.json new file mode 100644 index 0000000..8662012 --- /dev/null +++ b/test-files/tariff_korneuburg.json @@ -0,0 +1,629 @@ +{ + "Project" : "Korneuburg", + "Version" : "1.0.0", + "Info" : "", + "Currency": [ + { + "pcu_id": 2, + "pcu_sign": "€", + "pcu_major": "EUR", + "pcu_minor": "", + "pcu_active": true + } + ], + "PaymentMethod": [ + { + "pme_id": 1, + "pme_label": "progressive" + }, + { + "pme_id": 2, + "pme_label": "degressive" + }, + { + "pme_id": 3, + "pme_label": "linear" + }, + { + "pme_id": 4, + "pme_label": "steps" + } + ], + "PaymentOption": [ + { + "pop_id": 1049, + "pop_label": "Zone 1", + "pop_payment_method_id": 3, + "pop_day_end_time": "00:00:00", + "pop_day_night_end_time": "00:00:00", + "pop_price_night": 0, + "pop_min_time": 30, + "pop_max_time": 180, + "pop_min_price": 60, + "pop_carry_over": 1, + "pop_daily_card_price": 0 + } + ], + "PaymentRate": [ + { + "pra_payment_option_id": 1049, + "pra_payment_unit_id": 1, + "pra_price": 10 + } + ], + "Duration": [ + { + "pun_id": 1, + "pun_label": "5 min", + "pun_duration": 5 + }, + { + "pun_id": 3, + "pun_label": "15 min", + "pun_duration": 15 + }, + { + "pun_id": 4, + "pun_label": "1 min", + "pun_duration": 1 + } + ], + "WeekDaysWorktime": [ + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 621, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 1, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 622, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 2, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 623, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 3, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 624, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 4, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + }, + { + "pwd_id": 625, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 5, + "pwd_time_from": "14:00:00", + "pwd_time_to": "18:00:00" + }, + { + "pwd_id": 626, + "pwd_period_week_day_id": 36, + "pwd_period_day_in_week_id": 6, + "pwd_time_from": "08:00:00", + "pwd_time_to": "12:00:00" + } + ], + "SpecialDaysWorktime": [ + { + "pedwt_id": 2156, + "pedwt_period_exc_day_id": 2024, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2158, + "pedwt_period_exc_day_id": 2025, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2160, + "pedwt_period_exc_day_id": 2026, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2162, + "pedwt_period_exc_day_id": 2027, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2164, + "pedwt_period_exc_day_id": 2028, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2170, + "pedwt_period_exc_day_id": 2030, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2172, + "pedwt_period_exc_day_id": 2032, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2174, + "pedwt_period_exc_day_id": 11, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2175, + "pedwt_period_exc_day_id": 13, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2178, + "pedwt_period_exc_day_id": 2022, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2179, + "pedwt_period_exc_day_id": 14, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2184, + "pedwt_period_exc_day_id": 2021, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2188, + "pedwt_period_exc_day_id": 2031, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2189, + "pedwt_period_exc_day_id": 2029, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2194, + "pedwt_period_exc_day_id": 2034, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2200, + "pedwt_period_exc_day_id": 2037, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2202, + "pedwt_period_exc_day_id": 2038, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2226, + "pedwt_period_exc_day_id": 2016, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2245, + "pedwt_period_exc_day_id": 2035, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2246, + "pedwt_period_exc_day_id": 2036, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2249, + "pedwt_period_exc_day_id": 2050, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2250, + "pedwt_period_exc_day_id": 2051, + "pedwt_time_from": "08:00:00", + "pedwt_time_to": "16:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2251, + "pedwt_period_exc_day_id": 2052, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2252, + "pedwt_period_exc_day_id": 2053, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2253, + "pedwt_period_exc_day_id": 2054, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2254, + "pedwt_period_exc_day_id": 2055, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2255, + "pedwt_period_exc_day_id": 2056, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2256, + "pedwt_period_exc_day_id": 2057, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2257, + "pedwt_period_exc_day_id": 2058, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2258, + "pedwt_period_exc_day_id": 2059, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + }, + { + "pedwt_id": 2259, + "pedwt_period_exc_day_id": 2060, + "pedwt_time_from": "00:00:00", + "pedwt_time_to": "00:00:00", + "pedwt_price": 0 + } + ], + "SpecialDays": [ + { + "ped_id": 11, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2023-12-08", + "ped_date_end": "2023-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 13, + "ped_label": "Christtag", + "ped_date_start": "2023-12-25", + "ped_date_end": "2023-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 14, + "ped_label": "Stefanitag", + "ped_date_start": "2023-12-26", + "ped_date_end": "2023-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2016, + "ped_label": "Neujahr", + "ped_date_start": "2024-01-01", + "ped_date_end": "2024-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2021, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2024-01-06", + "ped_date_end": "2024-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2022, + "ped_label": "Ostermontag", + "ped_date_start": "2024-01-04", + "ped_date_end": "2024-01-04", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2024, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2024-05-01", + "ped_date_end": "2024-05-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2025, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2024-05-09", + "ped_date_end": "2024-05-09", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2026, + "ped_label": "Pfingst Montag", + "ped_date_start": "2024-05-20", + "ped_date_end": "2024-05-20", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2027, + "ped_label": "Fronleichnam", + "ped_date_start": "2024-05-30", + "ped_date_end": "2024-05-30", + "ped_period_special_day_id": 1, + "ped_year": 2024 + }, + { + "ped_id": 2028, + "ped_label": "Maria Himmelfahrt", + "ped_date_start": "2024-08-15", + "ped_date_end": "2024-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2029, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2024-10-26", + "ped_date_end": "2024-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2030, + "ped_label": "Allerheiligen", + "ped_date_start": "2024-11-01", + "ped_date_end": "2024-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2031, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2024-08-12", + "ped_date_end": "2024-08-12", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2032, + "ped_label": "Christtag", + "ped_date_start": "2024-12-25", + "ped_date_end": "2024-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2034, + "ped_label": "Stefanitag", + "ped_date_start": "2024-12-26", + "ped_date_end": "2024-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2035, + "ped_label": "Neujahr", + "ped_date_start": "2025-01-01", + "ped_date_end": "2025-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2036, + "ped_label": "Heilig Drei Koenige", + "ped_date_start": "2025-06-01", + "ped_date_end": "2025-06-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2037, + "ped_label": "Ostermontag", + "ped_date_start": "2025-04-21", + "ped_date_end": "2025-04-21", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2038, + "ped_label": "Staatsfeiertag", + "ped_date_start": "2025-05-01", + "ped_date_end": "2025-05-01", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2050, + "ped_label": "Christi Himmelfahrt", + "ped_date_start": "2025-05-29", + "ped_date_end": "2025-05-29", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2051, + "ped_label": "Pfingstmontag", + "ped_date_start": "2025-06-09", + "ped_date_end": "2025-06-09", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2052, + "ped_label": "Fronlaeichnam", + "ped_date_start": "2025-06-19", + "ped_date_end": "2025-06-19", + "ped_period_special_day_id": 1, + "ped_year": 2025 + }, + { + "ped_id": 2053, + "ped_label": "Mariae Himmelfahrt", + "ped_date_start": "2025-08-15", + "ped_date_end": "2025-08-15", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2054, + "ped_label": "Nationalfeiertag", + "ped_date_start": "2025-10-26", + "ped_date_end": "2025-10-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2055, + "ped_label": "Allerheiligen", + "ped_date_start": "2025-11-01", + "ped_date_end": "2025-11-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2056, + "ped_label": "Mariae Empfaengnis", + "ped_date_start": "2025-12-08", + "ped_date_end": "2025-12-08", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2057, + "ped_label": "Christtag", + "ped_date_start": "2025-12-25", + "ped_date_end": "2025-12-25", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2058, + "ped_label": "Stefanitag", + "ped_date_start": "2025-12-26", + "ped_date_end": "2025-12-26", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2059, + "ped_label": "Neujahr", + "ped_date_start": "2026-01-01", + "ped_date_end": "2026-01-01", + "ped_period_special_day_id": 1, + "ped_year": 0 + }, + { + "ped_id": 2060, + "ped_label": "Heilige Drei Koenige", + "ped_date_start": "2026-01-06", + "ped_date_end": "2026-01-06", + "ped_period_special_day_id": 1, + "ped_year": 0 + } + ], + "PeriodYear": [ + { + "pye_id": 8, + "pye_label": "Whole year", + "pye_start_month": 1, + "pye_start_day": 1, + "pye_end_month": 12, + "pye_end_day": 31 + } + ] +} diff --git a/vue/become_a_ninja_with_vue_sample.pdf b/vue/become_a_ninja_with_vue_sample.pdf new file mode 100644 index 0000000..d5edfe6 Binary files /dev/null and b/vue/become_a_ninja_with_vue_sample.pdf differ diff --git a/vue/javascript-the-gefinitive-guide-6th-edition.pdf b/vue/javascript-the-gefinitive-guide-6th-edition.pdf new file mode 100644 index 0000000..1bef08c Binary files /dev/null and b/vue/javascript-the-gefinitive-guide-6th-edition.pdf differ diff --git a/vue/vue.js-in-action.pdf b/vue/vue.js-in-action.pdf new file mode 100644 index 0000000..020a88e Binary files /dev/null and b/vue/vue.js-in-action.pdf differ