From 7ac033720ef8d0d815502aa3291ab624a16f910d Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Sun, 26 Nov 2023 19:55:21 +0100 Subject: [PATCH] Started re-implementation of GetCostFromDuration() using private_GetCostFromDuration(). --- library/src/calculator_functions.cpp | 122 +++++++++++++++++---------- 1 file changed, 77 insertions(+), 45 deletions(-) diff --git a/library/src/calculator_functions.cpp b/library/src/calculator_functions.cpp index 763e8e0..abdb439 100644 --- a/library/src/calculator_functions.cpp +++ b/library/src/calculator_functions.cpp @@ -395,8 +395,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, QDateTime &end_datetime, int durationMinutes, bool nextDay, - bool prepaid) -{ + bool prepaid) { if (cfg->YearPeriod.size() == 0 && cfg->SpecialDays.size() == 0 && cfg->SpecialDaysWorktime.size() == 0) @@ -405,58 +404,91 @@ double Calculator::GetCostFromDuration(Configuration* cfg, return GetCostFromDuration(cfg, start_datetime, end_datetime); } - //Get min and max time defined in JSON - static int const minMin = std::max((int)cfg->PaymentOption.find(payment_option)->second.pop_min_time, 0); - static int const maxMin = std::max((int)cfg->PaymentOption.find(payment_option)->second.pop_max_time, 0); + return private_GetCostFromDuration(cfg, start_datetime, + end_datetime, durationMinutes, + nextDay, prepaid); +} - static const bool checkMinMaxMinutes = [](int minMin, int maxMin){ return (minMin < maxMin) ? true : false; }(minMin, maxMin); +int Calculator::getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_time, 0); +} + +int Calculator::getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId) { + return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_time, 0); +} + +bool Calculator::checkDurationMinutes(bool overtime, + int minParkingTime, + int maxParkingTime, + int durationMinutes) { + if (!overtime) { + if (durationMinutes > maxParkingTime) { + qWarning() << QString("Total duration >= max_min (%1 >= %2)").arg(durationMinutes).arg(maxParkingTime); + return false; + } + if (durationMinutes < minParkingTime) { + qWarning() << QString("Total duration <= minMin (%1 <= %2)").arg(durationMinutes).arg(minParkingTime); + return false; + } + } + return true; +} + +using namespace Utilities; + +uint32_t Calculator::private_GetCostFromDuration(Configuration const* cfg, + QDateTime const &start, + QDateTime &end, + int durationMinutes, + bool nextDay, + bool prepaid, + bool overtime) { + // TODO + static const PaymentMethod paymentMethodId = PaymentMethod::Linear; + + static int const minParkingTimeMinutes = getMinimalParkingTime(cfg, paymentMethodId); + static int const maxParkingTimeMinutes = getMaximalParkingTime(cfg, paymentMethodId); + + static bool const checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes); if (!checkMinMaxMinutes) { - qCritical() << QString("ERROR: CONDITION minMin < maxMin (%1 < %2) IS NOT VALID").arg(minMin).arg(maxMin); - return 0.0; + qCritical() << QString( + "ERROR: CONDITION minMin < maxMin (%1 < %2) IS NOT VALID") + .arg(minParkingTimeMinutes).arg(maxParkingTimeMinutes); + return 0; + } + + if (!checkDurationMinutes(overtime, minParkingTimeMinutes, + maxParkingTimeMinutes, durationMinutes)) { + return 0; } // Get input date - QDateTime inputDate = start_datetime; + QDateTime inputDate = start; // Get day of week int const weekdayId = inputDate.date().dayOfWeek(); - // weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year()); - // Check overtime - if (!overtime) { - if (durationMinutes > maxMin) { - qWarning() << QString("Total duration >= max_min (%1 >= %2)").arg(durationMinutes).arg(maxMin); - return maxMin; - } + uint32_t day_price = 0; + uint32_t price_per_unit = 0; - if (durationMinutes < minMin) { - qWarning() << QString("Total duration <= minMin (%1 <= %2)").arg(durationMinutes).arg(minMin); - return 0.0f; - } - } - - double day_price = 0.0; int current_special_day_id = -1; - double price_per_unit = 0.0f; int const timeRanges = std::max((int)cfg->WeekDaysWorktime.count(weekdayId), 1); QScopedArrayPointer worktime(new TariffTimeRange[timeRanges]); int index = 0; - if(Utilities::CheckSpecialDay(cfg, - inputDate.toString(Qt::ISODate).toStdString().c_str(), - ¤t_special_day_id, - &day_price)) { - // Set special day price - price_per_unit = Utilities::CalculatePricePerUnit(day_price); - worktime[index].setTimeRange(QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str()), - QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str())); + if(Utilities::CheckSpecialDay(cfg, inputDate, ¤t_special_day_id, &day_price)) { + // Set special day price: + // ACHTUNG: price_per_unit ist eigentlich immer preis pro minute !!! + price_per_unit = CalculatePricePerUnit(day_price); + worktime[index].setTimeRange(SpecialDaysWorkTimeFrom(cfg, current_special_day_id), + SpecialDaysWorkTimeUntil(cfg, current_special_day_id)); } else { // Set new price for the normal day - int pop_id = cfg->PaymentOption.find(payment_option)->second.pop_id; + int pop_id = cfg->PaymentOption.find(paymentMethodId)->second.pop_id; day_price = cfg->PaymentRate.find(pop_id)->second.pra_price; int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id; @@ -468,7 +500,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, // When no workday found, go to next available day qDebug() << "No workday found, trying to find next available day"; inputDate = inputDate.addDays(1); - return floor(GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMinutes, true, prepaid)); + return private_GetCostFromDuration(cfg, inputDate, end, durationMinutes, true, prepaid, overtime); } for (auto[itr, rangeEnd] = cfg->WeekDaysWorktime.equal_range(weekdayId); itr != rangeEnd; ++itr) { @@ -490,9 +522,9 @@ double Calculator::GetCostFromDuration(Configuration* cfg, if (price_per_unit == 0) { inputDate = inputDate.addDays(1); inputDate.setTime(worktime_from); - double const partialCost = GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMinutes, true, prepaid); - if (partialCost <= __DBL_MIN__) { - return 0.0; + uint32_t const partialCost = private_GetCostFromDuration(cfg, inputDate, end, durationMinutes, true, prepaid); + if (partialCost == 0) { + return 0; } costFromDuration += partialCost; continue; @@ -517,9 +549,9 @@ double Calculator::GetCostFromDuration(Configuration* cfg, } else if(inputDate.time() > worktime_to) { qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day"; inputDate = inputDate.addDays(1); - double const partialCost = GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMinutes, true, prepaid); - if (partialCost < __DBL_MIN__) { - return 0.0; + uint32_t const partialCost = private_GetCostFromDuration(cfg, inputDate, end, durationMinutes, true, prepaid); + if (partialCost == 0) { + return 0; } costFromDuration += partialCost; continue; @@ -545,7 +577,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, // Go to next day if minutes not spent if(inputDate.time() >= worktime_to) { // check for carry_over status - if (cfg->PaymentOption.find(payment_option)->second.pop_carry_over < 1) { + if (cfg->PaymentOption.find(paymentMethodId)->second.pop_carry_over < 1) { break; } @@ -553,9 +585,9 @@ double Calculator::GetCostFromDuration(Configuration* cfg, inputDate = inputDate.addDays(1); overtime = true; - double const partialCost = GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMinutes, false, false); - if (partialCost < __DBL_MIN__) { - return 0.0; + uint32_t const partialCost = private_GetCostFromDuration(cfg, inputDate, end, durationMinutes, true, prepaid, overtime); + if (partialCost == 0) { + return 0; } costFromDuration += partialCost; break; // stop while, and continue in outer loop @@ -570,7 +602,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, qDebug() << "GetCostFromDuration(): Valid until:" << inputDate.toString(Qt::ISODate); - end_datetime = inputDate; + end = inputDate; //double ret_val = total_cost; //total_cost = 0.0f;