Compare commits
70 Commits
2.3.99-21
...
f547f563bf
| Author | SHA1 | Date | |
|---|---|---|---|
| f547f563bf | |||
| 141d3281b7 | |||
|
f2156e4650
|
|||
|
338a1a4ebc
|
|||
| b4818a3918 | |||
| 35294e99f0 | |||
| edfa5dc1b1 | |||
| d95741baae | |||
| e172e814e7 | |||
| 37aa10fc85 | |||
| 4b9edb0f47 | |||
| e70e9a8586 | |||
| aec290fe26 | |||
| 78cae24389 | |||
| de0be1d19b | |||
| 54921f0e85 | |||
| 077c2334ca | |||
| d605af5c5a | |||
| c5900f9f2b | |||
| 9b137c2873 | |||
| dd249a87d5 | |||
| 575885c19e | |||
| d82a732a8d | |||
| 99dbd7c194 | |||
|
ae985d25ce
|
|||
|
6a215d4cf9
|
|||
|
a3f4a742ce
|
|||
| e6d8c04076 | |||
| 1f6606f382 | |||
| 4b9a4319b3 | |||
| 5e673788b4 | |||
| 7e2f40a7b5 | |||
| 44e2ce24a3 | |||
| 5a55ad6ef0 | |||
| 5a77958e8d | |||
| a1e7f4629a | |||
| efc2582c36 | |||
| a72f5a5019 | |||
| 28f0ea9fce | |||
| 3109e82ef8 | |||
| 03dd6c44da | |||
| 212c792b77 | |||
| ab3cdb32ae | |||
| 4f23ab3d68 | |||
| acbc27cfb2 | |||
| bcbe95d483 | |||
| e3bbca86d5 | |||
| 5868d3b510 | |||
| d4363e71cd | |||
| fd99c20bd9 | |||
| dbccdba9fe | |||
| b035f4f887 | |||
| 18f09fccb9 | |||
| 1086e360e5 | |||
| ada7bebd90 | |||
| 2b9ea67ef5 | |||
| d117328bed | |||
| fd04531474 | |||
| 5749fa422e | |||
| 1347f1f208 | |||
| 576c3fefdd | |||
| 9ca7018fc1 | |||
| 515dfaf35c | |||
| 0ab833709c | |||
| 8e4f47c7b6 | |||
| bc9645f1fa | |||
| 713b483918 | |||
| 3c7af1cb32 | |||
| 356e451839 | |||
| c4e1d412a5 |
@@ -4,20 +4,42 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
class ATBTime {
|
class ATBTime {
|
||||||
QDateTime const m_end;
|
static QDateTime const m_end;
|
||||||
mutable QDateTime m_time;
|
mutable QDateTime m_time;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ATBTime();
|
explicit ATBTime();
|
||||||
explicit ATBTime(int h, int m, int s = 0, int ms = 0);
|
explicit ATBTime(int h, int m, int s = 0, int ms = 0);
|
||||||
explicit ATBTime(QString const &time);
|
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 hour() const { return m_time.time().hour(); }
|
||||||
int minute() const { return m_time.time().minute(); }
|
int minute() const { return m_time.time().minute(); }
|
||||||
int second() const { return m_time.time().second(); }
|
int second() const { return m_time.time().second(); }
|
||||||
int msec() const { return m_time.time().msec(); }
|
int msec() const { return m_time.time().msec(); }
|
||||||
|
|
||||||
int secsTo(QTime t) const { return m_time.time().secsTo(t); }
|
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); }
|
int msecsTo(QTime t) const { return m_time.time().msecsTo(t); }
|
||||||
|
|
||||||
bool setHMS(int h, int m, int s, int ms = 0);
|
bool setHMS(int h, int m, int s, int ms = 0);
|
||||||
@@ -48,10 +70,12 @@ public:
|
|||||||
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 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 time);
|
friend QDataStream &operator<<(QDataStream &out, ATBTime const &time);
|
||||||
|
friend QDebug &operator<<(QDebug &out, ATBTime const &time);
|
||||||
friend QDataStream &operator>>(QDataStream &in, ATBTime &time);
|
friend QDataStream &operator>>(QDataStream &in, ATBTime &time);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
|||||||
, m_desc(desc) {
|
, m_desc(desc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CalcState(State state, QString desc = "",
|
explicit CalcState(State state, QString desc,
|
||||||
QTime const &from = QTime(),
|
QTime const &from,
|
||||||
QTime const &until = QTime())
|
QTime const &until)
|
||||||
: m_status(state)
|
: m_status(state)
|
||||||
, m_desc(desc)
|
, m_desc(desc)
|
||||||
, m_allowedTimeRange(from, until) {
|
, m_allowedTimeRange(from, until) {
|
||||||
@@ -277,6 +277,12 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
|
|||||||
void CALCULATE_LIBRARY_API free_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 get_zone_nr(int zone = -1);
|
||||||
|
|
||||||
|
|
||||||
|
int CALCULATE_LIBRARY_API isOutOfService(Configuration const *cfg,
|
||||||
|
QDateTime const &dt);
|
||||||
|
|
||||||
|
int CALCULATE_LIBRARY_API isOutOfService(QDateTime const &dt);
|
||||||
|
|
||||||
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes,
|
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes,
|
||||||
int UpDown, PermitType const &permitType);
|
int UpDown, PermitType const &permitType);
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,16 @@ class Calculator {
|
|||||||
QDateTime const &start,
|
QDateTime const &start,
|
||||||
int netto_parking_time,
|
int netto_parking_time,
|
||||||
int paymentOptionIndex);
|
int paymentOptionIndex);
|
||||||
|
struct State {
|
||||||
|
bool m_timeLimitReached;
|
||||||
|
uint32_t m_costAtTimeLimit;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Calculator() = default;
|
explicit Calculator() {
|
||||||
|
m_state.m_timeLimitReached = false;
|
||||||
|
m_state.m_costAtTimeLimit = ~0;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Calculator(Calculator const &other) = delete;
|
Calculator(Calculator const &other) = delete;
|
||||||
@@ -40,6 +47,12 @@ public:
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool timeLimitReached() const { return m_state.m_timeLimitReached; }
|
||||||
|
void setTimeLimitReached(bool timeLimitReached) { m_state.m_timeLimitReached = timeLimitReached; }
|
||||||
|
bool costAtTimeLimit() const { return m_state.m_costAtTimeLimit; }
|
||||||
|
void setCostAtTimeLimit(uint32_t cost) { if (m_state.m_costAtTimeLimit > cost) m_state.m_costAtTimeLimit = cost; }
|
||||||
|
void resetCostAtTimeLimit() { m_state.m_costAtTimeLimit = ~0; }
|
||||||
|
|
||||||
void ResetTimeSteps(int paymentOptionIndex) {
|
void ResetTimeSteps(int paymentOptionIndex) {
|
||||||
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
|
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
|
||||||
m_timeSteps[paymentOptionIndex].clear();
|
m_timeSteps[paymentOptionIndex].clear();
|
||||||
@@ -87,6 +100,9 @@ public:
|
|||||||
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
|
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
|
||||||
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
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);
|
||||||
|
|
||||||
// Daily ticket
|
// Daily ticket
|
||||||
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
|
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
|
||||||
std::optional<struct price_t> GetDailyTicketPrice(Configuration* cfg, QDateTime const &startDatetime, QDateTime &endTime, PERMIT_TYPE permitType);
|
std::optional<struct price_t> GetDailyTicketPrice(Configuration* cfg, QDateTime const &startDatetime, QDateTime &endTime, PERMIT_TYPE permitType);
|
||||||
|
|||||||
@@ -29,9 +29,13 @@
|
|||||||
#include "tariff_prepaid.h"
|
#include "tariff_prepaid.h"
|
||||||
#include "tariff_carryover.h"
|
#include "tariff_carryover.h"
|
||||||
#include "tariff_permit_type.h"
|
#include "tariff_permit_type.h"
|
||||||
|
#include "tariff_service.h"
|
||||||
|
#include "tariff_out_of_service.h"
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <QList>
|
||||||
|
#include <QPair>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
@@ -50,6 +54,10 @@ public:
|
|||||||
using TariffPrepaidType = std::multimap<int, ATBPrepaid>;
|
using TariffPrepaidType = std::multimap<int, ATBPrepaid>;
|
||||||
using TariffCarryOverType = std::multimap<int, ATBCarryOver>;
|
using TariffCarryOverType = std::multimap<int, ATBCarryOver>;
|
||||||
using TariffDurationType = std::multimap<int, ATBDuration>;
|
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;
|
ATBProject project;
|
||||||
ATBCurrency Currency;
|
ATBCurrency Currency;
|
||||||
@@ -73,6 +81,15 @@ public:
|
|||||||
TariffInterpolationType TariffInterpolations;
|
TariffInterpolationType TariffInterpolations;
|
||||||
TariffPrepaidType TariffPrepaidOptions;
|
TariffPrepaidType TariffPrepaidOptions;
|
||||||
TariffCarryOverType TariffCarryOverOptions;
|
TariffCarryOverType TariffCarryOverOptions;
|
||||||
|
TariffServiceType TariffServices;
|
||||||
|
TariffOutOfServiceType TariffOutOfServices;
|
||||||
|
ATBTariffPrepaidType TariffPrepaids;
|
||||||
|
ATBTariffCarryOverType TariffCarryOvers;
|
||||||
|
QList<QPair<QString, QString>> TariffIncludes;
|
||||||
|
|
||||||
|
QTime ValidFrom;
|
||||||
|
int ValidForWeekDay{};
|
||||||
|
QStringList tariffFileName{};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parse JSON string
|
/// Parse JSON string
|
||||||
@@ -113,6 +130,9 @@ public:
|
|||||||
std::optional<ATBWeekDaysWorktime> getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek);
|
std::optional<ATBWeekDaysWorktime> getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek);
|
||||||
std::optional<QVector<ATBWeekDaysWorktime>> getAllWeekDayWorkTimes();
|
std::optional<QVector<ATBWeekDaysWorktime>> getAllWeekDayWorkTimes();
|
||||||
|
|
||||||
|
QList<QPair<QString, QString>> const &getTariffIncludes() const { return TariffIncludes; }
|
||||||
|
QList<QPair<QString, QString>> &getTariffIncludes() { return TariffIncludes; }
|
||||||
|
|
||||||
std::optional<QDateTime> prepaidStart(QDateTime const &start, int prepaid_option_id);
|
std::optional<QDateTime> prepaidStart(QDateTime const &start, int prepaid_option_id);
|
||||||
int getPaymentOptionIndex(PERMIT_TYPE permitType);
|
int getPaymentOptionIndex(PERMIT_TYPE permitType);
|
||||||
int getPaymentOptionIndex(PERMIT_TYPE permitType) const;
|
int getPaymentOptionIndex(PERMIT_TYPE permitType) const;
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ enum MemberType
|
|||||||
ProductType = 0x0F,
|
ProductType = 0x0F,
|
||||||
InterpolationType = 0x10,
|
InterpolationType = 0x10,
|
||||||
PrepaidType = 0x11,
|
PrepaidType = 0x11,
|
||||||
CarryOverType = 0x12
|
CarryOverType = 0x12,
|
||||||
|
IncludesType = 0x13
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MEMBER_TYPE_H_INCLUDED
|
#endif // MEMBER_TYPE_H_INCLUDED
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ enum PaymentMethod {
|
|||||||
Progressive = 0x01,
|
Progressive = 0x01,
|
||||||
Degressive = 0x02,
|
Degressive = 0x02,
|
||||||
Linear = 0x03,
|
Linear = 0x03,
|
||||||
Steps = 0x04
|
Steps = 0x04,
|
||||||
|
Unified = 0x05
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAYMENT_METHOD_H_INCLUDED
|
#endif // PAYMENT_METHOD_H_INCLUDED
|
||||||
|
|||||||
@@ -3,6 +3,111 @@
|
|||||||
|
|
||||||
#include <QTime>
|
#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() << __func__ << ":" << __LINE__ << "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 ATBCarryOver {
|
||||||
struct week {
|
struct week {
|
||||||
int day;
|
int day;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#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
|
||||||
@@ -19,7 +19,12 @@ enum class PERMIT_TYPE : quint8 {
|
|||||||
SHORT_TERM_PARKING_CAMPER=12,
|
SHORT_TERM_PARKING_CAMPER=12,
|
||||||
DAY_TICKET_PKW=13,
|
DAY_TICKET_PKW=13,
|
||||||
DAY_TICKET_BUS=14,
|
DAY_TICKET_BUS=14,
|
||||||
DAY_TICKET_CAMPER=15
|
DAY_TICKET_CAMPER=15,
|
||||||
|
FREE_TICKET=16,
|
||||||
|
|
||||||
|
TEST_PRODUCT_1=17,
|
||||||
|
TEST_PRODUCT_2=18,
|
||||||
|
PRODUCT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PermitType {
|
struct PermitType {
|
||||||
@@ -73,6 +78,15 @@ struct PermitType {
|
|||||||
case 15:
|
case 15:
|
||||||
m_permitType = PERMIT_TYPE::DAY_TICKET_CAMPER;
|
m_permitType = PERMIT_TYPE::DAY_TICKET_CAMPER;
|
||||||
break;
|
break;
|
||||||
|
case 16:
|
||||||
|
m_permitType = PERMIT_TYPE::FREE_TICKET;
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
m_permitType = PERMIT_TYPE::TEST_PRODUCT_1;
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
m_permitType = PERMIT_TYPE::TEST_PRODUCT_2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
m_permitType = PERMIT_TYPE::INVALID;
|
m_permitType = PERMIT_TYPE::INVALID;
|
||||||
}
|
}
|
||||||
@@ -116,6 +130,12 @@ struct PermitType {
|
|||||||
return 14;
|
return 14;
|
||||||
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
||||||
return 15;
|
return 15;
|
||||||
|
case PERMIT_TYPE::FREE_TICKET:
|
||||||
|
return 16;
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_1:
|
||||||
|
return 17;
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_2:
|
||||||
|
return 18;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -132,9 +152,6 @@ struct PermitType {
|
|||||||
if (permitTypeStr == "DAY_TICKET_CHILD") {
|
if (permitTypeStr == "DAY_TICKET_CHILD") {
|
||||||
return PERMIT_TYPE::DAY_TICKET_CHILD;
|
return PERMIT_TYPE::DAY_TICKET_CHILD;
|
||||||
} else
|
} else
|
||||||
if (permitTypeStr == "DAY_TICKET_ADULT") {
|
|
||||||
return PERMIT_TYPE::DAY_TICKET_ADULT;
|
|
||||||
} else
|
|
||||||
if (permitTypeStr == "DAY_TICKET_TEEN") {
|
if (permitTypeStr == "DAY_TICKET_TEEN") {
|
||||||
return PERMIT_TYPE::DAY_TICKET_TEEN;
|
return PERMIT_TYPE::DAY_TICKET_TEEN;
|
||||||
} else
|
} else
|
||||||
@@ -170,6 +187,15 @@ struct PermitType {
|
|||||||
} else
|
} else
|
||||||
if (permitTypeStr == "DAY_TICKET_CAMPER") {
|
if (permitTypeStr == "DAY_TICKET_CAMPER") {
|
||||||
return PERMIT_TYPE::DAY_TICKET_CAMPER;
|
return PERMIT_TYPE::DAY_TICKET_CAMPER;
|
||||||
|
} else
|
||||||
|
if (permitTypeStr == "FREE_TICKET") {
|
||||||
|
return PERMIT_TYPE::FREE_TICKET;
|
||||||
|
} else
|
||||||
|
if (permitTypeStr == "TEST_PRODUCT_1") {
|
||||||
|
return PERMIT_TYPE::TEST_PRODUCT_1;
|
||||||
|
} else
|
||||||
|
if (permitTypeStr == "TEST_PRODUCT_2") {
|
||||||
|
return PERMIT_TYPE::TEST_PRODUCT_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PERMIT_TYPE::INVALID;
|
return PERMIT_TYPE::INVALID;
|
||||||
@@ -207,6 +233,12 @@ struct PermitType {
|
|||||||
return QString("DAY_TICKET_BUS");
|
return QString("DAY_TICKET_BUS");
|
||||||
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
||||||
return QString("DAY_TICKET_CAMPER");
|
return QString("DAY_TICKET_CAMPER");
|
||||||
|
case PERMIT_TYPE::FREE_TICKET:
|
||||||
|
return QString("FREE_TICKET");
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_1:
|
||||||
|
return QString("TEST_PRODUCT_1");
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_2:
|
||||||
|
return QString("TEST_PRODUCT_2");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,6 +277,12 @@ struct PermitType {
|
|||||||
return QString("DAY_TICKET_BUS");
|
return QString("DAY_TICKET_BUS");
|
||||||
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
||||||
return QString("DAY_TICKET_CAMPER");
|
return QString("DAY_TICKET_CAMPER");
|
||||||
|
case PERMIT_TYPE::FREE_TICKET:
|
||||||
|
return QString("FREE_TICKET");
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_1:
|
||||||
|
return QString("TEST_PRODUCT_1");
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_2:
|
||||||
|
return QString("TEST_PRODUCT_2");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,84 @@
|
|||||||
#ifndef TARIFF_PREPAID_H_INCLUDED
|
#ifndef TARIFF_PREPAID_H_INCLUDED
|
||||||
#define TARIFF_PREPAID_H_INCLUDED
|
#define TARIFF_PREPAID_H_INCLUDED
|
||||||
|
|
||||||
#include <QTime>
|
#include <QDateTime>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "atb_time.h"
|
#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() << __func__ << ":" << __LINE__ << "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 {
|
struct ATBPrepaid {
|
||||||
int id;
|
int id;
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#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
|
||||||
@@ -1,12 +1,46 @@
|
|||||||
#ifndef TIME_RANGE_H_INCLUDED
|
#ifndef TIME_RANGE_H_INCLUDED
|
||||||
#define TIME_RANGE_H_INCLUDED
|
#define TIME_RANGE_H_INCLUDED
|
||||||
|
|
||||||
#include "time_range_header.h"
|
#include "atb_time.h"
|
||||||
|
|
||||||
struct TimeRange {
|
#include <QString>
|
||||||
public:
|
|
||||||
bool IsActive;
|
struct TimeRange {
|
||||||
ATBTimeRange TimeRangeStructure;
|
ATBTime m_start;
|
||||||
};
|
ATBTime m_end;
|
||||||
|
int m_duration;
|
||||||
#endif // TIME_RANGE_H_INCLUDED
|
|
||||||
|
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
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -91,7 +91,9 @@ HEADERS += \
|
|||||||
include/mobilisis/tariff_prepaid.h \
|
include/mobilisis/tariff_prepaid.h \
|
||||||
include/mobilisis/tariff_carryover.h \
|
include/mobilisis/tariff_carryover.h \
|
||||||
include/mobilisis/tariff_global_defines.h \
|
include/mobilisis/tariff_global_defines.h \
|
||||||
include/mobilisis/atb_time.h
|
include/mobilisis/atb_time.h \
|
||||||
|
include/mobilisis/tariff_service.h \
|
||||||
|
include/mobilisis/tariff_out_of_service.h
|
||||||
|
|
||||||
OTHER_FILES += src/main.cpp \
|
OTHER_FILES += src/main.cpp \
|
||||||
../tariffs/tariff_korneuburg.json \
|
../tariffs/tariff_korneuburg.json \
|
||||||
|
|||||||
+48
-12
@@ -1,30 +1,40 @@
|
|||||||
#include "atb_time.h"
|
#include "atb_time.h"
|
||||||
|
#include <QDebugStateSaver>
|
||||||
|
|
||||||
|
QDateTime const ATBTime::m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate));
|
||||||
|
|
||||||
ATBTime::ATBTime()
|
ATBTime::ATBTime()
|
||||||
: m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate))
|
: m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
||||||
, m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATBTime::ATBTime(int h, int m, int s, int ms)
|
ATBTime::ATBTime(int h, int m, int /*s*/, int /*ms*/)
|
||||||
: m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate))
|
: m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
||||||
, m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
|
||||||
|
|
||||||
QTime t(h, m, s, ms);
|
if (h == 24 && m == 0) {
|
||||||
m_time.setTime(t);
|
m_time = m_end;
|
||||||
|
} else {
|
||||||
|
QTime const t(h, m, 0, 0);
|
||||||
|
m_time.setTime(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ATBTime::ATBTime(QString const &t)
|
ATBTime::ATBTime(QString const &t)
|
||||||
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
|
: m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
|
||||||
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
|
|
||||||
|
|
||||||
if (t == "24:00:00") {
|
if (t == "24:00:00") {
|
||||||
m_time = m_end;
|
m_time = m_end;
|
||||||
} else {
|
} else {
|
||||||
m_time.setTime(QTime::fromString(t, Qt::ISODate));
|
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 {
|
QTime ATBTime::addMSecs(int ms) const {
|
||||||
return m_time.time().addMSecs(ms);
|
return m_time.time().addMSecs(ms);
|
||||||
@@ -78,6 +88,9 @@ bool ATBTime::setHMS(int h, int m, int s, int ms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString ATBTime::toString(Qt::DateFormat format) const {
|
QString ATBTime::toString(Qt::DateFormat format) const {
|
||||||
|
if (m_time == m_end) {
|
||||||
|
return "24:00:00";
|
||||||
|
}
|
||||||
return m_time.time().toString(format);
|
return m_time.time().toString(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +99,20 @@ bool operator!=(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool operator<=(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
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();
|
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 {
|
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();
|
return lhs.m_time.time() < rhs.m_time.time();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,8 +124,22 @@ bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
|||||||
return lhs.m_time.time() == rhs.m_time.time();
|
return lhs.m_time.time() == rhs.m_time.time();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &out, ATBTime time) {
|
QDebug &operator<<(QDebug &debug, ATBTime const &time) {
|
||||||
out << time.m_time.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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+868
-129
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
@@ -0,0 +1,762 @@
|
|||||||
|
#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 ¤tTime = QDateTime::currentDateTime().time();
|
||||||
|
|
||||||
|
if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) {
|
||||||
|
return p.m_tariff_product_price;
|
||||||
|
} else {
|
||||||
|
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
|
||||||
|
<< "ERROR currentTime"
|
||||||
|
<< currentTime.toString(Qt::ISODate)
|
||||||
|
<< "INVALID ("
|
||||||
|
<< p.m_tariff_product_start.toString(Qt::ISODate)
|
||||||
|
<< p.m_tariff_product_end.toString(Qt::ISODate) << ")";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case PERMIT_TYPE::INVALID:
|
||||||
|
// [[fallthrough]];
|
||||||
|
case PERMIT_TYPE::DAY_TICKET: {
|
||||||
|
std::optional<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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "ticket.h"
|
#include "ticket.h"
|
||||||
#include "tariff_global_defines.h"
|
#include "tariff_global_defines.h"
|
||||||
#include "tariff_prepaid.h"
|
#include "tariff_prepaid.h"
|
||||||
|
#include "tariff_out_of_service.h"
|
||||||
|
#include "tariff_service.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -117,6 +119,677 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
|
|||||||
|
|
||||||
return QDateTime();
|
return QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getPrepaid
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
|
||||||
|
std::optional<ATBTariffPrepaid> getPrepaid(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffPrepaid> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay;
|
||||||
|
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
QDate d; // check if a special date is configured in tariff-file for this day
|
||||||
|
auto const &prepaidRange = cfg->TariffPrepaids.equal_range(weekDay);
|
||||||
|
|
||||||
|
for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) {
|
||||||
|
ATBTariffPrepaid const &prepaid = i->second;
|
||||||
|
if (!prepaid.m_date.isNull() && prepaid.m_date.isValid() && prepaid.m_date == dt.date()) {
|
||||||
|
d = dt.date();
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) {
|
||||||
|
ATBTariffPrepaid const &prepaid = i->second;
|
||||||
|
if (!prepaid.m_date.isNull() && prepaid.m_date.isValid() && prepaid.m_date == d) {
|
||||||
|
TimeRange const &prepaidTimeRange = prepaid.m_range;
|
||||||
|
if (inputTime >= prepaidTimeRange.m_start && inputTime < prepaidTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate);
|
||||||
|
for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) {
|
||||||
|
ATBTariffPrepaid const &prepaid = i->second;
|
||||||
|
if (prepaid.m_date.isNull() || !prepaid.m_date.isValid()) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "default";
|
||||||
|
TimeRange const &prepaidTimeRange = prepaid.m_range;
|
||||||
|
if (inputTime >= prepaidTimeRange.m_start && inputTime < prepaidTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << prepaidTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getCarryOver
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
std::optional<ATBTariffCarryOver> getCarryOver(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffCarryOver> value = std::nullopt;
|
||||||
|
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay;
|
||||||
|
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
auto const &carryOverRange = cfg->TariffCarryOvers.equal_range(weekDay);
|
||||||
|
|
||||||
|
QDate d; // check if a special date is configured in tariff-file for this day
|
||||||
|
for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) {
|
||||||
|
ATBTariffCarryOver const &carryOver = i->second;
|
||||||
|
if (!carryOver.m_date.isNull() && carryOver.m_date.isValid() && carryOver.m_date == dt.date()) {
|
||||||
|
d = dt.date();
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) {
|
||||||
|
ATBTariffCarryOver const &carryOver = i->second;
|
||||||
|
|
||||||
|
if (!carryOver.m_date.isNull() && carryOver.m_date.isValid() && carryOver.m_date == d) {
|
||||||
|
TimeRange const &carryOverTimeRange = carryOver.m_range;
|
||||||
|
if (inputTime >= carryOverTimeRange.m_start && inputTime < carryOverTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(carryOver);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate);
|
||||||
|
for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) {
|
||||||
|
ATBTariffCarryOver const &carryOver = i->second;
|
||||||
|
if (carryOver.m_date.isNull() || !carryOver.m_date.isValid()) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "default";
|
||||||
|
TimeRange const &carryOverTimeRange = carryOver.m_range;
|
||||||
|
if (inputTime >= carryOverTimeRange.m_start && inputTime < carryOverTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << carryOverTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(carryOver);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getService
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
|
||||||
|
std::optional<ATBTariffService> getService(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffService> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay;
|
||||||
|
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
auto const &serviceRange = cfg->TariffServices.equal_range(weekDay);
|
||||||
|
|
||||||
|
QDate d; // check if a special date is configured in tariff-file for this day
|
||||||
|
for (auto i = serviceRange.first; i != serviceRange.second; ++i) {
|
||||||
|
ATBTariffService const &service = i->second;
|
||||||
|
if (!service.m_date.isNull() && service.m_date.isValid() && service.m_date == dt.date()) {
|
||||||
|
d = dt.date();
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
for (auto i = serviceRange.first; i != serviceRange.second; ++i) {
|
||||||
|
ATBTariffService const &service = i->second;
|
||||||
|
|
||||||
|
if (!service.m_date.isNull() && service.m_date.isValid() && service.m_date == d) {
|
||||||
|
TimeRange const &serviceTimeRange = service.m_range;
|
||||||
|
if (inputTime >= serviceTimeRange.m_start && inputTime < serviceTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate);
|
||||||
|
for (auto i = serviceRange.first; i != serviceRange.second; ++i) {
|
||||||
|
ATBTariffService const &service = i->second;
|
||||||
|
if (service.m_date.isNull() || !service.m_date.isValid()) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "default";
|
||||||
|
TimeRange const &serviceTimeRange = service.m_range;
|
||||||
|
if (inputTime >= serviceTimeRange.m_start && inputTime < serviceTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << serviceTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getOutOfService
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
std::optional<ATBTariffOutOfService> getOutOfService(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffOutOfService> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << dt.toString(Qt::ISODate) << weekDay;
|
||||||
|
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
QDate date;
|
||||||
|
|
||||||
|
auto const &outOfServiceRange = cfg->TariffOutOfServices.equal_range(weekDay);
|
||||||
|
|
||||||
|
QDate d; // check if a special date is configured in tariff-file for this day
|
||||||
|
for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) {
|
||||||
|
ATBTariffOutOfService const &outOfService = i->second;
|
||||||
|
if (!outOfService.m_date.isNull() && outOfService.m_date.isValid() && outOfService.m_date == dt.date()) {
|
||||||
|
d = dt.date();
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "found special day" << d.toString(Qt::ISODate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) {
|
||||||
|
ATBTariffOutOfService const &outOfService = i->second;
|
||||||
|
|
||||||
|
if (!outOfService.m_date.isNull() && outOfService.m_date.isValid() && outOfService.m_date == d) {
|
||||||
|
TimeRange const &outOfServiceTimeRange = outOfService.m_range;
|
||||||
|
if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(outOfService);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "no special day" << dt.date().toString(Qt::ISODate);
|
||||||
|
for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) {
|
||||||
|
ATBTariffOutOfService const &outOfService = i->second;
|
||||||
|
if (outOfService.m_date.isNull() || !outOfService.m_date.isValid()) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "default";
|
||||||
|
TimeRange const &outOfServiceTimeRange = outOfService.m_range;
|
||||||
|
if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_start.toString(Qt::ISODate);
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << outOfServiceTimeRange.m_end.toString(Qt::ISODate);
|
||||||
|
value = value.value_or(outOfService);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<CalcState, QDateTime>
|
||||||
|
Calculator::ComputeDurationFromCost(Configuration *cfg,
|
||||||
|
QDateTime const &startDatetimePassed, // given in local time
|
||||||
|
int cost) {
|
||||||
|
|
||||||
|
QDateTime inputDate = startDatetimePassed;
|
||||||
|
inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0));
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
int paymentOptionIndex = 0;
|
||||||
|
|
||||||
|
bool overPaid = false;
|
||||||
|
bool successMaxPrice = false;
|
||||||
|
|
||||||
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price =
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price_save;
|
||||||
|
int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time;
|
||||||
|
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
||||||
|
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
||||||
|
|
||||||
|
int price = 0;
|
||||||
|
int durationId = 0;
|
||||||
|
int netto_parking_time_in_minutes = 0;
|
||||||
|
int brutto_parking_time_in_minutes = 0;
|
||||||
|
int free_parking_time_in_minutes = 0;
|
||||||
|
|
||||||
|
QMap<int, int> nettoParktimePrice;
|
||||||
|
QMap<int, int> priceNettoParktime;
|
||||||
|
|
||||||
|
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
|
||||||
|
durationId = itr->second.pra_payment_unit_id;
|
||||||
|
|
||||||
|
int const pra_price = itr->second.pra_price;
|
||||||
|
if (pop_accumulate_prices) {
|
||||||
|
price += pra_price;
|
||||||
|
} else {
|
||||||
|
price = pra_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if ((double)price == cost) {
|
||||||
|
auto search = cfg->Duration.find(durationId);
|
||||||
|
if (search != cfg->Duration.end()) {
|
||||||
|
// found now the duration in minutes
|
||||||
|
// check if we are still inside the working-time-range
|
||||||
|
ATBDuration duration = search->second;
|
||||||
|
nettoParktimePrice.insert(duration.pun_duration, price);
|
||||||
|
priceNettoParktime.insert(price, duration.pun_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << nettoParktimePrice;
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << priceNettoParktime;
|
||||||
|
|
||||||
|
if (cost == pop_max_price) {
|
||||||
|
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
successMaxPrice = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost > pop_max_price) {
|
||||||
|
qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
if (pop_allow_overpay == false) {
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID), QDateTime());
|
||||||
|
}
|
||||||
|
cost = pop_max_price;
|
||||||
|
overPaid = true;
|
||||||
|
qCritical() << DBG_HEADER << "OVERPAID, MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
// return CalcState::OVERPAID.toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost < pop_min_price) {
|
||||||
|
qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::BELOW_MIN_PARKING_PRICE), QDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
int weekDay = inputDate.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START weekDay" << weekDay << inputDate.toString(Qt::ISODate);
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START cost" << cost;
|
||||||
|
|
||||||
|
QDateTime dt;
|
||||||
|
bool computationStarted = false;
|
||||||
|
price = 0;
|
||||||
|
netto_parking_time_in_minutes = 0;
|
||||||
|
brutto_parking_time_in_minutes = 0;
|
||||||
|
free_parking_time_in_minutes = 0;
|
||||||
|
int nettoParktimeForCost = 0;
|
||||||
|
|
||||||
|
if (priceNettoParktime.contains(int(cost))) {
|
||||||
|
nettoParktimeForCost = priceNettoParktime[int(cost)];
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("cost=%1 nettoParkTimeForCost=%2").
|
||||||
|
arg(cost).arg(nettoParktimeForCost);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// cannot find netto-parking time for cost (=price)
|
||||||
|
// this happens for direct coin input and should not happen otherwise
|
||||||
|
// take the value for the nearest value of cost and mark result as overpaid
|
||||||
|
|
||||||
|
QList <int> keys = priceNettoParktime.keys(); // keys (=prices) are sorted in ascending order
|
||||||
|
QSet<int> s; // make keys unique
|
||||||
|
for (int k = 0; k < keys.size(); ++k) {
|
||||||
|
if (keys[k] < cost) {
|
||||||
|
s << keys[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys = s.values();
|
||||||
|
// sort in descending order
|
||||||
|
std::sort(std::begin(keys), std::end(keys), std::greater<>());
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "keys=" << keys;
|
||||||
|
if (!keys.isEmpty()) {
|
||||||
|
int const maxCost = keys[0];
|
||||||
|
auto const p = priceNettoParktime.equal_range(maxCost);
|
||||||
|
for (auto it = p.first; it != p.second; ++it) {
|
||||||
|
nettoParktimeForCost = std::max(nettoParktimeForCost, it.value());
|
||||||
|
}
|
||||||
|
ATBPaymentOption &po = cfg->getPaymentOptions(paymentOptionIndex);
|
||||||
|
po.pop_max_price = maxCost;
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxCost;
|
||||||
|
if (pop_allow_overpay) {
|
||||||
|
overPaid = true;
|
||||||
|
}
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("cost=%1 -> maxCost=%2 nettoParkTimeForCost=%3").
|
||||||
|
arg(cost).arg(maxCost).arg(nettoParktimeForCost);
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "ERROR empty keys -> check tariff file";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
while (++cnt < 20 && netto_parking_time_in_minutes < nettoParktimeForCost) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "cnt [" << cnt;
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffOutOfService> oos = getOutOfService(cfg, dt)) {
|
||||||
|
dt.setTime(QTime(oos.value().m_range.m_start.hour(),
|
||||||
|
oos.value().m_range.m_start.minute(), 0));
|
||||||
|
if (overPaid) {
|
||||||
|
QList <int> keys = nettoParktimePrice.keys();
|
||||||
|
for (int k = 0; k < keys.size(); ++k) {
|
||||||
|
if (keys[k] < netto_parking_time_in_minutes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int const maxPriceForTimeLimit = nettoParktimePrice[keys[k]];
|
||||||
|
if (cost > maxPriceForTimeLimit) {
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit;
|
||||||
|
|
||||||
|
CalcState cs(CalcState::State::OVERPAID);
|
||||||
|
return std::make_pair(cs, dt);
|
||||||
|
}
|
||||||
|
if (cost == maxPriceForTimeLimit) {
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit;
|
||||||
|
|
||||||
|
CalcState cs(CalcState::State::SUCCESS_MAXPRICE);
|
||||||
|
return std::make_pair(cs, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID), dt);
|
||||||
|
}
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "set time-limit reached";
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time_in_minutes;
|
||||||
|
|
||||||
|
Calculator::GetInstance().setTimeLimitReached(true);
|
||||||
|
QList <int> keys = nettoParktimePrice.keys();
|
||||||
|
for (int k = 0; k < keys.size(); ++k) {
|
||||||
|
if (keys[k] < netto_parking_time_in_minutes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int const maxPriceForTimeLimit = nettoParktimePrice[keys[k]];
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << keys[k] << maxPriceForTimeLimit << cost;
|
||||||
|
// Calculator::GetInstance().setCostAtTimeLimit(nettoParktimePrice[keys[k]]);
|
||||||
|
if (cost > maxPriceForTimeLimit) {
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit;
|
||||||
|
|
||||||
|
CalcState cs(CalcState::State::OVERPAID);
|
||||||
|
return std::make_pair(cs, dt);
|
||||||
|
}
|
||||||
|
if (cost == maxPriceForTimeLimit) {
|
||||||
|
cfg->getPaymentOptions(paymentOptionIndex).pop_max_price = maxPriceForTimeLimit;
|
||||||
|
|
||||||
|
CalcState cs(CalcState::State::SUCCESS_MAXPRICE);
|
||||||
|
return std::make_pair(cs, dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "DT" << dt.toString(Qt::ISODate);
|
||||||
|
return std::make_pair(CalcState(CalcState::State::SUCCESS), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "outside allowed parking time" << dt.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME,
|
||||||
|
CalcState::OUTSIDE_ALLOWED_PARKING_TIME), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computationStarted == false) {
|
||||||
|
computationStarted = true;
|
||||||
|
if (std::optional<ATBTariffPrepaid> pp = getPrepaid(cfg, dt)) {
|
||||||
|
TimeRange const &prepaidTimeRange = pp.value().m_range;
|
||||||
|
ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0);
|
||||||
|
free_parking_time_in_minutes += t.secsTo(prepaidTimeRange.m_end.toString(Qt::ISODate)) / 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffCarryOver> co = getCarryOver(cfg, dt)) {
|
||||||
|
int minutes = co.value().computeMinutesUntilCarryOverEnd(dt);
|
||||||
|
if (minutes > 0) {
|
||||||
|
free_parking_time_in_minutes += minutes;
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffService> serv = getService(cfg, dt)) {
|
||||||
|
TimeRange const &serviceTimeRange = serv.value().m_range;
|
||||||
|
|
||||||
|
if (nettoParktimeForCost > netto_parking_time_in_minutes) {
|
||||||
|
int rest_parking_time_in_minutes = nettoParktimeForCost - netto_parking_time_in_minutes;
|
||||||
|
ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0);
|
||||||
|
int timeToServiceEnd = t.secsTo(serviceTimeRange.m_end.toString(Qt::ISODate)) / 60;
|
||||||
|
|
||||||
|
// TODO: wohl aehnlich wie carry-over zu behandlen
|
||||||
|
if (serviceTimeRange.m_duration > 0) {
|
||||||
|
if (timeToServiceEnd < rest_parking_time_in_minutes) {
|
||||||
|
netto_parking_time_in_minutes += timeToServiceEnd;
|
||||||
|
} else {
|
||||||
|
netto_parking_time_in_minutes += rest_parking_time_in_minutes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "cnt" << cnt << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt >= 10) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "BREAK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure if last carry-over ranges shall be added to ticket-end-time
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
QVector<TimeRange> timeRanges;
|
||||||
|
while (std::optional<ATBTariffCarryOver> co = getCarryOver(cfg, dt)) {
|
||||||
|
if (++cnt > 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TimeRange const &carryOverTimeRange = co.value().m_range;
|
||||||
|
if (!timeRanges.isEmpty()) {
|
||||||
|
if (timeRanges.last().m_end != carryOverTimeRange.m_start) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeRanges.push_back(carryOverTimeRange);
|
||||||
|
|
||||||
|
int minutes = co.value().computeMinutesUntilCarryOverEnd(dt);
|
||||||
|
if (minutes > 0) {
|
||||||
|
free_parking_time_in_minutes += co.value().computeMinutesUntilCarryOverEnd(dt);
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("ticket-end-time %1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (successMaxPrice) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "SUCC" << dt;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::SUCCESS_MAXPRICE), dt);
|
||||||
|
}
|
||||||
|
if (overPaid) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "OVER" << dt;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "DT" << dt.toString(Qt::ISODate);
|
||||||
|
return std::make_pair(CalcState(CalcState::State::SUCCESS), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<CalcState, std::optional<int>>
|
||||||
|
Calculator::ComputeCostFromDuration(Configuration *cfg, QDateTime const &startDatetime,
|
||||||
|
QDateTime &endDatetime, int nettoParkingTime) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
int paymentOptionIndex = 0;
|
||||||
|
|
||||||
|
std::optional<int> cost{};
|
||||||
|
|
||||||
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
|
||||||
|
int price = 0;
|
||||||
|
int durationId = 0;
|
||||||
|
int netto_parking_time_in_minutes = 0;
|
||||||
|
int brutto_parking_time_in_minutes = 0;
|
||||||
|
int free_parking_time_in_minutes = 0;
|
||||||
|
|
||||||
|
QMap<int, int> nettoParktimePrice;
|
||||||
|
QMap<int, int> priceNettoParktime;
|
||||||
|
|
||||||
|
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
|
||||||
|
durationId = itr->second.pra_payment_unit_id;
|
||||||
|
|
||||||
|
int const pra_price = itr->second.pra_price;
|
||||||
|
if (pop_accumulate_prices) {
|
||||||
|
price += pra_price;
|
||||||
|
} else {
|
||||||
|
price = pra_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto search = cfg->Duration.find(durationId);
|
||||||
|
if (search != cfg->Duration.end()) {
|
||||||
|
// found now the duration in minutes
|
||||||
|
// check if we are still inside the working-time-range
|
||||||
|
ATBDuration duration = search->second;
|
||||||
|
nettoParktimePrice.insert(duration.pun_duration, price);
|
||||||
|
priceNettoParktime.insert(price, duration.pun_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START netto-parking-time" << nettoParkingTime;
|
||||||
|
CalcState returnState;
|
||||||
|
|
||||||
|
QList<int> keys = nettoParktimePrice.keys();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "Times Keys" << keys;
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "Prices Keys" << priceNettoParktime.keys();
|
||||||
|
|
||||||
|
int index = keys.indexOf(nettoParkingTime);
|
||||||
|
if (index != -1) {
|
||||||
|
int c = nettoParktimePrice[keys.at(index)];
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "cost for netto-parking-time" << c;
|
||||||
|
|
||||||
|
std::pair<CalcState, QDateTime> r = ComputeDurationFromCost(cfg, startDatetime, c);
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "result"
|
||||||
|
<< r.first.toString() << r.second.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
returnState = r.first;
|
||||||
|
endDatetime = r.second;
|
||||||
|
|
||||||
|
|
||||||
|
if (returnState.getStatus() == CalcState::State::SUCCESS ||
|
||||||
|
returnState.getStatus() == CalcState::State::SUCCESS_MAXPRICE ||
|
||||||
|
returnState.getStatus() == CalcState::State::OVERPAID) {
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- endDateTime" << endDatetime.toString(Qt::ISODate);
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "------ r.second" << r.second.toString(Qt::ISODate);
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "status" << returnState.toString() << (int)returnState.getStatus();
|
||||||
|
|
||||||
|
if (!endDatetime.isNull() && endDatetime.isValid()) {
|
||||||
|
cost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- return cost" << cost.value();
|
||||||
|
return std::make_pair(returnState, cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- return error for cost" << returnState.toString();
|
||||||
|
return std::make_pair(returnState, cost);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
std::pair<std::string, QDateTime>
|
std::pair<std::string, QDateTime>
|
||||||
Calculator::GetDurationFromCost(Configuration* cfg,
|
Calculator::GetDurationFromCost(Configuration* cfg,
|
||||||
@@ -253,6 +926,17 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
qCritical() << DBG_HEADER << " TODO";
|
qCritical() << DBG_HEADER << " TODO";
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
if (paymentMethodId == PaymentMethod::Unified) {
|
||||||
|
std::pair<CalcState, QDateTime> r =
|
||||||
|
ComputeDurationFromCost(cfg, QDateTime::fromString(startDatetimePassed, Qt::ISODate), cost);
|
||||||
|
|
||||||
|
CalcState cs = r.first;
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << cs.toString();
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << r.second.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
return std::make_pair(r.first.toString().toStdString(), r.second);
|
||||||
|
} else
|
||||||
if (paymentMethodId == PaymentMethod::Steps) {
|
if (paymentMethodId == PaymentMethod::Steps) {
|
||||||
if (tariffIs24_7(cfg)) {
|
if (tariffIs24_7(cfg)) {
|
||||||
// use tariff with structure as for instance Schoenau, Koenigsee:
|
// use tariff with structure as for instance Schoenau, Koenigsee:
|
||||||
@@ -270,9 +954,13 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price;
|
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price
|
||||||
|
= cfg->getPaymentOptions(paymentOptionIndex).pop_max_price_save;
|
||||||
|
//int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time;
|
||||||
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
||||||
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
int price = 0;
|
||||||
|
|
||||||
if (cost == pop_max_price) {
|
if (cost == pop_max_price) {
|
||||||
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
@@ -410,9 +1098,9 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate);
|
qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
// int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
// int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations;
|
// int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations;
|
||||||
int price = 0;
|
// int price = 0;
|
||||||
int new_price = 0;
|
int new_price = 0;
|
||||||
int durationInSecs = 0;
|
int durationInSecs = 0;
|
||||||
uint32_t duration_previous = 0;
|
uint32_t duration_previous = 0;
|
||||||
@@ -1203,7 +1891,7 @@ CalcState Calculator::isParkingAllowedForWeekDay(Configuration const *cfg,
|
|||||||
(int)cfg->TimeRange.count(pop_carry_over_end_time_range) <= 0) {
|
(int)cfg->TimeRange.count(pop_carry_over_end_time_range) <= 0) {
|
||||||
|
|
||||||
qCritical() << DBG_HEADER << "PARKING_ALLOWED. startTime" << startTime.toString(Qt::ISODate);
|
qCritical() << DBG_HEADER << "PARKING_ALLOWED. startTime" << startTime.toString(Qt::ISODate);
|
||||||
return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", startTime);
|
return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", startTime, QTime());
|
||||||
|
|
||||||
} else
|
} else
|
||||||
// search entry in time-range-field of tariff-file
|
// search entry in time-range-field of tariff-file
|
||||||
@@ -2939,7 +3627,9 @@ uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep, int p
|
|||||||
qCritical() << "(" << __func__ << ":" << __LINE__ << ") timeStep" << timeStep;
|
qCritical() << "(" << __func__ << ":" << __LINE__ << ") timeStep" << timeStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeStep == pun_duration) {
|
// allow some tolerance when searching for [timeStep == pun_duration]:
|
||||||
|
// this might happen when crossing minute boundaries
|
||||||
|
if (std::abs(timeStep - pun_duration) < 4) {
|
||||||
qCritical() << "(" << __func__ << ":" << __LINE__ << ") return price" << price;
|
qCritical() << "(" << __func__ << ":" << __LINE__ << ") return price" << price;
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
@@ -3010,6 +3700,9 @@ Calculator::GetDailyTicketPrice(Configuration* cfg,
|
|||||||
if (dailyTickets) {
|
if (dailyTickets) {
|
||||||
QVector<ATBDailyTicket> const tickets = dailyTickets.value();
|
QVector<ATBDailyTicket> const tickets = dailyTickets.value();
|
||||||
switch (permitType) {
|
switch (permitType) {
|
||||||
|
case PERMIT_TYPE::FREE_TICKET: {
|
||||||
|
// TODO
|
||||||
|
} break;
|
||||||
case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: {
|
case PERMIT_TYPE::TWENTY_FOUR_HOURS_TICKET: {
|
||||||
// TODO
|
// TODO
|
||||||
} break;
|
} break;
|
||||||
@@ -3097,6 +3790,10 @@ Calculator::GetDailyTicketPrice(Configuration* cfg,
|
|||||||
// [[fallthrough]];
|
// [[fallthrough]];
|
||||||
case PERMIT_TYPE::SHORT_TERM_PARKING: {
|
case PERMIT_TYPE::SHORT_TERM_PARKING: {
|
||||||
}
|
}
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_1: {
|
||||||
|
}
|
||||||
|
case PERMIT_TYPE::TEST_PRODUCT_2: {
|
||||||
|
}
|
||||||
// [[fallthrough]];
|
// [[fallthrough]];
|
||||||
case PERMIT_TYPE::DAY_TICKET: {
|
case PERMIT_TYPE::DAY_TICKET: {
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
+436
-15
@@ -10,10 +10,15 @@
|
|||||||
#include "tariff_global_defines.h"
|
#include "tariff_global_defines.h"
|
||||||
#include "tariff_settings.h"
|
#include "tariff_settings.h"
|
||||||
#include "tariff_carryover_settings.h"
|
#include "tariff_carryover_settings.h"
|
||||||
|
#include "atb_time.h"
|
||||||
|
#include "tariff_prepaid.h"
|
||||||
|
#include "tariff_carryover.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
MemberType Configuration::IdentifyJsonMember(const char* member_name)
|
MemberType Configuration::IdentifyJsonMember(const char* member_name)
|
||||||
@@ -43,6 +48,7 @@ MemberType Configuration::IdentifyJsonMember(const char* member_name)
|
|||||||
if (strcmp(member_name, "Interpolation") == 0) return MemberType::InterpolationType;
|
if (strcmp(member_name, "Interpolation") == 0) return MemberType::InterpolationType;
|
||||||
if (strcmp(member_name, "Prepaid") == 0) return MemberType::PrepaidType;
|
if (strcmp(member_name, "Prepaid") == 0) return MemberType::PrepaidType;
|
||||||
if (strcmp(member_name, "CarryOver") == 0) return MemberType::CarryOverType;
|
if (strcmp(member_name, "CarryOver") == 0) return MemberType::CarryOverType;
|
||||||
|
if (strcmp(member_name, "Includes") == 0) return MemberType::IncludesType;
|
||||||
else return MemberType::UnknownType;
|
else return MemberType::UnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +67,414 @@ ATBWeekDay parseWeekDay(Configuration &cfg,
|
|||||||
ATBWeekDay WeekDay;
|
ATBWeekDay WeekDay;
|
||||||
QTime start, end, parking_time_limit, about_to_exceed_limit;
|
QTime start, end, parking_time_limit, about_to_exceed_limit;
|
||||||
ATBTariffCarryOverSettings::ParkingTimeLimitChecker parkTimeLimitChecker;
|
ATBTariffCarryOverSettings::ParkingTimeLimitChecker parkTimeLimitChecker;
|
||||||
|
QDate const &d = QDate::fromString(innerObjName, Qt::ISODate);
|
||||||
|
if (innerObjName == QString("default") ||
|
||||||
|
(!d.isNull() && d.isValid())) { // special day, given in date-format
|
||||||
|
// start with new implementation of tariff-calculator
|
||||||
|
// see for instance: bad neuenahr (249), Zone5
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << innerObjName;
|
||||||
|
|
||||||
|
if (k->value.IsObject()) {
|
||||||
|
auto obj = k->value.GetObject();
|
||||||
|
for (auto m = obj.MemberBegin(); m != obj.MemberEnd(); ++m) {
|
||||||
|
QString const &name = m->name.GetString();
|
||||||
|
if (name == "payment_settings") {
|
||||||
|
if (m->value.IsArray()) {
|
||||||
|
auto payment = m->value.GetArray();
|
||||||
|
if (payment.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no payment settings for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
for (rapidjson::SizeType j = 0; j < payment.Size(); ++j) {
|
||||||
|
if (payment[j].IsObject()) {
|
||||||
|
auto paymentSetting = payment[j].GetObject();
|
||||||
|
for (auto n = paymentSetting.MemberBegin(); n != paymentSetting.MemberEnd(); ++n) {
|
||||||
|
QString const &name = QString::fromStdString(n->name.GetString());
|
||||||
|
if (name == "min_time") {
|
||||||
|
if (n->value.IsInt()) { min_time = n->value.GetInt(); }
|
||||||
|
} else if (name == "max_time") {
|
||||||
|
if (n->value.IsInt()) { max_time = n->value.GetInt(); }
|
||||||
|
} else if (name == "min_price") {
|
||||||
|
if (n->value.IsInt()) { min_price = n->value.GetInt(); }
|
||||||
|
} else if (name == "max_price") {
|
||||||
|
if (n->value.IsInt()) { max_price = n->value.GetInt(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
if (name == "prepaid_settings") {
|
||||||
|
if (m->value.IsArray()) {
|
||||||
|
auto prepaid = m->value.GetArray();
|
||||||
|
if (prepaid.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no prepaid-settings for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
ATBTariffPrepaid TariffPrepaid;
|
||||||
|
for (rapidjson::SizeType j = 0; j < prepaid.Size(); ++j) {
|
||||||
|
if (prepaid[j].IsObject()) {
|
||||||
|
auto prepaidSetting = prepaid[j].GetObject();
|
||||||
|
for (auto n = prepaidSetting.MemberBegin(); n != prepaidSetting.MemberEnd(); ++n) {
|
||||||
|
QString const &name = QString::fromStdString(n->name.GetString());
|
||||||
|
if (name == "prepaid_ranges") {
|
||||||
|
if (n->value.IsArray()) {
|
||||||
|
auto prepaidRanges = n->value.GetArray();
|
||||||
|
if (prepaidRanges.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no prepaid-ranges for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
QString prepaidStartStr;
|
||||||
|
QString prepaidEndStr;
|
||||||
|
QString prepaidIf;
|
||||||
|
int prepaidDuration = -1;
|
||||||
|
for (rapidjson::SizeType i = 0; i < prepaidRanges.Size(); ++i) {
|
||||||
|
if (prepaidRanges[j].IsObject()) {
|
||||||
|
auto prepaidRange = prepaidRanges[i].GetObject();
|
||||||
|
for (auto r = prepaidRange.MemberBegin(); r != prepaidRange.MemberEnd(); ++r) {
|
||||||
|
QString const &memName = QString::fromStdString(r->name.GetString());
|
||||||
|
if (memName == "prepaid_id") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
TariffPrepaid.m_id = r->value.GetInt();
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "prepaidId not an integer";
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "prepaid_duration") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
prepaidDuration = r->value.GetInt();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "prepaid_start") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
prepaidStartStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "prepaid_end") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
prepaidEndStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "prepaid_if") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
prepaidIf = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown prepaid setting" << memName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prepaidStartStr.isEmpty() && !prepaidEndStr.isEmpty() && prepaidDuration != -1) {
|
||||||
|
ATBTime prepaidStart(prepaidStartStr);
|
||||||
|
ATBTime prepaidEnd(prepaidEndStr);
|
||||||
|
if (prepaidStart.isValid() && prepaidEnd.isValid()) {
|
||||||
|
TariffPrepaid.m_range = TimeRange(prepaidStart, prepaidEnd, prepaidDuration);
|
||||||
|
TariffPrepaid.m_weekDay = weekDayName;
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
TariffPrepaid.m_date = d;
|
||||||
|
}
|
||||||
|
if (!prepaidIf.isNull() && !prepaidIf.trimmed().isEmpty()) {
|
||||||
|
TariffPrepaid.setPrepaidIf(prepaidIf);
|
||||||
|
}
|
||||||
|
qCritical() << TariffPrepaid;
|
||||||
|
|
||||||
|
cfg.TariffPrepaids.insert(std::pair<int, ATBTariffPrepaid>(weekDay, TariffPrepaid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (name == "carry_over_settings") {
|
||||||
|
if (m->value.IsArray()) {
|
||||||
|
auto carryOver = m->value.GetArray();
|
||||||
|
if (carryOver.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no carry-over-settings for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
ATBTariffCarryOver TariffCarryOver;
|
||||||
|
for (rapidjson::SizeType j = 0; j < carryOver.Size(); ++j) {
|
||||||
|
if (carryOver[j].IsObject()) {
|
||||||
|
auto carryOverSetting = carryOver[j].GetObject();
|
||||||
|
for (auto n = carryOverSetting.MemberBegin(); n != carryOverSetting.MemberEnd(); ++n) {
|
||||||
|
QString const &name = QString::fromStdString(n->name.GetString());
|
||||||
|
if (name == "carry_over_ranges") {
|
||||||
|
if (n->value.IsArray()) {
|
||||||
|
auto carryOverRanges = n->value.GetArray();
|
||||||
|
if (carryOverRanges.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no carry-over-ranges for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
QString carryOverStartStr;
|
||||||
|
QString carryOverEndStr;
|
||||||
|
QString carryOverIf;
|
||||||
|
int carryOverDuration = -1;
|
||||||
|
for (rapidjson::SizeType i = 0; i < carryOverRanges.Size(); ++i) {
|
||||||
|
if (carryOverRanges[j].IsObject()) {
|
||||||
|
auto carryOverRange = carryOverRanges[i].GetObject();
|
||||||
|
for (auto r = carryOverRange.MemberBegin(); r != carryOverRange.MemberEnd(); ++r) {
|
||||||
|
QString const &memName = QString::fromStdString(r->name.GetString());
|
||||||
|
if (memName == "carry_over_id") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
TariffCarryOver.m_id = r->value.GetInt();
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "carryOverId not an integer";
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "carry_over_duration") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
carryOverDuration = r->value.GetInt();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "carry_over_start") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
carryOverStartStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "carry_over_end") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
carryOverEndStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "carry_over_if") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
carryOverIf = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown carry-over setting" << memName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!carryOverStartStr.isEmpty() && !carryOverEndStr.isEmpty() && carryOverDuration != -1) {
|
||||||
|
ATBTime carryOverStart(carryOverStartStr);
|
||||||
|
ATBTime carryOverEnd(carryOverEndStr);
|
||||||
|
if (carryOverStart.isValid() && carryOverEnd.isValid()) {
|
||||||
|
TariffCarryOver.m_range = TimeRange(carryOverStart, carryOverEnd, carryOverDuration);
|
||||||
|
TariffCarryOver.m_weekDay = weekDayName;
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
TariffCarryOver.m_date = d;
|
||||||
|
}
|
||||||
|
if (!carryOverIf.isNull() && !carryOverIf.trimmed().isEmpty()) {
|
||||||
|
TariffCarryOver.setCarryOverIf(carryOverIf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// qCritical() << TariffCarryOver;
|
||||||
|
|
||||||
|
cfg.TariffCarryOvers.insert(std::pair<int, ATBTariffCarryOver>(weekDay, TariffCarryOver));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (name == "service_settings") {
|
||||||
|
ATBTariffService TariffService;
|
||||||
|
if (m->value.IsArray()) {
|
||||||
|
auto service = m->value.GetArray();
|
||||||
|
if (service.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no service settings for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
for (rapidjson::SizeType j = 0; j < service.Size(); ++j) {
|
||||||
|
if (service[j].IsObject()) {
|
||||||
|
auto serviceSetting = service[j].GetObject();
|
||||||
|
for (auto n = serviceSetting.MemberBegin(); n != serviceSetting.MemberEnd(); ++n) {
|
||||||
|
QString const &name = QString::fromStdString(n->name.GetString());
|
||||||
|
if (name == "service_ranges") {
|
||||||
|
if (n->value.IsArray()) {
|
||||||
|
auto serviceRanges = n->value.GetArray();
|
||||||
|
if (serviceRanges.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no service ranges for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
QString serviceStartStr;
|
||||||
|
QString serviceEndStr;
|
||||||
|
QString serviceIf;
|
||||||
|
int serviceDuration = -1;
|
||||||
|
for (rapidjson::SizeType i = 0; i < serviceRanges.Size(); ++i) {
|
||||||
|
if (serviceRanges[j].IsObject()) {
|
||||||
|
auto serviceRange = serviceRanges[i].GetObject();
|
||||||
|
for (auto r = serviceRange.MemberBegin(); r != serviceRange.MemberEnd(); ++r) {
|
||||||
|
QString const &memName = QString::fromStdString(r->name.GetString());
|
||||||
|
if (memName == "service_id") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
TariffService.m_id = r->value.GetInt();
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "serviceId not an integer";
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "service_duration") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
serviceDuration = r->value.GetInt();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "service_start") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
serviceStartStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "service_end") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
serviceEndStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "service_if") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
serviceIf = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown service setting" << memName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!serviceStartStr.isEmpty() && !serviceEndStr.isEmpty() && serviceDuration != -1) {
|
||||||
|
ATBTime serviceStart(serviceStartStr);
|
||||||
|
ATBTime serviceEnd(serviceEndStr);
|
||||||
|
if (serviceStart.isValid() && serviceEnd.isValid()) {
|
||||||
|
TariffService.m_range = TimeRange(serviceStart, serviceEnd, serviceDuration);
|
||||||
|
TariffService.m_weekDay = weekDayName;
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
TariffService.m_date = d;
|
||||||
|
}
|
||||||
|
if (!serviceIf.isEmpty()) {
|
||||||
|
TariffService.setServiceIf(serviceIf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// qCritical() << TariffService;
|
||||||
|
|
||||||
|
cfg.TariffServices.insert(std::pair<int, ATBTariffService>(weekDay, TariffService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (name == "out_of_service_settings") {
|
||||||
|
ATBTariffOutOfService TariffOutOfService;
|
||||||
|
if (m->value.IsArray()) {
|
||||||
|
auto outOfService = m->value.GetArray();
|
||||||
|
if (outOfService.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no out of service settings for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
for (rapidjson::SizeType j = 0; j < outOfService.Size(); ++j) {
|
||||||
|
if (outOfService[j].IsObject()) {
|
||||||
|
auto outOfServiceSetting = outOfService[j].GetObject();
|
||||||
|
for (auto n = outOfServiceSetting.MemberBegin(); n != outOfServiceSetting.MemberEnd(); ++n) {
|
||||||
|
QString const &name = QString::fromStdString(n->name.GetString());
|
||||||
|
if (name == "out_of_service_ranges") {
|
||||||
|
if (n->value.IsArray()) {
|
||||||
|
auto outOfServiceRanges = n->value.GetArray();
|
||||||
|
if (outOfServiceRanges.Size() == 0) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "no out of service ranges for" << weekDayName;
|
||||||
|
} else {
|
||||||
|
QString outOfServiceStartStr;
|
||||||
|
QString outOfServiceEndStr;
|
||||||
|
QString outOfServiceIf;
|
||||||
|
int outOfServiceDuration = -1;
|
||||||
|
for (rapidjson::SizeType i = 0; i < outOfServiceRanges.Size(); ++i) {
|
||||||
|
if (outOfServiceRanges[j].IsObject()) {
|
||||||
|
auto outOfServiceRange = outOfServiceRanges[i].GetObject();
|
||||||
|
for (auto r = outOfServiceRange.MemberBegin(); r != outOfServiceRange.MemberEnd(); ++r) {
|
||||||
|
QString const &memName = QString::fromStdString(r->name.GetString());
|
||||||
|
if (memName == "out_of_service_id") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
TariffOutOfService.m_id = r->value.GetInt();
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "outOfServiceId not an integer";
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "out_of_service_duration") {
|
||||||
|
if (r->value.IsInt()) {
|
||||||
|
outOfServiceDuration = r->value.GetInt();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "out_of_service_start") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
outOfServiceStartStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "out_of_service_end") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
outOfServiceEndStr = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (memName == "out_of_service_if") {
|
||||||
|
if (r->value.IsString()) {
|
||||||
|
outOfServiceIf = QString::fromStdString(r->value.GetString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown out of service setting" << memName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outOfServiceStartStr.isEmpty() && !outOfServiceEndStr.isEmpty() && outOfServiceDuration != -1) {
|
||||||
|
ATBTime outOfServiceStart(outOfServiceStartStr);
|
||||||
|
ATBTime outOfServiceEnd(outOfServiceEndStr);
|
||||||
|
if (outOfServiceStart.isValid() && outOfServiceEnd.isValid()) {
|
||||||
|
TariffOutOfService.m_range = TimeRange(outOfServiceStart, outOfServiceEnd, outOfServiceDuration);
|
||||||
|
TariffOutOfService.m_weekDay = weekDayName;
|
||||||
|
if (!d.isNull() && d.isValid()) {
|
||||||
|
TariffOutOfService.m_date = d;
|
||||||
|
}
|
||||||
|
if (!outOfServiceIf.isEmpty()) {
|
||||||
|
TariffOutOfService.setOutOfServiceIf(outOfServiceIf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// qCritical() << TariffOutOfService;
|
||||||
|
|
||||||
|
cfg.TariffOutOfServices.insert(std::pair<int, ATBTariffOutOfService>(weekDay, TariffOutOfService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ATBTariffSettings ts(max_price, min_price, max_time, min_time);
|
||||||
|
ATBTariffCarryOverSettings cs(duration, start, end, parking_time_limit, about_to_exceed_limit,
|
||||||
|
parkTimeLimitChecker);
|
||||||
|
if (!d.isNull() && d.isValid()) { // special day, given in date-format
|
||||||
|
WeekDay = ATBWeekDay(weekDay, weekDayName, ATBWeekDay::HOLIDAY, QDate(), ts, cs);
|
||||||
|
} else {
|
||||||
|
WeekDay = ATBWeekDay(weekDay, weekDayName, ATBWeekDay::USUAL_WEEKDAY, QDate(), ts, cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
if (innerObjName == QString("week_day_default")) {
|
if (innerObjName == QString("week_day_default")) {
|
||||||
if (k->value.IsObject()) {
|
if (k->value.IsObject()) {
|
||||||
auto obj = k->value.GetObject();
|
auto obj = k->value.GetObject();
|
||||||
@@ -408,6 +822,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
ATBInterpolation TariffInterpolation;
|
ATBInterpolation TariffInterpolation;
|
||||||
ATBPrepaid TariffPrepaidOption;
|
ATBPrepaid TariffPrepaidOption;
|
||||||
ATBCarryOver TariffCarryOver;
|
ATBCarryOver TariffCarryOver;
|
||||||
|
QList<QPair<QString, QString>> TariffIncludes;
|
||||||
|
|
||||||
MemberType mb_type = MemberType::UnknownType;
|
MemberType mb_type = MemberType::UnknownType;
|
||||||
this->currentPaymentOptions.clear();
|
this->currentPaymentOptions.clear();
|
||||||
@@ -473,32 +888,32 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
break;
|
break;
|
||||||
case MemberType::WeekDaysType: {
|
case MemberType::WeekDaysType: {
|
||||||
ATBWeekDay WeekDay;
|
ATBWeekDay WeekDay;
|
||||||
if (QString(mb_name) == "Monday") {
|
if (QString(mb_name).trimmed() == "Monday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Monday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Monday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Tuesday") {
|
if (QString(mb_name).trimmed() == "Tuesday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Tuesday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Tuesday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Wednesday") {
|
if (QString(mb_name).trimmed() == "Wednesday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Wednesday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Wednesday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Thursday") {
|
if (QString(mb_name).trimmed() == "Thursday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Thursday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Thursday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Friday") {
|
if (QString(mb_name).trimmed() == "Friday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Friday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Friday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Saturday") {
|
if (QString(mb_name).trimmed() == "Saturday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Saturday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Saturday, QString(mb_name).trimmed());
|
||||||
} else
|
} else
|
||||||
if (QString(mb_name) == "Sunday") {
|
if (QString(mb_name).trimmed() == "Sunday") {
|
||||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Sunday, mb_name);
|
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Sunday, QString(mb_name).trimmed());
|
||||||
} else {
|
} else {
|
||||||
qCritical() << "ERROR: unknown week day" << mb_name;
|
qCritical() << "ERROR: unknown week day" << mb_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg->WeekDays.insert(pair<Qt::DayOfWeek, ATBWeekDay>(WeekDay.m_id, WeekDay));
|
cfg->WeekDays.insert(pair<Qt::DayOfWeek, ATBWeekDay>(WeekDay.m_id, WeekDay));
|
||||||
// qCritical() << WeekDay;
|
qCritical() << __func__ << ":" << __LINE__ << cfg << "CCCC insert" << (int)WeekDay.m_id << WeekDay.m_name;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case MemberType::CarryOverType: {
|
case MemberType::CarryOverType: {
|
||||||
@@ -939,6 +1354,9 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString();
|
else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString();
|
||||||
else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool();
|
else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool();
|
||||||
break;
|
break;
|
||||||
|
case MemberType::IncludesType:
|
||||||
|
TariffIncludes << QPair<QString, QString>(QString(inner_obj_name), k->value.GetString());
|
||||||
|
break;
|
||||||
case MemberType::PaymentMethodType:
|
case MemberType::PaymentMethodType:
|
||||||
if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt();
|
if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt();
|
||||||
else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString();
|
else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString();
|
||||||
@@ -1228,6 +1646,9 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
cfg->TariffCarryOverOptions.insert(pair<int, ATBCarryOver>(TariffCarryOver.id, TariffCarryOver));
|
cfg->TariffCarryOverOptions.insert(pair<int, ATBCarryOver>(TariffCarryOver.id, TariffCarryOver));
|
||||||
// qCritical() << TariffCarryOver;
|
// qCritical() << TariffCarryOver;
|
||||||
break;
|
break;
|
||||||
|
case MemberType::IncludesType:
|
||||||
|
cfg->TariffIncludes = TariffIncludes;
|
||||||
|
// qCritical() << "TariffIncludes" << cfg->TariffIncludes;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -427,6 +427,8 @@ PaymentMethod Utilities::getPaymentMethodId(Configuration const *cfg) {
|
|||||||
return PaymentMethod::Degressive;
|
return PaymentMethod::Degressive;
|
||||||
case PaymentMethod::Progressive:
|
case PaymentMethod::Progressive:
|
||||||
return PaymentMethod::Progressive;
|
return PaymentMethod::Progressive;
|
||||||
|
case PaymentMethod::Unified:
|
||||||
|
return PaymentMethod::Unified;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+162
-27
@@ -39,11 +39,11 @@ extern "C" char* strptime(const char* s,
|
|||||||
|
|
||||||
#define SZEGED (0)
|
#define SZEGED (0)
|
||||||
#define SCHOENAU_KOENIGSEE (0)
|
#define SCHOENAU_KOENIGSEE (0)
|
||||||
#define NEUHAUSER_KORNEUBURG (0)
|
#define NEUHAUSER_KORNEUBURG (1)
|
||||||
#define NEUHAUSER_LINSINGER_MASCHINENBAU (0)
|
#define NEUHAUSER_LINSINGER_MASCHINENBAU (0)
|
||||||
#define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0)
|
#define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0)
|
||||||
#define NEUHAUSER_BILEXA_GALTUER (0)
|
#define NEUHAUSER_BILEXA_GALTUER (0)
|
||||||
#define BAD_NEUENAHR_AHRWEILER (1)
|
#define BAD_NEUENAHR_AHRWEILER (0)
|
||||||
#define NEUHAUSER_CHRISTOPH_REISEN (0)
|
#define NEUHAUSER_CHRISTOPH_REISEN (0)
|
||||||
#define NEUHAUSER_PERNEGG_AN_DER_MUR (0)
|
#define NEUHAUSER_PERNEGG_AN_DER_MUR (0)
|
||||||
#define NEUHAUSER_STOCKERAU (0)
|
#define NEUHAUSER_STOCKERAU (0)
|
||||||
@@ -52,6 +52,7 @@ extern "C" char* strptime(const char* s,
|
|||||||
#define SCHNALS_LEITER_KIRCHL (0)
|
#define SCHNALS_LEITER_KIRCHL (0)
|
||||||
#define SCHNALS_STAUMAUER (SCHNALS_LEITER_KIRCHL)
|
#define SCHNALS_STAUMAUER (SCHNALS_LEITER_KIRCHL)
|
||||||
#define VALSER_ALM (0)
|
#define VALSER_ALM (0)
|
||||||
|
#define NEUHAUSER_FORCHACH (0)
|
||||||
|
|
||||||
#if NEUHAUSER_KIRCHDORF==1
|
#if NEUHAUSER_KIRCHDORF==1
|
||||||
static bool test_neuhauser_kirchdorf(int step, double cost) {
|
static bool test_neuhauser_kirchdorf(int step, double cost) {
|
||||||
@@ -210,21 +211,73 @@ static bool test_neuhauser_kirchdorf(int step, double cost) {
|
|||||||
return 0;
|
return 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
QString getCalculatorLibVersion() {
|
||||||
|
static QString v;
|
||||||
|
if (v.isEmpty()) {
|
||||||
|
QProcess shell;
|
||||||
|
QString command = QString("cat /proc/%1/maps | awk '{print $6;}' | grep 'libmobilisis_calc' | uniq").arg(QCoreApplication::applicationPid());
|
||||||
|
|
||||||
|
shell.start("/bin/bash", {"-c", command});
|
||||||
|
if ( shell.waitForFinished( 5000 )) {
|
||||||
|
v = shell.readAllStandardOutput();
|
||||||
|
// /usr/lib/libmobilisis_calc.so.2.3.99-18
|
||||||
|
if (!v.isEmpty()) {
|
||||||
|
QStringList vlst = v.trimmed().split("/", QString::SkipEmptyParts);
|
||||||
|
if (vlst.size() > 0) {
|
||||||
|
vlst = vlst.last().split(".", QString::SkipEmptyParts);
|
||||||
|
if (vlst.size() > 4) {
|
||||||
|
v = QString("%1.%2.%3").arg(vlst[2]).arg(vlst[3]).arg(vlst[4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isProductSupportedInCalculatorLib(QString const &product) {
|
||||||
|
bool supported{false};
|
||||||
|
|
||||||
|
QProcess shell;
|
||||||
|
QString command = QString("cat /proc/%1/maps | awk '{print $6;}' | grep 'libmobilisis_calc' | uniq | xargs strings | grep %2").arg(QCoreApplication::applicationPid()).arg(product);
|
||||||
|
|
||||||
|
shell.start("/bin/bash", {"-c", command});
|
||||||
|
if ( shell.waitForFinished( 5000 )) {
|
||||||
|
QString s = shell.readAllStandardOutput().trimmed();
|
||||||
|
// /usr/lib/libmobilisis_calc.so.2.3.99-18
|
||||||
|
if (!s.isEmpty() && (s == product)) {
|
||||||
|
qCritical() << "product" << s << "supported";
|
||||||
|
supported = true;
|
||||||
|
} else {
|
||||||
|
qCritical() << "product" << product << "not supported";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
qCritical() << getCalculatorLibVersion();
|
||||||
|
isProductSupportedInCalculatorLib("FREE_TICKET");
|
||||||
|
return 0;
|
||||||
//487 {
|
//487 {
|
||||||
// 488 "pra_payment_option_id": 1049,
|
// 488 "pra_payment_option_id": 1049,
|
||||||
// 489 "pra_payment_unit_id": 84,
|
// 489 "pra_payment_unit_id": 84,
|
||||||
// 490 "pra_price":"840"
|
// 490 "pra_price":"840"
|
||||||
//>>491 }
|
//>>491 }
|
||||||
|
|
||||||
//for (int i = 1; i < 85; ++i) {
|
//for (int i = 1; i < 346; ++i) {
|
||||||
//printf("{\n \"\pra_payment_option_id\": 1049,\n \"\pra_payment_unit_id\": %d,\n \"pra_price\": %d\n},\n",
|
//printf("{\n \"pun_id\": %i,\n \"pun_duration\": %d\n},\n",
|
||||||
// i, i*10);
|
// i, 60 + i*4);
|
||||||
//}
|
//}
|
||||||
//return 0;
|
for (int i = 1; i < 361; ++i) {
|
||||||
|
printf("{\n \"pra_payment_option_id\": 1049,\n \"pra_payment_unit_id\": %i,\n \"pra_price\":%i\n},\n",
|
||||||
|
i, i*10);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
#if 0
|
#if 0
|
||||||
MessageHelper msgHelp;
|
MessageHelper msgHelp;
|
||||||
// msgHelp.createLoginMessageChunksToSend(0x02);
|
// msgHelp.createLoginMessageChunksToSend(0x02);
|
||||||
@@ -755,7 +808,7 @@ int main() {
|
|||||||
int pop_max_price;
|
int pop_max_price;
|
||||||
int pop_daily_card_price;
|
int pop_daily_card_price;
|
||||||
|
|
||||||
int zone = 3;
|
int zone = 1;
|
||||||
|
|
||||||
if (zone == 1) {
|
if (zone == 1) {
|
||||||
input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff01.json");
|
input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff01.json");
|
||||||
@@ -844,7 +897,7 @@ int main() {
|
|||||||
CalcState calcState;
|
CalcState calcState;
|
||||||
QDateTime s(QDateTime::currentDateTime());
|
QDateTime s(QDateTime::currentDateTime());
|
||||||
|
|
||||||
s.setTime(QTime(12, 0, 0));
|
// s.setTime(QTime(12, 0, 0));
|
||||||
|
|
||||||
//calcState = compute_duration_for_parking_ticket(&cfg, s,
|
//calcState = compute_duration_for_parking_ticket(&cfg, s,
|
||||||
// (double)1200, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW));
|
// (double)1200, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW));
|
||||||
@@ -852,9 +905,26 @@ int main() {
|
|||||||
//qCritical() << calcState.toString();
|
//qCritical() << calcState.toString();
|
||||||
|
|
||||||
calcState = compute_duration_for_parking_ticket(&cfg, s,
|
calcState = compute_duration_for_parking_ticket(&cfg, s,
|
||||||
(double)50, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_BUS));
|
(double)9000, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_BUS));
|
||||||
qCritical() << end.toString(Qt::ISODate);
|
qCritical() << end.toString(Qt::ISODate);
|
||||||
qCritical() << calcState.toString();
|
qCritical() << calcState.toString();
|
||||||
|
|
||||||
|
struct price_t costs;
|
||||||
|
|
||||||
|
CalcState cs;
|
||||||
|
|
||||||
|
for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) {
|
||||||
|
QDateTime end = start.addSecs(timeSteps.at(i)*60);
|
||||||
|
|
||||||
|
qCritical() << "XXXXX end" << end.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
cs = compute_price_for_parking_ticket(&cfg, s, timeSteps.at(i), end, &costs,
|
||||||
|
PermitType(PERMIT_TYPE::SHORT_TERM_PARKING));
|
||||||
|
if (cs.getStatus() != CalcState::State::SUCCESS) {
|
||||||
|
qCritical() << "ERROR STATUS" << costs.netto;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zone == 2) {
|
if (zone == 2) {
|
||||||
@@ -1369,6 +1439,29 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if NEUHAUSER_FORCHACH==1
|
||||||
|
std::ifstream input;
|
||||||
|
input.open("/opt/ptu5/opt/customer_749/etc/psa_tariff/tariff01.json");
|
||||||
|
|
||||||
|
std::stringstream sstr;
|
||||||
|
while(input >> sstr.rdbuf());
|
||||||
|
std::string json(sstr.str());
|
||||||
|
|
||||||
|
Configuration cfg;
|
||||||
|
|
||||||
|
bool isParsed = cfg.ParseJson(&cfg, json.c_str());
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
if (isParsed) {
|
||||||
|
compute_product_price(&cfg, PermitType(PERMIT_TYPE::DAY_TICKET_PKW));
|
||||||
|
compute_product_price(&cfg, PermitType(PERMIT_TYPE::DAY_TICKET_CAMPER));
|
||||||
|
|
||||||
|
QDateTime start = QDateTime::currentDateTime();
|
||||||
|
QDateTime ticketEndTime;
|
||||||
|
compute_duration_for_daily_ticket(&cfg, start, ticketEndTime, PermitType(PERMIT_TYPE::DAY_TICKET));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if BAD_NEUENAHR_AHRWEILER==1
|
#if BAD_NEUENAHR_AHRWEILER==1
|
||||||
std::ifstream input;
|
std::ifstream input;
|
||||||
@@ -1391,7 +1484,8 @@ int main() {
|
|||||||
case 2: {
|
case 2: {
|
||||||
qCritical() << " ZONE 2: KURZZEIT 1";
|
qCritical() << " ZONE 2: KURZZEIT 1";
|
||||||
// kuzzeit-1-tarif
|
// kuzzeit-1-tarif
|
||||||
input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json");
|
//input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json");
|
||||||
|
input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json");
|
||||||
//pop_max_time = 5*60;
|
//pop_max_time = 5*60;
|
||||||
} break;
|
} break;
|
||||||
case 3: {
|
case 3: {
|
||||||
@@ -1583,7 +1677,8 @@ int main() {
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
//start = QDateTime(QDate(2024, 10, 3), QTime(17, 0, 0)); // sunday
|
//start = QDateTime(QDate(2024, 10, 3), QTime(17, 0, 0)); // sunday
|
||||||
start = QDateTime(QDate(2024, 9, 8), QTime(16, 2, 0)); // sunday
|
//start = QDateTime(QDate(2025, 4, 20), QTime(18, 0, 0)); // sunday
|
||||||
|
start = QDateTime(QDate(2024, 9, 27), QTime(17, 0, 0)); // friday
|
||||||
fail = false;
|
fail = false;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
@@ -1615,8 +1710,8 @@ int main() {
|
|||||||
// << "START" << start.toString(Qt::ISODate)
|
// << "START" << start.toString(Qt::ISODate)
|
||||||
// << "<duration" << *step;
|
// << "<duration" << *step;
|
||||||
|
|
||||||
// if (*step != 180)
|
if (*step != 180)
|
||||||
// continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
double cost = 0;
|
double cost = 0;
|
||||||
@@ -2761,24 +2856,62 @@ int main() {
|
|||||||
bool nextDay = false;
|
bool nextDay = false;
|
||||||
bool prePaid = true;
|
bool prePaid = true;
|
||||||
// zone 1 (lila)
|
// zone 1 (lila)
|
||||||
QDateTime s(QDate(2023, 11, 30), QTime());
|
QDateTime s(QDate(2024, 10, 8), QTime());
|
||||||
QDateTime end;
|
QDateTime end;
|
||||||
|
|
||||||
|
static QList<int> const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg);
|
||||||
|
qCritical() << "TimeSteps" << timeSteps;
|
||||||
|
|
||||||
for (int duration = 30; duration <= pop_max_time; duration += 5) {
|
for (int duration = 30; duration <= pop_max_time; duration += 5) {
|
||||||
for (int offset = 420; offset < 1140; ++offset) {
|
int offset = 600;
|
||||||
if (offset > 720 && offset < 840) {
|
//for (int offset = 720; offset < 601; ++offset) {
|
||||||
continue;
|
//if (offset > 720 && offset < 840) {
|
||||||
}
|
// continue;
|
||||||
|
//}
|
||||||
QDateTime start = s.addSecs(offset * 60);
|
QDateTime start = s.addSecs(offset * 60);
|
||||||
//qCritical() << "start" << start.toString(Qt::ISODate);
|
//qCritical() << "start" << start.toString(Qt::ISODate);
|
||||||
|
|
||||||
double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid);
|
CalcState cs;
|
||||||
|
#if 1
|
||||||
|
struct price_t costs;
|
||||||
|
for (int i = 0, j=timeSteps.size() ; i < timeSteps.size(); --j, ++i) {
|
||||||
|
QDateTime end = start.addSecs(timeSteps.at(i)*60);
|
||||||
|
|
||||||
|
// if (i != 2) continue;
|
||||||
|
|
||||||
|
cs = compute_price_for_parking_ticket(&cfg, start, timeSteps.at(i), end, &costs, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING));
|
||||||
|
int price1 = costs.netto;
|
||||||
|
|
||||||
|
qCritical() << "compute_price_for_parking_ticket()/GetCostFromDuration() TIME: "
|
||||||
|
<< timeSteps.at(i) << "ZZZZZZZZZZZZZ PRICE=" << price1 << "end=" << end.toString(Qt::ISODate);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
#else
|
||||||
|
|
||||||
|
double cost = 360;
|
||||||
|
qCritical() << "XXXXXXXX START" << start.toString(Qt::ISODate) << "cost" << cost;
|
||||||
|
QDateTime end;
|
||||||
|
|
||||||
|
cs = compute_duration_for_parking_ticket(&cfg, start, cost, end,
|
||||||
|
PermitType(PERMIT_TYPE::SHORT_TERM_PARKING));
|
||||||
|
qCritical() << __LINE__ << cs.toString()
|
||||||
|
<< "START" << start.toString(Qt::ISODate)
|
||||||
|
<< "<duration" << start.secsTo(end) / 60
|
||||||
|
<< "cost" << cost
|
||||||
|
<< "> end" << end.toString(Qt::ISODate);
|
||||||
|
//}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid);
|
||||||
//Q_ASSERT(cost == duration*2.5);
|
//Q_ASSERT(cost == duration*2.5);
|
||||||
//qCritical() << "";
|
//qCritical() << "";
|
||||||
qCritical() << "start" << start.toString(Qt::ISODate)
|
//qCritical() << "start" << start.toString(Qt::ISODate)
|
||||||
<< "end" << end.toString(Qt::ISODate)
|
// << "end" << end.toString(Qt::ISODate)
|
||||||
<< "duration" << duration
|
// << "duration" << duration
|
||||||
<< "cost" << cost;
|
// << "cost" << cost;
|
||||||
|
#if 0
|
||||||
switch(duration) {
|
switch(duration) {
|
||||||
case 30:
|
case 30:
|
||||||
if (cost == 60.0) {
|
if (cost == 60.0) {
|
||||||
@@ -2942,15 +3075,17 @@ int main() {
|
|||||||
<< "cost" << cost;
|
<< "cost" << cost;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
|
//std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
|
||||||
//Q_ASSERT(cost == duration*2.5);
|
//Q_ASSERT(cost == duration*2.5);
|
||||||
//qCritical() << "start" << start.toString(Qt::ISODate)
|
//qCritical() << "start" << start.toString(Qt::ISODate)
|
||||||
// << "cost" << cost
|
// << "cost" << cost
|
||||||
// << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60;
|
// << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Configuration::SpecialDaysType specialDays = cfg.SpecialDays;
|
Configuration::SpecialDaysType specialDays = cfg.SpecialDays;
|
||||||
for (Configuration::SpecialDaysType::const_iterator it = specialDays.cbegin();
|
for (Configuration::SpecialDaysType::const_iterator it = specialDays.cbegin();
|
||||||
it != specialDays.cend(); ++it) {
|
it != specialDays.cend(); ++it) {
|
||||||
@@ -2971,7 +3106,7 @@ int main() {
|
|||||||
<< "duration" << duration
|
<< "duration" << duration
|
||||||
<< "cost" << cost;
|
<< "cost" << cost;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+4
-1
@@ -1,3 +1,5 @@
|
|||||||
|
QT += core
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = main
|
TARGET = main
|
||||||
|
|
||||||
@@ -38,7 +40,8 @@ OTHER_FILES += \
|
|||||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff04.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/tariff05.json \
|
||||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff06.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/tariff07.json \
|
||||||
|
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff08.json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user