GetCostFromDuration(): implement progressive tariff for Kirchdorf.
This commit is contained in:
parent
8470bdd574
commit
1d7779f666
@ -255,7 +255,7 @@ CalcState Calculator::isParkingAllowed(Configuration const *cfg, QDateTime const
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
double Calculator::GetCostFromDuration(Configuration* cfg,
|
double Calculator::GetCostFromDuration(Configuration* cfg,
|
||||||
uint8_t payment_option,
|
uint8_t payment_option,
|
||||||
const QDateTime start_datetime,
|
QDateTime &start_datetime,
|
||||||
QDateTime &end_datetime,
|
QDateTime &end_datetime,
|
||||||
int durationMinutes,
|
int durationMinutes,
|
||||||
bool nextDay,
|
bool nextDay,
|
||||||
@ -286,6 +286,179 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
|
|||||||
return 0;
|
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<int, ATBWeekDaysWorktime>::const_iterator;
|
||||||
|
std::pair<WTIterator, WTIterator> 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<int, ATBWeekDaysWorktime>::const_iterator;
|
||||||
|
std::pair<WTIterator, WTIterator> 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;
|
QDateTime start = start_datetime;
|
||||||
|
Loading…
Reference in New Issue
Block a user