Compare commits

..

5 Commits

Author SHA1 Message Date
102607b71f GetTimeSteps(): adapt for progressive tariff (e.g. neuhauser/kirchdorf).
Compute timesteps according to tariff01.json file.
2024-02-21 11:16:44 +01:00
81d515eb7f GetCostFromDuration(): set endtime to start in case cost==0. 2024-02-21 11:13:53 +01:00
ce61e5d3b2 compute_next_timestep(): use fpr PaymentMenthod::Progressive
same code as for PaymentMethod::Steps, as GetTimeSteps() inside
the Calculator class has been adapted accordingly.
2024-02-21 11:11:09 +01:00
b6a0f5e8af tests for neuhauser/kirchdorf 2024-02-21 11:08:49 +01:00
e0223b50f9 Added helper getTimeRangeStep() (useful for progressive tariff as for neuhauser/kirchdorf (743) 2024-02-21 09:31:13 +01:00
5 changed files with 73 additions and 53 deletions

View File

@ -90,6 +90,7 @@ namespace Utilities {
uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId); uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
uint32_t getMaximalParkingPrice(Configuration const *cfg, PaymentMethod methodId); uint32_t getMaximalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId); uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId);
uint32_t getTimeRangeStep(Configuration const *cfg, int step, PaymentMethod methodId);
BusinessHours getBusinessHours(Configuration const *cfg, PaymentMethod methodId); BusinessHours getBusinessHours(Configuration const *cfg, PaymentMethod methodId);
uint32_t computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id); uint32_t computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id);
double computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id); double computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id);

View File

@ -222,7 +222,9 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
// use tariff with structure as for instance Schnau, Koenigsee: // use tariff with structure as for instance Schnau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime // without given YearPeriod, SpecialDays and SpecialDaysWorktime
if (paymentMethodId == PaymentMethod::Steps) if ((paymentMethodId == PaymentMethod::Steps) ||
// progressive tariff: e.g. Neuhauser, Kirchdorf (743)
(paymentMethodId == PaymentMethod::Progressive))
{ {
const QList<int> stepList = Calculator::GetInstance().GetTimeSteps(tariff); const QList<int> stepList = Calculator::GetInstance().GetTimeSteps(tariff);
qCritical() << " compute_next_timestep() timeSteps:" << stepList; qCritical() << " compute_next_timestep() timeSteps:" << stepList;

View File

@ -548,6 +548,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
if (current.time() >= to) { if (current.time() >= to) {
if (carryOverNotSet) { if (carryOverNotSet) {
end_datetime = start;
return 0; return 0;
} else { } else {
QDateTime const dt = start; QDateTime const dt = start;
@ -583,7 +584,6 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES"); Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES");
if (current.time() >= to) { if (current.time() >= to) {
continue; // try to use next available work-time continue; // try to use next available work-time
} else } else
@ -1166,6 +1166,8 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
int const pop_carry_over = cfg->getPaymentOptions().pop_carry_over; int const pop_carry_over = cfg->getPaymentOptions().pop_carry_over;
int const pop_time_step_config = cfg->getPaymentOptions().pop_time_step_config; int const pop_time_step_config = cfg->getPaymentOptions().pop_time_step_config;
static PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg);
qCritical() << __func__ << ":" << __LINE__ << " start parking time:" << start.toString(Qt::ISODate); qCritical() << __func__ << ":" << __LINE__ << " start parking time:" << start.toString(Qt::ISODate);
qCritical() << __func__ << ":" << __LINE__ << " payment option id:" << pop_id; qCritical() << __func__ << ":" << __LINE__ << " payment option id:" << pop_id;
qCritical() << __func__ << ":" << __LINE__ << "payment option carry over:" << pop_carry_over; qCritical() << __func__ << ":" << __LINE__ << "payment option carry over:" << pop_carry_over;
@ -1173,63 +1175,71 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) { if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) {
//qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::DYNAMIC"; //qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::DYNAMIC";
uint16_t timeStepCompensation = 0; if (paymentMethodId == PaymentMethod::Progressive) { // e.g. neuhauser kirchdorf (743)
std::size_t const s = cfg->TimeRange.size();
for (std::size_t id = 1; id <= s; ++id) {
int const step = Utilities::getTimeRangeStep(cfg, id, paymentMethodId);
m_timeSteps.append(step);
}
} else {
uint16_t timeStepCompensation = 0;
if (pop_carry_over) { if (pop_carry_over) {
int const pop_carry_over_time_range_id = cfg->getPaymentOptions().pop_carry_over_time_range_id; int const pop_carry_over_time_range_id = cfg->getPaymentOptions().pop_carry_over_time_range_id;
QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from; QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from;
QTime const carryOverTimeRangeTo = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_to; QTime const carryOverTimeRangeTo = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_to;
if (carryOverTimeRangeFrom.secsTo(carryOverTimeRangeTo) <= 60) { // carry over time point, usually 00:00:00 if (carryOverTimeRangeFrom.secsTo(carryOverTimeRangeTo) <= 60) { // carry over time point, usually 00:00:00
if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { if (carryOverTimeRangeFrom == QTime(0, 0, 0)) {
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) { for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
int const durationId = itr->second.pra_payment_unit_id; int const durationId = itr->second.pra_payment_unit_id;
auto search = cfg->Duration.find(durationId); auto search = cfg->Duration.find(durationId);
if (search != cfg->Duration.end()) { if (search != cfg->Duration.end()) {
ATBDuration duration = search->second; ATBDuration duration = search->second;
if (durationId == 1) { if (durationId == 1) {
QDateTime carryOver = start; QDateTime carryOver = start;
carryOver = carryOver.addDays(1); carryOver = carryOver.addDays(1);
carryOver.setTime(QTime(0, 0, 0)); carryOver.setTime(QTime(0, 0, 0));
int const timeStep = std::ceil(start.secsTo(carryOver) / 60.0); int const timeStep = std::ceil(start.secsTo(carryOver) / 60.0);
if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) { if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) {
qCritical() qCritical()
<< QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)") << QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)")
.arg(timeStep).arg(duration.pun_duration_min) .arg(timeStep).arg(duration.pun_duration_min)
.arg(timeStep).arg(duration.pun_duration_max); .arg(timeStep).arg(duration.pun_duration_max);
break; break;
}
qCritical() << __PRETTY_FUNCTION__ << "configured minimal parking time:" << cfg->getPaymentOptions().pop_min_time;
// set dynamic minimal parking time
cfg->getPaymentOptions().pop_min_time = timeStep;
qCritical() << __PRETTY_FUNCTION__ << " computed minimal parking time:" << cfg->getPaymentOptions().pop_min_time;
duration.pun_duration = timeStep;
timeStepCompensation = duration.pun_duration_max - duration.pun_duration;
m_timeSteps << duration.pun_duration;
} else {
duration.pun_duration = duration.pun_duration_max - timeStepCompensation;
m_timeSteps << duration.pun_duration;;
} }
qCritical() << __PRETTY_FUNCTION__ << "configured minimal parking time:" << cfg->getPaymentOptions().pop_min_time;
// set dynamic minimal parking time cfg->Duration.erase(search);
cfg->getPaymentOptions().pop_min_time = timeStep; cfg->Duration.insert(pair<int, ATBDuration>(duration.pun_id, duration));
qCritical() << __PRETTY_FUNCTION__ << " computed minimal parking time:" << cfg->getPaymentOptions().pop_min_time; } else { // if (search != cfg->Duration.end()) {
// TODO
duration.pun_duration = timeStep;
timeStepCompensation = duration.pun_duration_max - duration.pun_duration;
m_timeSteps << duration.pun_duration;
} else {
duration.pun_duration = duration.pun_duration_max - timeStepCompensation;
m_timeSteps << duration.pun_duration;;
} }
cfg->Duration.erase(search);
cfg->Duration.insert(pair<int, ATBDuration>(duration.pun_id, duration));
} else { // if (search != cfg->Duration.end()) {
// TODO
} }
} else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) {
// TODO
} }
} else { // if (carryOverTimeRangeFrom == QTime(0, 0, 0)) { } else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) {
// TODO // TODO
} }
} else { // if (carryOverTimeRangeFrom == carryOverTimeRangeTo) { } else { // if (pop_carry_over) {
// TODO // TODO
} }
} else { // if (pop_carry_over) {
// TODO
} }
} else { } else {
qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::STATIC"; qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::STATIC";

View File

@ -397,6 +397,14 @@ uint32_t Utilities::getMaximalParkingPrice(Configuration const *cfg, PaymentMeth
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_price, 0); return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_price, 0);
} }
uint32_t Utilities::getTimeRangeStep(Configuration const *cfg, int step, PaymentMethod methodId) {
if (methodId == PaymentMethod::Progressive) {
return std::max((int)cfg->TimeRange.find(step)->second.time_range_to_in_minutes_from_start, 0);
}
return 0;
}
uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId) { uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId) {
int const popId = cfg->PaymentOption.find(methodId)->second.pop_id; int const popId = cfg->PaymentOption.find(methodId)->second.pop_id;

View File

@ -115,12 +115,12 @@ int main() {
bool prePaid = true; bool prePaid = true;
// bool carryOver = false; // bool carryOver = false;
QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime s(QDate(2024, 2, 21), QTime());
// QDateTime s(QDate(2023, 11, 26), QTime());
QDateTime end; QDateTime end;
for (int duration = 30; duration <= 90; duration += 5) { for (int duration = 30; duration <= 90; duration += 5) {
// for (int duration = 30; duration <= maxParkingTime; duration += 5) { // for (int duration = 30; duration <= maxParkingTime; duration += 5) {
qCritical() << ""; qCritical() << "";
//for (int offset = 420; offset <= 1080; ++offset) {
for (int offset = 420; offset <= 1080; ++offset) { for (int offset = 420; offset <= 1080; ++offset) {
//for (int offset = 420; offset <= 1080; ++offset) { //for (int offset = 420; offset <= 1080; ++offset) {
//if (offset > 720 && offset < 840) { //if (offset > 720 && offset < 840) {
@ -140,7 +140,6 @@ int main() {
duration_ist = duration_ist - 120; duration_ist = duration_ist - 120;
} }
qCritical() << "****" << offset << duration << "****"; qCritical() << "****" << offset << duration << "****";
qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate); qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate);
qCritical() << " start :" << start.toString(Qt::ISODate); qCritical() << " start :" << start.toString(Qt::ISODate);
@ -150,16 +149,16 @@ int main() {
qCritical() << " cost (soll):" << cost_soll; qCritical() << " cost (soll):" << cost_soll;
qCritical() << " cost (ist) :" << cost; qCritical() << " cost (ist) :" << cost;
if (cost_soll != cost) { // if (cost_soll != cost) {
//qCritical() << "ERROR" << __func__ << ":" << __LINE__ //qCritical() << "ERROR" << __func__ << ":" << __LINE__
// << "cost_soll" << cost_soll << "cost_ist" << cost; // << "cost_soll" << cost_soll << "cost_ist" << cost;
//break; //break;
} // }
if (duration != duration_ist) { // if (duration != duration_ist) {
//qCritical() << "ERROR" << __func__ << ":" << __LINE__ //qCritical() << "ERROR" << __func__ << ":" << __LINE__
// << "duration_soll" << duration << "duration_ist" << duration_ist; // << "duration_soll" << duration << "duration_ist" << duration_ist;
//break; //break;
} // }
//#else //#else
start = s.addSecs(offset * 60); start = s.addSecs(offset * 60);