Compare commits

..

5 Commits

41 changed files with 1663 additions and 12521 deletions

1
\
View File

@ -1 +0,0 @@
return std::make_pair(CalcState(CalcState::State::OVERPAID), dt);

View File

@ -1,83 +0,0 @@
#ifndef ATB_TIME_H_INCLUDED
#define ATB_TIME_H_INCLUDED
#include <QDateTime>
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

View File

@ -56,7 +56,6 @@ struct CALCULATE_LIBRARY_API CalcState {
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,
@ -72,8 +71,7 @@ struct CALCULATE_LIBRARY_API CalcState {
BELOW_MIN_PARKING_PRICE,
ABOVE_MAX_PARKING_PRICE,
OVERPAID,
OUTSIDE_ALLOWED_PARKING_TIME,
SUCCESS_MAXPRICE
OUTSIDE_ALLOWED_PARKING_TIME
};
State m_status;
@ -90,9 +88,9 @@ struct CALCULATE_LIBRARY_API CalcState {
, m_desc(desc) {
}
explicit CalcState(State state, QString desc,
QTime const &from,
QTime const &until)
explicit CalcState(State state, QString desc = "",
QTime const &from = QTime(),
QTime const &until = QTime())
: m_status(state)
, m_desc(desc)
, m_allowedTimeRange(from, until) {
@ -108,9 +106,6 @@ struct CALCULATE_LIBRARY_API CalcState {
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;
@ -163,9 +158,6 @@ struct CALCULATE_LIBRARY_API CalcState {
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;
@ -215,9 +207,6 @@ struct CALCULATE_LIBRARY_API CalcState {
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
@ -277,8 +266,7 @@ 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);
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown);
QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg);
@ -309,8 +297,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // depre
parking_tariff_t *tariff,
time_t start_parking_time,
time_t end_parking_time,
struct price_t *price,
PermitType permitType);
struct price_t *price);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff,
@ -318,28 +305,24 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
int netto_parking_time,
QDateTime &end_parking_time, // 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,
PermitType permitType);
QString &duration);
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
double cost,
QDateTime &ticketEndTime,
PermitType permitType); // return value
QDateTime &ticketEndTime); // return value
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime &ticketEndTime,
PermitType permitType);
QDateTime &ticketEndTime);
CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket(
parking_tariff_t *tariff,

View File

@ -3,7 +3,6 @@
#include <iostream>
#include <optional>
#include <utility>
#include "configuration.h"
#include "calculate_price.h"
@ -27,16 +26,9 @@ class Calculator {
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;
}
explicit Calculator() = default;
public:
Calculator(Calculator const &other) = delete;
@ -47,19 +39,13 @@ public:
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()) {
if (m_timeSteps.size() > 0) {
m_timeSteps[paymentOptionIndex].clear();
}
}
QList<int> timeSteps(int paymentOptionIndex=0) const {
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
if (m_timeSteps.size() > 0) {
return m_timeSteps[paymentOptionIndex];
}
return QList<int>();
@ -84,9 +70,7 @@ public:
/// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z)</param>
/// <param name="price"></param>
/// <returns>Returns duration in seconds (data type: double)</returns>
std::pair<std::string, QDateTime>
GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price,
PermitType permitType, bool nextDay = false, bool prepaid = false);
std::string GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price, bool nextDay = false, bool prepaid = false);
/// <summary>
/// Gets cost from duration in seconds
@ -97,11 +81,7 @@ public:
/// <param name="end_datetime">Date/time of park end to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param>
/// <param name="durationMin">Duration of parking in minutes</param>
/// <returns>Returns cost (data type: double)</returns>
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<CalcState, QDateTime> ComputeDurationFromCost(Configuration *cfg, QDateTime const &startDatetimePassed, int cost);
std::pair<CalcState, std::optional<int>> ComputeCostFromDuration(Configuration *cfg, QDateTime const &startDatetime, QDateTime &endDatetime, int nettoParkingTime);
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin, bool nextDay = false, bool prepaid = false);
// Daily ticket
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
@ -111,10 +91,8 @@ public:
// helper function to find time steps for a tariff with PaymentMethod::Steps
// (e.g. Schoenau/Koenigsee)
//
QList<int> &GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const;
QList<int> GetSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const {
return GetTimeSteps(cfg, paymentOptionIndex, start);
}
QList<int> &GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0) const;
QList<int> GetSteps(Configuration *cfg, int paymentOptionIndex=0) const { return GetTimeSteps(cfg, paymentOptionIndex); }
QList<int> GetPriceSteps(Configuration *cfg) const;
@ -137,7 +115,7 @@ public:
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:
// private:
Ticket private_GetCostFromDuration(Configuration const* cfg,
QDateTime const &start,
int durationMinutes,
@ -151,10 +129,10 @@ private:
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 GetPriceForTimeStep(Configuration *cfg, int timeStep, int paymentOptionIndex=0) const;
uint32_t GetPriceForStep(Configuration *cfg, int step) const {
return GetPriceForTimeStep(cfg, step);
}
uint32_t GetDurationForPrice(Configuration *cfg, int price) const;
uint32_t GetStepForPrice(Configuration *cfg, int price) const {
return GetDurationForPrice(cfg, price);

View File

@ -25,12 +25,6 @@
#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 <QVector>
#include <optional>
@ -38,7 +32,6 @@
using namespace std;
using namespace rapidjson;
class Calculator;
class Configuration
{
@ -48,41 +41,26 @@ public:
using TimeRangeType = std::multimap<int, ATBTimeRange>;
using TariffProductType = std::multimap<int, ATBTariffProduct>;
using ATBPaymentOptionType = std::multimap<int, ATBPaymentOption>;
using TariffInterpolationType = std::multimap<int, ATBInterpolation>;
using TariffPrepaidType = std::multimap<int, ATBPrepaid>;
using TariffCarryOverType = std::multimap<int, ATBCarryOver>;
using TariffDurationType = std::multimap<int, ATBDuration>;
using TariffServiceType = std::multimap<int, ATBTariffService>;
using TariffOutOfServiceType = std::multimap<int, ATBTariffOutOfService>;
using ATBTariffPrepaidType = std::multimap<int, ATBTariffPrepaid>;
using ATBTariffCarryOverType = std::multimap<int, ATBTariffCarryOver>;
ATBProject project;
ATBCurrency Currency;
ATBDuration duration;
ATBDuration duration;
TariffDurationType Duration;
multimap<int, ATBDuration> Duration;
multimap<int, ATBPaymentMethod> PaymentMethod;
multimap<int, ATBPaymentRate> PaymentRate;
SpecialDaysWorktimeType SpecialDaysWorktime;
SpecialDaysType SpecialDays;
multimap<Qt::DayOfWeek, ATBWeekDay> WeekDays;
SpecialDaysWorktimeType SpecialDaysWorktime;
SpecialDaysType SpecialDays;
multimap<int, ATBWeekDays> WeekDays;
multimap<int, ATBPeriodYear> YearPeriod;
multimap<int, ATBWeekDaysWorktime> WeekDaysWorktime;
ATBPaymentOptionType PaymentOption;
multimap<int, ATBDailyTicket> DailyTicket;
TimeRangeType TimeRange;
multimap<int, ATBTimeStepConfig> TimeStepConfig;
multimap<int, ATBTimeBase> TimeBase;
multimap<int, ATBCustomer> Customer;
TariffProductType TariffProduct;
TariffInterpolationType TariffInterpolations;
TariffPrepaidType TariffPrepaidOptions;
TariffCarryOverType TariffCarryOverOptions;
TariffServiceType TariffServices;
TariffOutOfServiceType TariffOutOfServices;
ATBTariffPrepaidType TariffPrepaids;
ATBTariffCarryOverType TariffCarryOvers;
ATBPaymentOptionType PaymentOption;
multimap<int, ATBDailyTicket> DailyTicket;
TimeRangeType TimeRange;
multimap<int, ATBTimeStepConfig> TimeStepConfig;
multimap<int, ATBTimeBase> TimeBase;
multimap<int, ATBCustomer> Customer;
TariffProductType TariffProduct;
/// <summary>
/// Parse JSON string
@ -104,28 +82,15 @@ public:
bool isDayIncludedAsSpecialDay(uint64_t businessHours, QDateTime const &dt) const;
bool isDayIncludedAsSpecialDay(uint64_t businessHours, int specialDayId) const;
std::optional<QVector<ATBPaymentRate>> getPaymentRateForAllKeys() const;
std::optional<QVector<ATBPaymentOption>> getPaymentOptionsForAllKeys() const;
std::optional<ATBPaymentOption> getPaymentOptionForId(int key) const;
std::optional<QVector<ATBPaymentRate>> getPaymentRateForKey(int key) const;
std::optional<ATBPaymentOption> getPaymentOptionForKey(PERMIT_TYPE permitType) const;
std::optional<ATBPaymentOption> getPaymentOptionForKey(int permitType) const;
std::optional<ATBPaymentOption> getPaymentOptionForKey(QString const &permitType) const;
std::optional<QVector<ATBDailyTicket>> getDailyTicketsForAllKeys() const;
std::optional<QVector<ATBDailyTicket>> getDailyTicketsForKey(int key) const;
std::optional<ATBInterpolation> getInterpolationType(int type) const;
std::optional<QDateTime> getInterpolationEnd(QDateTime const &start, int paymentOptionIndex) const;
std::optional<ATBPrepaid> getPrepaidType(int type) const;
std::optional<QVector<ATBTariffProduct>> getTariffProductForAllKeys() const;
std::optional<QVector<ATBTariffProduct>> getTariffProductForProductId(int id) const;
std::optional<QVector<ATBTariffProduct>> getTariffProductForProductId(PermitType permitType) const;
std::optional<QVector<ATBTariffProduct>> getTariffProductForProductTypeName(QString const &permitTypeName) const;
std::optional<ATBCustomer> getCustomerForType(ATBCustomer::CustomerType customerType);
std::optional<ATBWeekDaysWorktime> getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek);
std::optional<QVector<ATBWeekDaysWorktime>> getAllWeekDayWorkTimes();
std::optional<QDateTime> prepaidStart(QDateTime const &start, int prepaid_option_id);
int getPaymentOptionIndex(PERMIT_TYPE permitType);
int getPaymentOptionIndex(PERMIT_TYPE permitType) const;
private:
/// <summary>
@ -135,17 +100,5 @@ private:
/// <returns></returns>
MemberType IdentifyJsonMember(const char* member_name);
QVector<ATBPaymentOption> currentPaymentOptions;
QVector<ATBPaymentOption> 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<false,
rapidjson::UTF8<char>,
rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>> k,
QString const &innerObjName,
Qt::DayOfWeek weekDay,
QString const &weekDayName);

View File

@ -1,40 +1,11 @@
#include <string>
#include <QDebug>
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;
int pun_duration_saved;
int pun_duration_min;
int pun_duration_max;
int pun_interpolation_id;
};

View File

@ -19,10 +19,7 @@ enum MemberType
TimeBaseType = 0x0C,
TimeRangeType = 0x0D,
TimeStepConfigType = 0x0E,
ProductType = 0x0F,
InterpolationType = 0x10,
PrepaidType = 0x11,
CarryOverType = 0x12
ProductType = 0x0F
};
#endif // MEMBER_TYPE_H_INCLUDED

View File

@ -6,8 +6,7 @@ enum PaymentMethod {
Progressive = 0x01,
Degressive = 0x02,
Linear = 0x03,
Steps = 0x04,
Unified = 0x05
Steps = 0x04
};
#endif // PAYMENT_METHOD_H_INCLUDED

View File

@ -15,8 +15,6 @@ public:
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 = "";
@ -25,36 +23,23 @@ public:
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_prepay = false;
pop_prepay_time_range_id = -1;
pop_prepay_over_start_time_range = -1;
pop_prepay_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 <x=1> steps forward
pop_plus_steps_saved = 1;
pop_minus_steps = 1; // -: jump <x=1> 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;
@ -62,25 +47,18 @@ public:
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;
bool pop_prepay;
int pop_prepay_time_range_id;
int pop_prepay_over_start_time_range;
int pop_prepay_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;

View File

@ -8,9 +8,5 @@ public:
int pedwt_period_exc_day_id;
std::string pedwt_time_from;
std::string pedwt_time_to;
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
};
double pedwt_price;
};

View File

@ -1,194 +0,0 @@
#ifndef TARIFF_CARRYOVER_H_INCLUDED
#define TARIFF_CARRYOVER_H_INCLUDED
#include <QTime>
#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<int>(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

View File

@ -1,69 +0,0 @@
#ifndef ATB_TARIFF_CARRYOVER_SETTINGS_H_INCLUDED
#define ATB_TARIFF_CARRYOVER_SETTINGS_H_INCLUDED
#include <QDebug>
#include <QDateTime>
#include <functional>
struct ATBTariffCarryOverSettings {
// parking time limit not violated: return false, otherwise: return true.
using ParkingTimeLimitChecker = std::function<bool(ATBTariffCarryOverSettings const&,
QDateTime const &startTime,
QDateTime const &endTime,
int paymentOptionIndex)>;
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

View File

@ -1,3 +1,4 @@
#pragma once
#include <variant>
#include <cstddef>
#include <stdio.h>

View File

@ -3,18 +3,4 @@
#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

View File

@ -1,95 +0,0 @@
#ifndef TARIFF_INTERPOLATION_H_INCLUDED
#define TARIFF_INTERPOLATION_H_INCLUDED
#include <QTime>
#include <QString>
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

View File

@ -14,8 +14,6 @@
void setDebugLevel(int level);
int getDebugLevel();
#if 0
static void print() {
std::cerr << "\n";
if (getDebugLevel() == DBG_LEVEL_FATAL) {
@ -77,6 +75,4 @@ static void LOG_FATAL(const Arg1& arg1, const Args&&... args) {
}
}
#endif
#endif // TARIFF_LOG_INCLUDED_H

View File

@ -1,79 +0,0 @@
#ifndef TARIFF_OUT_OF_SERVICE_H_INCLUDED
#define TARIFF_OUT_OF_SERVICE_H_INCLUDED
#include <QDateTime>
#include <QString>
#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<int>(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

View File

@ -13,13 +13,7 @@ enum class PERMIT_TYPE : quint8 {
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
TWENTY_FOUR_HOURS_TICKET=9
};
struct PermitType {
@ -49,30 +43,12 @@ struct PermitType {
case 6:
m_permitType = PERMIT_TYPE::DAY_TICKET_CHILD;
break;
case 8:
case 7:
m_permitType = PERMIT_TYPE::FOOD_STAMP;
break;
case 9:
case 8:
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;
}
@ -101,78 +77,14 @@ struct PermitType {
case PERMIT_TYPE::DAY_TICKET_TEEN:
return 6;
case PERMIT_TYPE::FOOD_STAMP:
return 8;
return 7;
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;
return 8;
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() {
@ -195,18 +107,6 @@ struct PermitType {
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;
}
@ -233,18 +133,6 @@ struct PermitType {
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;
}

View File

@ -1,160 +0,0 @@
#ifndef TARIFF_PREPAID_H_INCLUDED
#define TARIFF_PREPAID_H_INCLUDED
#include <QDateTime>
#include <QString>
#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<int>(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

View File

@ -1,81 +0,0 @@
#ifndef TARIFF_SERVICE_H_INCLUDED
#define TARIFF_SERVICE_H_INCLUDED
#include <QDateTime>
#include <QString>
#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<int>(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

View File

@ -1,40 +0,0 @@
#ifndef ATB_TARIFF_SETTINGS_H_INCLUDED
#define ATB_TARIFF_SETTINGS_H_INCLUDED
#include <QDebug>
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

View File

@ -1,46 +1,12 @@
#ifndef TIME_RANGE_H_INCLUDED
#define TIME_RANGE_H_INCLUDED
#include "atb_time.h"
#include <QString>
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
#ifndef TIME_RANGE_H_INCLUDED
#define TIME_RANGE_H_INCLUDED
#include "time_range_header.h"
struct TimeRange {
public:
bool IsActive;
ATBTimeRange TimeRangeStructure;
};
#endif // TIME_RANGE_H_INCLUDED

View File

@ -3,7 +3,6 @@
#include <ctime>
#include <iostream>
#include <cmath>
#include <optional>
#include "day_of_week.h"
#include "configuration.h"
@ -63,7 +62,6 @@ namespace Utilities {
/// <returns></returns>
bool IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTime);
bool IsYearPeriodActive(Configuration const *cfg, QDateTime const &currentDateTime);
std::optional<ATBPeriodYear> GetYearPeriodActive(Configuration const *cfg, QDateTime const &currentDateTime);
/// <summary>
/// Check permissions

View File

@ -1,57 +1,10 @@
#include "tariff_settings.h"
#include "tariff_carryover_settings.h"
#pragma once
#include <string>
#include <QString>
#include <Qt>
#include <QDate>
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;
}
};
class ATBWeekDays
{
public:
int pdiw_id;
std::string pdiw_label;
int pdiw_index;
};

View File

@ -4,10 +4,8 @@
class ATBWeekDaysWorktime
{
public:
int pwd_id;
int pwd_pop_id;
int pwd_next_id;
int pwd_period_week_day_id;
int pwd_id;
int pwd_period_week_day_id;
int pwd_period_day_in_week_id;
std::string pwd_time_from;
std::string pwd_time_to;

File diff suppressed because it is too large Load Diff

View File

@ -34,9 +34,7 @@ SOURCES += \
src/configuration.cpp \
src/tariff_log.cpp \
src/calculate_price.cpp \
src/ticket.cpp \
src/tariff_global_defines.cpp \
src/atb_time.cpp
src/ticket.cpp
HEADERS += \
include/mobilisis/calculator_functions.h \
@ -86,14 +84,7 @@ HEADERS += \
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
include/mobilisis/tariff_global_defines.h
OTHER_FILES += src/main.cpp \
../tariffs/tariff_korneuburg.json \

View File

@ -1,151 +0,0 @@
#include "atb_time.h"
#include <QDebugStateSaver>
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,762 +0,0 @@
#include "calculate_price.h"
#include "configuration.h"
#include "calculator_functions.h"
#include "payment_option.h"
#include "utilities.h"
#include <QFile>
#include <QFileInfo>
#include <QDateTime>
#include <QDebug>
#include <QList>
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<int> 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<int> 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<QVector<ATBTariffProduct>> products = cfg->getTariffProductForProductId(permitType);
if (products) {
QVector<ATBTariffProduct> 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 &currentTime = 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<QVector<ATBTariffProduct>> products = cfg->getTariffProductForProductId(permitType);
if (products) {
QVector<ATBTariffProduct> 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<ATBTariffProduct>::size_type i=0; i<product.size(); ++i) {
ATBTariffProduct const &p = product[i];
QTime const &startTime = p.getTimeStart();
QTime const &endTime = p.getTimeEnd();
// qCritical() << __LINE__ << startTime.toString(Qt::ISODate);
// qCritical() << __LINE__ << endTime.toString(Qt::ISODate);
// qCritical() << __LINE__ << start.toString(Qt::ISODate);
if (start.time() >= 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<QVector<ATBTariffProduct>> products = cfg->getTariffProductForProductId(permitType);
if (products) {
int product_price = 0;
QVector<ATBTariffProduct> 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<QVector<ATBPaymentRate>> const &pv = cfg->getPaymentRateForKey(key);
if (pv) {
QVector<ATBPaymentRate> 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<int> 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<struct price_t> 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);
}

File diff suppressed because it is too large Load Diff

View File

@ -115,8 +115,8 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
/// <inheritdoc/>
std::string Calculator::GetDurationFromCost(Configuration* cfg,
uint8_t payment_option,
char const *startDatetimePassed, // given in local time
double cost,
char const* start_datetime, // given in local time
double price,
bool nextDay,
bool prepaid)
{
@ -124,14 +124,14 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
Q_UNUSED(nextDay);
// Get input date
QDateTime inputDate = QDateTime::fromString(startDatetimePassed,Qt::ISODate);
QDateTime inputDate = QDateTime::fromString(start_datetime,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);
inputDate = inputDate.addSecs(GetDurationForPrice(cfg, price) * 60);
return inputDate.toString(Qt::ISODate).toStdString();
} else {
if (Utilities::IsYearPeriodActive(cfg, inputDate)) {
@ -147,226 +147,9 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
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<int, ATBWeekDaysWorktime>::const_iterator;
std::pair<WTIterator, WTIterator> 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<int, ATBWeekDaysWorktime>::const_iterator;
std::pair<WTIterator, WTIterator> 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);
Ticket t = private_GetDurationFromCost(cfg, inputDate, price, prepaid);
// qCritical().noquote() << t;
@ -496,11 +279,9 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
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";
qCritical() << __PRETTY_FUNCTION__ << "NOT YET IMPLEMENTED";
end_datetime = QDateTime();
return 0;
}
@ -518,18 +299,34 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
QDateTime start = start_datetime;
#define DEBUG 0
#if DEBUG==1
qCritical() << "start" << start.toString(Qt::ISODate) << durationMinutes;
#endif
int weekdayId = -1;
int weekdayIdLast = -1;
int timeRanges = 0;
int durationMinutesBrutto = 0;
QDateTime current = start;
//if ((durationMinutes % 5) != 0) {
// qCritical() << "ERROR DURATION (" << durationMinutes
// << ") NOT A MULTIPLE Of 5";
//}
int days = 7;
while (--days > 0) {
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "start" << start.toString(Qt::ISODate)
<< "current" << current.toString(Qt::ISODate);
#endif
weekdayId = current.date().dayOfWeek();
weekdayIdLast = weekdayId; // TODO: some end condition in json-file
while (cfg->WeekDaysWorktime.count(weekdayId) == 0) {
while ((timeRanges = cfg->WeekDaysWorktime.count(weekdayId)) == 0) {
current = current.addDays(1);
weekdayId = current.date().dayOfWeek();
if (weekdayId == weekdayIdLast) {
@ -538,6 +335,11 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
}
}
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.toString(Qt::ISODate);
#endif
using WTIterator = std::multimap<int, ATBWeekDaysWorktime>::const_iterator;
std::pair<WTIterator, WTIterator> p = cfg->WeekDaysWorktime.equal_range(weekdayId);
@ -545,169 +347,235 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
for (WTIterator itr = p.first; itr != p.second; ++itr) {
QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr);
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.time().toString(Qt::ISODate)
<< "t" << t.toString(Qt::ISODate)
<< "to" << to.toString(Qt::ISODate);
#endif
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;
}
if (current.time() >= to) {
QDateTime const dt = start;
start = start.addDays(1);
start.setTime(QTime(0, 0, 0));
durationMinutesBrutto += dt.secsTo(start) / 60;
current = start;
} else {
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.toString(Qt::ISODate)
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
break;
}
}
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "timeRanges" << timeRanges << weekdayId
<< "durationMinutesBrutto" << durationMinutesBrutto
<< "start" << start.toString(Qt::ISODate)
<< "current" << current.toString(Qt::ISODate);
#endif
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<int, ATBWeekDaysWorktime>::const_iterator;
std::pair<WTIterator, WTIterator> p = cfg->WeekDaysWorktime.equal_range(weekdayId);
auto timeRangeIt = cfg->TimeRange.cbegin();
for (; timeRangeIt != cfg->TimeRange.cend(); ++timeRangeIt) {
using WTIterator = std::multimap<int, ATBWeekDaysWorktime>::const_iterator;
std::pair<WTIterator, WTIterator> p = cfg->WeekDaysWorktime.equal_range(weekdayId);
for (WTIterator itr = p.first; itr != p.second; ++itr) {
++range;
for (WTIterator itr = p.first; itr != p.second; ++itr) {
++range;
QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr);
QTime const &to = Utilities::WeekDaysWorkTimeUntil(itr);
QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr);
QTime const &to = Utilities::WeekDaysWorkTimeUntil(itr);
Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES");
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;
if (current.time() >= to) {
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.toString(Qt::ISODate)
<< "from" << from.toString(Qt::ISODate)
<< "to" << to.toString(Qt::ISODate);
#endif
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;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.toString(Qt::ISODate)
<< "lastCurrent" << lastCurrent.toString(Qt::ISODate)
<< "minutesMoved" << minutesMoved
<< "durationMinutes" << durationMinutes;
#endif
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__
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "from" << from.toString(Qt::ISODate)
<< "to" << to.toString(Qt::ISODate)
<< "current" << current.toString(Qt::ISODate)
<< "duration" << duration
<< "minsUsed" << minsUsed
<< "minsToCarryOver" << minsToCarryOver;
<< "durationMinutes" << durationMinutes;
#endif
while (timeRangeIt != cfg->TimeRange.cend()) {
ATBTimeRange timeRange = timeRangeIt->second;
//if (minsUsed > 0) {
// duration -= minsUsed;
// minsUsed = 0;
//}
timeRange.computeQTimes(current.time());
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) {
int duration = timeRange.time_range_to_in_minutes_from_start -
timeRange.time_range_from_in_minutes_from_start;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << duration << timeRange.time_range_id
<< "current" << current.toString(Qt::ISODate)
<< "minsToCarryOver" << minsToCarryOver
<< "durationMinutes" << durationMinutes;
#endif
if (current.addSecs(duration * 60).time() <= to) {
for(const auto &x: cfg->PaymentRate) {
ATBPaymentRate const rate = x.second;
if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) {
if (minsToCarryOver > 0) {
durationMinutes -= minsToCarryOver;
durationMinutesNetto += minsToCarryOver;
durationMinutesBrutto += minsToCarryOver;
current = current.addSecs(minsToCarryOver*60);
minsToCarryOver = 0;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "durationMinutes" << durationMinutes
<< "durationMinutesNetto" << durationMinutesNetto
<< "durationMinutesBrutto" << durationMinutesBrutto
<< "current" << current.toString(Qt::ISODate);
#endif
} else {
price += (uint)rate.pra_price;
durationMinutes -= duration;
durationMinutesNetto += duration;
durationMinutesBrutto += duration;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << duration
<< "durationMinutes" << durationMinutes
<< "durationMinutesNetto" << durationMinutesNetto
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
current = current.addSecs(duration * 60);
if (durationMinutes <= 0) {
end_datetime = current;
return price;
}
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.toString(Qt::ISODate)
<< "price" << price;
#endif
}
break;
}
}
if (durationMinutes <= 0) {
end_datetime = current;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << durationMinutesNetto << ", price" << price
<< current.toString(Qt::ISODate)
<< end_datetime.toString(Qt::ISODate);
#endif
return price;
}
++timeRangeIt;
} else {
lastCurrent = current;
current.setTime(to);
int const minsLeft = lastCurrent.secsTo(current) / 60;
// mod duration: possibly discard some minutes in
// the next time-range
minsToCarryOver = (durationMinutes - minsLeft) % duration;
durationMinutes -= minsLeft;
durationMinutesNetto += minsLeft;
durationMinutesBrutto += minsLeft;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "lastCurrent" << lastCurrent.toString(Qt::ISODate)
<< "current" << current.toString(Qt::ISODate)
<< "minsLeft" << minsLeft;
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << duration
<< "durationMinutes" << durationMinutes
<< "durationMinutesNetto" << durationMinutesNetto
<< "durationMinutesBrutto" << durationMinutesBrutto
<< "minsToCarryOver" << minsToCarryOver;
#endif
if (minsLeft > 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 DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "price" << price;
#endif
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;
}
}
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);
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << durationMinutesNetto
<< ", price" << std::max(price, minParkingPrice)
<< start.toString(Qt::ISODate)
<< end_datetime.toString(Qt::ISODate);
#endif
return std::max(price, minParkingPrice);
}
}
@ -1204,8 +1072,6 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
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;
@ -1213,71 +1079,63 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
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;
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 (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));
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;;
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;
cfg->Duration.erase(search);
cfg->Duration.insert(pair<int, ATBDuration>(duration.pun_id, duration));
// set dynamic minimal parking time
cfg->getPaymentOptions().pop_min_time = timeStep;
} else { // if (search != cfg->Duration.end()) {
// TODO
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<int, ATBDuration>(duration.pun_id, duration));
} else { // if (search != cfg->Duration.end()) {
// TODO
}
} else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) {
// TODO
}
} else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) {
} else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) {
// TODO
}
} else { // if (pop_carry_over) {
} else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) {
// TODO
}
} else { // if (pop_carry_over) {
// TODO
}
} else {
qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::STATIC";
@ -1450,18 +1308,6 @@ Calculator::GetDailyTicketPrice(Configuration* cfg,
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);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
#include "tariff_global_defines.h"
int DBG_LEVEL = DBG_NOTICE;
// int DBG_LEVEL = DBG_INFORMATION;
// int DBG_LEVEL = DBG_DEBUG;

View File

@ -207,13 +207,7 @@ bool Utilities::IsYearPeriodActive(Configuration const *cfg, QDateTime const &dt
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);
return (d >= s && d <= e);
})) {
qCritical() << "NO VALID YEAR PERIOD";
return false;
@ -221,43 +215,6 @@ bool Utilities::IsYearPeriodActive(Configuration const *cfg, QDateTime const &dt
return true;
}
std::optional<ATBPeriodYear>
Utilities::GetYearPeriodActive(Configuration const *cfg, QDateTime const &currentDateTime) {
ATBPeriodYear period;
std::optional<ATBPeriodYear> value;
for (multimap<int, ATBPeriodYear>::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;
}
/// <inheritdoc/>
bool Utilities::CheckSpecialDay(Configuration* cfg, const char* currentDateTimeStr, int* specialDayId, double* specialDayPrice)
{
@ -427,8 +384,6 @@ PaymentMethod Utilities::getPaymentMethodId(Configuration const *cfg) {
return PaymentMethod::Degressive;
case PaymentMethod::Progressive:
return PaymentMethod::Progressive;
case PaymentMethod::Unified:
return PaymentMethod::Unified;
}
}

113
main/cc_iuc_asynchpos.h Executable file
View File

@ -0,0 +1,113 @@
#ifndef CC_IUC_ASYNCHPOS_H
#define CC_IUC_ASYNCHPOS_H
/*
* cc_iuc_asynchpos.c
*
* Created: 21.11.2017
* Author: Matthias
*/
#include <cstdlib>
#include <cinttypes>
//#define IUC_ASYCHNPOS_TESTMODE 1
#define IUC_ASYNCHPOS_COINCOIDE_H 0x09
#define IUC_ASYNCHPOS_COINCOIDE_L 0x78
#define IUC_ASYNCHPOS_MAX_ARRAY_SIZE 1024
#define IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE 300
#define IUC_ASYNCHPOS_MAX_RX_MESSAGE_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 IUC_ASYNCHPOS_RECEIPT_LENGTH 16384
#define STX 0x01
#define ETX1 0x02
#define ETX2 0x03
#define EOT 0x04
#define ENQ 0x05
#define ACK1 0x06
#define ACK2 0x07
#define DLE 0x10
#define NAK 0x15
unsigned static char terminalID[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
unsigned static char terminalAPAK[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
unsigned static char rxAsynchData[IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE];
unsigned static char terminalSignature[16];
//unsigned static char messageData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
unsigned static char receiptData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1];
unsigned static char txAsynchData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
unsigned static char ENQrecieved;
unsigned static int rxCounter;
unsigned static int messageLength;
unsigned static long timeInitalized;
unsigned static long timeHoldISMAS;
unsigned static long crcTable[256];
unsigned static char tableCreated;
unsigned static int asynchState;
unsigned static char asynchSessionClosed;
unsigned static char iuc_asynch_PRNrecieved;
unsigned static char iuc_asynch_keepAlive;
unsigned static char iuc_asynch_PrintControl;
unsigned static char iuc_asynchpos_crc_old;
unsigned static int iuc_print_counter;
unsigned static int iuc_asynch_printTimeout;
unsigned static char iucAsynchpoxDataContext;
//Prozessdaten - highly private
struct billAsynchData {
unsigned char time[20]; //UCHAR tagValue[] = "2017-12-19 13:40:00";
unsigned char id[37];
unsigned char printId[129];
unsigned 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];
unsigned char errCode[17];
//unsigned char receiptData[IUC_ASYNCHPOS_RECEIPT_LENGTH];
};
//private
unsigned int iuc_asynchpos_send(unsigned char packetType, unsigned char* pData, unsigned int length, unsigned char needRTS);
//void iuc_asynchpos_interpretCommand(unsigned int readLength_);
//public
void iuc_asynchpos_setTerminalID(unsigned char *pID, unsigned int length);
void iuc_asynchpos_setTerminalAPAK(unsigned char *pAPAK, unsigned int length);
unsigned char iuc_asynchpos_recieve_serial(unsigned char waitforACK);
void iuc_asynchpos_init();
void iuc_asynchpos_handleCommand(unsigned char command, unsigned char status);
int iuc_asynchpos_checkTime();
unsigned char iuc_asynchpos_getIsSaleRunning();
//commands
void iuc_asynchpos_command_ping_terminal(void);
void iuc_asynchpos_command_Login();
void iuc_asynchpos_command_Logout();
void iuc_asynchpos_command_authorize(unsigned int vkPreis);
void iuc_asynchpos_command_cancel_authorize();
void iuc_asynchpos_command_close_Document(unsigned char isStorno);
void iuc_asynchpos_command_print_Result(unsigned char status);
//void iuc_asynchpos_handleCommand(unsigned char command, unsigned char status);
//void iuc_asynchpos_init();
//int iuc_asynchpos_checkTime();
//unsigned char iuc_asynchpos_getCurrentStatus();
//int iuc_asynchpos_heartbeat();
uint32_t iuc_asynchpos_sub_updateCRC(uint32_t crc, char* pData, size_t len);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -25,21 +25,19 @@ CONFIG(debug, debug|release) {
}
}
SOURCES += main.cpp
SOURCES += main.cpp \
aes128.cpp \
cc_iuc_asynchpos.cpp \
terminal_utils.cpp \
MessageHelper.cpp
# HEADERS +=
HEADERS += aes128.h \
cc_iuc_asynchpos.h \
terminal_utils.h \
MessageHelper.h
# 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

1529
out.txt

File diff suppressed because it is too large Load Diff