diff --git a/library/src/calculator_functions.cpp b/library/src/calculator_functions.cpp index 5309bbc..0b085c4 100644 --- a/library/src/calculator_functions.cpp +++ b/library/src/calculator_functions.cpp @@ -615,8 +615,259 @@ uint32_t Calculator::GetCostFromDuration(Configuration * cfg, return 0; } +CalcState Calculator::isParkingAllowedForWeekDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { -CalcState Calculator::isParkingAllowed(Configuration const *cfg, QDateTime const &start) { + qCritical() << DBG_HEADER << "start" << start.toString(Qt::ISODate) + << "paymentOptionIndex" << paymentOptionIndex; + + QString errorStr = "UNKNOWN ERROR"; + + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + uint64_t const businessHours = cfg->getPaymentOptions(paymentOptionIndex).pop_business_hours; + if (cfg->isDayIncluded(businessHours, start)) { + if (businessHours == BusinessHours::NO_RESTRICTION_24_7) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + QTime(0, 0, 0), QTime(23, 59, 59)); + } + int const weekdayId = start.date().dayOfWeek(); + if (cfg->WeekDaysWorktime.count(weekdayId) > 0) { + using WTIterator = std::multimap::const_iterator; + std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId); + + for (WTIterator itr = p.first; itr != p.second; ++itr) { + QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr); + QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr); + + qCritical() << DBG_HEADER + << "CHECK IF PARKING IS ALLOWED IN TIME-RANGE (" + << from.toString(Qt::ISODate) << "->" << until.toString(Qt::ISODate) << ") ..."; + + QTime const &startTime = start.time(); + + if (startTime >= from && startTime <= until) { + QTime const endTime = start.addSecs(netto_parking_time*60).time(); + if (endTime <= until) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", from, until); + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(endTime.toString(Qt::ISODate)); + } + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)); + } + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + if (pop_carry_over == 1) { + qCritical() << DBG_HEADER + << "NO. CHECK IF PARKING IS ALLOWED WITH CARRY-OVER ..."; + + int const pop_carry_over_start_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_start_time_range; + int const pop_carry_over_end_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_end_time_range; + + if (cfg->TimeRange.count(pop_carry_over_start_time_range) == 1 && + cfg->TimeRange.count(pop_carry_over_end_time_range) == 1) { + + ATBTimeRange s = cfg->TimeRange.find(pop_carry_over_start_time_range)->second; + ATBTimeRange e = cfg->TimeRange.find(pop_carry_over_end_time_range)->second; + + if (startTime >= s.getTimeFrom() && startTime <= s.getTimeUntil()) { + QDateTime sd = start; + sd.setTime(s.getTimeUntil()); + + QDateTime ed = start.addDays(1); + ed.setTime(e.getTimeFrom()); + + int const jumpSecs = sd.secsTo(ed); + QDateTime const end = start.addSecs(netto_parking_time*60 + jumpSecs); + if (end.time() <= e.getTimeUntil()) { + + qCritical() << DBG_HEADER + << "PARKING IS ALLOWED WITH CARRY-OVER (" + << start.toString(Qt::ISODate) << "->" << ed.toString(Qt::ISODate) << ")"; + + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + startTime, end.time()); + } else { + errorStr = QString("endTime %1 exceeds [%2, %3))") + .arg(end.toString(Qt::ISODate)) + .arg(sd.toString(Qt::ISODate)) + .arg(ed.toString(Qt::ISODate)); + } + } else { + errorStr = QString("startTime %1 exceeds [%2, %3))") + .arg(startTime.toString(Qt::ISODate)) + .arg(s.getTimeFrom().toString(Qt::ISODate)) + .arg(s.getTimeUntil().toString(Qt::ISODate)); + } + } else { + errorStr = "no carry-over limits configured"; + } + } else { + errorStr = "no carry-over configured"; + } + } + } else { + errorStr = QString("no weekday configured for day-id %1").arg(weekdayId); + } + + } else { + errorStr = QString("start %1 not contained in business hours %2") + .arg(start.toString(Qt::ISODate)) + .arg(businessHours); + } + } + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, errorStr, + QTime(), QTime()); +} + + +CalcState Calculator::isParkingAllowedForSpecialDay(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { + QString errorStr = "UNKNOWN ERROR"; + + qCritical() << DBG_HEADER << "start" << start.toString(Qt::ISODate) + << "paymentOptionIndex" << paymentOptionIndex; + + PaymentMethod const paymentMethodId = Utilities::getPaymentMethodId(cfg); + if (paymentMethodId == PaymentMethod::Steps) { + //uint64_t const businessHours = cfg->getPaymentOptions(paymentOptionIndex).pop_business_hours; + int const specialDayId = cfg->specialDayId(start); + if ((specialDayId > 0) && (cfg->SpecialDaysWorktime.count(specialDayId) > 0)) { + using SDIterator = Configuration::SpecialDaysWorktimeType::const_iterator; + std::pair p = cfg->SpecialDaysWorktime.equal_range(specialDayId); + + for (SDIterator it = p.first; it != p.second; ++it) { + QTime const &from = Utilities::SpecialDaysWorkTimeFrom(it); + QTime const &until = Utilities::SpecialDaysWorkTimeUntil(it); + + qCritical() << DBG_HEADER + << "CHECK IF PARKING IS ALLOWED IN TIME-RANGE (" + << from.toString(Qt::ISODate) << "->" << until.toString(Qt::ISODate) << ") ..."; + + QTime const &startTime = start.time(); + + if (startTime >= from && startTime <= until) { + QTime const endTime = start.addSecs(netto_parking_time*60).time(); + if (endTime <= until) { + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", from, until); + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(endTime.toString(Qt::ISODate)); + } + } else { + errorStr = QString("%1 startTime not in range (%2 not in [%3, %4))") + .arg(__LINE__) + .arg(startTime.toString(Qt::ISODate)) + .arg(from.toString(Qt::ISODate)) + .arg(until.toString(Qt::ISODate)); + } + + int const pop_carry_over = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over; + if (pop_carry_over == 1) { + qCritical() << DBG_HEADER << "NO. CHECK IF PARKING IS ALLOWED WITH CARRY-OVER ..."; + + int const pop_carry_over_start_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_start_time_range; + int const pop_carry_over_end_time_range = cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over_end_time_range; + + if (cfg->TimeRange.count(pop_carry_over_start_time_range) == 1 && + cfg->TimeRange.count(pop_carry_over_end_time_range) == 1) { + + ATBTimeRange s = cfg->TimeRange.find(pop_carry_over_start_time_range)->second; + ATBTimeRange e = cfg->TimeRange.find(pop_carry_over_end_time_range)->second; + + if (startTime >= s.getTimeFrom() && startTime <= s.getTimeUntil()) { + QDateTime sd = start; + sd.setTime(s.getTimeUntil()); + + QDateTime ed = start.addDays(1); + ed.setTime(e.getTimeFrom()); + + int const jumpSecs = sd.secsTo(ed); + QDateTime const end = start.addSecs(netto_parking_time*60 + jumpSecs); + if (end.time() <= e.getTimeUntil()) { + + ed.setTime(e.getTimeUntil()); // for printing + + qCritical() << DBG_HEADER + << "PARKING IS ALLOWED WITH CARRY-OVER (" + << start.toString(Qt::ISODate) << "->" << ed.toString(Qt::ISODate) << ")"; + + return CalcState(CalcState::State::SUCCESS, "PARKING_ALLOWED", + startTime, end.time()); + } else { + ed.setTime(e.getTimeUntil()); // for printing + + errorStr = QString("endTime %1 exceeds [%2, %3))") + .arg(end.toString(Qt::ISODate)) + .arg(sd.toString(Qt::ISODate)) + .arg(ed.toString(Qt::ISODate)); + } + } else { + errorStr = QString("startTime %1 exceeds [%2, %3))") + .arg(startTime.toString(Qt::ISODate)) + .arg(s.getTimeFrom().toString(Qt::ISODate)) + .arg(s.getTimeUntil().toString(Qt::ISODate)); + } + } else { + errorStr = "no carry-over limits configured"; + } + } else { + errorStr = "no carry-over configured"; + } + } + } + } + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, errorStr, + QTime(), QTime()); +} + + +CalcState Calculator::isParkingAllowed(Configuration const *cfg, + QDateTime const &start, + int netto_parking_time, + int paymentOptionIndex) { + + qCritical() << DBG_HEADER << "CHECK IF PARKING IS ALLOWED AT" + << start.toString(Qt::ISODate) << "..."; + + CalcState cs; + + if ((cs = isParkingAllowedForWeekDay(cfg, start, netto_parking_time, paymentOptionIndex))) { + return cs; + } + + qCritical() << DBG_HEADER << QString(cs); + + if ((cs = isParkingAllowedForSpecialDay(cfg, start, netto_parking_time, paymentOptionIndex))) { + return cs; + } + + qCritical() << DBG_HEADER << QString(cs); + + return CalcState(CalcState::State::OUTSIDE_ALLOWED_PARKING_TIME, "UNKNOWN ERROR", + QTime(), QTime()); +} + +CalcState Calculator::isParkingAllowed(Configuration const *cfg, + QDateTime const &start) { static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg); if (paymentMethodId == PaymentMethod::Steps) {