Compare commits

...

11 Commits

Author SHA1 Message Date
932d4e8cb9 check it ticket-end-time hits carry-over-start. if configured, move to end of carry-over. 2024-09-16 16:56:48 +02:00
38abc65425 compute_price_for_parking_ticket():
Check if minutesUntilCarryOver is positive (usually must be).
2024-09-16 16:54:25 +02:00
205896903b Handle SUCCESS_MAXPRICE (calc-state). 2024-09-16 16:53:44 +02:00
dbedfd094f Add some OTHER files 2024-09-16 16:52:00 +02:00
57b9d16abc GetDurationFromCost():
Handle carry-over for direct coin insertion.
	Carefully check if this might be a problem for other projects.
2024-09-16 16:50:16 +02:00
48afbc071c Added new calc-state: SUCCESS_MAXPRICE.
Return whenever cost (=price) equals max-price.
2024-09-16 16:49:00 +02:00
7a7b10260a Add untracked(!) files 2024-09-16 16:47:01 +02:00
1874b08210 Merge branch 'kleipeda-experimental-snapshot-2024-09-12' into kleipeda-experimental 2024-09-16 10:49:23 +02:00
88a0ebb688 Add atb-time. 2024-09-16 10:42:56 +02:00
a8ae9fc602 Add own Time class (similar QTime) 2024-09-16 10:42:08 +02:00
7c0514e241 save current state 2024-09-13 10:42:45 +02:00
11 changed files with 901 additions and 72 deletions

View File

@ -0,0 +1,354 @@
#ifndef CALCULATE_PRICE_H
#define CALCULATE_PRICE_H
#include <time.h>
#include <inttypes.h>
#include "tariff_time_range.h"
#include <QString>
#include <QDateTime>
#ifdef WIN32
#ifdef CALCULATE_LIBRARY_EXPORTS
#define CALCULATE_LIBRARY_API __declspec(dllexport)
#else
#define CALCULATE_LIBRARY_API __declspec(dllimport)
#endif
#else
#define CALCULATE_LIBRARY_API
#endif
#include "tariff_permit_type.h"
class Configuration;
typedef Configuration parking_tariff_t;
//#ifdef __cplusplus
//extern "C" {
//#endif
struct CALCULATE_LIBRARY_API price_t {
uint32_t units;
double netto;
double brutto;
double vat_percentage;
double vat;
explicit price_t() {
units = 0;
netto = brutto = vat_percentage = vat = 0.0;
}
};
struct CALCULATE_LIBRARY_API CalcState {
static QString const SUCCESS;
static QString const ERROR_PARSING_ZONE_NR;
static QString const ERROR_LOADING_TARIFF;
static QString const ERROR_PARSING_TARIFF;
static QString const NEGATIVE_PARKING_TIME;
static QString const INVALID_START_DATE;
static QString const WRONG_PARAM_VALUES;
static QString const WRONG_ISO_TIME_FORMAT;
static QString const ABOVE_MAX_PARKING_TIME;
static QString const BELOW_MIN_PARKING_TIME;
static QString const BELOW_MIN_PARKING_PRICE;
static QString const ABOVE_MAX_PARKING_PRICE;
static QString const OVERPAID;
static QString const OUTSIDE_ALLOWED_PARKING_TIME;
static QString const SUCCESS_MAXPRICE;
enum class State : uint8_t {
SUCCESS,
ERROR_PARSING_ZONE_NR,
ERROR_LOADING_TARIFF,
ERROR_PARSING_TARIFF,
NEGATIVE_PARKING_TIME,
INVALID_START_DATE,
WRONG_PARAM_VALUES,
WRONG_ISO_TIME_FORMAT,
ABOVE_MAX_PARKING_TIME,
BELOW_MIN_PARKING_TIME,
BELOW_MIN_PARKING_PRICE,
ABOVE_MAX_PARKING_PRICE,
OVERPAID,
OUTSIDE_ALLOWED_PARKING_TIME,
SUCCESS_MAXPRICE
};
State m_status;
QString m_desc;
TariffTimeRange m_allowedTimeRange;
explicit CalcState()
: m_status(State::SUCCESS)
, m_desc("") {
}
explicit CalcState(State state, QString desc = "")
: m_status(state)
, m_desc(desc) {
}
explicit CalcState(State state, QString desc = "",
QTime const &from = QTime(),
QTime const &until = QTime())
: m_status(state)
, m_desc(desc)
, m_allowedTimeRange(from, until) {
}
explicit operator bool() const noexcept {
return (m_status == State::SUCCESS);
}
QString toString() {
QString s;
switch (m_status) {
case State::SUCCESS:
s = CalcState::SUCCESS;
break;
case State::SUCCESS_MAXPRICE:
s = CalcState::SUCCESS_MAXPRICE;
break;
case State::ERROR_PARSING_ZONE_NR:
s = CalcState::ERROR_PARSING_ZONE_NR;
break;
case State::ERROR_LOADING_TARIFF:
s = CalcState::ERROR_LOADING_TARIFF;
break;
case State::ERROR_PARSING_TARIFF:
s = CalcState::ERROR_PARSING_TARIFF;
break;
case State::NEGATIVE_PARKING_TIME:
s = CalcState::NEGATIVE_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_TIME:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
case State::WRONG_PARAM_VALUES:
s = CalcState::WRONG_PARAM_VALUES;
break;
case State::BELOW_MIN_PARKING_TIME:
s = CalcState::BELOW_MIN_PARKING_TIME;
break;
case State::BELOW_MIN_PARKING_PRICE:
s = CalcState::BELOW_MIN_PARKING_PRICE;
break;
case State::OVERPAID:
s = CalcState::OVERPAID;
break;
case State::INVALID_START_DATE:
s = CalcState::INVALID_START_DATE;
break;
case State::WRONG_ISO_TIME_FORMAT:
s = CalcState::WRONG_ISO_TIME_FORMAT;
break;
case State::OUTSIDE_ALLOWED_PARKING_TIME:
s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_PRICE:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
}
if (m_desc.size() > 0) {
return s + ":" + m_desc;
}
return s;
}
explicit operator QString () const noexcept {
QString s;
switch (m_status) {
case State::SUCCESS:
s = CalcState::SUCCESS;
break;
case State::SUCCESS_MAXPRICE:
s = CalcState::SUCCESS_MAXPRICE;
break;
case State::ERROR_PARSING_ZONE_NR:
s = CalcState::ERROR_PARSING_ZONE_NR;
break;
case State::ERROR_LOADING_TARIFF:
s = CalcState::ERROR_LOADING_TARIFF;
break;
case State::ERROR_PARSING_TARIFF:
s = CalcState::ERROR_PARSING_TARIFF;
break;
case State::NEGATIVE_PARKING_TIME:
s = CalcState::NEGATIVE_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_TIME:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
case State::WRONG_PARAM_VALUES:
s = CalcState::WRONG_PARAM_VALUES;
break;
case State::BELOW_MIN_PARKING_TIME:
s = CalcState::BELOW_MIN_PARKING_TIME;
break;
case State::BELOW_MIN_PARKING_PRICE:
s = CalcState::BELOW_MIN_PARKING_PRICE;
break;
case State::OVERPAID:
s = CalcState::OVERPAID;
break;
case State::INVALID_START_DATE:
s = CalcState::INVALID_START_DATE;
break;
case State::WRONG_ISO_TIME_FORMAT:
s = CalcState::WRONG_ISO_TIME_FORMAT;
break;
case State::OUTSIDE_ALLOWED_PARKING_TIME:
s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_PRICE:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
}
return s + ":" + m_desc;
}
CalcState &set(State s) { m_status = s; return *this; }
CalcState &setStatus(State s) { return set(s); }
CalcState &setStatus(QString const &desc) {
if (desc == SUCCESS) {
m_status = State::SUCCESS;
} else
if (desc == SUCCESS_MAXPRICE) {
m_status = State::SUCCESS_MAXPRICE;
}
if (desc == ERROR_PARSING_ZONE_NR) {
m_status = State::ERROR_PARSING_ZONE_NR;
} else
if (desc == ERROR_LOADING_TARIFF) {
m_status = State::SUCCESS;
} else
if (desc == ERROR_PARSING_TARIFF) {
m_status = State::ERROR_LOADING_TARIFF;
} else
if (desc == NEGATIVE_PARKING_TIME) {
m_status = State::NEGATIVE_PARKING_TIME;
} else
if (desc == INVALID_START_DATE) {
m_status = State::INVALID_START_DATE;
} else
if (desc == WRONG_PARAM_VALUES) {
m_status = State::WRONG_PARAM_VALUES;
} else
if (desc == WRONG_ISO_TIME_FORMAT) {
m_status = State::WRONG_ISO_TIME_FORMAT;
} else
if (desc == ABOVE_MAX_PARKING_TIME) {
m_status = State::ABOVE_MAX_PARKING_TIME;
} else
if (desc == BELOW_MIN_PARKING_TIME) {
m_status = State::BELOW_MIN_PARKING_TIME;
} else
if (desc == BELOW_MIN_PARKING_PRICE) {
m_status = State::BELOW_MIN_PARKING_PRICE;
} else
if (desc == OVERPAID) {
m_status = State::OVERPAID;
} else
if (desc == OUTSIDE_ALLOWED_PARKING_TIME) {
m_status = State::OUTSIDE_ALLOWED_PARKING_TIME;
} else
if (desc == ABOVE_MAX_PARKING_PRICE) {
m_status = State::ABOVE_MAX_PARKING_PRICE;
}
return *this;
}
State getStatus() const { return m_status; }
CalcState &setDesc(QString const &s) { m_desc = s; return *this; }
void setAllowedTimeRange(QTime const &from, QTime const &until) {
m_allowedTimeRange.setTimeRange(from, until);
}
TariffTimeRange getAllowedTimeRange() {
return m_allowedTimeRange;
}
};
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
char const *config_file);
void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff);
int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes,
int UpDown, PermitType const &permitType);
QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg);
int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg,
PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING,
int paymentOptionIndex=0);
int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg,
PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING,
int paymentOptionIndex=0);
int CALCULATE_LIBRARY_API get_minimal_parkingprice(Configuration *cfg,
PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING,
int paymentOptionIndex = 0,
QDateTime const &start = QDateTime::currentDateTime());
int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg,
PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING,
int paymentOptionIndex=0);
int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg,
PERMIT_TYPE permitType = PERMIT_TYPE::SHORT_TERM_PARKING,
QDateTime const &start = QDateTime::currentDateTime(),
QDateTime *productStart = nullptr,
QDateTime *productEnd = nullptr);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated
parking_tariff_t *tariff,
time_t start_parking_time,
time_t end_parking_time,
struct price_t *price,
PermitType permitType);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime &start_parking_time,
int netto_parking_time,
QDateTime &end_parking_time, // return value
struct price_t *price, // return value
PermitType permitType,
bool prepaid = true);
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( // deprecated
parking_tariff_t *tariff,
time_t start_parking_time,
double cost,
QString &duration,
PermitType permitType);
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
double cost,
QDateTime &ticketEndTime,
PermitType permitType); // return value
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime &ticketEndTime,
PermitType permitType);
CalcState CALCULATE_LIBRARY_API compute_price_for_daily_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime &ticketEndTime,
PERMIT_TYPE permitType,
struct price_t *price);
//#ifdef __cplusplus
//} // extern "C"
//#endif
#endif // CALCULATE_PRICE_H

View File

@ -0,0 +1,155 @@
#ifndef CALCULATOR_FUNCTIONS_H_INCLUDED
#define CALCULATOR_FUNCTIONS_H_INCLUDED
#include <iostream>
#include <optional>
#include <utility>
#include "configuration.h"
#include "calculate_price.h"
#include "payment_method.h"
#include "ticket.h"
#include "tariff_time_range.h"
#include <QDateTime>
using namespace std;
class Calculator {
mutable QVector<QList<int>> m_timeSteps;
mutable QList<int> m_priceSteps;
CalcState isParkingAllowedForWeekDay(Configuration const *cfg,
QDateTime const &start,
int netto_parking_time,
int paymentOptionIndex);
CalcState isParkingAllowedForSpecialDay(Configuration const *cfg,
QDateTime const &start,
int netto_parking_time,
int paymentOptionIndex);
protected:
explicit Calculator() = default;
public:
Calculator(Calculator const &other) = delete;
void operator=(Calculator const &) = delete;
static Calculator &GetInstance() {
static Calculator c;
return c;
}
void ResetTimeSteps(int paymentOptionIndex) {
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
m_timeSteps[paymentOptionIndex].clear();
}
}
QList<int> timeSteps(int paymentOptionIndex=0) const {
if (m_timeSteps.size() > 0 && paymentOptionIndex < m_timeSteps.size()) {
return m_timeSteps[paymentOptionIndex];
}
return QList<int>();
}
void ResetPriceSteps() { m_priceSteps.clear(); }
QList<int> priceSteps() const { return m_priceSteps; }
CalcState isParkingAllowed(Configuration const *cfg,
QDateTime const &start);
CalcState isParkingAllowed(Configuration const *cfg,
QDateTime const &start,
int netto_parking_time,
int paymentOptionIndex);
/// <summary>
/// Gets duration in seconds from cost
/// </summary>
/// <param name="tariff_cfg">Pointer to configuration</param>
/// <param name="vehicle_type">Type of vehicle</param>
/// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z)</param>
/// <param name="price"></param>
/// <returns>Returns duration in seconds (data type: double)</returns>
std::pair<std::string, QDateTime>
GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price,
PermitType permitType, bool nextDay = false, bool prepaid = false);
/// <summary>
/// Gets cost from duration in seconds
/// </summary>
/// <param name="tariff_cfg">Pointer to configuration</param>
/// <param name="vehicle_type">Type of vehicle</param>
/// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param>
/// <param name="end_datetime">Date/time of park end to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param>
/// <param name="durationMin">Duration of parking in minutes</param>
/// <returns>Returns cost (data type: double)</returns>
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
PermitType permitType, bool nextDay = false, bool prepaid = false);
// 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);
//
// helper function to find time steps for a tariff with PaymentMethod::Steps
// (e.g. Schoenau/Koenigsee)
//
QList<int> &GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const;
QList<int> GetSteps(Configuration *cfg, int paymentOptionIndex=0, QDateTime const &start = QDateTime::currentDateTime()) const {
return GetTimeSteps(cfg, paymentOptionIndex, start);
}
QList<int> GetPriceSteps(Configuration *cfg) const;
// additional helper functions
bool noSpecialDays(Configuration const *cfg) const {
return (cfg->SpecialDays.size() == 0) && (cfg->SpecialDaysWorktime.size() == 0);
}
bool specialDays(Configuration const *cfg) const {
return !noSpecialDays(cfg);
}
bool tariffIs24_7(Configuration const *cfg) const {
return (cfg->YearPeriod.size() == 0 &&
cfg->SpecialDays.size() == 0 &&
cfg->SpecialDaysWorktime.size() == 0);
}
// testing public:
// Introduced for PaymentMethod::Steps (e.g. Schoenau)
// For tariff of following structure: only steps, no special days, nonstop.
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, quint64 durationMinutes, int paymentOptionIndex=0) const;
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, QDateTime const &end, int paymentOptionIndex=0) const;
private:
Ticket private_GetCostFromDuration(Configuration const* cfg,
QDateTime const &start,
int durationMinutes,
bool prepaid = false);
Ticket private_GetDurationFromCost(Configuration *cfg,
QDateTime const &start,
uint32_t price,
bool prepaid = false);
bool checkDurationMinutes(int minParkingTime, int maxParkingTime,
int durationMinutes);
//
uint32_t GetPriceForTimeStep(Configuration *cfg, int timeStep, int paymentOptionIndex) const;
//uint32_t GetPriceForStep(Configuration *cfg, int step) const {
// return GetPriceForTimeStep(cfg, step, 0);
//}
uint32_t GetDurationForPrice(Configuration *cfg, int price) const;
uint32_t GetStepForPrice(Configuration *cfg, int price) const {
return GetDurationForPrice(cfg, price);
}
int findWorkTimeRange(QDateTime const &dt,
QScopedArrayPointer<TariffTimeRange> const &worktime,
size_t size);
int findNextWorkTimeRange(QDateTime const &dt,
QScopedArrayPointer<TariffTimeRange> const &worktime,
size_t size);
};
#endif // CALCULATOR_FUNCTIONS_H_INCLUDED

View File

@ -0,0 +1,58 @@
#ifndef ATB_TIME_H_INCLUDED
#define ATB_TIME_H_INCLUDED
#include <QDateTime>
class ATBTime {
QDateTime const m_end;
mutable QDateTime m_time;
public:
explicit ATBTime();
explicit ATBTime(int h, int m, int s = 0, int ms = 0);
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(QTime t) const { return m_time.time().secsTo(t); }
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 QDataStream &operator<<(QDataStream &out, ATBTime time);
friend QDataStream &operator>>(QDataStream &in, ATBTime &time);
};
#endif // ATB_TIME_H_INCLUDED

View File

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include <optional> #include <optional>
#include <utility>
#include "configuration.h" #include "configuration.h"
#include "calculate_price.h" #include "calculate_price.h"
@ -70,7 +71,8 @@ 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="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z)</param>
/// <param name="price"></param> /// <param name="price"></param>
/// <returns>Returns duration in seconds (data type: double)</returns> /// <returns>Returns duration in seconds (data type: double)</returns>
std::string GetDurationFromCost(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double price, 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); PermitType permitType, bool nextDay = false, bool prepaid = false);
/// <summary> /// <summary>

View File

@ -9,4 +9,8 @@ public:
std::string pedwt_time_from; std::string pedwt_time_from;
std::string pedwt_time_to; 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
}; };

View File

@ -35,7 +35,8 @@ SOURCES += \
src/tariff_log.cpp \ src/tariff_log.cpp \
src/calculate_price.cpp \ src/calculate_price.cpp \
src/ticket.cpp \ src/ticket.cpp \
src/tariff_global_defines.cpp src/tariff_global_defines.cpp \
src/atb_time.cpp
HEADERS += \ HEADERS += \
include/mobilisis/calculator_functions.h \ include/mobilisis/calculator_functions.h \
@ -89,7 +90,8 @@ HEADERS += \
include/mobilisis/tariff_interpolation.h \ include/mobilisis/tariff_interpolation.h \
include/mobilisis/tariff_prepaid.h \ include/mobilisis/tariff_prepaid.h \
include/mobilisis/tariff_carryover.h \ include/mobilisis/tariff_carryover.h \
include/mobilisis/tariff_global_defines.h include/mobilisis/tariff_global_defines.h \
include/mobilisis/atb_time.h
OTHER_FILES += src/main.cpp \ OTHER_FILES += src/main.cpp \
../tariffs/tariff_korneuburg.json \ ../tariffs/tariff_korneuburg.json \

103
library/src/atb_time.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "atb_time.h"
ATBTime::ATBTime()
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
}
ATBTime::ATBTime(int h, int m, int s, int ms)
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
QTime t(h, m, s, ms);
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 {
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 {
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();
}
bool operator==(const ATBTime &lhs, const ATBTime &rhs) noexcept {
return lhs.m_time.time() == rhs.m_time.time();
}
QDataStream &operator<<(QDataStream &out, ATBTime time) {
out << time.m_time.time();
return out;
}
QDataStream &operator>>(QDataStream &in, ATBTime &time) {
QTime t;
in >> t;
time.m_time.setTime(t);
return in;
}

View File

@ -26,6 +26,7 @@ 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::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE";
QString const CalcState::OVERPAID = "OVERPAID"; QString const CalcState::OVERPAID = "OVERPAID";
QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME"; QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME";
QString const CalcState::SUCCESS_MAXPRICE = "SUCCESS_MAXPRICE";
QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) {
return Calculator::GetInstance().GetTimeSteps(cfg); return Calculator::GetInstance().GetTimeSteps(cfg);
@ -808,8 +809,10 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
int pop_prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; int pop_prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id;
std::optional<ATBPeriodYear> yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time); std::optional<ATBPeriodYear> yperiod = Utilities::GetYearPeriodActive(tariff, start_parking_time);
int period_id = -1;
if (yperiod.has_value()) { if (yperiod.has_value()) {
ATBPeriodYear const &period = yperiod.value(); ATBPeriodYear const &period = yperiod.value();
period_id = period.pye_id;
pop_carry_over_option_id = period.pye_id; pop_carry_over_option_id = period.pye_id;
pop_prepaid_option_id = period.pye_id; pop_prepaid_option_id = period.pye_id;
qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id; qCritical() << __func__ << ":" << __LINE__ << "re-computed carry-over-id" << pop_carry_over_option_id;
@ -822,8 +825,39 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate); qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate);
qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration; qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration;
// handle prepaid option
QDateTime effectiveStartTime(start_parking_time); QDateTime effectiveStartTime(start_parking_time);
// handle special days
int const specialDayId = tariff->specialDayId(start_parking_time);
if (specialDayId > 0) { // found special day
for (auto[itr, rangeEnd] = tariff->SpecialDaysWorktime.equal_range(specialDayId); itr != rangeEnd; ++itr) {
ATBSpecialDaysWorktime const &wt = itr->second;
switch(period_id) {
case 1: // summer term
if ((wt.pedwt_paid & 1) == 0) {
// does not have to be paid, move to next midnight
// better: start of next day (falls kein vorkauf besteht)
effectiveStartTime = effectiveStartTime.addDays(1);
effectiveStartTime.setTime(QTime(0, 0, 0));
}
break;
case 2: // winter term
if ((wt.pedwt_paid & 2) == 0) {
// does not have to be paid, move to next midnight
// better: start of next day (falls kein vorkauf besteht)
effectiveStartTime = effectiveStartTime.addDays(1);
effectiveStartTime.setTime(QTime(0, 0, 0));
}
break;
default:;
}
}
}
// handle prepaid option
int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id; int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id;
std::optional<ATBPrepaid> prepaidOption = tariff->getPrepaidType(prepaid_option_id); std::optional<ATBPrepaid> prepaidOption = tariff->getPrepaidType(prepaid_option_id);
if (prepaidOption.has_value()) { if (prepaidOption.has_value()) {
@ -846,9 +880,20 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
qCritical() << __func__ << ":" << __LINE__ << "effectiveStartTime:" << effectiveStartTime.toString(Qt::ISODate); qCritical() << __func__ << ":" << __LINE__ << "effectiveStartTime:" << effectiveStartTime.toString(Qt::ISODate);
int const carryOver = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over;
qCritical() << __func__ << ":" << __LINE__ << " carryOver flag" << carryOver;
if (carryOver == 1) {
QTime carryOverStart = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].static_start;
int carryOverDuration = tariff->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration;
qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate);
qCritical() << __func__ << ":" << __LINE__ << "carryOverDuration" << carryOverDuration;
// handle carry over // handle carry over
int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60; int minutesUntilCarryOver = effectiveStartTime.time().secsTo(carryOverStart) / 60;
if (netto_parking_time > minutesUntilCarryOver) { if ((minutesUntilCarryOver > 0) && (netto_parking_time > minutesUntilCarryOver)) {
int const rest = netto_parking_time - minutesUntilCarryOver; int const rest = netto_parking_time - minutesUntilCarryOver;
QDateTime s(effectiveStartTime); QDateTime s(effectiveStartTime);
s = s.addSecs(minutesUntilCarryOver * 60); s = s.addSecs(minutesUntilCarryOver * 60);
@ -878,6 +923,10 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate); qCritical() << __func__ << ":" << __LINE__ << "end-parking-time:" << end_parking_time.toString(Qt::ISODate);
} }
} }
} else {
qCritical() << __func__ << ":" << __LINE__ << "NO carryOver configured";
end_parking_time = effectiveStartTime.addSecs(netto_parking_time*60);
}
end_parking_time.setTime(QTime(end_parking_time.time().hour(), end_parking_time.setTime(QTime(end_parking_time.time().hour(),
end_parking_time.time().minute(), 0)); end_parking_time.time().minute(), 0));
@ -970,10 +1019,14 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
qCritical() << " start (cs): " << cs; qCritical() << " start (cs): " << cs;
qCritical() << " price: " << price; qCritical() << " price: " << price;
duration = Calculator::GetInstance().GetDurationFromCost(tariff, std::pair<std::string, QDateTime> p_duration
= Calculator::GetInstance().GetDurationFromCost(tariff,
tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id, tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
price, permitType, nextDay, prepaid).c_str(); price, permitType, nextDay, prepaid);
duration = p_duration.first.c_str();
QDateTime d = QDateTime::fromString(duration, Qt::ISODate); QDateTime d = QDateTime::fromString(duration, Qt::ISODate);
if (!d.isValid()) { if (!d.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); calcState.setDesc(QString("ticketEndTime=%1").arg(duration));
@ -1044,15 +1097,26 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
} }
QString cs = start_parking_time.toString(Qt::ISODate); QString cs = start_parking_time.toString(Qt::ISODate);
QString endTime = Calculator::GetInstance().GetDurationFromCost(
std::pair<std::string, QDateTime> p_endTime
= Calculator::GetInstance().GetDurationFromCost(
tariff, tariff,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
price, permitType, nextDay, prepaid).c_str(); price, permitType, nextDay, prepaid);
QString endTime = p_endTime.first.c_str();
ticketEndTime = p_endTime.second;
if (endTime == CalcState::SUCCESS) { if (endTime == CalcState::SUCCESS) {
calcState.setDesc(QString("SUCCESS")); calcState.setDesc(QString("SUCCESS"));
calcState.setStatus(endTime); calcState.setStatus(endTime);
qCritical() << __func__ << ":" << __LINE__ << "SUCCESS";
} else
if (endTime == CalcState::SUCCESS_MAXPRICE) {
calcState.setDesc(QString("SUCCESS_MAXPRICE"));
calcState.setStatus(endTime);
qCritical() << __func__ << ":" << __LINE__ << "SUCCESS_MAXPRICE";
} else } else
if (endTime == CalcState::ERROR_PARSING_ZONE_NR) { if (endTime == CalcState::ERROR_PARSING_ZONE_NR) {
calcState.setStatus(endTime); calcState.setStatus(endTime);
@ -1157,6 +1221,15 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
if (ticketEndTime.time() > carryOverStart) { if (ticketEndTime.time() > carryOverStart) {
// qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60); ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60);
} else
if (ticketEndTime.time() == carryOverStart) {
qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
qCritical() << __func__ << ":" << __LINE__ << " carryOverStart" << carryOverStart.toString(Qt::ISODate);
ATBPaymentOption const &po = tariff->getPaymentOptions(paymentOptionIndex);
if (po.pop_apply_carry_over_to_ticket_endtime) {
ticketEndTime = ticketEndTime.addSecs(carryOverDuration * 60);
qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
}
} else { } else {
// qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate); // qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
if (ticketEndTime.time() < carryOverEnd) { if (ticketEndTime.time() < carryOverEnd) {
@ -1205,7 +1278,9 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
return calcState.set(CalcState::State::INVALID_START_DATE); return calcState.set(CalcState::State::INVALID_START_DATE);
} }
return calcState.set(CalcState::State::SUCCESS); //return calcState.set(CalcState::State::SUCCESS);
qCritical() << __func__ << ":" << __LINE__ << " calcState" << calcState.toString();
return calcState;
} }
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff,

View File

@ -118,7 +118,8 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
return QDateTime(); return QDateTime();
} }
/// <inheritdoc/> /// <inheritdoc/>
std::string Calculator::GetDurationFromCost(Configuration* cfg, std::pair<std::string, QDateTime>
Calculator::GetDurationFromCost(Configuration* cfg,
uint8_t payment_option, uint8_t payment_option,
char const *startDatetimePassed, // given in local time char const *startDatetimePassed, // given in local time
double cost, double cost,
@ -134,6 +135,9 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0)); inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0));
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
bool overPaid = false;
bool successMaxPrice = false; // max-price and cost match
int paymentOptionIndex = getPaymentOptionIndex(*cfg, inputDate); int paymentOptionIndex = getPaymentOptionIndex(*cfg, inputDate);
if (paymentOptionIndex == -1) { if (paymentOptionIndex == -1) {
paymentOptionIndex = cfg->getPaymentOptionIndex(QDateTime::fromString(startDatetimePassed, Qt::ISODate)); paymentOptionIndex = cfg->getPaymentOptionIndex(QDateTime::fromString(startDatetimePassed, Qt::ISODate));
@ -162,7 +166,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
// minimal price is set by GetTimeSteps() // minimal price is set by GetTimeSteps()
qCritical() << DBG_HEADER << " provided price (cost):" << cost; qCritical() << DBG_HEADER << " provided price (cost):" << cost;
qCritical() << DBG_HEADER << "configured minimal price:" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; qCritical() << DBG_HEADER << "configured minimal price:" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
return CalcState::BELOW_MIN_PARKING_PRICE.toStdString(); return std::make_pair(CalcState::BELOW_MIN_PARKING_PRICE.toStdString(), QDateTime());
} }
if (prepaid == false) { if (prepaid == false) {
@ -225,9 +229,9 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
qCritical() << DBG_HEADER << " minimal parking time (minutes):" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_time; qCritical() << DBG_HEADER << " minimal parking time (minutes):" << cfg->getPaymentOptions(paymentOptionIndex).pop_min_time;
if (duration_previous < cfg->getPaymentOptions(paymentOptionIndex).pop_min_time) { if (duration_previous < cfg->getPaymentOptions(paymentOptionIndex).pop_min_time) {
return CalcState::BELOW_MIN_PARKING_TIME.toStdString(); // minimal parking time is set by GetTimeSteps() return std::make_pair(CalcState::BELOW_MIN_PARKING_TIME.toStdString(), d); // minimal parking time is set by GetTimeSteps()
} }
return d.toString(Qt::ISODate).toStdString(); return std::make_pair(d.toString(Qt::ISODate).toStdString(), d);
} }
} }
@ -240,7 +244,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
qCritical() << DBG_HEADER << " provided price (cost):" << cost; qCritical() << DBG_HEADER << " provided price (cost):" << cost;
qCritical() << DBG_HEADER << " duration for price:" << durationStr; qCritical() << DBG_HEADER << " duration for price:" << durationStr;
return durationStr.toStdString(); return std::make_pair(durationStr.toStdString(), d);
} }
} }
} }
@ -254,14 +258,14 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
// use tariff with structure as for instance Schoenau, Koenigsee: // use tariff with structure as for instance Schoenau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime // without given YearPeriod, SpecialDays and SpecialDaysWorktime
inputDate = inputDate.addSecs(GetDurationForPrice(cfg, cost) * 60); inputDate = inputDate.addSecs(GetDurationForPrice(cfg, cost) * 60);
return inputDate.toString(Qt::ISODate).toStdString(); return std::make_pair(inputDate.toString(Qt::ISODate).toStdString(), inputDate);
} else { } else {
if (Utilities::IsYearPeriodActive(cfg, inputDate)) { if (Utilities::IsYearPeriodActive(cfg, inputDate)) {
if (!prepaid) { if (!prepaid) {
CalcState cs = isParkingAllowed(cfg, inputDate); CalcState cs = isParkingAllowed(cfg, inputDate);
if (cs) { if (cs) {
inputDate.setTime(cs.getAllowedTimeRange().getTimeUntil()); inputDate.setTime(cs.getAllowedTimeRange().getTimeUntil());
return inputDate.toString(Qt::ISODate).toStdString(); return std::make_pair(inputDate.toString(Qt::ISODate).toStdString(), inputDate);
} }
} }
@ -270,18 +274,25 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price; int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay; int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
if (cost == pop_max_price) {
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
successMaxPrice = true;
}
if (cost > pop_max_price) { if (cost > pop_max_price) {
qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost; qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
if (pop_allow_overpay == false) { if (pop_allow_overpay == false) {
return CalcState::OVERPAID.toStdString(); return std::make_pair(CalcState::OVERPAID.toStdString(), QDateTime());
} }
cost = pop_max_price; cost = pop_max_price;
overPaid = true;
qCritical() << DBG_HEADER << "OVERPAID, MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
// return CalcState::OVERPAID.toStdString(); // return CalcState::OVERPAID.toStdString();
} }
if (cost < pop_min_price) { if (cost < pop_min_price) {
qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost; qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost;
return CalcState::BELOW_MIN_PARKING_PRICE.toStdString(); return std::make_pair(CalcState::BELOW_MIN_PARKING_PRICE.toStdString(), QDateTime());
} }
// int const pop_pre_paid = 1; // int const pop_pre_paid = 1;
@ -366,7 +377,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
qCritical() << DBG_HEADER qCritical() << DBG_HEADER
<< "ERROR" << inputDate.toString(Qt::ISODate) << "ERROR" << inputDate.toString(Qt::ISODate)
<< "NOT IN VALID WORKING TIME-RANGE"; << "NOT IN VALID WORKING TIME-RANGE";
return ""; return std::make_pair("", QDateTime());
} }
//qCritical() << __func__ << __LINE__; //qCritical() << __func__ << __LINE__;
@ -391,7 +402,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
qCritical() << DBG_HEADER qCritical() << DBG_HEADER
<< "ERROR" << inputDate.toString(Qt::ISODate) << "ERROR" << inputDate.toString(Qt::ISODate)
<< "NOT IN VALID WORKING TIME-RANGE"; << "NOT IN VALID WORKING TIME-RANGE";
return ""; return std::make_pair("", QDateTime());
} }
#if DEBUG_GET_DURATION_FROM_COST==1 #if DEBUG_GET_DURATION_FROM_COST==1
@ -440,7 +451,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
QDateTime d(QDateTime::fromString(s, Qt::ISODate)); QDateTime d(QDateTime::fromString(s, Qt::ISODate));
d = d.addSecs(duration_previous * 60); d = d.addSecs(duration_previous * 60);
//qCritical() << DBG_HEADER << "XXXXXXXXXXXXXXXXXXXXX" << d; //qCritical() << DBG_HEADER << "XXXXXXXXXXXXXXXXXXXXX" << d;
return d.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), d);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), d);
}
return std::make_pair(d.toString(Qt::ISODate).toStdString(), d);
} }
} else { } else {
durationInSecs = cfg->Duration.find(durationId)->second.pun_duration * 60; durationInSecs = cfg->Duration.find(durationId)->second.pun_duration * 60;
@ -516,6 +533,16 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
//qCritical() << DBG_HEADER << "NEW INPUT" << inputDate.toString(Qt::ISODate); //qCritical() << DBG_HEADER << "NEW INPUT" << inputDate.toString(Qt::ISODate);
int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over;
if (pop_carry_over) {
int weekDay = inputDate.date().dayOfWeek();
int const pop_carry_over_option_id = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_option_id;
if (pop_carry_over_option_id != -1) {
int const carryOverDuration = cfg->TariffCarryOverOptions.find(pop_carry_over_option_id)->second.carryover[weekDay].duration;
inputDate = inputDate.addSecs(carryOverDuration * 60);
}
}
inputDate = inputDate.addSecs(durationInSecs); inputDate = inputDate.addSecs(durationInSecs);
#if DEBUG_GET_DURATION_FROM_COST==1 #if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate); qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate);
@ -551,7 +578,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
qCritical() << DBG_HEADER << "TICKET-END" << s; qCritical() << DBG_HEADER << "TICKET-END" << s;
#endif #endif
return s.toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), inputDate);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), inputDate);
}
return std::make_pair(s.toStdString(), inputDate);
} // if ((double)price == cost) { } // if ((double)price == cost) {
else { else {
//qCritical() << DBG_HEADER; //qCritical() << DBG_HEADER;
@ -561,7 +594,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
} }
} }
return ""; return std::make_pair("", QDateTime());
} }
} }
} else } else
@ -578,7 +611,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
if (cost < minParkingPrice) { if (cost < minParkingPrice) {
qCritical() << QString("ERROR: COST < MIN_PARKING_PRICE (%1 < %2)").arg(cost).arg(minParkingPrice); qCritical() << QString("ERROR: COST < MIN_PARKING_PRICE (%1 < %2)").arg(cost).arg(minParkingPrice);
return QDateTime().toString(Qt::ISODate).toStdString(); return std::make_pair(QDateTime().toString(Qt::ISODate).toStdString(), QDateTime());
} }
if (cost > maxParkingPrice) { if (cost > maxParkingPrice) {
@ -617,7 +650,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
weekdayId = current.date().dayOfWeek(); weekdayId = current.date().dayOfWeek();
if (weekdayId == weekdayIdLast) { if (weekdayId == weekdayIdLast) {
qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED"; qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED";
return QDateTime().toString(Qt::ISODate).toStdString(); return std::make_pair(QDateTime().toString(Qt::ISODate).toStdString(), QDateTime());
} }
} }
@ -635,7 +668,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
if (current.time() >= to) { if (current.time() >= to) {
if (carryOverNotSet) { if (carryOverNotSet) {
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} else { } else {
QDateTime const dt = start; QDateTime const dt = start;
start = start.addDays(1); start = start.addDays(1);
@ -682,7 +721,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "price" << price; << "price" << price;
#endif #endif
end_datetime = current; end_datetime = current;
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
QTime const &from = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_from.c_str(), Qt::ISODate); QTime const &from = QTime::fromString(weekDayWorkTimeRanges[weekDayWorkTimeIndex].pwd_time_from.c_str(), Qt::ISODate);
@ -777,7 +822,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "end_datetime" << end_datetime.toString(Qt::ISODate) << "end_datetime" << end_datetime.toString(Qt::ISODate)
<< "price" << price; << "price" << price;
#endif #endif
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
} }
@ -818,7 +869,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "end_datetime" << end_datetime.toString(Qt::ISODate) << "end_datetime" << end_datetime.toString(Qt::ISODate)
<< "price" << price; << "price" << price;
#endif #endif
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
// price has been updated; use next time range // price has been updated; use next time range
@ -849,7 +906,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "price" << price; << "price" << price;
#endif #endif
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
if (moveToNextTimeRange) { if (moveToNextTimeRange) {
@ -965,8 +1028,13 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "end_datetime" << end_datetime.toString(Qt::ISODate) << "end_datetime" << end_datetime.toString(Qt::ISODate)
<< "price" << price; << "price" << price;
#endif #endif
if (overPaid) {
return end_datetime.toString(Qt::ISODate).toStdString(); return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
if (successMaxPrice) {
return std::make_pair(CalcState::SUCCESS_MAXPRICE.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
} }
@ -979,7 +1047,10 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "final price" << std::max(price, minParkingPrice); << "final price" << std::max(price, minParkingPrice);
#endif #endif
return end_datetime.toString(Qt::ISODate).toStdString(); if (overPaid) {
return std::make_pair(CalcState::OVERPAID.toStdString(), end_datetime);
}
return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} // while (timeRangeIt != cfg->TimeRange.cend()) { } // while (timeRangeIt != cfg->TimeRange.cend()) {
} }
@ -988,7 +1059,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
<< "INVALID END TIME"; << "INVALID END TIME";
#endif #endif
end_datetime = QDateTime(); end_datetime = QDateTime();
return end_datetime.toString(Qt::ISODate).toStdString(); return std::make_pair(end_datetime.toString(Qt::ISODate).toStdString(), end_datetime);
} }
Ticket t = private_GetDurationFromCost(cfg, inputDate, cost, prepaid); Ticket t = private_GetDurationFromCost(cfg, inputDate, cost, prepaid);
@ -996,7 +1067,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
// qCritical().noquote() << t; // qCritical().noquote() << t;
// TODO: im fehlerfall // TODO: im fehlerfall
return t.getValidUntil().toString(Qt::ISODate).toStdString(); return std::make_pair(t.getValidUntil().toString(Qt::ISODate).toStdString(), t.getValidUntil());
} }
#undef _DEBUG_ #undef _DEBUG_

View File

@ -1110,6 +1110,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_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_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_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble();
else if (strcmp(inner_obj_name, "pedwt_paid") == 0) SpecialDaysWorktime.pedwt_paid = k->value.GetInt();
break; break;
/*case MemberType::WeekDaysType: /*case MemberType::WeekDaysType:
if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt(); if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt();

View File

@ -34,7 +34,11 @@ OTHER_FILES += \
/opt/ptu5/opt/customer_335/etc/psa_tariff/tariff02.json \ /opt/ptu5/opt/customer_335/etc/psa_tariff/tariff02.json \
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff01.json \ /opt/ptu5/opt/customer_249/etc/psa_tariff/tariff01.json \
/opt/ptu5/opt/customer_249/etc/psa_tariff/tariff02.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