#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 { 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 /// /// Pointer to configuration /// Type of vehicle /// 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::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 /// /// Pointer to configuration /// Type of vehicle /// Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) /// 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, 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, 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); } 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, 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, 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