Compare commits
10 Commits
5749fa422e
...
d4363e71cd
Author | SHA1 | Date | |
---|---|---|---|
d4363e71cd | |||
fd99c20bd9 | |||
dbccdba9fe | |||
b035f4f887 | |||
18f09fccb9 | |||
1086e360e5 | |||
ada7bebd90 | |||
2b9ea67ef5 | |||
d117328bed | |||
fd04531474 |
@ -90,9 +90,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
|||||||
, m_desc(desc) {
|
, m_desc(desc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CalcState(State state, QString desc = "",
|
explicit CalcState(State state, QString desc,
|
||||||
QTime const &from = QTime(),
|
QTime const &from,
|
||||||
QTime const &until = QTime())
|
QTime const &until)
|
||||||
: m_status(state)
|
: m_status(state)
|
||||||
, m_desc(desc)
|
, m_desc(desc)
|
||||||
, m_allowedTimeRange(from, until) {
|
, m_allowedTimeRange(from, until) {
|
||||||
|
@ -87,6 +87,9 @@ public:
|
|||||||
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
|
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, QDateTime &start_datetime, QDateTime & end_datetime, int durationMin,
|
||||||
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
PermitType permitType, bool nextDay = false, bool prepaid = false);
|
||||||
|
|
||||||
|
std::pair<CalcState, QDateTime> ComputeDurationFromCost(Configuration const* cfg, QDateTime const &startDatetimePassed, int cost);
|
||||||
|
std::pair<CalcState, std::optional<int>> ComputeCostFromDuration(Configuration const* cfg, QDateTime const &startDatetime, QDateTime &endDatetime, int nettoParkingTime);
|
||||||
|
|
||||||
// Daily ticket
|
// Daily ticket
|
||||||
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
|
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
|
||||||
std::optional<struct price_t> GetDailyTicketPrice(Configuration* cfg, QDateTime const &startDatetime, QDateTime &endTime, PERMIT_TYPE permitType);
|
std::optional<struct price_t> GetDailyTicketPrice(Configuration* cfg, QDateTime const &startDatetime, QDateTime &endTime, PERMIT_TYPE permitType);
|
||||||
|
@ -6,7 +6,8 @@ enum PaymentMethod {
|
|||||||
Progressive = 0x01,
|
Progressive = 0x01,
|
||||||
Degressive = 0x02,
|
Degressive = 0x02,
|
||||||
Linear = 0x03,
|
Linear = 0x03,
|
||||||
Steps = 0x04
|
Steps = 0x04,
|
||||||
|
Unified = 0x05
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAYMENT_METHOD_H_INCLUDED
|
#endif // PAYMENT_METHOD_H_INCLUDED
|
||||||
|
@ -338,7 +338,9 @@ int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg,
|
|||||||
|
|
||||||
switch(permitType) {
|
switch(permitType) {
|
||||||
case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281)
|
case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281)
|
||||||
if (paymentMethodId == PaymentMethod::Progressive || paymentMethodId == PaymentMethod::Steps) {
|
if (paymentMethodId == PaymentMethod::Progressive
|
||||||
|
|| paymentMethodId == PaymentMethod::Steps
|
||||||
|
|| paymentMethodId == PaymentMethod::Unified) {
|
||||||
//maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId);
|
//maxPrice = Utilities::getMaximalParkingPrice(cfg, paymentMethodId);
|
||||||
ATBPaymentOption const &po = cfg->getPaymentOptions(paymentOptionIndex);
|
ATBPaymentOption const &po = cfg->getPaymentOptions(paymentOptionIndex);
|
||||||
maxPrice = po.pop_max_price; // maxTime is given in minutes
|
maxPrice = po.pop_max_price; // maxTime is given in minutes
|
||||||
@ -518,6 +520,9 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
|
|||||||
case PaymentMethod::Steps:
|
case PaymentMethod::Steps:
|
||||||
qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps";
|
qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Steps";
|
||||||
break;
|
break;
|
||||||
|
case PaymentMethod::Unified:
|
||||||
|
qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Unified";
|
||||||
|
break;
|
||||||
case PaymentMethod::Undefined:
|
case PaymentMethod::Undefined:
|
||||||
qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined";
|
qCritical() << __LINE__ << "compute_next_timestep() paymentMethodId: Undefined";
|
||||||
break;
|
break;
|
||||||
@ -528,6 +533,8 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
|
|||||||
if ((paymentMethodId == PaymentMethod::Steps) ||
|
if ((paymentMethodId == PaymentMethod::Steps) ||
|
||||||
// progressive tariff: e.g. Neuhauser, Kirchdorf (743)
|
// progressive tariff: e.g. Neuhauser, Kirchdorf (743)
|
||||||
(paymentMethodId == PaymentMethod::Progressive) ||
|
(paymentMethodId == PaymentMethod::Progressive) ||
|
||||||
|
// unified tariff: starting with Bad Neuenahr (249), Tariff for Zone5
|
||||||
|
(paymentMethodId == PaymentMethod::Unified) ||
|
||||||
// degressive tariff: e.g. Fuchs Technik (500)
|
// degressive tariff: e.g. Fuchs Technik (500)
|
||||||
(paymentMethodId == PaymentMethod::Degressive))
|
(paymentMethodId == PaymentMethod::Degressive))
|
||||||
{
|
{
|
||||||
@ -960,6 +967,19 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
|
|||||||
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
if (tariff->getPaymentOptions(0).pop_payment_method_id == PaymentMethod::Unified) {
|
||||||
|
std::pair<CalcState, std::optional<int>> p =
|
||||||
|
Calculator::GetInstance().ComputeCostFromDuration(tariff, start_parking_time, end_parking_time, netto_parking_time);
|
||||||
|
CalcState const cs = p.first;
|
||||||
|
|
||||||
|
if ((cs.getStatus() == CalcState::State::SUCCESS || cs.getStatus() == CalcState::State::SUCCESS_MAXPRICE)) {
|
||||||
|
if (p.second.has_value()) {
|
||||||
|
cost = p.second.value();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cost = Calculator::GetInstance().GetCostFromDuration(
|
cost = Calculator::GetInstance().GetCostFromDuration(
|
||||||
tariff,
|
tariff,
|
||||||
@ -969,7 +989,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
|
|||||||
netto_parking_time, // minutes, netto
|
netto_parking_time, // minutes, netto
|
||||||
false, prepaid);
|
false, prepaid);
|
||||||
}
|
}
|
||||||
// qCritical() << __func__ << __LINE__;
|
|
||||||
double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
double minCost = tariff->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
||||||
if (cost < minCost) {
|
if (cost < minCost) {
|
||||||
calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost));
|
calcState.setDesc(QString("line=%1 minCost=%2, cost=%3").arg(__LINE__).arg(minCost).arg(cost));
|
||||||
@ -1125,6 +1145,9 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
|||||||
QString endTime = p_endTime.first.c_str();
|
QString endTime = p_endTime.first.c_str();
|
||||||
ticketEndTime = p_endTime.second;
|
ticketEndTime = p_endTime.second;
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << endTime;
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << ticketEndTime.toString(Qt::ISODate);
|
||||||
|
|
||||||
if (endTime == CalcState::SUCCESS) {
|
if (endTime == CalcState::SUCCESS) {
|
||||||
calcState.setDesc(QString("SUCCESS"));
|
calcState.setDesc(QString("SUCCESS"));
|
||||||
calcState.setStatus(endTime);
|
calcState.setStatus(endTime);
|
||||||
@ -1205,6 +1228,8 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
|||||||
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
|
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tariff->getPaymentOptions().pop_payment_method_id != PaymentMethod::Unified) {
|
||||||
|
|
||||||
if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) {
|
if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::STATIC) {
|
||||||
// handle carry over for ticket-end-time
|
// handle carry over for ticket-end-time
|
||||||
qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate);
|
qCritical() << __func__ << ":" << __LINE__ << "ticketEndTime:" << ticketEndTime.toString(Qt::ISODate);
|
||||||
@ -1355,6 +1380,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
|||||||
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) {
|
if (ticketEndTime.time().hour() == 0 && ticketEndTime.time().minute() == 0) {
|
||||||
ticketEndTime = ticketEndTime.addDays(-1);
|
ticketEndTime = ticketEndTime.addDays(-1);
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "ticket.h"
|
#include "ticket.h"
|
||||||
#include "tariff_global_defines.h"
|
#include "tariff_global_defines.h"
|
||||||
#include "tariff_prepaid.h"
|
#include "tariff_prepaid.h"
|
||||||
|
#include "tariff_out_of_service.h"
|
||||||
|
#include "tariff_service.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -117,6 +119,430 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
|
|||||||
|
|
||||||
return QDateTime();
|
return QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getPrepaid
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
|
||||||
|
std::optional<ATBTariffPrepaid> getPrepaid(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffPrepaid> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
auto const &prepaidRange = cfg->TariffPrepaids.equal_range(weekDay);
|
||||||
|
for (auto i = prepaidRange.first; i != prepaidRange.second; ++i) {
|
||||||
|
ATBTariffPrepaid const &prepaid = i->second;
|
||||||
|
TimeRange const &prepaidTimeRange = prepaid.m_range;
|
||||||
|
if (inputTime >= prepaidTimeRange.m_start && inputTime < prepaidTimeRange.m_end) {
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getCarryOver
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
std::optional<ATBTariffCarryOver> getCarryOver(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffCarryOver> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
auto const &carryOverRange = cfg->TariffCarryOvers.equal_range(weekDay);
|
||||||
|
for (auto i = carryOverRange.first; i != carryOverRange.second; ++i) {
|
||||||
|
ATBTariffCarryOver const &carryOver = i->second;
|
||||||
|
TimeRange const &carryOverTimeRange = carryOver.m_range;
|
||||||
|
if (inputTime >= carryOverTimeRange.m_start && inputTime < carryOverTimeRange.m_end) {
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getService
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
|
||||||
|
std::optional<ATBTariffService> getService(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffService> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
auto const &serviceRange = cfg->TariffServices.equal_range(weekDay);
|
||||||
|
for (auto i = serviceRange.first; i != serviceRange.second; ++i) {
|
||||||
|
ATBTariffService const &service = i->second;
|
||||||
|
TimeRange const &serviceTimeRange = service.m_range;
|
||||||
|
if (inputTime >= serviceTimeRange.m_start && inputTime < serviceTimeRange.m_end) {
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief getOutOfService
|
||||||
|
/// \param cfg
|
||||||
|
/// \param dt
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
std::optional<ATBTariffOutOfService> getOutOfService(Configuration const *cfg, QDateTime const &dt) {
|
||||||
|
std::optional<ATBTariffOutOfService> value = std::nullopt;
|
||||||
|
|
||||||
|
int weekDay = dt.date().dayOfWeek();
|
||||||
|
ATBTime inputTime(dt.time());
|
||||||
|
QDate date;
|
||||||
|
|
||||||
|
auto const &outOfServiceRange = cfg->TariffOutOfServices.equal_range(weekDay);
|
||||||
|
for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) {
|
||||||
|
ATBTariffOutOfService const &outOfService = i->second;
|
||||||
|
TimeRange const &outOfServiceTimeRange = outOfService.m_range;
|
||||||
|
if (outOfService.m_date == dt.date()) {
|
||||||
|
date = dt.date();
|
||||||
|
if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) {
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date.isNull() || !date.isValid()) {
|
||||||
|
for (auto i = outOfServiceRange.first; i != outOfServiceRange.second; ++i) {
|
||||||
|
ATBTariffOutOfService const &outOfService = i->second;
|
||||||
|
TimeRange const &outOfServiceTimeRange = outOfService.m_range;
|
||||||
|
if (inputTime >= outOfServiceTimeRange.m_start && inputTime < outOfServiceTimeRange.m_end) {
|
||||||
|
value = value.value_or(i->second);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<CalcState, QDateTime>
|
||||||
|
Calculator::ComputeDurationFromCost(Configuration const *cfg,
|
||||||
|
QDateTime const &startDatetimePassed, // given in local time
|
||||||
|
int cost) {
|
||||||
|
|
||||||
|
QDateTime inputDate = startDatetimePassed;
|
||||||
|
inputDate.setTime(QTime(inputDate.time().hour(), inputDate.time().minute(), 0));
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
int paymentOptionIndex = 0;
|
||||||
|
|
||||||
|
bool overPaid = false;
|
||||||
|
bool successMaxPrice = false;
|
||||||
|
|
||||||
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price;
|
||||||
|
int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time;
|
||||||
|
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
||||||
|
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
||||||
|
|
||||||
|
int price = 0;
|
||||||
|
int durationId = 0;
|
||||||
|
int netto_parking_time_in_minutes = 0;
|
||||||
|
int brutto_parking_time_in_minutes = 0;
|
||||||
|
int free_parking_time_in_minutes = 0;
|
||||||
|
|
||||||
|
QMap<int, int> nettoParktimePrice;
|
||||||
|
QMap<int, int> priceNettoParktime;
|
||||||
|
|
||||||
|
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
|
||||||
|
durationId = itr->second.pra_payment_unit_id;
|
||||||
|
|
||||||
|
int const pra_price = itr->second.pra_price;
|
||||||
|
if (pop_accumulate_prices) {
|
||||||
|
price += pra_price;
|
||||||
|
} else {
|
||||||
|
price = pra_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if ((double)price == cost) {
|
||||||
|
auto search = cfg->Duration.find(durationId);
|
||||||
|
if (search != cfg->Duration.end()) {
|
||||||
|
// found now the duration in minutes
|
||||||
|
// check if we are still inside the working-time-range
|
||||||
|
ATBDuration duration = search->second;
|
||||||
|
nettoParktimePrice.insert(duration.pun_duration, price);
|
||||||
|
priceNettoParktime.insert(price, duration.pun_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << nettoParktimePrice;
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << priceNettoParktime;
|
||||||
|
|
||||||
|
if (cost == pop_max_price) {
|
||||||
|
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
successMaxPrice = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost > pop_max_price) {
|
||||||
|
qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
if (pop_allow_overpay == false) {
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID), QDateTime());
|
||||||
|
}
|
||||||
|
cost = pop_max_price;
|
||||||
|
overPaid = true;
|
||||||
|
qCritical() << DBG_HEADER << "OVERPAID, MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
|
// return CalcState::OVERPAID.toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost < pop_min_price) {
|
||||||
|
qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::BELOW_MIN_PARKING_PRICE), QDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
int weekDay = inputDate.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START weekDay" << weekDay << inputDate.toString(Qt::ISODate);
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START cost" << cost;
|
||||||
|
|
||||||
|
QDateTime dt;
|
||||||
|
bool computationStarted = false;
|
||||||
|
price = 0;
|
||||||
|
netto_parking_time_in_minutes = 0;
|
||||||
|
brutto_parking_time_in_minutes = 0;
|
||||||
|
free_parking_time_in_minutes = 0;
|
||||||
|
|
||||||
|
int const nettoParktimeForCost = priceNettoParktime[int(cost)];
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "nettoParktimeForCost" << nettoParktimeForCost;
|
||||||
|
|
||||||
|
bool startDateNotOutOfService = false;
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
while (++cnt < 10 && netto_parking_time_in_minutes < nettoParktimeForCost) {
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "cnt [" << cnt;
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffOutOfService> oos = getOutOfService(cfg, dt)) {
|
||||||
|
if (overPaid || startDateNotOutOfService) {
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID,
|
||||||
|
CalcState::OVERPAID), dt);
|
||||||
|
}
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME,
|
||||||
|
CalcState::OUTSIDE_ALLOWED_PARKING_TIME), dt);
|
||||||
|
} else {
|
||||||
|
startDateNotOutOfService = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computationStarted == false) {
|
||||||
|
computationStarted = true;
|
||||||
|
if (std::optional<ATBTariffPrepaid> pp = getPrepaid(cfg, dt)) {
|
||||||
|
TimeRange const &prepaidTimeRange = pp.value().m_range;
|
||||||
|
ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0);
|
||||||
|
free_parking_time_in_minutes += t.secsTo(prepaidTimeRange.m_end.toString(Qt::ISODate)) / 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffCarryOver> co = getCarryOver(cfg, inputDate.addSecs(brutto_parking_time_in_minutes * 60))) {
|
||||||
|
TimeRange const &carryOverTimeRange = co.value().m_range;
|
||||||
|
free_parking_time_in_minutes += carryOverTimeRange.m_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (std::optional<ATBTariffService> serv = getService(cfg, dt)) {
|
||||||
|
TimeRange const &serviceTimeRange = serv.value().m_range;
|
||||||
|
|
||||||
|
if (nettoParktimeForCost > netto_parking_time_in_minutes) {
|
||||||
|
int rest_parking_time_in_minutes = nettoParktimeForCost - netto_parking_time_in_minutes;
|
||||||
|
ATBTime t(dt.time().hour(), dt.time().minute(), 0, 0);
|
||||||
|
int timeToServiceEnd = t.secsTo(serviceTimeRange.m_end.toString(Qt::ISODate)) / 60;
|
||||||
|
if (serviceTimeRange.m_duration > 0) {
|
||||||
|
if (timeToServiceEnd < rest_parking_time_in_minutes) {
|
||||||
|
netto_parking_time_in_minutes += timeToServiceEnd;
|
||||||
|
} else {
|
||||||
|
netto_parking_time_in_minutes += rest_parking_time_in_minutes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("%1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
// qCritical() << __func__ << ":" << __LINE__ << "cnt" << cnt << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt >= 10) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "BREAK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure if last carry-over ranges shall be added to ticket-end-time
|
||||||
|
cnt = 0;
|
||||||
|
while (std::optional<ATBTariffCarryOver> co = getCarryOver(cfg, inputDate.addSecs(brutto_parking_time_in_minutes * 60))) {
|
||||||
|
if (++cnt > 5) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "BREAK";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TimeRange const &carryOverTimeRange = co.value().m_range;
|
||||||
|
free_parking_time_in_minutes += carryOverTimeRange.m_duration;
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
brutto_parking_time_in_minutes = free_parking_time_in_minutes + netto_parking_time_in_minutes;
|
||||||
|
dt = inputDate.addSecs(brutto_parking_time_in_minutes * 60);
|
||||||
|
weekDay = dt.date().dayOfWeek();
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << QString("ticket-end-time %1 (%2): brutto: %3 = netto: %4 + free: %5")
|
||||||
|
.arg(dt.toString(Qt::ISODate))
|
||||||
|
.arg(weekDay)
|
||||||
|
.arg(brutto_parking_time_in_minutes)
|
||||||
|
.arg(netto_parking_time_in_minutes)
|
||||||
|
.arg(free_parking_time_in_minutes);
|
||||||
|
|
||||||
|
if (successMaxPrice) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "SUCC" << dt;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::SUCCESS_MAXPRICE), dt);
|
||||||
|
}
|
||||||
|
if (overPaid) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "OVER" << dt;
|
||||||
|
return std::make_pair(CalcState(CalcState::State::OVERPAID), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "DT" << dt.toString(Qt::ISODate);
|
||||||
|
return std::make_pair(CalcState(CalcState::State::SUCCESS), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<CalcState, std::optional<int>>
|
||||||
|
Calculator::ComputeCostFromDuration(Configuration const* cfg, QDateTime const &startDatetime,
|
||||||
|
QDateTime &endDatetime, int nettoParkingTime) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
int paymentOptionIndex = 0;
|
||||||
|
|
||||||
|
std::optional<int> cost{};
|
||||||
|
|
||||||
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
|
||||||
|
int price = 0;
|
||||||
|
int durationId = 0;
|
||||||
|
int netto_parking_time_in_minutes = 0;
|
||||||
|
int brutto_parking_time_in_minutes = 0;
|
||||||
|
int free_parking_time_in_minutes = 0;
|
||||||
|
|
||||||
|
QMap<int, int> nettoParktimePrice;
|
||||||
|
QMap<int, int> priceNettoParktime;
|
||||||
|
|
||||||
|
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
|
||||||
|
durationId = itr->second.pra_payment_unit_id;
|
||||||
|
|
||||||
|
int const pra_price = itr->second.pra_price;
|
||||||
|
if (pop_accumulate_prices) {
|
||||||
|
price += pra_price;
|
||||||
|
} else {
|
||||||
|
price = pra_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto search = cfg->Duration.find(durationId);
|
||||||
|
if (search != cfg->Duration.end()) {
|
||||||
|
// found now the duration in minutes
|
||||||
|
// check if we are still inside the working-time-range
|
||||||
|
ATBDuration duration = search->second;
|
||||||
|
nettoParktimePrice.insert(duration.pun_duration, price);
|
||||||
|
priceNettoParktime.insert(price, duration.pun_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "START netto-parking-time" << nettoParkingTime;
|
||||||
|
CalcState returnState;
|
||||||
|
|
||||||
|
QList<int> keys = nettoParktimePrice.keys();
|
||||||
|
int index = keys.indexOf(nettoParkingTime);
|
||||||
|
if (index != -1) {
|
||||||
|
int c = nettoParktimePrice[keys.at(index)];
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "cost for netto-parking-time" << c;
|
||||||
|
|
||||||
|
std::pair<CalcState, QDateTime> r = ComputeDurationFromCost(cfg, startDatetime, c);
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "result"
|
||||||
|
<< r.first.toString() << r.second.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
|
||||||
|
returnState = r.first;
|
||||||
|
|
||||||
|
if (returnState.getStatus() == CalcState::State::SUCCESS ||
|
||||||
|
returnState.getStatus() == CalcState::State::SUCCESS_MAXPRICE) {
|
||||||
|
|
||||||
|
endDatetime = r.second;
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- endDateTime" << endDatetime.toString(Qt::ISODate);
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "------ r.second" << r.second.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
if (!endDatetime.isNull() && endDatetime.isValid()) {
|
||||||
|
cost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost) {
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- return cost" << cost.value();
|
||||||
|
return std::make_pair(returnState, cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << "--- return error for cost" << returnState.toString();
|
||||||
|
return std::make_pair(returnState, cost);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
std::pair<std::string, QDateTime>
|
std::pair<std::string, QDateTime>
|
||||||
Calculator::GetDurationFromCost(Configuration* cfg,
|
Calculator::GetDurationFromCost(Configuration* cfg,
|
||||||
@ -253,6 +679,17 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
qCritical() << DBG_HEADER << " TODO";
|
qCritical() << DBG_HEADER << " TODO";
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
if (paymentMethodId == PaymentMethod::Unified) {
|
||||||
|
std::pair<CalcState, QDateTime> r =
|
||||||
|
ComputeDurationFromCost(cfg, QDateTime::fromString(startDatetimePassed, Qt::ISODate), cost);
|
||||||
|
|
||||||
|
CalcState cs = r.first;
|
||||||
|
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << cs.toString();
|
||||||
|
qCritical() << __func__ << ":" << __LINE__ << r.second.toString(Qt::ISODate);
|
||||||
|
|
||||||
|
return std::make_pair(r.first.toString().toStdString(), r.second);
|
||||||
|
} else
|
||||||
if (paymentMethodId == PaymentMethod::Steps) {
|
if (paymentMethodId == PaymentMethod::Steps) {
|
||||||
if (tariffIs24_7(cfg)) {
|
if (tariffIs24_7(cfg)) {
|
||||||
// use tariff with structure as for instance Schoenau, Koenigsee:
|
// use tariff with structure as for instance Schoenau, Koenigsee:
|
||||||
@ -271,8 +708,11 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
|
|
||||||
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
|
||||||
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price;
|
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price;
|
||||||
|
//int const pop_max_time = cfg->getPaymentOptions(paymentOptionIndex).pop_max_time;
|
||||||
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
|
||||||
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
int const pop_allow_overpay = cfg->getPaymentOptions(paymentOptionIndex).pop_allow_overpay;
|
||||||
|
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
|
int price = 0;
|
||||||
|
|
||||||
if (cost == pop_max_price) {
|
if (cost == pop_max_price) {
|
||||||
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
qCritical() << DBG_HEADER << "SUCCESS MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
|
||||||
@ -410,9 +850,9 @@ Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate);
|
qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
// int const pop_accumulate_prices = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_prices;
|
||||||
// int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations;
|
// int const pop_accumulate_durations = cfg->getPaymentOptions(paymentOptionIndex).pop_accumulate_durations;
|
||||||
int price = 0;
|
// int price = 0;
|
||||||
int new_price = 0;
|
int new_price = 0;
|
||||||
int durationInSecs = 0;
|
int durationInSecs = 0;
|
||||||
uint32_t duration_previous = 0;
|
uint32_t duration_previous = 0;
|
||||||
@ -1203,7 +1643,7 @@ CalcState Calculator::isParkingAllowedForWeekDay(Configuration const *cfg,
|
|||||||
(int)cfg->TimeRange.count(pop_carry_over_end_time_range) <= 0) {
|
(int)cfg->TimeRange.count(pop_carry_over_end_time_range) <= 0) {
|
||||||
|
|
||||||
qCritical() << DBG_HEADER << "PARKING_ALLOWED. startTime" << startTime.toString(Qt::ISODate);
|
qCritical() << DBG_HEADER << "PARKING_ALLOWED. startTime" << startTime.toString(Qt::ISODate);
|
||||||
return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", startTime);
|
return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", startTime, QTime());
|
||||||
|
|
||||||
} else
|
} else
|
||||||
// search entry in time-range-field of tariff-file
|
// search entry in time-range-field of tariff-file
|
||||||
|
Loading…
Reference in New Issue
Block a user