Compare commits
12 Commits
4ca35fbe37
...
master
Author | SHA1 | Date | |
---|---|---|---|
ce66de0a72 | |||
69ac97f01c | |||
503d49ebb2 | |||
d18bce62bc | |||
cb407c9549 | |||
ad934929d1 | |||
fdafe1ff22 | |||
76cc30a7a3 | |||
da762b0441 | |||
a8484000cc | |||
5d337067cb | |||
d82a26bf05 |
30363
calculate_parking_tickets/apcoa_prio_1.conf
Normal file
30363
calculate_parking_tickets/apcoa_prio_1.conf
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,21 +23,21 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
calculate_parking_tickets.cpp \
|
calculate_parking_tickets.cpp \
|
||||||
calculate_parking_tickets_utils.cpp \
|
calculate_parking_tickets_utils.cpp \
|
||||||
calculate_parking_tickets_day.cpp \
|
# calculate_parking_tickets_day.cpp \
|
||||||
calculate_parking_tickets_algorithms.cpp \
|
calculate_parking_tickets_algorithms.cpp \
|
||||||
calculate_parking_tickets_tariff.cpp \
|
calculate_parking_tickets_tariff.cpp \
|
||||||
calculate_parking_tickets_tariff_step.cpp
|
# calculate_parking_tickets_tariff_step.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
calculate_parking_tickets_global.h \
|
calculate_parking_tickets_global.h \
|
||||||
calculate_parking_tickets.h \
|
calculate_parking_tickets.h \
|
||||||
calculate_parking_tickets_utils.h \
|
calculate_parking_tickets_utils.h \
|
||||||
calculate_parking_tickets_tariff_step.h \
|
# calculate_parking_tickets_tariff_step.h \
|
||||||
calculate_parking_tickets_day.h \
|
# calculate_parking_tickets_day.h \
|
||||||
calculate_parking_tickets_algorithms.h \
|
calculate_parking_tickets_algorithms.h \
|
||||||
calculate_parking_tickets_tariff.h
|
calculate_parking_tickets_tariff.h
|
||||||
|
|
||||||
OTHER_FILES += germersheim.conf
|
OTHER_FILES += germering.conf apcoa_prio_1.conf
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
unix {
|
unix {
|
||||||
|
@@ -59,6 +59,27 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static minute_t computeFreeOfCharge(parking_tariff_t const *tariff,
|
||||||
|
minute_t 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;
|
||||||
|
}
|
||||||
|
return 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,
|
||||||
minute_t startMinute, // CET
|
minute_t startMinute, // CET
|
||||||
minute_t endMinute, // CET
|
minute_t endMinute, // CET
|
||||||
@@ -73,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) {
|
||||||
@@ -85,17 +107,18 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minute_t const effectiveStartMinute = startMinute + tariff->free_of_charge;
|
|
||||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||||
//QDateTime const effStart = TUtils::fromMinutes(effectiveStartMinute);
|
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);
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +126,69 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG_INTERNAL 1
|
#define DEBUG_INTERNAL 0
|
||||||
|
#define DEBUG_MAX_PRICE_AT_MIDNIGHT 0
|
||||||
|
|
||||||
|
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,
|
||||||
@@ -117,7 +202,7 @@ compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
|||||||
|
|
||||||
int const minute = start.time().minute();
|
int const minute = start.time().minute();
|
||||||
int const hour = start.time().hour();
|
int const hour = start.time().hour();
|
||||||
int const day = start.date().dayOfWeek()-Qt::Monday;
|
int const day = start.date().dayOfWeek()-1;
|
||||||
int const week = 0;
|
int const week = 0;
|
||||||
|
|
||||||
// printf("%d%d%04d\n", week, day, hour*60+minute);
|
// printf("%d%d%04d\n", week, day, hour*60+minute);
|
||||||
@@ -129,12 +214,14 @@ compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
|||||||
|
|
||||||
|
|
||||||
uint32_t price_units = 0;
|
uint32_t price_units = 0;
|
||||||
if (tariff->max_price_for_24_hours == (uint32_t)(-1)) {
|
//if (tariff->max_price_for_24_hours == (uint32_t)(-1)) {
|
||||||
|
if (tariff->basic_tariff) {
|
||||||
while (step->dateTime() < end) {
|
while (step->dateTime() < end) {
|
||||||
price_units += step->price();
|
price_units += step->price();
|
||||||
step = step->next();
|
step = step->next();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (tariff->max_price_24h_after_arrival){
|
||||||
QDateTime stepDateTime = step->dateTime();
|
QDateTime stepDateTime = step->dateTime();
|
||||||
QDateTime nextStepDateTime;
|
QDateTime nextStepDateTime;
|
||||||
// QDateTime prevStepDateTime;
|
// QDateTime prevStepDateTime;
|
||||||
@@ -196,6 +283,10 @@ compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
|||||||
}
|
}
|
||||||
price_units += _24h_price_units;
|
price_units += _24h_price_units;
|
||||||
}
|
}
|
||||||
|
if (tariff->max_price_at_midnight) {
|
||||||
|
// restart pricing at midnight if current price is max_price_at_midnight
|
||||||
|
price_units = compute_price_for_max_price_at_midnight(tariff, end, step);
|
||||||
|
}
|
||||||
|
|
||||||
price->units = price_units;
|
price->units = price_units;
|
||||||
price->netto = roundf((price->units * tariff->unit_scale_factor) / tariff->unit_definition);
|
price->netto = roundf((price->units * tariff->unit_scale_factor) / tariff->unit_definition);
|
||||||
@@ -210,21 +301,21 @@ 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;
|
||||||
memset(price, 0x00, sizeof(*price));
|
memset(price, 0x00, sizeof(*price));
|
||||||
|
|
||||||
minute_t const effectiveStartMinute = startMinute + tariff->free_of_charge;
|
minute_t const effectiveStartMinute = computeEffectiveStartMinute(tariff, startMinute);
|
||||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
// QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||||
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,
|
||||||
@@ -271,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 {
|
||||||
@@ -281,27 +373,78 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEBUG_COMPUTE_DURATION 0
|
||||||
|
|
||||||
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;
|
||||||
@@ -314,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);
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ typedef struct price_t {
|
|||||||
double brutto;
|
double brutto;
|
||||||
double vat_percentage;
|
double vat_percentage;
|
||||||
double vat;
|
double vat;
|
||||||
|
bool valid;
|
||||||
} price_t;
|
} price_t;
|
||||||
|
|
||||||
static constexpr uint16_t const MIN_PER_DAY = 1440;
|
static constexpr uint16_t const MIN_PER_DAY = 1440;
|
||||||
|
@@ -17,7 +17,12 @@
|
|||||||
|
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
|
||||||
#define FREE_OF_CHARGE "free_of_charge"
|
#define DAY_TARIFF_START "day_tariff_start"
|
||||||
|
#define DAY_TARIFF_END "day_tariff_end"
|
||||||
|
#define NIGHT_TARIFF_START "night_tariff_start"
|
||||||
|
#define NIGHT_TARIFF_END "night_tariff_end"
|
||||||
|
#define FREE_OF_CHARGE_DAY_TARIFF "free_of_charge_day_tariff"
|
||||||
|
#define FREE_OF_CHARGE_NIGHT_TARIFF "free_of_charge_night_tariff"
|
||||||
#define UNIT_SCALE_FACTOR "unit_scale_factor"
|
#define UNIT_SCALE_FACTOR "unit_scale_factor"
|
||||||
#define UNIT_DEFINITION "unit_definition"
|
#define UNIT_DEFINITION "unit_definition"
|
||||||
#define VAT "vat"
|
#define VAT "vat"
|
||||||
@@ -29,6 +34,9 @@ using namespace rapidjson;
|
|||||||
#define WAITING_PERIOD "waiting_period"
|
#define WAITING_PERIOD "waiting_period"
|
||||||
#define PARKING_TIME_MIN "parking_time_min"
|
#define PARKING_TIME_MIN "parking_time_min"
|
||||||
#define PARKING_TIME_MAX "parking_time_max"
|
#define PARKING_TIME_MAX "parking_time_max"
|
||||||
|
#define BASIC_TARIFF "basic_tariff"
|
||||||
|
#define MAX_PRICE_24H_AFTER_ARRIVAL "max_price_24h_after_arrival"
|
||||||
|
#define MAX_PRICE_AT_MIDNIGHT "max_price_at_midnight"
|
||||||
|
|
||||||
static const char *weekStr[] {
|
static const char *weekStr[] {
|
||||||
"week1", "week2", "week3"
|
"week1", "week2", "week3"
|
||||||
@@ -89,6 +97,34 @@ parking_tariff_t *parking_tariff_t::parseTariff(const char *confFile) {
|
|||||||
sizeof(tariff->_tariff_features));
|
sizeof(tariff->_tariff_features));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (d.HasMember(DAY_TARIFF_START)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(DAY_TARIFF_START);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->day_tariff_start = std::stoi(s);
|
||||||
|
}
|
||||||
|
if (d.HasMember(DAY_TARIFF_END)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(DAY_TARIFF_END);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->day_tariff_end = std::stoi(s);
|
||||||
|
}
|
||||||
|
if (d.HasMember(NIGHT_TARIFF_START)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(NIGHT_TARIFF_START);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->night_tariff_start = std::stoi(s);
|
||||||
|
}
|
||||||
|
if (d.HasMember(NIGHT_TARIFF_END)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(NIGHT_TARIFF_END);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->night_tariff_end = std::stoi(s);
|
||||||
|
}
|
||||||
if (d.HasMember(WAITING_PERIOD)) {
|
if (d.HasMember(WAITING_PERIOD)) {
|
||||||
Value::MemberIterator o = d.FindMember(WAITING_PERIOD);
|
Value::MemberIterator o = d.FindMember(WAITING_PERIOD);
|
||||||
assert(o != d.MemberEnd());
|
assert(o != d.MemberEnd());
|
||||||
@@ -96,12 +132,19 @@ parking_tariff_t *parking_tariff_t::parseTariff(const char *confFile) {
|
|||||||
std::string wp = o->value.GetString();
|
std::string wp = o->value.GetString();
|
||||||
tariff->waiting_period = std::stoi(wp);
|
tariff->waiting_period = std::stoi(wp);
|
||||||
}
|
}
|
||||||
if (d.HasMember(FREE_OF_CHARGE)) {
|
if (d.HasMember(FREE_OF_CHARGE_DAY_TARIFF)) {
|
||||||
Value::MemberIterator o = d.FindMember(FREE_OF_CHARGE);
|
Value::MemberIterator o = d.FindMember(FREE_OF_CHARGE_DAY_TARIFF);
|
||||||
assert(o != d.MemberEnd());
|
assert(o != d.MemberEnd());
|
||||||
assert(o->value.IsString());
|
assert(o->value.IsString());
|
||||||
std::string foc = o->value.GetString();
|
std::string foc = o->value.GetString();
|
||||||
tariff->free_of_charge = std::stoi(foc);
|
tariff->free_of_charge_day_tariff = std::stoi(foc);
|
||||||
|
}
|
||||||
|
if (d.HasMember(FREE_OF_CHARGE_NIGHT_TARIFF)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(FREE_OF_CHARGE_NIGHT_TARIFF);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string foc = o->value.GetString();
|
||||||
|
tariff->free_of_charge_night_tariff = std::stoi(foc);
|
||||||
}
|
}
|
||||||
if (d.HasMember(UNIT_SCALE_FACTOR)) {
|
if (d.HasMember(UNIT_SCALE_FACTOR)) {
|
||||||
Value::MemberIterator o = d.FindMember(UNIT_SCALE_FACTOR);
|
Value::MemberIterator o = d.FindMember(UNIT_SCALE_FACTOR);
|
||||||
@@ -160,18 +203,40 @@ parking_tariff_t *parking_tariff_t::parseTariff(const char *confFile) {
|
|||||||
std::string mp = o->value.GetString();
|
std::string mp = o->value.GetString();
|
||||||
if (mp == "unlimited") {
|
if (mp == "unlimited") {
|
||||||
tariff->max_price_for_24_hours = ~0;
|
tariff->max_price_for_24_hours = ~0;
|
||||||
|
} else if (mp == "n/a") {
|
||||||
|
tariff->max_price_for_24_hours = 0;
|
||||||
} else {
|
} else {
|
||||||
tariff->max_price_for_24_hours = (uint32_t)std::stoul(mp);
|
tariff->max_price_for_24_hours = (uint32_t)std::stoul(mp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (d.HasMember(BASIC_TARIFF)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(BASIC_TARIFF);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->basic_tariff = (s == "1");
|
||||||
|
}
|
||||||
|
if (d.HasMember(MAX_PRICE_24H_AFTER_ARRIVAL)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(MAX_PRICE_24H_AFTER_ARRIVAL);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->max_price_24h_after_arrival = (uint32_t)std::stoul(s);
|
||||||
|
}
|
||||||
|
if (d.HasMember(MAX_PRICE_AT_MIDNIGHT)) {
|
||||||
|
Value::MemberIterator o = d.FindMember(MAX_PRICE_AT_MIDNIGHT);
|
||||||
|
assert(o != d.MemberEnd());
|
||||||
|
assert(o->value.IsString());
|
||||||
|
std::string s = o->value.GetString();
|
||||||
|
tariff->max_price_at_midnight = (uint32_t)std::stoul(s);
|
||||||
|
}
|
||||||
|
|
||||||
QDate today = QDate::currentDate();
|
QDate today = QDate::currentDate();
|
||||||
|
|
||||||
int const todayWeekDay = today.dayOfWeek(); // qt: 1 (mon) - 7 (sun)
|
int const todayWeekDay = today.dayOfWeek(); // qt: 1 (mon) - 7 (sun)
|
||||||
if (todayWeekDay > Qt::Monday) {
|
if (todayWeekDay > Qt::Monday) {
|
||||||
int day = today.day();
|
today = today.addDays(Qt::Monday - todayWeekDay);
|
||||||
day -= (todayWeekDay - Qt::Monday);
|
if (!today.isValid()) {
|
||||||
if (!today.setDate(today.year(), today.month(), day)) {
|
|
||||||
qFatal("Setting today failed");
|
qFatal("Setting today failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,13 @@
|
|||||||
#define VERANSTALTUNG_AUSWAHL_KULTUR (uint64_t)(0x0000000000000010)
|
#define VERANSTALTUNG_AUSWAHL_KULTUR (uint64_t)(0x0000000000000010)
|
||||||
|
|
||||||
struct parking_tariff_t {
|
struct parking_tariff_t {
|
||||||
// parking_tariff_t();
|
explicit parking_tariff_t()
|
||||||
|
: day_tariff_start(0)
|
||||||
|
, day_tariff_end(0)
|
||||||
|
, night_tariff_start(0)
|
||||||
|
, night_tariff_end(0) {
|
||||||
|
}
|
||||||
|
|
||||||
static parking_tariff_t *parseTariff(const char *confFile);
|
static parking_tariff_t *parseTariff(const char *confFile);
|
||||||
|
|
||||||
/// \brief Express computational units in cent.
|
/// \brief Express computational units in cent.
|
||||||
@@ -41,6 +47,26 @@ struct parking_tariff_t {
|
|||||||
///
|
///
|
||||||
TariffStep m_tariffSteps[3][7][MIN_PER_DAY];
|
TariffStep m_tariffSteps[3][7][MIN_PER_DAY];
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief day_tariff_start
|
||||||
|
///
|
||||||
|
minute_t day_tariff_start;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief day_tariff_end
|
||||||
|
///
|
||||||
|
minute_t day_tariff_end;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief night_tariff_start
|
||||||
|
///
|
||||||
|
minute_t night_tariff_start;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief night_tariff_end
|
||||||
|
///
|
||||||
|
minute_t night_tariff_end;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief waiting_period
|
/// \brief waiting_period
|
||||||
/// @note Also called "Karenzzeit". Allowed values: [0, 3]
|
/// @note Also called "Karenzzeit". Allowed values: [0, 3]
|
||||||
@@ -49,7 +75,12 @@ struct parking_tariff_t {
|
|||||||
///
|
///
|
||||||
/// \brief free_of_charge
|
/// \brief free_of_charge
|
||||||
///
|
///
|
||||||
minute_t free_of_charge;
|
minute_t free_of_charge_day_tariff;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief free_of_charge_night_tariff
|
||||||
|
///
|
||||||
|
minute_t free_of_charge_night_tariff;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief max_parking_price_units
|
/// \brief max_parking_price_units
|
||||||
@@ -86,159 +117,20 @@ struct parking_tariff_t {
|
|||||||
///
|
///
|
||||||
minute_t parking_time_max;
|
minute_t parking_time_max;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/// Minimal amount of money for buying a ticket.
|
|
||||||
///
|
///
|
||||||
/// The minimal amount of money a user has to provide \n
|
/// \brief basic_tariff
|
||||||
/// to get a valid (parking) ticket.
|
///
|
||||||
uint32_t money_min;
|
bool basic_tariff;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Minimal parking time.
|
/// \brief max_price_24h_after_arrival
|
||||||
///
|
///
|
||||||
/// Minimal parking time. The full parking time must be \n
|
uint32_t max_price_24h_after_arrival;
|
||||||
/// a multiple of @see parking_time_min.
|
|
||||||
minute_t parking_time_min;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Maximal parking time. Must be a multiple of @see parking_time_min.
|
/// \brief max_price_at_midnight
|
||||||
///
|
///
|
||||||
minute_t parking_time_max;
|
uint32_t max_price_at_midnight;
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief integration_time_max
|
|
||||||
/// Maximal possible integration time, i.e. the time after which all tickets
|
|
||||||
/// will be closed.
|
|
||||||
/// \note parking_time_max <= integration_time_max.
|
|
||||||
minute_t integration_time_max;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief tages_ticket_uebertrag
|
|
||||||
///
|
|
||||||
bool tages_ticket_uebertrag;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief free_of_charge_uebertrag
|
|
||||||
/// Carry FOC (usually at midnight) or not.
|
|
||||||
/// The default setting is true.
|
|
||||||
bool free_of_charge_uebertrag;
|
|
||||||
|
|
||||||
/// \brief Time for optionally changing tariff-table.
|
|
||||||
///
|
|
||||||
/// Depending on the configuration, a table in the tariff can be swapped
|
|
||||||
/// in, typically at midnight. But it is also possible that this event happens
|
|
||||||
/// during the day.
|
|
||||||
/// @note 0 ≤ tariff_deadline $lt; 1440
|
|
||||||
minute_t tages_ticket_offset;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief vorkauf
|
|
||||||
///
|
|
||||||
/// Maximal time in minutes before business hours where a presales
|
|
||||||
/// ("vorkauf") operation is possible.
|
|
||||||
minute_t vorkauf;
|
|
||||||
|
|
||||||
/// \brief Memory consumption of calculate price algorithm
|
|
||||||
uint32_t memory_consumption;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Time-range which is free of charge.
|
|
||||||
///
|
|
||||||
struct free_of_charge_range_t free_of_charge;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief business_hours
|
|
||||||
///
|
|
||||||
struct business_hours_range_t business_hours;
|
|
||||||
|
|
||||||
|
|
||||||
/// Array of possible days: DEFAULT, SUN - SAT plus HOLIDAY.
|
|
||||||
///
|
|
||||||
day_t *day[DAYS];
|
|
||||||
|
|
||||||
/// Pointer to current day in tariff-table.
|
|
||||||
///
|
|
||||||
day_t *current_day;
|
|
||||||
|
|
||||||
/// Array of holiday dates. Format: YYYY:MM:DD
|
|
||||||
///
|
|
||||||
holiday_date_t *holiday_date;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief algorithm_features
|
|
||||||
///
|
|
||||||
uint16_t algorithm_features;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief tariff_features
|
|
||||||
///
|
|
||||||
/// @todo: add comment
|
|
||||||
uint64_t tariff_features;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief _tariff_features
|
|
||||||
///
|
|
||||||
/// @todo: add comment
|
|
||||||
uint64_t _tariff_features[64];
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief closed_tickets_local_end_times
|
|
||||||
///
|
|
||||||
/// @note The end times of all closed tickets: the possible values are
|
|
||||||
/// 0 <= end_time <= 168h.
|
|
||||||
///
|
|
||||||
bool closed_tickets_sorted;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief closed_tickets_count
|
|
||||||
///
|
|
||||||
/// @note Used internally for optimizations.
|
|
||||||
int closed_tickets_count;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief closed_tickets
|
|
||||||
/// @todo: add comment
|
|
||||||
ticket_t *closed_tickets[NUMBER_OF_TICKETS];
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief tariff_step_min
|
|
||||||
///
|
|
||||||
/// @todo: add comment
|
|
||||||
time_t tariff_step_min;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief tariff_step_max
|
|
||||||
///
|
|
||||||
/// @todo: add comment
|
|
||||||
time_t tariff_step_max;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief tariff_version
|
|
||||||
/// Version for a given config-file, associated to a given tariff.
|
|
||||||
char tariff_version[64];
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief free_of_charge_at_start;
|
|
||||||
///
|
|
||||||
/// Free-of-charge minutes at beginning of tariff computation
|
|
||||||
///
|
|
||||||
uint16_t free_of_charge_at_start;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief repeated_default_without_carryover
|
|
||||||
///
|
|
||||||
/// Setting describing a special tariff:
|
|
||||||
/// - All days are equal
|
|
||||||
/// - 24:00 is a "tariff-schnitt" (=without_carryover)
|
|
||||||
/// (i.e. computation is carried out
|
|
||||||
/// on a per day basis. Total price is the sum of all days.)
|
|
||||||
bool repeated_default_without_carryover;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief waiting_period
|
|
||||||
/// @note Also called "Karenzzeit". Allowed values: [0, 3]
|
|
||||||
minute_t waiting_period;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CALCULATE_PARKING_TICKETS_TARIFF_H_INCLUDED
|
#endif // CALCULATE_PARKING_TICKETS_TARIFF_H_INCLUDED
|
||||||
|
@@ -18,13 +18,15 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parking_tariff_t *tariff =
|
parking_tariff_t *tariff =
|
||||||
parking_tariff_t::parseTariff("/opt/ptu5/opt/calculate_parking/calculate_parking_tickets/germersheim.conf");
|
//parking_tariff_t::parseTariff("/opt/ptu5/opt/calculate_parking/calculate_parking_tickets/germersheim.conf");
|
||||||
|
parking_tariff_t::parseTariff("/opt/ptu5/opt/calculate_parking/calculate_parking_tickets/apcoa_prio_1.conf");
|
||||||
|
|
||||||
if (tariff) {
|
if (tariff) {
|
||||||
price_t price;
|
price_t price;
|
||||||
memset(&price, 0x00, sizeof(price));
|
memset(&price, 0x00, sizeof(price));
|
||||||
QDateTime start = QDateTime::currentDateTime();
|
QDateTime start = QDateTime::currentDateTime();
|
||||||
QDateTime end;
|
QDateTime st = start;
|
||||||
|
QDateTime end, tmp;
|
||||||
start.setTime(QTime());
|
start.setTime(QTime());
|
||||||
int d1, d2 = 0;
|
int d1, d2 = 0;
|
||||||
|
|
||||||
@@ -34,7 +36,9 @@ int main() {
|
|||||||
|
|
||||||
for (int h = 0; h < 6; ++h) {
|
for (int h = 0; h < 6; ++h) {
|
||||||
for (int i = 0; i < MIN_PER_DAY; ++i) {
|
for (int i = 0; i < MIN_PER_DAY; ++i) {
|
||||||
fprintf(stderr, "\n*** %5d *** (parkdauer:%dh)", i*(h+1), hour[h]);
|
//int __x = i*(h+1);
|
||||||
|
//if (__x == 3060) {
|
||||||
|
fprintf(stderr, "\n*** %d:%d *** (parkdauer:%dh)", h, i, hour[h]);
|
||||||
|
|
||||||
if (d1 != d2) {
|
if (d1 != d2) {
|
||||||
qDebug() << ((i==0) ? 0: i/MIN_PER_DAY) << d1 << "***\n";
|
qDebug() << ((i==0) ? 0: i/MIN_PER_DAY) << d1 << "***\n";
|
||||||
@@ -44,25 +48,30 @@ int main() {
|
|||||||
//start = start.addSecs(i*60);
|
//start = start.addSecs(i*60);
|
||||||
//start = start.addSecs(420*60);
|
//start = start.addSecs(420*60);
|
||||||
minute_t const s = TUtils::toMinutes(start);
|
minute_t const s = TUtils::toMinutes(start);
|
||||||
end = start.addSecs(hour[h]*60*60);
|
tmp = start;
|
||||||
|
end = tmp.addSecs(hour[h]*60*60);
|
||||||
minute_t const e = TUtils::toMinutes(end);
|
minute_t const e = TUtils::toMinutes(end);
|
||||||
//minute_t const e = s + 24*60*3 + 123;
|
//minute_t const e = s + 24*60*3 + 123;
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"[EINFAHRT: %s:%02d:%02d, %ld Minuten frei, "
|
"[EINFAHRT: %s:%02d:%02d, (day:%ld,night:%ld) Minuten frei, "
|
||||||
"AUSFAHRT: %s:%02d:%02d]\n",
|
"AUSFAHRT: %s:%02d:%02d]\n",
|
||||||
start.date().toString().toStdString().c_str(),
|
start.date().toString().toStdString().c_str(),
|
||||||
start.time().hour(), start.time().minute(),
|
start.time().hour(), start.time().minute(),
|
||||||
tariff->free_of_charge,
|
tariff->free_of_charge_day_tariff,
|
||||||
|
tariff->free_of_charge_night_tariff,
|
||||||
end.date().toString().toStdString().c_str(),
|
end.date().toString().toStdString().c_str(),
|
||||||
end.time().hour(), end.time().minute());
|
end.time().hour(), end.time().minute());
|
||||||
|
|
||||||
if (compute_price_for_parking_ticket(tariff, s, e, &price)) {
|
if (compute_price_for_parking_ticket(tariff, s, e, &price)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
start = start.addSecs(60);
|
start = start.addSecs(60);
|
||||||
d1 = start.date().dayOfWeek();
|
d1 = start.date().dayOfWeek();
|
||||||
}
|
}
|
||||||
|
start = st;
|
||||||
|
d1 = start.date().dayOfWeek();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
175342
results/apcoa_prio_1.txt
Normal file
175342
results/apcoa_prio_1.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user