checkin for the weekend. proper commit-messages later

This commit is contained in:
2024-02-16 13:37:24 +01:00
parent 1d7779f666
commit c0f0648a74
12 changed files with 3374 additions and 14 deletions

View File

@@ -115,8 +115,8 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
/// <inheritdoc/>
std::string Calculator::GetDurationFromCost(Configuration* cfg,
uint8_t payment_option,
char const* start_datetime, // given in local time
double price,
char const *start_datetime, // given in local time
double cost,
bool nextDay,
bool prepaid)
{
@@ -131,7 +131,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
if (tariffIs24_7(cfg)) {
// use tariff with structure as for instance Schoenau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime
inputDate = inputDate.addSecs(GetDurationForPrice(cfg, price) * 60);
inputDate = inputDate.addSecs(GetDurationForPrice(cfg, cost) * 60);
return inputDate.toString(Qt::ISODate).toStdString();
} else {
if (Utilities::IsYearPeriodActive(cfg, inputDate)) {
@@ -147,9 +147,282 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
return "";
}
}
} 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);
Q_ASSERT_X(carryOverNotSet, __func__, "CARRYOVER SET (FOR KIRCHDORF)");
Q_ASSERT_X(prepaid, __func__, "PREPAID NOT SET (FOR KIRCHDORF)");
QDateTime start = QDateTime::fromString(QString(start_datetime));
QDateTime end = QDateTime();
int weekdayId = -1;
int weekdayIdLast = -1;
int timeRanges = 0;
int durationMinutesBrutto = 0;
int durationMinutes = Utilities::getMaximalParkingPrice(cfg, paymentMethodId);
QDateTime current = QDateTime::fromString(QString(start_datetime), Qt::ISODate);
#define DEBUG 1
//#define DEBUG 0
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "current" << current.time().toString(Qt::ISODate)
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
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;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "start" << start.time().toString(Qt::ISODate)
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
current = start;
} else {
break;
}
}
int durationMinutesNetto = 0;
uint price = cost;
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 DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "lastCurrent" << lastCurrent.time().toString(Qt::ISODate)
<< "current" << current.time().toString(Qt::ISODate)
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
if (range == 1) {
// TODO
// 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 DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "duration" << duration
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
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;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "price" << price
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
} else {
price -= (uint)rate.pra_price;
durationMinutes -= duration;
durationMinutesNetto += duration;
durationMinutesBrutto += duration;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "price" << price
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
current = current.addSecs(duration * 60);
if (price <= 0) {
//end = start.addSecs(durationMinutesBrutto * 60);
end = current;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "durationMinutesBrutto" << durationMinutesBrutto
<< "price" << price
<< "current" << current.toString(Qt::ISODate)
<< "end" << end.toString(Qt::ISODate);
#endif
return end.toString(Qt::ISODate).toStdString();
}
}
break;
}
}
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< durationMinutes << durationMinutes;
#endif
if (durationMinutes <= 0) {
end = current;
return end.toString(Qt::ISODate).toStdString();
}
++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 DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "lastCurrent" << lastCurrent.time().toString(Qt::ISODate)
<< "current" << current.time().toString(Qt::ISODate)
<< "minsLeft" << minsLeft
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
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;
if (price <= 0) {
end = lastCurrent;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "lastCurrent" << lastCurrent.time().toString(Qt::ISODate)
<< "current" << current.time().toString(Qt::ISODate)
<< "price" << price
<< "end" << end.toString(Qt::ISODate);
#endif
// return end.toString(Qt::ISODate).toStdString();
break;
} else break;
}
}
}
break;
}
}
}
end = current;
#if DEBUG==1
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "end" << end.toString(Qt::ISODate)
<< "durationMinutes" << durationMinutes
<< "durationMinutesBrutto" << durationMinutesBrutto;
#endif
return end.toString(Qt::ISODate).toStdString();
}
}
end = QDateTime();
return end.toString(Qt::ISODate).toStdString();
}
Ticket t = private_GetDurationFromCost(cfg, inputDate, price, prepaid);
Ticket t = private_GetDurationFromCost(cfg, inputDate, cost, prepaid);
// qCritical().noquote() << t;
@@ -301,7 +574,6 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
int weekdayId = -1;
int weekdayIdLast = -1;
int timeRanges = 0;
int durationMinutesBrutto = 0;
QDateTime current = start;
@@ -311,7 +583,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
weekdayId = current.date().dayOfWeek();
weekdayIdLast = weekdayId; // TODO: some end condition in json-file
while ((timeRanges = cfg->WeekDaysWorktime.count(weekdayId)) == 0) {
while (cfg->WeekDaysWorktime.count(weekdayId) == 0) {
current = current.addDays(1);
weekdayId = current.date().dayOfWeek();
if (weekdayId == weekdayIdLast) {

File diff suppressed because it is too large Load Diff

View File

@@ -356,6 +356,8 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
this->currentPaymentOptions.last().pop_price_night = k->value.GetDouble();
} else if (strcmp(inner_obj_name, "pop_min_time") == 0) {
this->currentPaymentOptions.last().pop_min_time = k->value.GetDouble();
} else if (strcmp(inner_obj_name, "pop_max_price") == 0) {
this->currentPaymentOptions.last().pop_max_price = k->value.GetDouble();
} else if (strcmp(inner_obj_name, "pop_max_time") == 0) {
this->currentPaymentOptions.last().pop_max_time = k->value.GetDouble();
} else if (strcmp(inner_obj_name, "pop_min_price") == 0) {

View File

@@ -393,6 +393,10 @@ uint32_t Utilities::getMinimalParkingPrice(Configuration const *cfg, PaymentMeth
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_price, 0);
}
uint32_t Utilities::getMaximalParkingPrice(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_price, 0);
}
uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId) {
int const popId = cfg->PaymentOption.find(methodId)->second.pop_id;