diff --git a/library/src/calculator_functions.cpp b/library/src/calculator_functions.cpp
index 986dadf..1b7cb56 100644
--- a/library/src/calculator_functions.cpp
+++ b/library/src/calculator_functions.cpp
@@ -255,7 +255,7 @@ CalcState Calculator::isParkingAllowed(Configuration const *cfg, QDateTime const
///
double Calculator::GetCostFromDuration(Configuration* cfg,
uint8_t payment_option,
- const QDateTime start_datetime,
+ QDateTime &start_datetime,
QDateTime &end_datetime,
int durationMinutes,
bool nextDay,
@@ -286,6 +286,179 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
return 0;
}
}
+ } else
+ if (paymentMethodId == PaymentMethod::Progressive) {
+ // started with Neuhauser, Kirchdorf: merge into main algo. later
+ // for now try out some ideas
+
+ static const bool carryOverNotSet = Utilities::isCarryOverNotSet(cfg, paymentMethodId);
+ static const uint minParkingPrice = Utilities::getMinimalParkingPrice(cfg, paymentMethodId);
+
+ Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)");
+ Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)");
+
+ QDateTime start = start_datetime;
+
+ int weekdayId = -1;
+ int weekdayIdLast = -1;
+ int timeRanges = 0;
+ int durationMinutesBrutto = 0;
+
+ QDateTime current = start;
+
+ int days = 7;
+ while (--days > 0) {
+ weekdayId = current.date().dayOfWeek();
+ weekdayIdLast = weekdayId; // TODO: some end condition in json-file
+
+ while ((timeRanges = cfg->WeekDaysWorktime.count(weekdayId)) == 0) {
+ current = current.addDays(1);
+ weekdayId = current.date().dayOfWeek();
+ if (weekdayId == weekdayIdLast) {
+ qCritical() << "ERROR: NO VALID WORKDAY-TIMES DEFINED";
+ return 0;
+ }
+ }
+
+ using WTIterator = std::multimap::const_iterator;
+ std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId);
+
+ QTime to = QTime(0, 0, 0);
+ for (WTIterator itr = p.first; itr != p.second; ++itr) {
+ QTime const &t = Utilities::WeekDaysWorkTimeUntil(itr);
+
+ if (to < t) {
+ to = t;
+ }
+ }
+
+
+ if (current.time() >= to) {
+ QDateTime const dt = start;
+ start = start.addDays(1);
+ start.setTime(QTime(0, 0, 0));
+
+ durationMinutesBrutto += dt.secsTo(start) / 60;
+ current = start;
+ } else {
+ break;
+ }
+ }
+
+ int durationMinutesNetto = 0;
+ uint price = 0;
+
+ if (carryOverNotSet) {
+ int range = 0;
+ int minsToCarryOver = 0; // from one work-time to the other on the same day
+ QDateTime lastCurrent = QDateTime();
+
+ auto timeRangeIt = cfg->TimeRange.cbegin();
+ for (; timeRangeIt != cfg->TimeRange.cend(); ++timeRangeIt) {
+ using WTIterator = std::multimap::const_iterator;
+ std::pair p = cfg->WeekDaysWorktime.equal_range(weekdayId);
+
+ for (WTIterator itr = p.first; itr != p.second; ++itr) {
+ ++range;
+
+ QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr);
+ QTime const &to = Utilities::WeekDaysWorkTimeUntil(itr);
+
+ Q_ASSERT_X(from < to, __func__, "MISCONFIGURED WORK-TIMES");
+
+
+ if (current.time() >= to) {
+ continue; // try to use next available work-time
+ } else
+ if (current.time() <= from) {
+ if (prepaid) {
+ lastCurrent = current;
+ current.setTime(from); // move current forward (range==1),
+ // as prepaid is set
+ uint const minutesMoved = lastCurrent.secsTo(current) / 60;
+ durationMinutesBrutto += minutesMoved;
+
+ if (range == 1) {
+ start_datetime = current;
+ }
+ }
+ }
+
+ while (timeRangeIt != cfg->TimeRange.cend()) {
+ ATBTimeRange timeRange = timeRangeIt->second;
+
+ timeRange.computeQTimes(current.time());
+
+ int duration = timeRange.time_range_to_in_minutes_from_start -
+ timeRange.time_range_from_in_minutes_from_start;
+
+ if (current.addSecs(duration * 60).time() <= to) {
+
+ for(const auto &x: cfg->PaymentRate) {
+ ATBPaymentRate const rate = x.second;
+ if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) {
+ if (minsToCarryOver > 0) {
+ durationMinutes -= minsToCarryOver;
+ durationMinutesNetto += minsToCarryOver;
+ durationMinutesBrutto += minsToCarryOver;
+ current = current.addSecs(minsToCarryOver*60);
+ minsToCarryOver = 0;
+ } else {
+ price += (uint)rate.pra_price;
+
+ durationMinutes -= duration;
+ durationMinutesNetto += duration;
+ durationMinutesBrutto += duration;
+
+ current = current.addSecs(duration * 60);
+ }
+ break;
+ }
+ }
+
+ if (durationMinutes <= 0) {
+ end_datetime = current;
+ return price;
+ }
+
+ ++timeRangeIt;
+
+ } else {
+
+ lastCurrent = current;
+ current.setTime(to);
+ int const minsLeft = lastCurrent.secsTo(current) / 60;
+
+ // mod duration: possibly discard some minutes in
+ // the next time-range
+ minsToCarryOver = (durationMinutes - minsLeft) % duration;
+
+ durationMinutes -= minsLeft;
+ durationMinutesNetto += minsLeft;
+ durationMinutesBrutto += minsLeft;
+
+ if (minsLeft > 0) {
+ for(const auto &x: cfg->PaymentRate) {
+ ATBPaymentRate const rate = x.second;
+ if (rate.pra_payment_unit_id == timeRange.time_range_payment_type_id) {
+ price += (uint)rate.pra_price;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ end_datetime = start.addSecs(durationMinutesBrutto * 60);
+ return std::max(price, minParkingPrice);
+ }
+ }
+
+ end_datetime = QDateTime();
+ return 0;
}
QDateTime start = start_datetime;