Compare commits

..

No commits in common. "d0e06999065dba8c3ec0d730770ff310c147cafd" and "0f05a1a784c52ee27816a283073da7f881e765ac" have entirely different histories.

11 changed files with 92 additions and 222 deletions

View File

@ -45,20 +45,6 @@ public:
// (e.g. Schoenau/Koenigsee)
//
QList<int> GetTimeSteps(Configuration *cfg) const;
QList<int> GetSteps(Configuration *cfg) const { return GetTimeSteps(cfg); }
// additional helper functions
bool noSpecialDays(Configuration const *cfg) const {
return (cfg->SpecialDays.size() == 0) && (cfg->SpecialDaysWorktime.size() == 0);
}
bool specialDays(Configuration const *cfg) const {
return !noSpecialDays(cfg);
}
bool tariffIs24_7(Configuration const *cfg) const {
return (cfg->YearPeriod.size() == 0 &&
cfg->SpecialDays.size() == 0 &&
cfg->SpecialDaysWorktime.size() == 0);
}
private:
// Introduced for PaymentMethod::Steps (e.g. Schoenau)
@ -66,6 +52,11 @@ private:
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, quint64 durationMinutes) const;
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, QDateTime const &end) const;
PaymentMethod getPaymentMethodId(Configuration const *cfg);
int getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId);
int getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId);
uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
Ticket private_GetCostFromDuration(Configuration const* cfg,
QDateTime const &start,
int durationMinutes,
@ -80,13 +71,7 @@ private:
//
uint32_t GetPriceForTimeStep(Configuration *cfg, int timeStep) const;
uint32_t GetPriceForStep(Configuration *cfg, int step) const {
return GetPriceForTimeStep(cfg, step);
}
uint32_t GetDurationForPrice(Configuration *cfg, int price) const;
uint32_t GetStepForPrice(Configuration *cfg, int price) const {
return GetDurationForPrice(cfg, price);
}
int findWorkTimeRange(QDateTime const &dt,
QScopedArrayPointer<TariffTimeRange> const &worktime,
@ -94,6 +79,9 @@ private:
int findNextWorkTimeRange(QDateTime const &dt,
QScopedArrayPointer<TariffTimeRange> const &worktime,
size_t size);
uint32_t computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id) const;
double computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id) const;
};
#endif // CALCULATOR_FUNCTIONS_H_INCLUDED

View File

@ -4,8 +4,6 @@
class ATBPaymentOption
{
public:
ATBPaymentOption() = default;
int pop_id;
std::string pop_label;
int pop_payment_method_id;
@ -17,5 +15,4 @@ public:
double pop_min_price;
int pop_carry_over;
int pop_daily_card_price;
int pop_business_hours;
};

View File

@ -1,21 +0,0 @@
#ifndef TARIFF_BUSINESS_HOURS_H_INCLUDED
#define TARIFF_BUSINESS_HOURS_H_INCLUDED
/// <summary>
/// Business hours (byte represents payment option id)
/// </summary>
enum BusinessHours
{
NoRestriction_24_7 = 0,
OnlyWorkingDays = 1, // [Monday-Friday]
OnlyWeekDays = 2, // [Monday-Saturday]
OnlyWeekEnd = 4, // [Saturday+Sunday]
OnlyOfficialHolidays = 8,
OnlySpecialDays = 16,
OnlySchoolHolidays = 32,
SpecialAndSchoolHolidays = 48,
OnlyOpenForBusinessDays = 64, // verkaufsoffen
NoBusinessHoursDefined = 255
};
#endif // TARIFF_BUSINESS_HOURS_H_INCLUDED

View File

@ -16,12 +16,6 @@ public:
: m_time_from(QTime())
, m_time_until(QTime()) {}
TariffTimeRange(QTime const& from, QTime const &until)
: m_time_from(from)
, m_time_until(until) {
}
void setTimeRange(QTime const& from, QTime const &until) {
m_time_from = from;
m_time_until = until;

View File

@ -1,5 +1,6 @@
#pragma once
#include <cstring>
#include <string.h>
#include <ctime>
#include <iostream>
#include <cmath>
@ -8,7 +9,6 @@
#include "configuration.h"
#include "time_range.h"
#include "payment_method.h"
#include "tariff_business_hours.h"
#include <QDateTime>
@ -87,7 +87,4 @@ namespace Utilities {
int getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId);
uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId);
BusinessHours getBusinessHours(Configuration const *cfg, PaymentMethod methodId);
uint32_t computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id);
double computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id);
}

View File

@ -68,8 +68,7 @@ HEADERS += \
include/mobilisis/tariff_log.h \
include/mobilisis/calculate_price.h \
include/mobilisis/atb_project.h \
include/mobilisis/ticket.h \
include/mobilisis/tariff_business_hours.h
include/mobilisis/ticket.h
OTHER_FILES += src/main.cpp

View File

@ -173,9 +173,9 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
qCritical() << " compute_next_timestep() firstDurationStep:" << firstDurationStep;
int const nextTimeStep = currentTimeMinutes + firstDurationStep;
int nextTimeStep = currentTimeMinutes + firstDurationStep;
if (nextTimeStep >= minParkingTime && nextTimeStep <= maxParkingTime) {
if (currentTimeMinutes >= minParkingTime && nextTimeStep <= maxParkingTime) {
qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep;
return nextTimeStep;
}

View File

@ -128,40 +128,14 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
// Get input date
QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate);
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
if (paymentMethodId == PaymentMethod::Steps) {
if (tariffIs24_7(cfg)) {
// use tariff with structure as for instance Schoenau, Koenigsee:
// use tariff with structure as for instance Schnau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime
if (cfg->YearPeriod.size() == 0
&& cfg->SpecialDays.size() == 0
&& cfg->SpecialDaysWorktime.size() == 0)
{
inputDate = inputDate.addSecs(GetDurationForPrice(cfg, price) * 60);
return inputDate.toString(Qt::ISODate).toStdString();
} else {
QDateTime const &start = QDateTime::fromString(start_datetime, Qt::ISODate);
if (Utilities::IsYearPeriodActive(cfg, start)) {
if (!prepaid) {
BusinessHours businessHours = Utilities::getBusinessHours(cfg, paymentMethodId);
if (businessHours == BusinessHours::OnlyWeekDays) {
int const weekdayId = start.date().dayOfWeek();
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) {
QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr);
QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr);
QTime const& startTime = start.time();
if (from <= startTime && startTime <= until) {
return inputDate.addSecs(GetDurationForPrice(cfg, price) * 60).toString(Qt::ISODate).toStdString();
}
}
}
}
qCritical() << __PRETTY_FUNCTION__ << "NOT YET IMPLEMENTED";
return 0;
}
}
}
Ticket t = private_GetDurationFromCost(cfg, inputDate, price, prepaid);
@ -182,8 +156,9 @@ uint32_t Calculator::GetCostFromDuration(Configuration *cfg,
quint64 timeStepInMinutes) const {
// for instance, a tariff as used in Schoenau, Koenigssee: only steps, no
// special days, nonstop.
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
if (paymentMethodId == PaymentMethod::Steps) {
if (cfg->YearPeriod.size() == 0
&& cfg->SpecialDays.size() == 0
&& cfg->SpecialDaysWorktime.size() == 0) {
QDateTime const end = start.addSecs(timeStepInMinutes*60);
return GetCostFromDuration(cfg, start, end);
}
@ -193,8 +168,9 @@ uint32_t Calculator::GetCostFromDuration(Configuration *cfg,
uint32_t Calculator::GetCostFromDuration(Configuration * cfg,
QDateTime const &start,
QDateTime const &end) const {
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
if (paymentMethodId == PaymentMethod::Steps) {
if (cfg->YearPeriod.size() == 0
&& cfg->SpecialDays.size() == 0
&& cfg->SpecialDaysWorktime.size() == 0) {
int const timeStepInMinutes = start.secsTo(end) / 60;
return GetPriceForTimeStep(cfg, timeStepInMinutes);
}
@ -217,39 +193,12 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
Q_UNUSED(payment_option);
Q_UNUSED(nextDay);
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
if (paymentMethodId == PaymentMethod::Steps) {
if (tariffIs24_7(cfg)) {
if (cfg->YearPeriod.size() == 0
&& cfg->SpecialDays.size() == 0
&& cfg->SpecialDaysWorktime.size() == 0)
{
end_datetime = start_datetime.addSecs(durationMinutes*60);
return GetCostFromDuration(cfg, start_datetime, end_datetime);
} else {
if (Utilities::IsYearPeriodActive(cfg, start_datetime)) {
if (!prepaid) {
BusinessHours businessHours = Utilities::getBusinessHours(cfg, paymentMethodId);
if (businessHours == BusinessHours::OnlyWeekDays) {
int const weekdayId = start_datetime.date().dayOfWeek();
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) {
QTime const &from = Utilities::WeekDaysWorkTimeFrom(itr);
QTime const &until = Utilities::WeekDaysWorkTimeUntil(itr);
QTime const &startTime = start_datetime.time();
if (from <= startTime && startTime <= until) {
end_datetime = start_datetime.addSecs(durationMinutes*60);
return GetCostFromDuration(cfg, start_datetime, end_datetime);
}
}
}
}
qCritical() << __PRETTY_FUNCTION__ << "NOT YET IMPLEMENTED";
end_datetime = QDateTime();
return 0;
}
}
}
QDateTime start = start_datetime;
@ -266,6 +215,18 @@ double Calculator::GetCostFromDuration(Configuration* cfg,
return t.getPrice();
}
int Calculator::getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_time, 0);
}
int Calculator::getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_time, 0);
}
uint32_t Calculator::getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_price, 0);
}
bool Calculator::checkDurationMinutes(int minParkingTime,
int maxParkingTime,
int durationMinutes) {
@ -310,6 +271,17 @@ int Calculator::findNextWorkTimeRange(QDateTime const &dt,
return nextWorkTimeRange;
}
uint32_t Calculator::computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id) const {
int pop_id = cfg->PaymentOption.find(id)->second.pop_id;
return cfg->PaymentRate.find(pop_id)->second.pra_price;
}
double Calculator::computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id) const {
int pop_id = cfg->PaymentOption.find(id)->second.pop_id;
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
return (double)(cfg->Duration.find(durationId)->second.pun_duration);
}
using namespace Utilities;
Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
@ -319,12 +291,12 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId);
static const int minParkingTimeMinutes = Utilities::getMinimalParkingTime(cfg, paymentMethodId);
static const int maxParkingTimeMinutes = Utilities::getMaximalParkingTime(cfg, paymentMethodId);
static const int minParkingTimeMinutes = getMinimalParkingTime(cfg, paymentMethodId);
static const int maxParkingTimeMinutes = getMaximalParkingTime(cfg, paymentMethodId);
static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes);
static const int durationMinutesNetto = durationMinutes;
static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId);
static const double weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId);
static const uint32_t weekDaysPrice = computeWeekDaysPrice(cfg, paymentMethodId);
static const double weekDaysDurationUnit = computeWeekDaysDurationUnit(cfg, paymentMethodId);
static const double specialDaysDurationUnit = 60.0;
if (!checkMinMaxMinutes) {
@ -508,14 +480,29 @@ Ticket Calculator::private_GetDurationFromCost(Configuration *cfg,
// Get input date
QDateTime current = start;
// use tariff with structure as for instance Schnau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime
if (cfg->YearPeriod.size() == 0
&& cfg->SpecialDays.size() == 0
&& cfg->SpecialDaysWorktime.size() == 0)
{
uint64_t const durationMinutes = GetDurationForPrice(cfg, cost);
uint64_t const durationSeconds = durationMinutes * 60;
current = current.addSecs(durationSeconds);
return
Ticket(start, current, durationMinutes, durationMinutes,
cost, Ticket::s[VALID]);
}
static const PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
static const bool carryOverNotSet = isCarryOverNotSet(cfg, paymentMethodId);
static const uint32_t minParkingTimeMinutes = std::max(Utilities::getMinimalParkingTime(cfg, paymentMethodId), 0);
static const uint32_t maxParkingTimeMinutes = std::max(Utilities::getMaximalParkingTime(cfg, paymentMethodId), 0);
static const uint32_t minParkingTimeMinutes = std::max(getMinimalParkingTime(cfg, paymentMethodId), 0);
static const uint32_t maxParkingTimeMinutes = std::max(getMaximalParkingTime(cfg, paymentMethodId), 0);
static const uint32_t minParkingPrice = getMinimalParkingPrice(cfg, paymentMethodId);
// static const bool checkMinMaxMinutes = (minParkingTimeMinutes < maxParkingTimeMinutes);
static const uint32_t weekDaysPrice = Utilities::computeWeekDaysPrice(cfg, paymentMethodId);
static const uint32_t weekDaysDurationUnit = Utilities::computeWeekDaysDurationUnit(cfg, paymentMethodId);
static const uint32_t weekDaysPrice = computeWeekDaysPrice(cfg, paymentMethodId);
static const uint32_t weekDaysDurationUnit = computeWeekDaysDurationUnit(cfg, paymentMethodId);
static const uint32_t specialDaysDurationUnit = 60;
if(cost < minParkingPrice) {

View File

@ -78,7 +78,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
ATBWeekDaysWorktime WeekDaysWorktime;
ATBPaymentOption PaymentOption;
ATBPeriodYear YearPeriod;
MemberType mb_type = MemberType::UnknownType;
MemberType mb_type;
// Get all JSON object members
// This code should run only once (to load JSON variables into memory)
@ -169,7 +169,6 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
else if (strcmp(inner_obj_name, "pop_min_price") == 0) PaymentOption.pop_min_price = k->value.GetDouble();
else if (strcmp(inner_obj_name, "pop_carry_over") == 0) PaymentOption.pop_carry_over = k->value.GetInt();
else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) PaymentOption.pop_daily_card_price = k->value.GetInt();
else if (strcmp(inner_obj_name, "pop_business_hours") == 0) PaymentOption.pop_business_hours = k->value.GetInt();
this->currentPaymentOptions = PaymentOption;
break;
case MemberType::DurationType:

View File

@ -197,8 +197,7 @@ bool Utilities::IsYearPeriodActive(Configuration* cfg, struct tm* currentDateTim
}
bool Utilities::IsYearPeriodActive(Configuration const *cfg, QDateTime const &dt) {
if ((cfg->YearPeriod.size() > 0) &&
std::none_of(cfg->YearPeriod.cbegin(),
if (std::none_of(cfg->YearPeriod.cbegin(),
cfg->YearPeriod.cend(),
[&dt](std::pair<int, ATBPeriodYear> const &year) {
QDate const d(2004, // 2004 is a leap year
@ -400,30 +399,3 @@ uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod
return firstDurationStep;
}
BusinessHours Utilities::getBusinessHours(Configuration const *cfg, PaymentMethod methodId) {
int businessHours = cfg->PaymentOption.find(methodId)->second.pop_business_hours;
switch (businessHours) {
case NoRestriction_24_7: return NoRestriction_24_7;
case OnlyWorkingDays: return OnlyWorkingDays;
case OnlyWeekDays: return OnlyWeekDays;
case OnlyWeekEnd: return OnlyWeekEnd;
case OnlyOfficialHolidays: return OnlyOfficialHolidays;
case OnlySpecialDays: return OnlySpecialDays;
case OnlySchoolHolidays: return OnlySchoolHolidays;
case SpecialAndSchoolHolidays: return SpecialAndSchoolHolidays;
case OnlyOpenForBusinessDays: return OnlyOpenForBusinessDays;
}
return NoBusinessHoursDefined;
}
uint32_t Utilities::computeWeekDaysPrice(Configuration const *cfg, PaymentMethod id) {
int pop_id = cfg->PaymentOption.find(id)->second.pop_id;
return cfg->PaymentRate.find(pop_id)->second.pra_price;
}
double Utilities::computeWeekDaysDurationUnit(Configuration const *cfg, PaymentMethod id) {
int pop_id = cfg->PaymentOption.find(id)->second.pop_id;
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
return (double)(cfg->Duration.find(durationId)->second.pun_duration);
}

View File

@ -33,53 +33,11 @@ extern "C" char* strptime(const char* s,
#include "calculator_functions.h"
#include <calculate_price.h>
#define SZEGED (0)
#define SZEGED (1)
#define NEUHAUSER_KORNEUBURG (0)
#define NEUHAUSER_LINSINGER_MASCHINENBAU (1)
int main() {
#if NEUHAUSER_LINSINGER_MASCHINENBAU==1
std::ifstream input("/tmp/tariff_linsinger_maschinenbau.json");
std::stringstream sstr;
while(input >> sstr.rdbuf());
std::string json(sstr.str());
Calculator calculator;
Configuration cfg;
bool isParsed = cfg.ParseJson(&cfg, json.c_str());
cout << endl;
if (isParsed) {
bool nextDay = false;
bool prePaid = false;
// zone 1 (lila)
QDateTime s(QDate(2023, 11, 30), QTime());
QDateTime end;
int marken[] = { 3*60, 5*60, 10*60};
for (int duration = 0; duration < 3; ++duration) {
for (int offset = 360; offset <= 1080; ++offset) {
QDateTime start = s.addSecs(offset * 60);
//qCritical() << "start" << start.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration(&cfg, 4, start, end, marken[duration], nextDay, prePaid);
//qCritical() << "";
//qCritical() << "start" << start.toString(Qt::ISODate)
// << "end" << end.toString(Qt::ISODate)
// << "duration" << marken[duration]
// << "cost" << cost;
std::string d = calculator.GetDurationFromCost(&cfg, 4, start.toString(Qt::ISODate).toStdString().c_str(), cost);
qCritical() << "start" << start.toString(Qt::ISODate)
<< "cost" << cost
<< "until" << d.c_str() << start.secsTo(QDateTime::fromString(d.c_str(), Qt::ISODate)) / 60;
}
}
}
#endif
#if NEUHAUSER_KORNEUBURG==1
std::ifstream input("/tmp/tariff_korneuburg.json");