Added several functions: computeFreeOfCharge, computeEffectiveStartMinute, compute_price_for_max_price_at_midnight -> implementation of a special apcoa-tariff, implementation of compute_duration_for_parking_ticket
This commit is contained in:
parent
503d49ebb2
commit
69ac97f01c
@ -59,7 +59,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static minute_t computeEffectiveStartMinute(parking_tariff_t const *tariff,
|
static minute_t computeFreeOfCharge(parking_tariff_t const *tariff,
|
||||||
minute_t startMinute) {
|
minute_t startMinute) {
|
||||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||||
minute_t free_of_charge = 0;
|
minute_t free_of_charge = 0;
|
||||||
@ -72,8 +72,12 @@ static minute_t computeEffectiveStartMinute(parking_tariff_t const *tariff,
|
|||||||
(startMinuteDay >= 0 && startMinuteDay < tariff->night_tariff_end)) {
|
(startMinuteDay >= 0 && startMinuteDay < tariff->night_tariff_end)) {
|
||||||
free_of_charge = tariff->free_of_charge_night_tariff;
|
free_of_charge = tariff->free_of_charge_night_tariff;
|
||||||
}
|
}
|
||||||
|
return free_of_charge;
|
||||||
|
}
|
||||||
|
|
||||||
return (startMinute + free_of_charge);
|
static minute_t computeEffectiveStartMinute(parking_tariff_t const *tariff,
|
||||||
|
minute_t startMinute) {
|
||||||
|
return (startMinute + computeFreeOfCharge(tariff, startMinute));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
||||||
@ -90,8 +94,9 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
|||||||
minute_t const parkingTime = endMinute - startMinute;
|
minute_t const parkingTime = endMinute - startMinute;
|
||||||
|
|
||||||
if (parkingTime == 0) {
|
if (parkingTime == 0) {
|
||||||
qCritical() << "startMinute == endMinute => no parking time";
|
price->units = 0;
|
||||||
return false;
|
//qInfo() << "startMinute == endMinute => no parking time";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tariff->parking_time_max != -1) {
|
if (tariff->parking_time_max != -1) {
|
||||||
@ -103,26 +108,17 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||||
//minute_t free_of_charge = 0;
|
|
||||||
//minute_t startMinuteDay = start.time().hour()*60 +start.time().minute();
|
|
||||||
//if (startMinuteDay >= tariff->day_tariff_start &&
|
|
||||||
// startMinuteDay < tariff->day_tariff_end) {
|
|
||||||
// free_of_charge = tariff->free_of_charge_day_tariff;
|
|
||||||
//} else
|
|
||||||
//if ((startMinuteDay >= tariff->night_tariff_start && startMinuteDay < MINUTES_PER_DAY) ||
|
|
||||||
// (startMinuteDay >= 0 && startMinuteDay < tariff->night_tariff_end)) {
|
|
||||||
// free_of_charge = tariff->free_of_charge_night_tariff;
|
|
||||||
//}
|
|
||||||
|
|
||||||
minute_t const effectiveStartMinute = computeEffectiveStartMinute(tariff, startMinute);
|
minute_t const effectiveStartMinute = computeEffectiveStartMinute(tariff, startMinute);
|
||||||
QDateTime const end = TUtils::fromMinutes(endMinute);
|
QDateTime const end = TUtils::fromMinutes(endMinute);
|
||||||
|
|
||||||
if (effectiveStartMinute > endMinute) {
|
if (effectiveStartMinute > endMinute) {
|
||||||
fprintf(stderr,
|
//minute_t free_of_charge = computeFreeOfCharge(tariff, startMinute);
|
||||||
"[start:%02d:%02d, ende:%02d:%02d]: %ld free minutes. no charge.\n",
|
//fprintf(stderr,
|
||||||
start.time().hour(), start.time().minute(),
|
// "[start:%02d:%02d, ende:%02d:%02d]: %ld free minutes. no charge.\n",
|
||||||
end.time().hour(), end.time().minute(), tariff->free_of_charge_day_tariff);
|
// start.time().hour(), start.time().minute(),
|
||||||
memset(price, 0x00, sizeof(*price));
|
// end.time().hour(), end.time().minute(), free_of_charge);
|
||||||
|
price->units = 0;
|
||||||
|
price->valid = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +127,68 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG_INTERNAL 0
|
#define DEBUG_INTERNAL 0
|
||||||
|
#define DEBUG_MAX_PRICE_AT_MIDNIGHT 1
|
||||||
|
|
||||||
|
uint32_t compute_price_for_max_price_at_midnight(parking_tariff_t const *tariff,
|
||||||
|
QDateTime const &end,
|
||||||
|
TariffStep const *step) {
|
||||||
|
uint32_t price_units = 0;
|
||||||
|
QDateTime stepDateTime = step->dateTime();
|
||||||
|
QDateTime nextStepDateTime;
|
||||||
|
QDateTime midnight(stepDateTime.date().addDays(1), QTime(0,0));
|
||||||
|
uint32_t day_price_units = 0;
|
||||||
|
bool dbg = true;
|
||||||
|
while (stepDateTime < end) {
|
||||||
|
uint32_t const price_units_tmp = step->price();
|
||||||
|
step = step->next();
|
||||||
|
nextStepDateTime = step->dateTime();
|
||||||
|
if (stepDateTime < midnight) {
|
||||||
|
day_price_units += price_units_tmp;
|
||||||
|
if (day_price_units > tariff->max_price_at_midnight) {
|
||||||
|
day_price_units = tariff->max_price_at_midnight;
|
||||||
|
if (dbg) {
|
||||||
|
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||||
|
fprintf(stderr,
|
||||||
|
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||||
|
stepDateTime.date().toString().toStdString().c_str(),
|
||||||
|
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||||
|
price_units, day_price_units);
|
||||||
|
//dbg = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||||
|
dbg = true;
|
||||||
|
fprintf(stderr,
|
||||||
|
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||||
|
stepDateTime.date().toString().toStdString().c_str(),
|
||||||
|
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||||
|
price_units, day_price_units);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (day_price_units == tariff->max_price_at_midnight) {
|
||||||
|
price_units += day_price_units;
|
||||||
|
day_price_units = 0;
|
||||||
|
} else {
|
||||||
|
day_price_units += price_units_tmp;
|
||||||
|
}
|
||||||
|
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||||
|
fprintf(stderr,
|
||||||
|
"[%s:%02d:%02d 24h max. price_so_far=%d day_price=%d]\n",
|
||||||
|
stepDateTime.date().toString().toStdString().c_str(),
|
||||||
|
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||||
|
price_units, day_price_units);
|
||||||
|
#endif
|
||||||
|
midnight = stepDateTime;
|
||||||
|
midnight.setDate(midnight.date().addDays(1));
|
||||||
|
midnight.setTime(QTime(0, 0));
|
||||||
|
}
|
||||||
|
stepDateTime = nextStepDateTime;
|
||||||
|
}
|
||||||
|
price_units += day_price_units;
|
||||||
|
return price_units;
|
||||||
|
}
|
||||||
|
|
||||||
TariffStep const *
|
TariffStep const *
|
||||||
compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
||||||
@ -227,60 +285,7 @@ compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
|||||||
}
|
}
|
||||||
if (tariff->max_price_at_midnight) {
|
if (tariff->max_price_at_midnight) {
|
||||||
// restart pricing at midnight if current price is max_price_at_midnight
|
// restart pricing at midnight if current price is max_price_at_midnight
|
||||||
QDateTime stepDateTime = step->dateTime();
|
price_units = compute_price_for_max_price_at_midnight(tariff, end, step);
|
||||||
QDateTime nextStepDateTime;
|
|
||||||
QDateTime midnight(stepDateTime.date().addDays(1), QTime(0,0));
|
|
||||||
uint32_t day_price_units = 0;
|
|
||||||
bool dbg = true;
|
|
||||||
while (stepDateTime < end) {
|
|
||||||
uint32_t const price_units_tmp = step->price();
|
|
||||||
step = step->next();
|
|
||||||
nextStepDateTime = step->dateTime();
|
|
||||||
if (stepDateTime < midnight) {
|
|
||||||
day_price_units += price_units_tmp;
|
|
||||||
if (day_price_units > tariff->max_price_at_midnight) {
|
|
||||||
day_price_units = tariff->max_price_at_midnight;
|
|
||||||
if (dbg) {
|
|
||||||
#if DEBUG_INTERNAL
|
|
||||||
fprintf(stderr,
|
|
||||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
|
||||||
stepDateTime.date().toString().toStdString().c_str(),
|
|
||||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
|
||||||
price_units, day_price_units);
|
|
||||||
//dbg = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#if DEBUG_INTERNAL
|
|
||||||
dbg = true;
|
|
||||||
fprintf(stderr,
|
|
||||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
|
||||||
stepDateTime.date().toString().toStdString().c_str(),
|
|
||||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
|
||||||
price_units, day_price_units);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (day_price_units == tariff->max_price_at_midnight) {
|
|
||||||
price_units += day_price_units;
|
|
||||||
day_price_units = 0;
|
|
||||||
} else {
|
|
||||||
day_price_units += price_units_tmp;
|
|
||||||
}
|
|
||||||
#if DEBUG_INTERNAL
|
|
||||||
fprintf(stderr,
|
|
||||||
"[%s:%02d:%02d 24h max. price_so_far=%d day_price=%d]\n",
|
|
||||||
stepDateTime.date().toString().toStdString().c_str(),
|
|
||||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
|
||||||
price_units, day_price_units);
|
|
||||||
#endif
|
|
||||||
midnight = stepDateTime;
|
|
||||||
midnight.setDate(midnight.date().addDays(1));
|
|
||||||
midnight.setTime(QTime(0, 0));
|
|
||||||
}
|
|
||||||
stepDateTime = nextStepDateTime;
|
|
||||||
}
|
|
||||||
price_units += day_price_units;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
price->units = price_units;
|
price->units = price_units;
|
||||||
@ -296,9 +301,9 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
|||||||
minute_t startMinute, // CET
|
minute_t startMinute, // CET
|
||||||
minute_t endMinute, // CET
|
minute_t endMinute, // CET
|
||||||
struct price_t *price) {
|
struct price_t *price) {
|
||||||
|
price->valid = false;
|
||||||
if (!checkCalculatePreConditions(tariff, startMinute, endMinute, price)) { // CET
|
if (!checkCalculatePreConditions(tariff, startMinute, endMinute, price)) { // CET
|
||||||
return false;
|
return price->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// minute_t const parkingTime = endMinute - startMinute;
|
// minute_t const parkingTime = endMinute - startMinute;
|
||||||
@ -309,8 +314,8 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
|||||||
// QDateTime const effStart = TUtils::fromMinutes(effectiveStartMinute);
|
// QDateTime const effStart = TUtils::fromMinutes(effectiveStartMinute);
|
||||||
// QDateTime const end = TUtils::fromMinutes(endMinute);
|
// QDateTime const end = TUtils::fromMinutes(endMinute);
|
||||||
|
|
||||||
//qDebug() << effStart;
|
// qDebug() << "XXX" << effStart;
|
||||||
//qDebug() << end;
|
// qDebug() << "XXX" << end;
|
||||||
|
|
||||||
TariffStep const *stepDbg =
|
TariffStep const *stepDbg =
|
||||||
compute_price_for_parking_ticket_internal(tariff,
|
compute_price_for_parking_ticket_internal(tariff,
|
||||||
@ -357,7 +362,8 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, " : gesamt %.2f (netto: %.2f)\n", price->brutto/100, price->netto/100);
|
// fprintf(stderr, " : gesamt %.2f (netto: %.2f)\n", price->brutto/100, price->netto/100);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -367,27 +373,78 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEBUG_COMPUTE_DURATION 1
|
||||||
|
|
||||||
bool compute_duration_for_parking_ticket(parking_tariff_t const *tariff,
|
bool compute_duration_for_parking_ticket(parking_tariff_t const *tariff,
|
||||||
minute_t start_parking_time,
|
minute_t start_parking_time,
|
||||||
minute_t *end_parking_time,
|
minute_t *end_parking_time,
|
||||||
struct price_t const *price) {
|
struct price_t const *price) {
|
||||||
price_t p;
|
QDateTime const s = TUtils::fromMinutes(start_parking_time);
|
||||||
for (int i = 0; i < tariff->parking_time_max; ++i) {
|
|
||||||
minute_t end_time = start_parking_time + i;
|
#if DEBUG_COMPUTE_DURATION==1
|
||||||
if (compute_price_for_parking_ticket(tariff, start_parking_time,
|
fprintf(stderr, "price %u, start_parking_time %s:%02d:%02d\n",
|
||||||
end_time, &p)) {
|
price->units, s.date().toString().toStdString().c_str(),
|
||||||
if (p.netto >= price->netto) {
|
s.time().hour(), s.time().minute());
|
||||||
*end_parking_time = end_time;
|
#endif
|
||||||
|
|
||||||
|
minute_t free_of_charge = computeFreeOfCharge(tariff, start_parking_time);
|
||||||
|
minute_t end_time_at_max_price = start_parking_time;
|
||||||
|
for (int now = 0; now < tariff->parking_time_max; ++now) {
|
||||||
|
if (price->units == 0) {
|
||||||
|
if (free_of_charge >= now) {
|
||||||
|
*end_parking_time = start_parking_time + free_of_charge;
|
||||||
|
|
||||||
|
#if DEBUG_COMPUTE_DURATION==1
|
||||||
|
QDateTime const e = TUtils::fromMinutes(*end_parking_time);
|
||||||
|
fprintf(stderr, "price %u, end_parking_time %s:%02d:%02d\n",
|
||||||
|
price->units, e.date().toString().toStdString().c_str(),
|
||||||
|
e.time().hour(), e.time().minute());
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
minute_t end_time = start_parking_time + now;
|
||||||
|
price_t p;
|
||||||
|
if (compute_price_for_parking_ticket(tariff, start_parking_time,
|
||||||
|
end_time, &p)) {
|
||||||
|
if (p.units <= price->units) {
|
||||||
|
end_time_at_max_price = end_time;
|
||||||
|
} else {
|
||||||
|
if (end_time_at_max_price >= free_of_charge) {
|
||||||
|
*end_parking_time = end_time_at_max_price - free_of_charge;
|
||||||
|
|
||||||
|
#if DEBUG_COMPUTE_DURATION==1
|
||||||
|
QDateTime const e = TUtils::fromMinutes(*end_parking_time);
|
||||||
|
fprintf(stderr, "price %u, end_parking_time %s:%02d:%02d\n",
|
||||||
|
price->units, e.date().toString().toStdString().c_str(),
|
||||||
|
e.time().hour(), e.time().minute());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR end_time_at_max_price(%lu) < free_of_charge(%lu)\n",
|
||||||
|
end_time_at_max_price, free_of_charge);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO ausgabe
|
||||||
|
//return false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "ERROR %s start_parking_time for price %u: %s:%02d:%02d\n",
|
||||||
|
__func__, price->units, s.date().toString().toStdString().c_str(),
|
||||||
|
s.time().hour(), s.time().minute());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compute_price_for_tages_ticket(parking_tariff_t *tariff,
|
bool compute_price_for_tages_ticket(parking_tariff_t *tariff,
|
||||||
time_t parking_time_start, // minutes
|
time_t parking_time_start, // minutes
|
||||||
struct price_t *price) {
|
struct price_t *price) {
|
||||||
|
// NOT TESTED
|
||||||
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
||||||
dateTime.setTime(QTime(0, 0));
|
dateTime.setTime(QTime(0, 0));
|
||||||
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
||||||
@ -400,6 +457,7 @@ bool compute_price_for_24h_ticket(parking_tariff_t *tariff,
|
|||||||
struct price_t *price) {
|
struct price_t *price) {
|
||||||
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
||||||
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
||||||
|
// NOT TESTED
|
||||||
return compute_price_for_parking_ticket(tariff, parking_time_start,
|
return compute_price_for_parking_ticket(tariff, parking_time_start,
|
||||||
parking_time_end, price);
|
parking_time_end, price);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user