Compare commits

..

8 Commits

Author SHA1 Message Date
77e1414c13 compute_duration_for_parking_ticket():
Recompute pop_max_price using netto-parking-time.
	Search Duration for the time-step with time-step == netto-parking-time,
	then search for the corresponding price in PaymentRate.
	The result is the new pop_max_price.
2024-09-17 17:05:23 +02:00
d95275a72d Compute real netto_parking_time.
This time will be used to find the real time-step, and from here the actual price to pay.
2024-09-17 17:04:27 +02:00
577a17dc6a Set seconds of serveral date-times to 0.
Compute netto_parking_time (which includes carry-over duration).
2024-09-17 17:03:29 +02:00
d8d32820a3 compute_price_for_parking_ticket():
Reset pop_max_price to original value using pop_max_price_saved.
2024-09-17 17:01:32 +02:00
2ce0aeef1d Minor: include atb_time.h 2024-09-17 16:59:07 +02:00
0cba85eafb Set pop_max_price_saved 2024-09-17 16:58:20 +02:00
4030a4b165 Add pop_max_price_save in case pop_max_price has to be re-computed dynamically, so it can be reset 2024-09-17 16:57:34 +02:00
8c7afdfcb1 Add additional constructor. 2024-09-17 16:53:45 +02:00
6 changed files with 122 additions and 13 deletions

View File

@ -10,6 +10,7 @@ class ATBTime {
public:
explicit ATBTime();
explicit ATBTime(int h, int m, int s = 0, int ms = 0);
explicit ATBTime(QString const &time);
int hour() const { return m_time.time().hour(); }
int minute() const { return m_time.time().minute(); }

View File

@ -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;

View File

@ -4,6 +4,8 @@
#include <QTime>
#include <QString>
#include "atb_time.h"
struct ATBPrepaid {
int id;
bool anytime;

View File

@ -2,18 +2,30 @@
ATBTime::ATBTime()
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
: m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate))
, m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
}
ATBTime::ATBTime(int h, int m, int s, int ms)
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
: m_end(QDateTime::fromString("1970-01-02T00:00:00", Qt::ISODate))
, m_time(QDateTime::fromString("1970-01-01T00:00:00", Qt::ISODate)) {
QTime t(h, m, s, ms);
m_time.setTime(t);
}
ATBTime::ATBTime(QString const &t)
: m_end(QDateTime::fromString("1970-01-02T00:00:00"))
, m_time(QDateTime::fromString("1970-01-01T00:00:00")) {
if (t == "24:00:00") {
m_time = m_end;
} else {
m_time.setTime(QTime::fromString(t, Qt::ISODate));
}
}
QTime ATBTime::addMSecs(int ms) const {
return m_time.time().addMSecs(ms);
}

View File

@ -77,6 +77,7 @@ int CALCULATE_LIBRARY_API get_maximal_parkingtime(Configuration const *cfg,
if (paymentOptionIndex == -1) {
paymentOptionIndex = cfg->getPaymentOptionIndex(permitType);
}
int maxTime = 0;
switch(permitType) {
@ -683,6 +684,9 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
paymentOptionIndex = tariff->getPaymentOptionIndex(permitType.get());
}
tariff->getPaymentOptions(paymentOptionIndex).pop_max_price
= tariff->getPaymentOptions(paymentOptionIndex).pop_max_price_save;
double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_min_time;
double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions(paymentOptionIndex).pop_payment_method_id)->second.pop_max_time;
@ -753,6 +757,9 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
paymentOptionIndex = tariff->getPaymentOptionIndex(permitType);
}
tariff->getPaymentOptions(paymentOptionIndex).pop_max_price
= tariff->getPaymentOptions(paymentOptionIndex).pop_max_price_save;
double minMin = tariff->getPaymentOptions(paymentOptionIndex).pop_min_time;
double maxMin = tariff->getPaymentOptions(paymentOptionIndex).pop_max_time;
@ -878,6 +885,9 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
}
}
effectiveStartTime.setTime(QTime(effectiveStartTime.time().hour(),
effectiveStartTime.time().minute(), 0));
qCritical() << __func__ << ":" << __LINE__ << "effectiveStartTime:" << effectiveStartTime.toString(Qt::ISODate);
int const carryOver = tariff->getPaymentOptions(paymentOptionIndex).pop_carry_over;
@ -943,6 +953,8 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
//QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit();
//end_parking_time.setTime(tlimit);
// max_price neu berechnen
calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__)
.arg(end_parking_time.time().toString(Qt::ISODate)));
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
@ -1079,6 +1091,10 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) {
// handle prepaid option
QDateTime effectiveStartTime(start_parking_time);
effectiveStartTime.setTime(QTime(effectiveStartTime.time().hour(),
effectiveStartTime.time().minute(), 0));
int const prepaid_option_id = tariff->getPaymentOptions(paymentOptionIndex).pop_prepaid_option_id;
std::optional<ATBPrepaid> prepaidOption = tariff->getPrepaidType(prepaid_option_id);
if (prepaidOption.has_value()) {
@ -1095,8 +1111,9 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
}
}
}
QString cs = start_parking_time.toString(Qt::ISODate);
QDateTime start(start_parking_time);
start.setTime(QTime(start.time().hour(), start.time().minute(), 0));
QString cs = start.toString(Qt::ISODate);
std::pair<std::string, QDateTime> p_endTime
= Calculator::GetInstance().GetDurationFromCost(
@ -1174,8 +1191,14 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
} else {
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
ticketEndTime.setTime(QTime(ticketEndTime.time().hour(),
ticketEndTime.time().minute(), 0));
int netto_parking_time = start_parking_time.secsTo(ticketEndTime) / 60;
qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate);
qCritical() << __func__ << ":" << __LINE__ << "step-config:" << pop_time_step_config;
qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time;
if (!ticketEndTime.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(endTime));
@ -1217,6 +1240,12 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
}
if (carryOverStart.isValid() && carryOverEnd.isValid() && carryOverDuration != -1) {
// note: in such a case (direct coins) carry-over has been handled
// already in GetDurationFromCost()
netto_parking_time -= carryOverDuration;
qCritical() << __func__ << ":" << __LINE__ << "netto-parking-time" << netto_parking_time;
// qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
if (ticketEndTime.time() > carryOverStart) {
// qCritical() << __func__ << __LINE__ << "ticketEndTime.time():" << ticketEndTime.time().toString(Qt::ISODate);
@ -1242,23 +1271,85 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
}
}
ticketEndTime.setTime(QTime(ticketEndTime.time().hour(),
ticketEndTime.time().minute(), 0));
qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate);
for (auto[itr, rangeEnd] = tariff->WeekDays.equal_range((Qt::DayOfWeek)(ticketEndTime.date().dayOfWeek()));
itr != rangeEnd;
++itr) {
ATBWeekDay const &wd = itr->second;
bool const parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(start_parking_time,
ticketEndTime,
paymentOptionIndex);
bool parkTimeLimitViolated = wd.getTariffCarryOverSettings().parkingTimeLimitExceeded(start_parking_time,
ticketEndTime,
paymentOptionIndex);
if (parkTimeLimitViolated) {
//QTime const &tlimit = wd.getTariffCarryOverSettings().parkingTimeLimit();
//ticketEndTime.setTime(tlimit);
QList<int> const &stepList = Calculator::GetInstance().GetTimeSteps(tariff, paymentOptionIndex);
QDateTime newTicketEndTime = ticketEndTime;
qCritical() << __func__ << ":" << __LINE__ << "PARK-TIME VIOLATED";
for (int i = stepList.size() - 1; i > 0; --i) {
// qCritical() << __func__ << ":" << __LINE__ << "step[" << i << "]" << stepList.at(i);
if (netto_parking_time > 0 && stepList.at(i) <= netto_parking_time) {
int const diff = stepList.at(i-1) - stepList.at(i);
newTicketEndTime = newTicketEndTime.addSecs(diff * 60);
// qCritical() << __func__ << ":" << __LINE__ << "new-ticket-end-time" << newTicketEndTime.toString(Qt::ISODate);
parkTimeLimitViolated
= wd.getTariffCarryOverSettings()
.parkingTimeLimitExceeded(start_parking_time, newTicketEndTime, paymentOptionIndex);
if (!parkTimeLimitViolated) {
qCritical() << __func__ << ":" << __LINE__
<< "PARK-TIME NOT VIOLATED FOR" << newTicketEndTime.toString(Qt::ISODate);
int duration = stepList.at(i-1);
// qCritical() << __func__ << ":" << __LINE__ << "duration" << duration;
std::multimap<int, ATBDuration>::const_iterator it;
for (it = tariff->Duration.cbegin();
it != tariff->Duration.cend();
++it) {
if (duration == it->second.pun_duration) {
// qCritical() << __func__ << ":" << __LINE__ << "duration" << duration;
ATBPaymentOption &po = tariff->getPaymentOptions(paymentOptionIndex);
int const pop_id = po.pop_id;
for (auto[itr, rangeEnd] = tariff->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
int const durationId = itr->second.pra_payment_unit_id;
// qCritical() << __func__ << ":" << __LINE__ << "durationId" << durationId << it->second.pun_id;
// note: for this to work, Duration and PaymentRate must have
// exactly the same structure
if (durationId == it->second.pun_id) {
int const pra_price = itr->second.pra_price;
po.pop_max_price = pra_price;
qCritical() << __func__ << ":" << __LINE__ << "new max-price" << po.pop_max_price;
// note: ABOVE_MAX_PARKING_TIME would also be possible
// but here max-parking-time is dynamic. And for
// this dynamic value, opverpaid is actually correct
calcState.setDesc(CalcState::OVERPAID);
calcState.setStatus(CalcState::OVERPAID);
return calcState;
}
}
}
}
}
}
}
calcState.setDesc(QString("line=%1 endTime=%2: park-time-limit violated").arg(__LINE__)
.arg(ticketEndTime.time().toString(Qt::ISODate)));
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);

View File

@ -1000,6 +1000,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) {