Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed6d355517 | |||
| f1f033d1cd | |||
| 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 | |||
|
1b716c48d2
|
|||
| 77e1414c13 | |||
| d95275a72d | |||
| 577a17dc6a | |||
| d8d32820a3 | |||
| 2ce0aeef1d | |||
| 0cba85eafb | |||
| 4030a4b165 | |||
| 8c7afdfcb1 | |||
| 932d4e8cb9 | |||
| 38abc65425 | |||
| 205896903b | |||
| dbedfd094f | |||
| 57b9d16abc | |||
| 48afbc071c | |||
| 7a7b10260a | |||
| 1874b08210 | |||
| 88a0ebb688 | |||
| a8ae9fc602 | |||
| 7c0514e241 |
@@ -0,0 +1,83 @@
|
||||
#ifndef ATB_TIME_H_INCLUDED
|
||||
#define ATB_TIME_H_INCLUDED
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class ATBTime {
|
||||
static QDateTime const m_end;
|
||||
mutable QDateTime m_time;
|
||||
|
||||
public:
|
||||
explicit ATBTime();
|
||||
explicit ATBTime(int h, int m, int s = 0, int ms = 0);
|
||||
explicit ATBTime(QString const &time);
|
||||
explicit ATBTime(QTime const &time);
|
||||
|
||||
explicit ATBTime(ATBTime const &atbTime) {
|
||||
m_time = atbTime.m_time;
|
||||
}
|
||||
|
||||
ATBTime &operator=(ATBTime && atbTime) {
|
||||
m_time = std::move(atbTime.m_time);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ATBTime &operator=(ATBTime const &atbTime) {
|
||||
m_time = atbTime.m_time;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
int hour() const { return m_time.time().hour(); }
|
||||
int minute() const { return m_time.time().minute(); }
|
||||
int second() const { return m_time.time().second(); }
|
||||
int msec() const { return m_time.time().msec(); }
|
||||
|
||||
int secsTo(QString const &t) const {
|
||||
if (t == "24:00:00") {
|
||||
return m_time.secsTo(m_end);
|
||||
}
|
||||
return m_time.time().secsTo(QTime::fromString(t, Qt::ISODate));
|
||||
}
|
||||
|
||||
int msecsTo(QTime t) const { return m_time.time().msecsTo(t); }
|
||||
|
||||
bool setHMS(int h, int m, int s, int ms = 0);
|
||||
|
||||
bool isNull() const { return m_time.time().isNull(); }
|
||||
bool isValid() const { return m_time.time().isValid(); }
|
||||
|
||||
|
||||
QTime addMSecs(int ms) const;
|
||||
QTime addMSecs(int ms);
|
||||
|
||||
QTime addSecs(int s) const;
|
||||
QTime addSecs(int s);
|
||||
|
||||
int msecsSinceStartOfDay() const;
|
||||
QString toString(Qt::DateFormat format = Qt::TextDate) const;
|
||||
|
||||
|
||||
static bool isValid(int h, int m, int s, int ms = 0);
|
||||
|
||||
static QTime currentTime() { return QDateTime::currentDateTime().time(); }
|
||||
|
||||
static constexpr QTime fromMSecsSinceStartOfDay(int msecs);
|
||||
|
||||
static QTime fromString(QString const &string, Qt::DateFormat format = Qt::TextDate);
|
||||
static QTime fromString(QString const &string, const QString &format);
|
||||
|
||||
friend bool operator!=(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator<=(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator>=(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator>(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept;
|
||||
friend QDataStream &operator<<(QDataStream &out, ATBTime const &time);
|
||||
friend QDebug &operator<<(QDebug &out, ATBTime const &time);
|
||||
friend QDataStream &operator>>(QDataStream &in, ATBTime &time);
|
||||
};
|
||||
|
||||
|
||||
#endif // ATB_TIME_H_INCLUDED
|
||||
@@ -56,6 +56,7 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
static QString const ABOVE_MAX_PARKING_PRICE;
|
||||
static QString const OVERPAID;
|
||||
static QString const OUTSIDE_ALLOWED_PARKING_TIME;
|
||||
static QString const SUCCESS_MAXPRICE;
|
||||
|
||||
enum class State : uint8_t {
|
||||
SUCCESS,
|
||||
@@ -71,7 +72,8 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
BELOW_MIN_PARKING_PRICE,
|
||||
ABOVE_MAX_PARKING_PRICE,
|
||||
OVERPAID,
|
||||
OUTSIDE_ALLOWED_PARKING_TIME
|
||||
OUTSIDE_ALLOWED_PARKING_TIME,
|
||||
SUCCESS_MAXPRICE
|
||||
};
|
||||
|
||||
State m_status;
|
||||
@@ -88,9 +90,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
, m_desc(desc) {
|
||||
}
|
||||
|
||||
explicit CalcState(State state, QString desc = "",
|
||||
QTime const &from = QTime(),
|
||||
QTime const &until = QTime())
|
||||
explicit CalcState(State state, QString desc,
|
||||
QTime const &from,
|
||||
QTime const &until)
|
||||
: m_status(state)
|
||||
, m_desc(desc)
|
||||
, m_allowedTimeRange(from, until) {
|
||||
@@ -106,6 +108,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
case State::SUCCESS:
|
||||
s = CalcState::SUCCESS;
|
||||
break;
|
||||
case State::SUCCESS_MAXPRICE:
|
||||
s = CalcState::SUCCESS_MAXPRICE;
|
||||
break;
|
||||
case State::ERROR_PARSING_ZONE_NR:
|
||||
s = CalcState::ERROR_PARSING_ZONE_NR;
|
||||
break;
|
||||
@@ -158,6 +163,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
case State::SUCCESS:
|
||||
s = CalcState::SUCCESS;
|
||||
break;
|
||||
case State::SUCCESS_MAXPRICE:
|
||||
s = CalcState::SUCCESS_MAXPRICE;
|
||||
break;
|
||||
case State::ERROR_PARSING_ZONE_NR:
|
||||
s = CalcState::ERROR_PARSING_ZONE_NR;
|
||||
break;
|
||||
@@ -207,6 +215,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
||||
if (desc == SUCCESS) {
|
||||
m_status = State::SUCCESS;
|
||||
} else
|
||||
if (desc == SUCCESS_MAXPRICE) {
|
||||
m_status = State::SUCCESS_MAXPRICE;
|
||||
}
|
||||
if (desc == ERROR_PARSING_ZONE_NR) {
|
||||
m_status = State::ERROR_PARSING_ZONE_NR;
|
||||
} else
|
||||
@@ -266,6 +277,12 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
|
||||
void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff);
|
||||
int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
|
||||
|
||||
|
||||
int CALCULATE_LIBRARY_API 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 UpDown, PermitType const &permitType);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "calculate_price.h"
|
||||
@@ -26,9 +27,16 @@ class Calculator {
|
||||
QDateTime const &start,
|
||||
int netto_parking_time,
|
||||
int paymentOptionIndex);
|
||||
struct State {
|
||||
bool m_timeLimitReached;
|
||||
uint32_t m_costAtTimeLimit;
|
||||
} m_state;
|
||||
|
||||
protected:
|
||||
explicit Calculator() = default;
|
||||
explicit Calculator() {
|
||||
m_state.m_timeLimitReached = false;
|
||||
m_state.m_costAtTimeLimit = ~0;
|
||||
}
|
||||
|
||||
public:
|
||||
Calculator(Calculator const &other) = delete;
|
||||
@@ -39,6 +47,12 @@ public:
|
||||
return c;
|
||||
}
|
||||
|
||||
bool timeLimitReached() const { return m_state.m_timeLimitReached; }
|
||||
void setTimeLimitReached(bool timeLimitReached) { m_state.m_timeLimitReached = timeLimitReached; }
|
||||
bool costAtTimeLimit() const { return m_state.m_costAtTimeLimit; }
|
||||
void setCostAtTimeLimit(uint32_t cost) { if (m_state.m_costAtTimeLimit > cost) m_state.m_costAtTimeLimit = cost; }
|
||||
void resetCostAtTimeLimit() { m_state.m_costAtTimeLimit = ~0; }
|
||||
|
||||
void ResetTimeSteps(int paymentOptionIndex) {
|
||||
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
|
||||
m_timeSteps[paymentOptionIndex].clear();
|
||||
@@ -70,8 +84,9 @@ public:
|
||||
/// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z)</param>
|
||||
/// <param name="price"></param>
|
||||
/// <returns>Returns duration in seconds (data type: double)</returns>
|
||||
std::string GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price,
|
||||
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
||||
std::pair<std::string, QDateTime>
|
||||
GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price,
|
||||
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets cost from duration in seconds
|
||||
@@ -85,6 +100,9 @@ public:
|
||||
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
|
||||
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
||||
|
||||
std::pair<CalcState, QDateTime> ComputeDurationFromCost(Configuration *cfg, QDateTime const &startDatetimePassed, int cost);
|
||||
std::pair<CalcState, std::optional<int>> ComputeCostFromDuration(Configuration *cfg, QDateTime const &startDatetime, QDateTime &endDatetime, int nettoParkingTime);
|
||||
|
||||
// Daily ticket
|
||||
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);
|
||||
|
||||
@@ -29,9 +29,13 @@
|
||||
#include "tariff_prepaid.h"
|
||||
#include "tariff_carryover.h"
|
||||
#include "tariff_permit_type.h"
|
||||
#include "tariff_service.h"
|
||||
#include "tariff_out_of_service.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <optional>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
|
||||
using namespace std;
|
||||
using namespace rapidjson;
|
||||
@@ -50,6 +54,10 @@ public:
|
||||
using TariffPrepaidType = std::multimap<int, ATBPrepaid>;
|
||||
using TariffCarryOverType = std::multimap<int, ATBCarryOver>;
|
||||
using TariffDurationType = std::multimap<int, ATBDuration>;
|
||||
using TariffServiceType = std::multimap<int, ATBTariffService>;
|
||||
using TariffOutOfServiceType = std::multimap<int, ATBTariffOutOfService>;
|
||||
using ATBTariffPrepaidType = std::multimap<int, ATBTariffPrepaid>;
|
||||
using ATBTariffCarryOverType = std::multimap<int, ATBTariffCarryOver>;
|
||||
|
||||
ATBProject project;
|
||||
ATBCurrency Currency;
|
||||
@@ -73,6 +81,15 @@ public:
|
||||
TariffInterpolationType TariffInterpolations;
|
||||
TariffPrepaidType TariffPrepaidOptions;
|
||||
TariffCarryOverType TariffCarryOverOptions;
|
||||
TariffServiceType TariffServices;
|
||||
TariffOutOfServiceType TariffOutOfServices;
|
||||
ATBTariffPrepaidType TariffPrepaids;
|
||||
ATBTariffCarryOverType TariffCarryOvers;
|
||||
QList<QPair<QString, QString>> TariffIncludes;
|
||||
|
||||
QTime ValidFrom;
|
||||
int ValidForWeekDay{};
|
||||
QStringList tariffFileName{};
|
||||
|
||||
/// <summary>
|
||||
/// Parse JSON string
|
||||
@@ -113,6 +130,9 @@ public:
|
||||
std::optional<ATBWeekDaysWorktime> getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek);
|
||||
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);
|
||||
int getPaymentOptionIndex(PERMIT_TYPE permitType);
|
||||
int getPaymentOptionIndex(PERMIT_TYPE permitType) const;
|
||||
|
||||
@@ -22,7 +22,8 @@ enum MemberType
|
||||
ProductType = 0x0F,
|
||||
InterpolationType = 0x10,
|
||||
PrepaidType = 0x11,
|
||||
CarryOverType = 0x12
|
||||
CarryOverType = 0x12,
|
||||
IncludesType = 0x13
|
||||
};
|
||||
|
||||
#endif // MEMBER_TYPE_H_INCLUDED
|
||||
|
||||
@@ -6,7 +6,8 @@ enum PaymentMethod {
|
||||
Progressive = 0x01,
|
||||
Degressive = 0x02,
|
||||
Linear = 0x03,
|
||||
Steps = 0x04
|
||||
Steps = 0x04,
|
||||
Unified = 0x05
|
||||
};
|
||||
|
||||
#endif // PAYMENT_METHOD_H_INCLUDED
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
pop_max_time = 0;
|
||||
pop_min_price = 0;
|
||||
pop_max_price = 0;
|
||||
pop_max_price_save = 0;
|
||||
pop_carry_over = -1;
|
||||
pop_carry_over_option_id = -1;
|
||||
pop_prepaid_option_id = -1;
|
||||
@@ -61,6 +62,7 @@ public:
|
||||
double pop_max_time;
|
||||
double pop_min_price;
|
||||
double pop_max_price;
|
||||
double pop_max_price_save;
|
||||
int pop_carry_over;
|
||||
int pop_carry_over_option_id;
|
||||
bool pop_truncate_last_interpolation_step;
|
||||
|
||||
@@ -8,5 +8,9 @@ public:
|
||||
int pedwt_period_exc_day_id;
|
||||
std::string pedwt_time_from;
|
||||
std::string pedwt_time_to;
|
||||
double pedwt_price;
|
||||
};
|
||||
double pedwt_price;
|
||||
int pedwt_paid; // 00: not paid (i.e. free)
|
||||
// 01: not paid in winter term, piad in summer term
|
||||
// 10: paid in winter term, not paid in summer term
|
||||
// 11: paid in winter and in summer term
|
||||
};
|
||||
|
||||
@@ -3,6 +3,111 @@
|
||||
|
||||
#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 week {
|
||||
int day;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
#include <variant>
|
||||
#include <cstddef>
|
||||
#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,
|
||||
DAY_TICKET_PKW=13,
|
||||
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 {
|
||||
@@ -73,6 +78,15 @@ struct PermitType {
|
||||
case 15:
|
||||
m_permitType = PERMIT_TYPE::DAY_TICKET_CAMPER;
|
||||
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:
|
||||
m_permitType = PERMIT_TYPE::INVALID;
|
||||
}
|
||||
@@ -116,6 +130,12 @@ struct PermitType {
|
||||
return 14;
|
||||
case PERMIT_TYPE::DAY_TICKET_CAMPER:
|
||||
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:
|
||||
break;
|
||||
}
|
||||
@@ -132,9 +152,6 @@ struct PermitType {
|
||||
if (permitTypeStr == "DAY_TICKET_CHILD") {
|
||||
return PERMIT_TYPE::DAY_TICKET_CHILD;
|
||||
} else
|
||||
if (permitTypeStr == "DAY_TICKET_ADULT") {
|
||||
return PERMIT_TYPE::DAY_TICKET_ADULT;
|
||||
} else
|
||||
if (permitTypeStr == "DAY_TICKET_TEEN") {
|
||||
return PERMIT_TYPE::DAY_TICKET_TEEN;
|
||||
} else
|
||||
@@ -170,6 +187,15 @@ struct PermitType {
|
||||
} else
|
||||
if (permitTypeStr == "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;
|
||||
@@ -207,6 +233,12 @@ struct PermitType {
|
||||
return QString("DAY_TICKET_BUS");
|
||||
case PERMIT_TYPE::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:
|
||||
break;
|
||||
}
|
||||
@@ -245,6 +277,12 @@ struct PermitType {
|
||||
return QString("DAY_TICKET_BUS");
|
||||
case PERMIT_TYPE::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:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,85 @@
|
||||
#ifndef TARIFF_PREPAID_H_INCLUDED
|
||||
#define TARIFF_PREPAID_H_INCLUDED
|
||||
|
||||
#include <QTime>
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
#include "time_range.h"
|
||||
|
||||
enum class ApplyPrepaid {
|
||||
NEVER = 0,
|
||||
MATCH_PREV_DAY = 1,
|
||||
MATCH_NEXT_DAY = 2,
|
||||
ALWAYS = 3
|
||||
};
|
||||
|
||||
struct ATBTariffPrepaid {
|
||||
int m_id;
|
||||
QString m_weekDay;
|
||||
QDate m_date;
|
||||
TimeRange m_range;
|
||||
ApplyPrepaid m_prepaidIf;
|
||||
|
||||
explicit ATBTariffPrepaid()
|
||||
: m_id(-1)
|
||||
, m_prepaidIf(ApplyPrepaid::NEVER) {
|
||||
}
|
||||
|
||||
void setPrepaidIf(QString const &ppif) {
|
||||
if (ppif == "never") {
|
||||
m_prepaidIf = ApplyPrepaid::NEVER;
|
||||
} else
|
||||
if (ppif == "match_prev_day") {
|
||||
m_prepaidIf = ApplyPrepaid::MATCH_PREV_DAY;
|
||||
} else
|
||||
if (ppif == "match_next_day") {
|
||||
m_prepaidIf = ApplyPrepaid::MATCH_NEXT_DAY;
|
||||
} else
|
||||
if (ppif == "always") {
|
||||
m_prepaidIf = ApplyPrepaid::ALWAYS;
|
||||
} else {
|
||||
qCritical() << __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 {
|
||||
int id;
|
||||
bool anytime;
|
||||
|
||||
@@ -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
|
||||
#define TIME_RANGE_H_INCLUDED
|
||||
|
||||
#include "time_range_header.h"
|
||||
|
||||
struct TimeRange {
|
||||
public:
|
||||
bool IsActive;
|
||||
ATBTimeRange TimeRangeStructure;
|
||||
};
|
||||
|
||||
#endif // TIME_RANGE_H_INCLUDED
|
||||
#ifndef TIME_RANGE_H_INCLUDED
|
||||
#define TIME_RANGE_H_INCLUDED
|
||||
|
||||
#include "atb_time.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct TimeRange {
|
||||
ATBTime m_start;
|
||||
ATBTime m_end;
|
||||
int m_duration;
|
||||
|
||||
explicit TimeRange() = default;
|
||||
explicit TimeRange(QString const &start, QString const &end, int duration)
|
||||
: m_start(start)
|
||||
, m_end(end)
|
||||
, m_duration(duration) {
|
||||
}
|
||||
explicit TimeRange(ATBTime const &start, ATBTime const &end, int duration)
|
||||
: m_start(start)
|
||||
, m_end(end)
|
||||
, m_duration(duration) {
|
||||
}
|
||||
|
||||
explicit TimeRange(TimeRange const &timeRange) {
|
||||
m_start = timeRange.m_start;
|
||||
m_end = timeRange.m_end;
|
||||
m_duration = timeRange.m_duration;
|
||||
}
|
||||
|
||||
TimeRange &operator=(TimeRange && timeRange) {
|
||||
m_start = std::move(timeRange.m_start);
|
||||
m_end = std::move(timeRange.m_end);
|
||||
m_duration = timeRange.m_duration;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TimeRange &operator=(TimeRange const &timeRange) {
|
||||
m_start = timeRange.m_start;
|
||||
m_end = timeRange.m_end;
|
||||
m_duration = timeRange.m_duration;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TIME_RANGE_H_INCLUDED
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -35,7 +35,8 @@ SOURCES += \
|
||||
src/tariff_log.cpp \
|
||||
src/calculate_price.cpp \
|
||||
src/ticket.cpp \
|
||||
src/tariff_global_defines.cpp
|
||||
src/tariff_global_defines.cpp \
|
||||
src/atb_time.cpp
|
||||
|
||||
HEADERS += \
|
||||
include/mobilisis/calculator_functions.h \
|
||||
@@ -89,7 +90,10 @@ HEADERS += \
|
||||
include/mobilisis/tariff_interpolation.h \
|
||||
include/mobilisis/tariff_prepaid.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/tariff_service.h \
|
||||
include/mobilisis/tariff_out_of_service.h
|
||||
|
||||
OTHER_FILES += src/main.cpp \
|
||||
../tariffs/tariff_korneuburg.json \
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
#include "atb_time.h"
|
||||
#include <QDebugStateSaver>
|
||||
|
||||
QDateTime const ATBTime::m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate));
|
||||
|
||||
ATBTime::ATBTime()
|
||||
: m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
||||
}
|
||||
|
||||
ATBTime::ATBTime(int h, int m, int /*s*/, int /*ms*/)
|
||||
: m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
|
||||
|
||||
if (h == 24 && m == 0) {
|
||||
m_time = m_end;
|
||||
} else {
|
||||
QTime const t(h, m, 0, 0);
|
||||
m_time.setTime(t);
|
||||
}
|
||||
}
|
||||
|
||||
ATBTime::ATBTime(QString const &t)
|
||||
: m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
|
||||
|
||||
if (t == "24:00:00") {
|
||||
m_time = m_end;
|
||||
} else {
|
||||
QTime tmp = QTime::fromString(t, Qt::ISODate);
|
||||
if (tmp.isValid()) {
|
||||
m_time.setTime(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ATBTime::ATBTime(QTime const &t)
|
||||
: m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
|
||||
m_time.setTime(t);
|
||||
}
|
||||
|
||||
QTime ATBTime::addMSecs(int ms) const {
|
||||
return m_time.time().addMSecs(ms);
|
||||
}
|
||||
|
||||
QTime ATBTime::addMSecs(int ms) {
|
||||
QTime t = m_time.time();
|
||||
t = t.addMSecs(ms);
|
||||
m_time.setTime(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
QTime ATBTime::addSecs(int s) const {
|
||||
return m_time.time().addSecs(s);
|
||||
}
|
||||
|
||||
QTime ATBTime::addSecs(int s) {
|
||||
QTime t = m_time.time();
|
||||
t = t.addSecs(s);
|
||||
m_time.setTime(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
constexpr QTime ATBTime::fromMSecsSinceStartOfDay(int msecs) {
|
||||
return QTime::fromMSecsSinceStartOfDay(msecs);
|
||||
}
|
||||
|
||||
QTime ATBTime::fromString(QString const &string, Qt::DateFormat format) {
|
||||
return QTime::fromString(string, format);
|
||||
}
|
||||
|
||||
QTime ATBTime::fromString(QString const &string, QString const &format) {
|
||||
return QTime::fromString(string, format);
|
||||
}
|
||||
|
||||
bool ATBTime::isValid(int h, int m, int s, int ms) {
|
||||
return QTime(h, m, s, ms).isValid();
|
||||
}
|
||||
|
||||
int ATBTime::msecsSinceStartOfDay() const {
|
||||
return m_time.time().msecsSinceStartOfDay();
|
||||
}
|
||||
|
||||
bool ATBTime::setHMS(int h, int m, int s, int ms) {
|
||||
if (isValid(h, m, s, ms)) {
|
||||
QTime t(h, m, s, ms);
|
||||
m_time.setTime(t);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ATBTime::toString(Qt::DateFormat format) const {
|
||||
if (m_time == m_end) {
|
||||
return "24:00:00";
|
||||
}
|
||||
return m_time.time().toString(format);
|
||||
}
|
||||
|
||||
bool operator!=(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
return lhs.m_time.time() != rhs.m_time.time();
|
||||
}
|
||||
|
||||
bool operator<=(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
if (rhs.m_time == rhs.m_end) {
|
||||
return true;
|
||||
}
|
||||
return lhs.m_time.time() <= rhs.m_time.time();
|
||||
}
|
||||
|
||||
bool operator>=(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
return lhs.m_time.time() >= rhs.m_time.time();
|
||||
}
|
||||
|
||||
bool operator<(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
if (rhs.m_time == rhs.m_end) {
|
||||
return true;
|
||||
}
|
||||
return lhs.m_time.time() < rhs.m_time.time();
|
||||
}
|
||||
|
||||
bool operator>(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
return lhs.m_time.time() > rhs.m_time.time();
|
||||
}
|
||||
|
||||
bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept {
|
||||
return lhs.m_time.time() == rhs.m_time.time();
|
||||
}
|
||||
|
||||
QDebug &operator<<(QDebug &debug, ATBTime const &time) {
|
||||
QDebugStateSaver saver(debug);
|
||||
if (time.m_time == time.m_end) {
|
||||
debug.nospace() << QString("24:00:00");
|
||||
} else {
|
||||
debug.nospace() << time.m_time.time().toString(Qt::ISODate);
|
||||
}
|
||||
return debug;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, ATBTime const &time) {
|
||||
if (time.m_time == time.m_end) {
|
||||
out << QString("24:00:00");
|
||||
} else {
|
||||
out << time.m_time.time();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, ATBTime &time) {
|
||||
QTime t;
|
||||
in >> t;
|
||||
time.m_time.setTime(t);
|
||||
return in;
|
||||
}
|
||||
+1018
-105
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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+438
-15
@@ -10,10 +10,15 @@
|
||||
#include "tariff_global_defines.h"
|
||||
#include "tariff_settings.h"
|
||||
#include "tariff_carryover_settings.h"
|
||||
#include "atb_time.h"
|
||||
#include "tariff_prepaid.h"
|
||||
#include "tariff_carryover.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QPair>
|
||||
#include <QList>
|
||||
|
||||
/// <inheritdoc/>
|
||||
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, "Prepaid") == 0) return MemberType::PrepaidType;
|
||||
if (strcmp(member_name, "CarryOver") == 0) return MemberType::CarryOverType;
|
||||
if (strcmp(member_name, "Includes") == 0) return MemberType::IncludesType;
|
||||
else return MemberType::UnknownType;
|
||||
}
|
||||
|
||||
@@ -61,6 +67,414 @@ ATBWeekDay parseWeekDay(Configuration &cfg,
|
||||
ATBWeekDay WeekDay;
|
||||
QTime start, end, parking_time_limit, about_to_exceed_limit;
|
||||
ATBTariffCarryOverSettings::ParkingTimeLimitChecker parkTimeLimitChecker;
|
||||
QDate const &d = QDate::fromString(innerObjName, Qt::ISODate);
|
||||
if (innerObjName == QString("default") ||
|
||||
(!d.isNull() && d.isValid())) { // special day, given in date-format
|
||||
// start with new implementation of tariff-calculator
|
||||
// see for instance: bad neuenahr (249), Zone5
|
||||
|
||||
qCritical() << __func__ << ":" << __LINE__ << innerObjName;
|
||||
|
||||
if (k->value.IsObject()) {
|
||||
auto obj = k->value.GetObject();
|
||||
for (auto m = obj.MemberBegin(); m != obj.MemberEnd(); ++m) {
|
||||
QString const &name = m->name.GetString();
|
||||
if (name == "payment_settings") {
|
||||
if (m->value.IsArray()) {
|
||||
auto payment = m->value.GetArray();
|
||||
if (payment.Size() == 0) {
|
||||
qCritical() << __func__ << ":" << __LINE__ << "no payment settings for" << weekDayName;
|
||||
} else {
|
||||
for (rapidjson::SizeType j = 0; j < payment.Size(); ++j) {
|
||||
if (payment[j].IsObject()) {
|
||||
auto paymentSetting = payment[j].GetObject();
|
||||
for (auto n = paymentSetting.MemberBegin(); n != paymentSetting.MemberEnd(); ++n) {
|
||||
QString const &name = QString::fromStdString(n->name.GetString());
|
||||
if (name == "min_time") {
|
||||
if (n->value.IsInt()) { min_time = n->value.GetInt(); }
|
||||
} else if (name == "max_time") {
|
||||
if (n->value.IsInt()) { max_time = n->value.GetInt(); }
|
||||
} else if (name == "min_price") {
|
||||
if (n->value.IsInt()) { min_price = n->value.GetInt(); }
|
||||
} else if (name == "max_price") {
|
||||
if (n->value.IsInt()) { max_price = n->value.GetInt(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
if (name == "prepaid_settings") {
|
||||
if (m->value.IsArray()) {
|
||||
auto prepaid = m->value.GetArray();
|
||||
if (prepaid.Size() == 0) {
|
||||
qCritical() << __func__ << ":" << __LINE__ << "no prepaid-settings for" << weekDayName;
|
||||
} else {
|
||||
ATBTariffPrepaid TariffPrepaid;
|
||||
for (rapidjson::SizeType j = 0; j < prepaid.Size(); ++j) {
|
||||
if (prepaid[j].IsObject()) {
|
||||
auto prepaidSetting = prepaid[j].GetObject();
|
||||
for (auto n = prepaidSetting.MemberBegin(); n != prepaidSetting.MemberEnd(); ++n) {
|
||||
QString const &name = QString::fromStdString(n->name.GetString());
|
||||
if (name == "prepaid_ranges") {
|
||||
if (n->value.IsArray()) {
|
||||
auto prepaidRanges = n->value.GetArray();
|
||||
if (prepaidRanges.Size() == 0) {
|
||||
qCritical() << __func__ << ":" << __LINE__ << "no prepaid-ranges for" << weekDayName;
|
||||
} else {
|
||||
QString prepaidStartStr;
|
||||
QString prepaidEndStr;
|
||||
QString prepaidIf;
|
||||
int prepaidDuration = -1;
|
||||
for (rapidjson::SizeType i = 0; i < prepaidRanges.Size(); ++i) {
|
||||
if (prepaidRanges[j].IsObject()) {
|
||||
auto prepaidRange = prepaidRanges[i].GetObject();
|
||||
for (auto r = prepaidRange.MemberBegin(); r != prepaidRange.MemberEnd(); ++r) {
|
||||
QString const &memName = QString::fromStdString(r->name.GetString());
|
||||
if (memName == "prepaid_id") {
|
||||
if (r->value.IsInt()) {
|
||||
TariffPrepaid.m_id = r->value.GetInt();
|
||||
} else {
|
||||
qCritical() << __func__ << ":" << __LINE__ << "prepaidId not an integer";
|
||||
}
|
||||
} else
|
||||
if (memName == "prepaid_duration") {
|
||||
if (r->value.IsInt()) {
|
||||
prepaidDuration = r->value.GetInt();
|
||||
}
|
||||
} else
|
||||
if (memName == "prepaid_start") {
|
||||
if (r->value.IsString()) {
|
||||
prepaidStartStr = QString::fromStdString(r->value.GetString());
|
||||
}
|
||||
} else
|
||||
if (memName == "prepaid_end") {
|
||||
if (r->value.IsString()) {
|
||||
prepaidEndStr = QString::fromStdString(r->value.GetString());
|
||||
}
|
||||
} else
|
||||
if (memName == "prepaid_if") {
|
||||
if (r->value.IsString()) {
|
||||
prepaidIf = QString::fromStdString(r->value.GetString());
|
||||
}
|
||||
} else {
|
||||
qCritical() << __func__ << ":" << __LINE__ << "WARNING unknown prepaid setting" << memName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!prepaidStartStr.isEmpty() && !prepaidEndStr.isEmpty() && prepaidDuration != -1) {
|
||||
ATBTime prepaidStart(prepaidStartStr);
|
||||
ATBTime prepaidEnd(prepaidEndStr);
|
||||
if (prepaidStart.isValid() && prepaidEnd.isValid()) {
|
||||
TariffPrepaid.m_range = TimeRange(prepaidStart, prepaidEnd, prepaidDuration);
|
||||
TariffPrepaid.m_weekDay = weekDayName;
|
||||
if (!d.isNull() && d.isValid()) {
|
||||
TariffPrepaid.m_date = d;
|
||||
}
|
||||
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 (k->value.IsObject()) {
|
||||
auto obj = k->value.GetObject();
|
||||
@@ -408,6 +822,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
||||
ATBInterpolation TariffInterpolation;
|
||||
ATBPrepaid TariffPrepaidOption;
|
||||
ATBCarryOver TariffCarryOver;
|
||||
QList<QPair<QString, QString>> TariffIncludes;
|
||||
|
||||
MemberType mb_type = MemberType::UnknownType;
|
||||
this->currentPaymentOptions.clear();
|
||||
@@ -473,32 +888,32 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
||||
break;
|
||||
case MemberType::WeekDaysType: {
|
||||
ATBWeekDay WeekDay;
|
||||
if (QString(mb_name) == "Monday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Monday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Monday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Monday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Tuesday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Tuesday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Tuesday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Tuesday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Wednesday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Wednesday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Wednesday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Wednesday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Thursday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Thursday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Thursday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Thursday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Friday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Friday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Friday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Friday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Saturday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Saturday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Saturday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Saturday, QString(mb_name).trimmed());
|
||||
} else
|
||||
if (QString(mb_name) == "Sunday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Sunday, mb_name);
|
||||
if (QString(mb_name).trimmed() == "Sunday") {
|
||||
WeekDay = parseWeekDay(*cfg, k, inner_obj_name, Qt::Sunday, QString(mb_name).trimmed());
|
||||
} else {
|
||||
qCritical() << "ERROR: unknown week day" << mb_name;
|
||||
}
|
||||
|
||||
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;
|
||||
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_active") == 0) Currency.pcu_active = k->value.GetBool();
|
||||
break;
|
||||
case MemberType::IncludesType:
|
||||
TariffIncludes << QPair<QString, QString>(QString(inner_obj_name), k->value.GetString());
|
||||
break;
|
||||
case MemberType::PaymentMethodType:
|
||||
if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt();
|
||||
else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString();
|
||||
@@ -1000,6 +1418,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
||||
this->currentPaymentOptions.last().pop_min_time = k->value.GetDouble();
|
||||
} else if (strcmp(inner_obj_name, "pop_max_price") == 0) {
|
||||
this->currentPaymentOptions.last().pop_max_price = k->value.GetDouble();
|
||||
this->currentPaymentOptions.last().pop_max_price_save = k->value.GetDouble();
|
||||
} else if (strcmp(inner_obj_name, "pop_max_time") == 0) {
|
||||
this->currentPaymentOptions.last().pop_max_time = k->value.GetDouble();
|
||||
} else if (strcmp(inner_obj_name, "pop_min_price") == 0) {
|
||||
@@ -1110,6 +1529,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
||||
else if (strcmp(inner_obj_name, "pedwt_time_from") == 0) SpecialDaysWorktime.pedwt_time_from = k->value.GetString();
|
||||
else if (strcmp(inner_obj_name, "pedwt_time_to") == 0) SpecialDaysWorktime.pedwt_time_to = k->value.GetString();
|
||||
else if (strcmp(inner_obj_name, "pedwt_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble();
|
||||
else if (strcmp(inner_obj_name, "pedwt_paid") == 0) SpecialDaysWorktime.pedwt_paid = k->value.GetInt();
|
||||
break;
|
||||
/*case MemberType::WeekDaysType:
|
||||
if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt();
|
||||
@@ -1226,6 +1646,9 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
||||
cfg->TariffCarryOverOptions.insert(pair<int, ATBCarryOver>(TariffCarryOver.id, TariffCarryOver));
|
||||
// qCritical() << TariffCarryOver;
|
||||
break;
|
||||
case MemberType::IncludesType:
|
||||
cfg->TariffIncludes = TariffIncludes;
|
||||
// qCritical() << "TariffIncludes" << cfg->TariffIncludes;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -427,6 +427,8 @@ PaymentMethod Utilities::getPaymentMethodId(Configuration const *cfg) {
|
||||
return PaymentMethod::Degressive;
|
||||
case 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 SCHOENAU_KOENIGSEE (0)
|
||||
#define NEUHAUSER_KORNEUBURG (0)
|
||||
#define NEUHAUSER_KORNEUBURG (1)
|
||||
#define NEUHAUSER_LINSINGER_MASCHINENBAU (0)
|
||||
#define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0)
|
||||
#define NEUHAUSER_BILEXA_GALTUER (0)
|
||||
#define BAD_NEUENAHR_AHRWEILER (1)
|
||||
#define BAD_NEUENAHR_AHRWEILER (0)
|
||||
#define NEUHAUSER_CHRISTOPH_REISEN (0)
|
||||
#define NEUHAUSER_PERNEGG_AN_DER_MUR (0)
|
||||
#define NEUHAUSER_STOCKERAU (0)
|
||||
@@ -52,6 +52,7 @@ extern "C" char* strptime(const char* s,
|
||||
#define SCHNALS_LEITER_KIRCHL (0)
|
||||
#define SCHNALS_STAUMAUER (SCHNALS_LEITER_KIRCHL)
|
||||
#define VALSER_ALM (0)
|
||||
#define NEUHAUSER_FORCHACH (0)
|
||||
|
||||
#if NEUHAUSER_KIRCHDORF==1
|
||||
static bool test_neuhauser_kirchdorf(int step, double cost) {
|
||||
@@ -210,21 +211,73 @@ static bool test_neuhauser_kirchdorf(int step, double cost) {
|
||||
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() {
|
||||
|
||||
|
||||
qCritical() << getCalculatorLibVersion();
|
||||
isProductSupportedInCalculatorLib("FREE_TICKET");
|
||||
return 0;
|
||||
//487 {
|
||||
// 488 "pra_payment_option_id": 1049,
|
||||
// 489 "pra_payment_unit_id": 84,
|
||||
// 490 "pra_price":"840"
|
||||
//>>491 }
|
||||
|
||||
//for (int i = 1; i < 85; ++i) {
|
||||
//printf("{\n \"\pra_payment_option_id\": 1049,\n \"\pra_payment_unit_id\": %d,\n \"pra_price\": %d\n},\n",
|
||||
// i, i*10);
|
||||
//for (int i = 1; i < 346; ++i) {
|
||||
//printf("{\n \"pun_id\": %i,\n \"pun_duration\": %d\n},\n",
|
||||
// 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
|
||||
MessageHelper msgHelp;
|
||||
// msgHelp.createLoginMessageChunksToSend(0x02);
|
||||
@@ -755,7 +808,7 @@ int main() {
|
||||
int pop_max_price;
|
||||
int pop_daily_card_price;
|
||||
|
||||
int zone = 3;
|
||||
int zone = 1;
|
||||
|
||||
if (zone == 1) {
|
||||
input.open("/opt/ptu5/opt/customer_502/etc/psa_tariff/tariff01.json");
|
||||
@@ -844,7 +897,7 @@ int main() {
|
||||
CalcState calcState;
|
||||
QDateTime s(QDateTime::currentDateTime());
|
||||
|
||||
s.setTime(QTime(12, 0, 0));
|
||||
// s.setTime(QTime(12, 0, 0));
|
||||
|
||||
//calcState = compute_duration_for_parking_ticket(&cfg, s,
|
||||
// (double)1200, end, PermitType(PERMIT_TYPE::SHORT_TERM_PARKING_PKW));
|
||||
@@ -852,9 +905,26 @@ int main() {
|
||||
//qCritical() << calcState.toString();
|
||||
|
||||
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() << 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) {
|
||||
@@ -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
|
||||
#if BAD_NEUENAHR_AHRWEILER==1
|
||||
std::ifstream input;
|
||||
@@ -1391,7 +1484,8 @@ int main() {
|
||||
case 2: {
|
||||
qCritical() << " ZONE 2: KURZZEIT 1";
|
||||
// kuzzeit-1-tarif
|
||||
input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json");
|
||||
//input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json");
|
||||
input.open("/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json");
|
||||
//pop_max_time = 5*60;
|
||||
} break;
|
||||
case 3: {
|
||||
@@ -1583,7 +1677,8 @@ int main() {
|
||||
break;
|
||||
case 1:
|
||||
//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;
|
||||
break;
|
||||
case 2:
|
||||
@@ -1615,8 +1710,8 @@ int main() {
|
||||
// << "START" << start.toString(Qt::ISODate)
|
||||
// << "<duration" << *step;
|
||||
|
||||
// if (*step != 180)
|
||||
// continue;
|
||||
if (*step != 180)
|
||||
continue;
|
||||
|
||||
|
||||
double cost = 0;
|
||||
@@ -2761,24 +2856,62 @@ int main() {
|
||||
bool nextDay = false;
|
||||
bool prePaid = true;
|
||||
// zone 1 (lila)
|
||||
QDateTime s(QDate(2023, 11, 30), QTime());
|
||||
QDateTime s(QDate(2024, 10, 8), QTime());
|
||||
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 offset = 420; offset < 1140; ++offset) {
|
||||
if (offset > 720 && offset < 840) {
|
||||
continue;
|
||||
}
|
||||
int offset = 600;
|
||||
//for (int offset = 720; offset < 601; ++offset) {
|
||||
//if (offset > 720 && offset < 840) {
|
||||
// continue;
|
||||
//}
|
||||
QDateTime start = s.addSecs(offset * 60);
|
||||
//qCritical() << "start" << start.toString(Qt::ISODate);
|
||||
|
||||
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);
|
||||
//qCritical() << "";
|
||||
qCritical() << "start" << start.toString(Qt::ISODate)
|
||||
<< "end" << end.toString(Qt::ISODate)
|
||||
<< "duration" << duration
|
||||
<< "cost" << cost;
|
||||
|
||||
//qCritical() << "start" << start.toString(Qt::ISODate)
|
||||
// << "end" << end.toString(Qt::ISODate)
|
||||
// << "duration" << duration
|
||||
// << "cost" << cost;
|
||||
#if 0
|
||||
switch(duration) {
|
||||
case 30:
|
||||
if (cost == 60.0) {
|
||||
@@ -2942,15 +3075,17 @@ int main() {
|
||||
<< "cost" << cost;
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
|
||||
//Q_ASSERT(cost == duration*2.5);
|
||||
//qCritical() << "start" << start.toString(Qt::ISODate)
|
||||
// << "cost" << cost
|
||||
// << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
#if 0
|
||||
Configuration::SpecialDaysType specialDays = cfg.SpecialDays;
|
||||
for (Configuration::SpecialDaysType::const_iterator it = specialDays.cbegin();
|
||||
it != specialDays.cend(); ++it) {
|
||||
@@ -2971,7 +3106,7 @@ int main() {
|
||||
<< "duration" << duration
|
||||
<< "cost" << cost;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
+8
-1
@@ -1,3 +1,5 @@
|
||||
QT += core
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = main
|
||||
|
||||
@@ -34,7 +36,12 @@ OTHER_FILES += \
|
||||
/opt/ptu5/opt/customer_335/etc/psa_tariff/tariff02.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff01.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff03.json
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff03.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff04.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff05.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff06.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff07.json \
|
||||
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff08.json
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user