Compare commits

...

9 Commits

5 changed files with 611 additions and 63 deletions

View File

@ -42,18 +42,34 @@ struct CALCULATE_LIBRARY_API price_t {
}; };
struct CALCULATE_LIBRARY_API CalcState { struct CALCULATE_LIBRARY_API CalcState {
static QString const SUCCESS;
static QString const ERROR_PARSING_ZONE_NR;
static QString const ERROR_LOADING_TARIFF;
static QString const ERROR_PARSING_TARIFF;
static QString const NEGATIVE_PARKING_TIME;
static QString const INVALID_START_DATE;
static QString const WRONG_PARAM_VALUES;
static QString const WRONG_ISO_TIME_FORMAT;
static QString const ABOVE_MAX_PARKING_TIME;
static QString const BELOW_MIN_PARKING_TIME;
static QString const BELOW_MIN_PARKING_PRICE;
static QString const ABOVE_MAX_PARKING_PRICE;
static QString const OVERPAID;
static QString const OUTSIDE_ALLOWED_PARKING_TIME;
enum class State : uint8_t { enum class State : uint8_t {
SUCCESS, SUCCESS,
ERROR_PARSING_ZONE_NR, ERROR_PARSING_ZONE_NR,
ERROR_LOADING_TARIFF, ERROR_LOADING_TARIFF,
ERROR_PARSING_TARIFF, ERROR_PARSING_TARIFF,
NEGATIVE_PARING_TIME, NEGATIVE_PARKING_TIME,
INVALID_START_DATE, INVALID_START_DATE,
WRONG_PARAM_VALUES, WRONG_PARAM_VALUES,
WRONG_ISO_TIME_FORMAT, WRONG_ISO_TIME_FORMAT,
ABOVE_MAX_PARKING_TIME, ABOVE_MAX_PARKING_TIME,
BELOW_MIN_PARKING_TIME, BELOW_MIN_PARKING_TIME,
BELOW_MIN_PARKING_PRICE, BELOW_MIN_PARKING_PRICE,
ABOVE_MAX_PARKING_PRICE,
OVERPAID, OVERPAID,
OUTSIDE_ALLOWED_PARKING_TIME OUTSIDE_ALLOWED_PARKING_TIME
}; };
@ -88,43 +104,47 @@ struct CALCULATE_LIBRARY_API CalcState {
QString s; QString s;
switch (m_status) { switch (m_status) {
case State::SUCCESS: case State::SUCCESS:
s = "SUCCESS"; s = CalcState::SUCCESS;
break; break;
case State::ERROR_PARSING_ZONE_NR: case State::ERROR_PARSING_ZONE_NR:
s = "ERROR_PARSING_ZONE_NR"; s = CalcState::ERROR_PARSING_ZONE_NR;
break; break;
case State::ERROR_LOADING_TARIFF: case State::ERROR_LOADING_TARIFF:
s = "ERROR_LOADING_TARIFF"; s = CalcState::ERROR_LOADING_TARIFF;
break; break;
case State::ERROR_PARSING_TARIFF: case State::ERROR_PARSING_TARIFF:
s = "ERROR_PARSING_TARIFF"; s = CalcState::ERROR_PARSING_TARIFF;
break; break;
case State::NEGATIVE_PARING_TIME: case State::NEGATIVE_PARKING_TIME:
s = "NEGATIVE_PARKING_TIME"; s = CalcState::NEGATIVE_PARKING_TIME;
break; break;
case State::ABOVE_MAX_PARKING_TIME: case State::ABOVE_MAX_PARKING_TIME:
s = "ABOVE_MAX_PARKING_TIME"; s = CalcState::ABOVE_MAX_PARKING_TIME;
break; break;
case State::WRONG_PARAM_VALUES: case State::WRONG_PARAM_VALUES:
s = "WRONG_PARAM_VALUES"; s = CalcState::WRONG_PARAM_VALUES;
break; break;
case State::BELOW_MIN_PARKING_TIME: case State::BELOW_MIN_PARKING_TIME:
s = "BELOW_MIN_PARKING_TIME"; s = CalcState::BELOW_MIN_PARKING_TIME;
break; break;
case State::BELOW_MIN_PARKING_PRICE: case State::BELOW_MIN_PARKING_PRICE:
s = "BELOW_MIN_PARKING_PRICE"; s = CalcState::BELOW_MIN_PARKING_PRICE;
break; break;
case State::OVERPAID: case State::OVERPAID:
s = "OVERPAID"; s = CalcState::OVERPAID;
break; break;
case State::INVALID_START_DATE: case State::INVALID_START_DATE:
s = "INVALID_START_DATE"; s = CalcState::INVALID_START_DATE;
break; break;
case State::WRONG_ISO_TIME_FORMAT: case State::WRONG_ISO_TIME_FORMAT:
s = "WRONG_ISO_TIME_FORMAT"; s = CalcState::WRONG_ISO_TIME_FORMAT;
break; break;
case State::OUTSIDE_ALLOWED_PARKING_TIME: case State::OUTSIDE_ALLOWED_PARKING_TIME:
s = "OUTSIDE_ALLOWED_PARKING_TIME"; s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_PRICE:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
} }
return s + ":" + m_desc; return s + ":" + m_desc;
} }
@ -133,51 +153,101 @@ struct CALCULATE_LIBRARY_API CalcState {
QString s; QString s;
switch (m_status) { switch (m_status) {
case State::SUCCESS: case State::SUCCESS:
s = "SUCCESS"; s = CalcState::SUCCESS;
break; break;
case State::ERROR_PARSING_ZONE_NR: case State::ERROR_PARSING_ZONE_NR:
s = "ERROR_PARSING_ZONE_NR"; s = CalcState::ERROR_PARSING_ZONE_NR;
break; break;
case State::ERROR_LOADING_TARIFF: case State::ERROR_LOADING_TARIFF:
s = "ERROR_LOADING_TARIFF"; s = CalcState::ERROR_LOADING_TARIFF;
break; break;
case State::ERROR_PARSING_TARIFF: case State::ERROR_PARSING_TARIFF:
s = "ERROR_PARSING_TARIFF"; s = CalcState::ERROR_PARSING_TARIFF;
break; break;
case State::NEGATIVE_PARING_TIME: case State::NEGATIVE_PARKING_TIME:
s = "NEGATIVE_PARKING_TIME"; s = CalcState::NEGATIVE_PARKING_TIME;
break; break;
case State::ABOVE_MAX_PARKING_TIME: case State::ABOVE_MAX_PARKING_TIME:
s = "ABOVE_MAX_PARKING_TIME"; s = CalcState::ABOVE_MAX_PARKING_TIME;
break; break;
case State::WRONG_PARAM_VALUES: case State::WRONG_PARAM_VALUES:
s = "WRONG_PARAM_VALUES"; s = CalcState::WRONG_PARAM_VALUES;
break; break;
case State::BELOW_MIN_PARKING_TIME: case State::BELOW_MIN_PARKING_TIME:
s = "BELOW_MIN_PARKING_TIME"; s = CalcState::BELOW_MIN_PARKING_TIME;
break; break;
case State::BELOW_MIN_PARKING_PRICE: case State::BELOW_MIN_PARKING_PRICE:
s = "BELOW_MIN_PARKING_PRICE"; s = CalcState::BELOW_MIN_PARKING_PRICE;
break; break;
case State::OVERPAID: case State::OVERPAID:
s = "OVERPAID"; s = CalcState::OVERPAID;
break; break;
case State::INVALID_START_DATE: case State::INVALID_START_DATE:
s = "INVALID_START_DATE"; s = CalcState::INVALID_START_DATE;
break; break;
case State::WRONG_ISO_TIME_FORMAT: case State::WRONG_ISO_TIME_FORMAT:
s = "WRONG_ISO_TIME_FORMAT"; s = CalcState::WRONG_ISO_TIME_FORMAT;
break; break;
case State::OUTSIDE_ALLOWED_PARKING_TIME: case State::OUTSIDE_ALLOWED_PARKING_TIME:
s = "OUTSIDE_ALLOWED_PARKING_TIME"; s = CalcState::OUTSIDE_ALLOWED_PARKING_TIME;
break;
case State::ABOVE_MAX_PARKING_PRICE:
s = CalcState::ABOVE_MAX_PARKING_TIME;
break;
} }
return s + ":" + m_desc; return s + ":" + m_desc;
} }
CalcState &set(State s) { m_status = s; return *this; } CalcState &set(State s) { m_status = s; return *this; }
CalcState &setStatus(State s) { return set(s); } CalcState &setStatus(State s) { return set(s); }
CalcState &setStatus(QString const &desc) {
if (desc == SUCCESS) {
m_status = State::SUCCESS;
} else
if (desc == ERROR_PARSING_ZONE_NR) {
m_status = State::ERROR_PARSING_ZONE_NR;
} else
if (desc == ERROR_LOADING_TARIFF) {
m_status = State::SUCCESS;
} else
if (desc == ERROR_PARSING_TARIFF) {
m_status = State::ERROR_LOADING_TARIFF;
} else
if (desc == NEGATIVE_PARKING_TIME) {
m_status = State::NEGATIVE_PARKING_TIME;
} else
if (desc == INVALID_START_DATE) {
m_status = State::INVALID_START_DATE;
} else
if (desc == WRONG_PARAM_VALUES) {
m_status = State::WRONG_PARAM_VALUES;
} else
if (desc == WRONG_ISO_TIME_FORMAT) {
m_status = State::WRONG_ISO_TIME_FORMAT;
} else
if (desc == ABOVE_MAX_PARKING_TIME) {
m_status = State::ABOVE_MAX_PARKING_TIME;
} else
if (desc == BELOW_MIN_PARKING_TIME) {
m_status = State::BELOW_MIN_PARKING_TIME;
} else
if (desc == BELOW_MIN_PARKING_PRICE) {
m_status = State::BELOW_MIN_PARKING_PRICE;
} else
if (desc == OVERPAID) {
m_status = State::OVERPAID;
} else
if (desc == OUTSIDE_ALLOWED_PARKING_TIME) {
m_status = State::OUTSIDE_ALLOWED_PARKING_TIME;
} else
if (desc == ABOVE_MAX_PARKING_PRICE) {
m_status = State::ABOVE_MAX_PARKING_PRICE;
}
return *this;
}
State getStatus() const { return m_status; } State getStatus() const { return m_status; }
CalcState &setDesc(QString s) { m_desc = s; return *this; } CalcState &setDesc(QString const &s) { m_desc = s; return *this; }
void setAllowedTimeRange(QTime const &from, QTime const &until) { void setAllowedTimeRange(QTime const &from, QTime const &until) {
m_allowedTimeRange.setTimeRange(from, until); m_allowedTimeRange.setTimeRange(from, until);

View File

@ -8,27 +8,28 @@
#include <Qt> #include <Qt>
#define _NO_RESTRICTION_24_7_ (uint64_t)(0ULL) #define _NO_RESTRICTION_24_7_ (uint64_t)(0ULL)
#define _MON_ (uint64_t)(1ULL << 8) #define _MON_ (uint64_t)(1ULL << 8)
#define _TUE_ (uint64_t)(1ULL << 9) #define _TUE_ (uint64_t)(1ULL << 9)
#define _WED_ (uint64_t)(1ULL << 10) #define _WED_ (uint64_t)(1ULL << 10)
#define _THU_ (uint64_t)(1ULL << 11) #define _THU_ (uint64_t)(1ULL << 11)
#define _FRI_ (uint64_t)(1ULL << 12) #define _FRI_ (uint64_t)(1ULL << 12)
#define _SAT_ (uint64_t)(1ULL << 13) #define _SAT_ (uint64_t)(1ULL << 13)
#define _SUN_ (uint64_t)(1ULL << 14) #define _SUN_ (uint64_t)(1ULL << 14)
#define _WEEK_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_)) #define _WEEK_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_))
#define _WORKING_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_)) #define _WORKING_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_))
#define _ALL_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_|_SUN_)) #define _ALL_DAYS_ ((_MON_|_TUE_|_WED_|_THU_|_FRI_|_SAT_|_SUN_))
#define _OFFICIAL_HOLIDAY_ (uint64_t)(1ULL << 15) #define _OFFICIAL_HOLIDAY_ (uint64_t)(1ULL << 15)
#define _ONLY_WEEKEND_ ((_SAT_|_SUN_)) #define _ONLY_WEEKEND_ ((_SAT_|_SUN_))
#define _ONLY_OPEN_FOR_BUSINESS_DAYS_ (uint64_t)(1ULL << 16) /* verkaufsoffen */ #define _ONLY_OPEN_FOR_BUSINESS_DAYS_ (uint64_t)(1ULL << 16) /* verkaufsoffen */
#define _WITH_RESTRICTED_HOURS_ (uint64_t)(1ULL << 17) #define _WITH_RESTRICTED_HOURS_ (uint64_t)(1ULL << 17)
#define _ALL_DAYS_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_ALL_DAYS_)) #define _ALL_DAYS_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_ALL_DAYS_))
#define _WEEKEND_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_|_SAT_|_SUN_)) #define _WEEKEND_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_|_SAT_|_SUN_))
#define _FRI_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_)) #define _WORKING_DAYS_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_WORKING_DAYS_))
#define _SAT_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SAT_)) #define _FRI_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_FRI_))
#define _SUN_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SUN_)) #define _SAT_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SAT_))
#define _NOT_DEFINED_ (uint64_t)(~0ULL) #define _SUN_WITH_RESTRICTED_HOURS_ ((_WITH_RESTRICTED_HOURS_|_SUN_))
#define _NOT_DEFINED_ (uint64_t)(~0ULL)
enum BusinessHours : std::uint64_t enum BusinessHours : std::uint64_t
{ {
@ -62,6 +63,7 @@ enum BusinessHours : std::uint64_t
ONLY_OPEN_FOR_BUSINESS_DAYS = _ONLY_OPEN_FOR_BUSINESS_DAYS_, ONLY_OPEN_FOR_BUSINESS_DAYS = _ONLY_OPEN_FOR_BUSINESS_DAYS_,
ALL_DAYS_WITH_RESTRICTED_HOURS = _ALL_DAYS_WITH_RESTRICTED_HOURS_, ALL_DAYS_WITH_RESTRICTED_HOURS = _ALL_DAYS_WITH_RESTRICTED_HOURS_,
WEEKEND_WITH_RESTRICTED_HOURS = _WEEKEND_WITH_RESTRICTED_HOURS_, WEEKEND_WITH_RESTRICTED_HOURS = _WEEKEND_WITH_RESTRICTED_HOURS_,
WORKING_DAYS_WITH_RESTRICTED_HOURS = _WORKING_DAYS_WITH_RESTRICTED_HOURS_,
FRI_WITH_RESTRICTED_HOURS = _FRI_WITH_RESTRICTED_HOURS_, FRI_WITH_RESTRICTED_HOURS = _FRI_WITH_RESTRICTED_HOURS_,
SAT_WITH_RESTRICTED_HOURS = _SAT_WITH_RESTRICTED_HOURS_, SAT_WITH_RESTRICTED_HOURS = _SAT_WITH_RESTRICTED_HOURS_,
SUN_WITH_RESTRICTED_HOURS = _SUN_WITH_RESTRICTED_HOURS_, SUN_WITH_RESTRICTED_HOURS = _SUN_WITH_RESTRICTED_HOURS_,

View File

@ -10,6 +10,21 @@
#include <QDebug> #include <QDebug>
#include <QList> #include <QList>
QString const CalcState::SUCCESS = "SUCCESS";
QString const CalcState::ERROR_PARSING_ZONE_NR = "ERROR_PARSING_ZONE_NR";
QString const CalcState::ERROR_LOADING_TARIFF = "ERROR_LOADING_TARIFF";
QString const CalcState::ERROR_PARSING_TARIFF = "ERROR_PARSING_TARIFF";
QString const CalcState::NEGATIVE_PARKING_TIME = "NEGATIVE_PARKING_TIME";
QString const CalcState::INVALID_START_DATE = "INVALID_START_DATE";
QString const CalcState::WRONG_PARAM_VALUES = "WRONG_PARAM_VALUES";
QString const CalcState::WRONG_ISO_TIME_FORMAT = "WRONG_ISO_TIME_FORMAT";
QString const CalcState::ABOVE_MAX_PARKING_TIME = "ABOVE_MAX_PARKING_TIME";
QString const CalcState::BELOW_MIN_PARKING_TIME = "BELOW_MIN_PARKING_TIME";
QString const CalcState::BELOW_MIN_PARKING_PRICE = "BELOW_MIN_PARKING_PRICE";
QString const CalcState::ABOVE_MAX_PARKING_PRICE = "ABOVE_MAX_PARKING_PRICE";
QString const CalcState::OVERPAID = "OVERPAID";
QString const CalcState::OUTSIDE_ALLOWED_PARKING_TIME = "OUTSIDE_ALLOWED_PARKING_TIME";
QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) { QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) {
return Calculator::GetInstance().GetTimeSteps(cfg); return Calculator::GetInstance().GetTimeSteps(cfg);
} }
@ -438,7 +453,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
if (duration < 0) { if (duration < 0) {
calcState.setDesc(QString("end=%1, start=%2") calcState.setDesc(QString("end=%1, start=%2")
.arg(end_parking_time, start_parking_time)); .arg(end_parking_time, start_parking_time));
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME);
} }
if (duration > maxMin) { if (duration > maxMin) {
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin)); calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration).arg(maxMin));
@ -506,7 +521,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
calcState.setDesc(QString("end=%1, start=%2") calcState.setDesc(QString("end=%1, start=%2")
.arg(end_parking_time.toString(Qt::ISODate), .arg(end_parking_time.toString(Qt::ISODate),
start_parking_time.toString(Qt::ISODate))); start_parking_time.toString(Qt::ISODate)));
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); return calcState.set(CalcState::State::NEGATIVE_PARKING_TIME);
} }
if (netto_parking_time > maxMin) { if (netto_parking_time > maxMin) {
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin));
@ -615,16 +630,76 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
price, false, true).c_str(); price, false, true).c_str();
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
// DEBUG if (endTime == CalcState::SUCCESS) {
qCritical() << "compute_duration_for_parking_ticket(): "; calcState.setDesc(QString("SUCCESS"));
qCritical() << " endTime: " << endTime; calcState.setStatus(endTime);
qCritical() << " ticketEndTime: " << ticketEndTime; } else
if (endTime == CalcState::ERROR_PARSING_ZONE_NR) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::ERROR_LOADING_TARIFF) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::ERROR_PARSING_TARIFF) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::NEGATIVE_PARKING_TIME) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::INVALID_START_DATE) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::WRONG_PARAM_VALUES) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::WRONG_ISO_TIME_FORMAT) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::ABOVE_MAX_PARKING_TIME) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::BELOW_MIN_PARKING_TIME) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::BELOW_MIN_PARKING_PRICE) {
calcState.setStatus(endTime);
return calcState;
} else
if (endTime == CalcState::ABOVE_MAX_PARKING_PRICE) {
calcState.setDesc(CalcState::ABOVE_MAX_PARKING_PRICE);
calcState.setStatus(CalcState::ABOVE_MAX_PARKING_PRICE);
return calcState;
} else
if (endTime == CalcState::OVERPAID) {
calcState.setDesc(CalcState::OVERPAID);
calcState.setStatus(CalcState::OVERPAID);
return calcState;
} else
if (endTime == CalcState::OUTSIDE_ALLOWED_PARKING_TIME) {
calcState.setStatus(endTime);
return calcState;
} else {
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
if (!ticketEndTime.isValid()) { // DEBUG
calcState.setDesc(QString("ticketEndTime=%1").arg(endTime)); //qCritical() << "compute_duration_for_parking_ticket(): ";
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); //qCritical() << " endTime: " << endTime;
//qCritical() << " ticketEndTime: " << ticketEndTime;
if (!ticketEndTime.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(endTime));
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
}
} }
} else { } else {
return calcState.set(CalcState::State::INVALID_START_DATE); return calcState.set(CalcState::State::INVALID_START_DATE);

View File

@ -144,7 +144,228 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
} }
} }
qCritical() << __func__ << ":" << __LINE__ << "NOT YET IMPLEMENTED"; // TODO: man braucht den richtigen Index
int paymentOptionIndex = 0;
int const pop_id = cfg->getPaymentOptions(paymentOptionIndex).pop_id;
int const pop_max_price = cfg->getPaymentOptions(paymentOptionIndex).pop_max_price;
int const pop_min_price = cfg->getPaymentOptions(paymentOptionIndex).pop_min_price;
if (cost > pop_max_price) {
qCritical() << DBG_HEADER << "MAX-PARKING-PRICE" << pop_max_price << ", COST" << cost;
return CalcState::OVERPAID.toStdString();
}
if (cost < pop_min_price) {
qCritical() << DBG_HEADER << "MIN-PARKING-PRICE" << pop_min_price << ", COST" << cost;
return CalcState::BELOW_MIN_PARKING_PRICE.toStdString();
}
// int const pop_pre_paid = 1;
if (prepaid) {
// no limits on pre-pay-option, i.e. pre-pay-ranges are exactly
// the complements of operational-ranges
// find out if we are in a pre-pay-range.
// in this case, adapt inputDate accordingly.
// #define DEBUG_GET_DURATION_FROM_COST 1
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "PRE-PAID-OPTION: ADAPT-INPUT-DATE" << inputDate.toString(Qt::ISODate);
#endif
QTime currentTime = inputDate.time();
int pwd_period_day_in_week_id = inputDate.date().dayOfWeek();
bool useWeekDaysWorkTimeOfOtherDay = true;
for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_day_in_week_id); iter != rEnd; ++iter) {
QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate);
QTime pwd_time_to = QTime::fromString(QString::fromStdString(iter->second.pwd_time_to), Qt::ISODate);
if (inputDate.time() < pwd_time_from) {
inputDate.setTime(pwd_time_from);
useWeekDaysWorkTimeOfOtherDay = false;
break;
}
if (currentTime <= pwd_time_to) {
useWeekDaysWorkTimeOfOtherDay = false;
break;
}
}
if (useWeekDaysWorkTimeOfOtherDay) {// for the current day, we are above
// the latest worktime-range -> find the next valid range
QTime pwd_time_from_next_valid_range(0, 0, 0);
int pwd_period_next_day_in_week_id = pwd_period_day_in_week_id;
for (int days = 1; days < 8; ++days) {
pwd_period_next_day_in_week_id += 1;
if (pwd_period_next_day_in_week_id > (int)Qt::Sunday) {
pwd_period_next_day_in_week_id = Qt::Monday;
}
if (cfg->WeekDaysWorktime.count(pwd_period_next_day_in_week_id) > 0) {
for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_next_day_in_week_id); iter != rEnd; ++iter) {
QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate);
if (pwd_time_from_next_valid_range < pwd_time_from) {
pwd_time_from_next_valid_range = pwd_time_from;
break;
}
}
inputDate = inputDate.addDays(days);
inputDate.setTime(pwd_time_from_next_valid_range);
break;
}
}
}
}
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "(ADAPTED) INPUT-DATE" << inputDate.toString(Qt::ISODate);
#endif
// inputDate is now located in a valid operational-working-range
// find this working-time-range
int pwd_period_day_in_week_id = inputDate.date().dayOfWeek();
if (cfg->WeekDaysWorktime.count(pwd_period_day_in_week_id) == 0) {
qCritical() << DBG_HEADER
<< "ERROR" << inputDate.toString(Qt::ISODate)
<< "NOT IN VALID WORKING TIME-RANGE";
return "";
}
QTime current_working_time_from;
QTime current_working_time_to;
for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(pwd_period_day_in_week_id); iter != rEnd; ++iter) {
QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate);
QTime pwd_time_to = QTime::fromString(QString::fromStdString(iter->second.pwd_time_to), Qt::ISODate);
if (pwd_time_from <= inputDate.time() && inputDate.time() <= pwd_time_to) {
current_working_time_from = pwd_time_from;
current_working_time_to = pwd_time_to;
}
}
if (current_working_time_from.isNull() || current_working_time_to.isNull()) {
// can never happen
qCritical() << DBG_HEADER
<< "ERROR" << inputDate.toString(Qt::ISODate)
<< "NOT IN VALID WORKING TIME-RANGE";
return "";
}
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "CURRENT WORKING-TIME-FROM" << current_working_time_from.toString(Qt::ISODate);
qCritical() << DBG_HEADER << " CURRENT WORKING-TIME-TO" << current_working_time_to.toString(Qt::ISODate);
#endif
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) {
int const pra_price = itr->second.pra_price;
if ((double)pra_price == cost) {
int const durationId = itr->second.pra_payment_unit_id;
auto search = cfg->Duration.find(durationId);
if (search != cfg->Duration.end()) {
// found now the duration in minutes
// check if we are still inside the working-time-range
ATBDuration duration = search->second;
int durationInSecs = duration.pun_duration * 60;
QDateTime current_working_date_time_to = inputDate;
current_working_date_time_to.setTime(current_working_time_to);
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "DURATION IN MINUTES" << duration.pun_duration;
qCritical() << DBG_HEADER << "DURATION IN SECONDS" << duration.pun_duration * 60;
qCritical() << DBG_HEADER << "CURRENT-WORKING-DATE-TIME-TO"
<< current_working_date_time_to.toString(Qt::ISODate);
qCritical() << DBG_HEADER << "NEW INPUT DATE" << inputDate.addSecs(durationInSecs).toString(Qt::ISODate);
#endif
if (inputDate.addSecs(durationInSecs) > current_working_date_time_to) {
QTime next_working_time_from;
if (cfg->getPaymentOptions(paymentOptionIndex).pop_carry_over != 0) {
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "CARRY-OVER SET";
#endif
// check for next working-time-range on same day
int day_in_week_id = inputDate.date().dayOfWeek();
for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(day_in_week_id); iter != rEnd; ++iter) {
QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate);
if (pwd_time_from > current_working_time_to) {
next_working_time_from = pwd_time_from;
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "NEXT-WORKING-TIME-FROM"
<< next_working_time_from.toString(Qt::ISODate);
#endif
break;
}
}
// check for next working-time-range on following day(s)
if (next_working_time_from.isNull()) {
next_working_time_from = QTime(0, 0, 0);
for (int days = 1; days < 8; ++days) {
day_in_week_id += 1;
if (day_in_week_id > (int)Qt::Sunday) {
day_in_week_id = Qt::Monday;
}
if (cfg->WeekDaysWorktime.count(day_in_week_id) > 0) {
for (auto[iter, rEnd] = cfg->WeekDaysWorktime.equal_range(day_in_week_id); iter != rEnd; ++iter) {
QTime pwd_time_from = QTime::fromString(QString::fromStdString(iter->second.pwd_time_from), Qt::ISODate);
if (next_working_time_from < pwd_time_from) {
next_working_time_from = pwd_time_from;
break;
}
}
QDateTime upper = inputDate.addDays(days);
upper.setTime(next_working_time_from);
QDateTime lower = inputDate;
lower.setTime(current_working_time_to);
inputDate = inputDate.addSecs(lower.secsTo(upper) + durationInSecs);
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate);
#endif
break;
}
} // for (int days = 1; days < 8; ++days) {
} else { // next working-time is on same day
QDateTime upper = inputDate;
upper.setTime(next_working_time_from);
QDateTime lower = inputDate;
lower.setTime(current_working_time_to);
inputDate = inputDate.addSecs(lower.secsTo(upper) + durationInSecs);
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "TICKET-END" << inputDate.toString(Qt::ISODate);
#endif
}
}
} else {
inputDate = inputDate.addSecs(duration.pun_duration * 60);
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "INPUT-DATE" << inputDate.toString(Qt::ISODate);
#endif
}
QString const &s = inputDate.toString(Qt::ISODate);
#if DEBUG_GET_DURATION_FROM_COST==1
qCritical() << DBG_HEADER << "TICKET-END" << s;
#endif
return s.toStdString();
}
}
}
return ""; return "";
} }
} }

View File

@ -36,7 +36,7 @@ extern "C" char* strptime(const char* s,
#include "calculator_functions.h" #include "calculator_functions.h"
#include "calculate_price.h" #include "calculate_price.h"
#define SZEGED (1) #define SZEGED (0)
#define SCHOENAU_KOENIGSEE (0) #define SCHOENAU_KOENIGSEE (0)
#define NEUHAUSER_KORNEUBURG (0) #define NEUHAUSER_KORNEUBURG (0)
#define NEUHAUSER_LINSINGER_MASCHINENBAU (0) #define NEUHAUSER_LINSINGER_MASCHINENBAU (0)
@ -45,6 +45,7 @@ extern "C" char* strptime(const char* s,
#define BAD_NEUENAHR_AHRWEILER (0) #define BAD_NEUENAHR_AHRWEILER (0)
#define NEUHAUSER_CHRISTOPH_REISEN (0) #define NEUHAUSER_CHRISTOPH_REISEN (0)
#define NEUHAUSER_PERNEGG_AN_DER_MUR (0) #define NEUHAUSER_PERNEGG_AN_DER_MUR (0)
#define NEUHAUSER_STOCKERAU (1)
#if NEUHAUSER_KIRCHDORF==1 #if NEUHAUSER_KIRCHDORF==1
static bool test_neuhauser_kirchdorf(int step, double cost) { static bool test_neuhauser_kirchdorf(int step, double cost) {
@ -164,8 +165,187 @@ static bool test_neuhauser_kirchdorf(int step, double cost) {
} }
#endif #endif
#include <cmath>
int main() { int main() {
#if NEUHAUSER_STOCKERAU==1
std::ifstream input;
int pop_min_time;
int pop_max_time;
int pop_min_price;
int pop_max_price;
int pop_daily_card_price;
input.open("/opt/ptu5/opt/customer_748/etc/psa_tariff/tariff01.json");
std::stringstream sstr;
while(input >> sstr.rdbuf());
std::string json(sstr.str());
Configuration cfg;
bool isParsed = cfg.ParseJson(&cfg, json.c_str());
cout << endl;
if (isParsed) {
pop_min_time = get_minimal_parkingtime(&cfg);
pop_max_time = get_maximal_parkingtime(&cfg);
pop_min_price = get_minimal_parkingprice(&cfg);
pop_max_price = get_maximal_parkingprice(&cfg);
pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price;
qCritical() << " pop_min_time: " << pop_min_time;
qCritical() << " pop_max_time: " << pop_max_time;
qCritical() << " pop_min_price: " << pop_min_price;
qCritical() << " pop_max_price: " << pop_max_price;
// tests:
// 1: Mon-Freitag: jeweils
// start 0-8.00
// start 8.00-12.00
// start 12.00-13.30
// start 13.30-18.00
// start 18.00-24.00
// alle kosten durchspielen
// 2. samstag
// start 0-8.00
// start 8.00-12.00
// start nach 12.00
// 2. sonntag
//QDateTime s(QDate(2024, 5, 27), QTime()); // monday
//QDateTime s(QDate(2024, 5, 28), QTime()); // tuesday
//QDateTime s(QDate(2024, 5, 29), QTime()); // wednesday
//QDateTime s(QDate(2024, 5, 30), QTime()); // thursday
CalcState cs;
double const x = 30.0/7.0;
double cost;
int durationInMinutes;
int offsetInMinutes = 0;
for (int day = Qt::Monday; day <= Qt::Sunday; ++day) {
QDateTime s(QDate(2024, 5, 19 + day), QTime()); // 20: (whit) monday,..., 26: sunday
QDateTime end;
for (int minutes = 0; minutes < 1440; ++minutes) {
//for (int minutes = 0; minutes < 1440; ++minutes) {
QDateTime start = s.addSecs(minutes * 60);
QDateTime effectiveStart = start;
if (day >= Qt::Monday && day <= Qt::Friday) {
if (start.time() < QTime(8,0,0)) {
effectiveStart.setTime(QTime(8,0,0));
} else
if (start.time() <= QTime(12,0,0)) {
effectiveStart = start;
} else
if (start.time() < QTime(13,30,0)) {
effectiveStart.setTime(QTime(13,30,0));
} else
if (start.time() <= QTime(18,0,0)) {
effectiveStart = start;
} else {
effectiveStart = start.addDays(1);
effectiveStart.setTime(QTime(8,0,0)); // saturday
}
} else
if (day == Qt::Saturday) {
if (start.time() < QTime(8,0,0)) {
effectiveStart.setTime(QTime(8,0,0));
} else
if (start.time() <= QTime(12,0,0)) {
effectiveStart = start;
} else {
effectiveStart = start.addDays(2);
effectiveStart.setTime(QTime(8,0,0)); // monday
}
} else
if (day == Qt::Sunday) {
effectiveStart = start.addDays(1);
effectiveStart.setTime(QTime(8,0,0)); // monday
}
for (int i = 70; i <= 600; i += 10) {
// for (int i = 70; i <= 70; i += 10) {
cost = i;
if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end))) { // return value
durationInMinutes = truncf(x * (i/10));
offsetInMinutes = 0;
if (day >= Qt::Monday && day <= Qt::Friday) {
if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) {
if (effectiveStart.date().dayOfWeek() == start.date().dayOfWeek()) {
if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) {
offsetInMinutes = 90; // 12:00 - 13:30
}
} else {
offsetInMinutes = 14 * 60; // 18:00 -> next day, 8:00
if (effectiveStart.time().addSecs(durationInMinutes * 60) <= QTime(12, 0, 0)) {
offsetInMinutes = 0;
} else {
if (effectiveStart.date().dayOfWeek() == Qt::Saturday) {
offsetInMinutes = (12 + 24 + 8) * 60;
} else {
offsetInMinutes = 90;
}
}
}
} else
if (effectiveStart.time() >= QTime(13, 30, 0)) {
if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(18, 0, 0)) {
offsetInMinutes = 14 * 60; // 18:00 -> next day, 8:00
}
}
} else
if (day == Qt::Saturday) {
if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) {
if (effectiveStart.date().dayOfWeek() == start.date().dayOfWeek()) {
if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) {
offsetInMinutes = (12 + 24 + 8) * 60; // monday, 8:00
}
} else {
offsetInMinutes = (12 + 24 + 8) * 60; // monday, 8:00
if (effectiveStart.time().addSecs(durationInMinutes * 60) <= QTime(12, 0, 0)) {
offsetInMinutes = 0;
} else {
offsetInMinutes = 90;
}
}
}
} else
if (day == Qt::Sunday) {
if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(12, 0, 0)) {
if (effectiveStart.time().addSecs(durationInMinutes * 60) > QTime(12, 0, 0)) {
offsetInMinutes = 90;
}
}
}
if ((durationInMinutes + offsetInMinutes) == (effectiveStart.secsTo(end) / 60)) {
continue;
}
}
if (!cs) {
qCritical() << "ERROR CalcState" << cs.toString() << endl;
} else {
qCritical() << "SUCCESS";
}
qCritical() << "start ............................" << start.toString(Qt::ISODate);
qCritical() << "effectiveStart ..................." << effectiveStart.toString(Qt::ISODate);
qCritical() << "cost ............................." << cost;
qCritical() << "durationMinutes .................." << durationInMinutes;
qCritical() << "offsetInMinutes .................." << offsetInMinutes;
qCritical() << "effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60;
qCritical() << "end .............................." << end.toString(Qt::ISODate) << endl;
exit(-1);
}
}
}
}
#endif
#if NEUHAUSER_PERNEGG_AN_DER_MUR==1 #if NEUHAUSER_PERNEGG_AN_DER_MUR==1
std::ifstream input; std::ifstream input;
int pop_min_time; int pop_min_time;