Compare commits

...

14 Commits

Author SHA1 Message Date
16ccb706da Merge branch 'neuhauser-kirchdorf' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into neuhauser-kirchdorf 2024-03-08 10:10:37 +01:00
fcbc8dcdc3 Merge branch 'neuhauser-kirchdorf' of https://git.mimbach49.de/GerhardHoffmann/MOBILISIS-Calculator into neuhauser-kirchdorf 2024-03-07 08:19:26 +01:00
ed99bae725 Use Calculator::getInstance() 2024-03-07 08:18:40 +01:00
627d14204d Use paymentRate.last() instead of aymentRate.at(0) so we can enter new entries
in tariff-files to provide the prices for an hour.
2024-03-07 08:17:32 +01:00
d8a4c4eaa7 Merge branch 'neuhauser-kirchdorf' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into neuhauser-kirchdorf 2024-02-29 09:30:22 +01:00
4f45db4fde revised tests for Neuhauser/Linsinger Maschinenbau (744) 2024-02-28 12:06:43 +01:00
a744a1ebb3 compute_product_price(): add handling for FOOD_STAMP 2024-02-28 12:06:02 +01:00
df16bd7f9c GetDailyTicketPrice(): add case for FOOD_STAMP (not implemented) 2024-02-28 12:05:14 +01:00
b751ba339e Add permit type FOOD_STAMP 2024-02-28 12:03:13 +01:00
588a88455b CalcState: add toString() method 2024-02-28 11:31:28 +01:00
92bfdced6a Merge branch 'neuhauser-kirchdorf' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into neuhauser-kirchdorf 2024-02-28 10:04:09 +01:00
8bbec596c9 Check for 08:00 <= currentTime <= 20:00 removed:
assumption is prepaid.
2024-02-28 09:58:00 +01:00
87b14ee3f8 Added check for NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM:
08:00 <= currentTime <= 20:00.
2024-02-28 09:26:51 +01:00
3ad2c77467 Adapted tests for NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM 2024-02-28 09:26:05 +01:00
5 changed files with 137 additions and 82 deletions

View File

@@ -84,6 +84,51 @@ struct CALCULATE_LIBRARY_API CalcState {
return (m_status == State::SUCCESS); return (m_status == State::SUCCESS);
} }
QString toString() {
QString s;
switch (m_status) {
case State::SUCCESS:
s = "SUCCESS";
break;
case State::ERROR_PARSING_ZONE_NR:
s = "ERROR_PARSING_ZONE_NR";
break;
case State::ERROR_LOADING_TARIFF:
s = "ERROR_LOADING_TARIFF";
break;
case State::ERROR_PARSING_TARIFF:
s = "ERROR_PARSING_TARIFF";
break;
case State::NEGATIVE_PARING_TIME:
s = "NEGATIVE_PARKING_TIME";
break;
case State::ABOVE_MAX_PARKING_TIME:
s = "ABOVE_MAX_PARKING_TIME";
break;
case State::WRONG_PARAM_VALUES:
s = "WRONG_PARAM_VALUES";
break;
case State::BELOW_MIN_PARKING_TIME:
s = "BELOW_MIN_PARKING_TIME";
break;
case State::BELOW_MIN_PARKING_PRICE:
s = "BELOW_MIN_PARKING_PRICE";
break;
case State::OVERPAID:
s = "OVERPAID";
break;
case State::INVALID_START_DATE:
s = "INVALID_START_DATE";
break;
case State::WRONG_ISO_TIME_FORMAT:
s = "WRONG_ISO_TIME_FORMAT";
break;
case State::OUTSIDE_ALLOWED_PARKING_TIME:
s = "OUTSIDE_ALLOWED_PARKING_TIME";
}
return s + ":" + m_desc;
}
explicit operator QString () const noexcept { explicit operator QString () const noexcept {
QString s; QString s;
switch (m_status) { switch (m_status) {

View File

@@ -11,6 +11,7 @@ enum class PERMIT_TYPE : quint8 {
DAY_TICKET_ADULT, DAY_TICKET_ADULT,
DAY_TICKET_TEEN, DAY_TICKET_TEEN,
DAY_TICKET_CHILD, DAY_TICKET_CHILD,
FOOD_STAMP,
INVALID INVALID
}; };
@@ -41,6 +42,9 @@ struct PermitType {
case 6: case 6:
m_permitType = PERMIT_TYPE::DAY_TICKET_CHILD; m_permitType = PERMIT_TYPE::DAY_TICKET_CHILD;
break; break;
case 7:
m_permitType = PERMIT_TYPE::FOOD_STAMP;
break;
default: default:
m_permitType = PERMIT_TYPE::INVALID; m_permitType = PERMIT_TYPE::INVALID;
} }
@@ -52,7 +56,7 @@ struct PermitType {
operator PERMIT_TYPE() const { return m_permitType; } operator PERMIT_TYPE() const { return m_permitType; }
operator int() const { operator int () const {
switch(m_permitType) { switch(m_permitType) {
case PERMIT_TYPE::SHORT_TERM_PARKING: case PERMIT_TYPE::SHORT_TERM_PARKING:
return 0; return 0;
@@ -68,6 +72,8 @@ struct PermitType {
return 5; return 5;
case PERMIT_TYPE::DAY_TICKET_TEEN: case PERMIT_TYPE::DAY_TICKET_TEEN:
return 6; return 6;
case PERMIT_TYPE::FOOD_STAMP:
return 7;
default: default:
break; break;
} }
@@ -75,7 +81,7 @@ struct PermitType {
} }
operator QString() const { operator QString () {
switch(m_permitType) { switch(m_permitType) {
case PERMIT_TYPE::DAY_TICKET: case PERMIT_TYPE::DAY_TICKET:
return QString("DAY_TICKET"); return QString("DAY_TICKET");
@@ -91,6 +97,32 @@ struct PermitType {
return QString("SZEGED_START"); return QString("SZEGED_START");
case PERMIT_TYPE::SZEGED_STOP: case PERMIT_TYPE::SZEGED_STOP:
return QString("SZEGED_STOP"); return QString("SZEGED_STOP");
case PERMIT_TYPE::FOOD_STAMP:
return QString("FOOD_STAMP");
default:
break;
}
return QString("INVALID");
}
operator QString () const {
switch(m_permitType) {
case PERMIT_TYPE::DAY_TICKET:
return QString("DAY_TICKET");
case PERMIT_TYPE::DAY_TICKET_ADULT:
return QString("DAY_TICKET_ADULT");
case PERMIT_TYPE::DAY_TICKET_CHILD:
return QString("DAY_TICKET_CHILD");
case PERMIT_TYPE::DAY_TICKET_TEEN:
return QString("DAY_TICKET_TEEN");
case PERMIT_TYPE::SHORT_TERM_PARKING:
return QString("SHORT_TERM_PARKING");
case PERMIT_TYPE::SZEGED_START:
return QString("SZEGED_START");
case PERMIT_TYPE::SZEGED_STOP:
return QString("SZEGED_STOP");
case PERMIT_TYPE::FOOD_STAMP:
return QString("FOOD_STAMP");
default: default:
break; break;
} }

View File

@@ -85,6 +85,8 @@ int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, PERMIT
// [[fallthrough]]; // [[fallthrough]];
case PERMIT_TYPE::DAY_TICKET_TEEN: case PERMIT_TYPE::DAY_TICKET_TEEN:
// [[fallthrough]]; // [[fallthrough]];
case PERMIT_TYPE::FOOD_STAMP:
// [[fallthrough]];
case PERMIT_TYPE::DAY_TICKET_ADULT: { case PERMIT_TYPE::DAY_TICKET_ADULT: {
std::optional<QVector<ATBTariffProduct>> products = cfg->getTariffProductForProductId(permitType); std::optional<QVector<ATBTariffProduct>> products = cfg->getTariffProductForProductId(permitType);
if (products) { if (products) {
@@ -92,6 +94,21 @@ int CALCULATE_LIBRARY_API compute_product_price(Configuration const *cfg, PERMIT
if (product.size() > 0) { if (product.size() > 0) {
ATBTariffProduct const &p = product[0]; ATBTariffProduct const &p = product[0];
return p.m_tariff_product_price; return p.m_tariff_product_price;
#if 0
// in case we do not have prepaid-option
QTime const &currentTime = QDateTime::currentDateTime().time();
if (p.m_tariff_product_start <= currentTime && currentTime <= p.m_tariff_product_end) {
return p.m_tariff_product_price;
} else {
qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
<< "ERROR currentTime"
<< currentTime.toString(Qt::ISODate)
<< "INVALID ("
<< p.m_tariff_product_start.toString(Qt::ISODate)
<< p.m_tariff_product_end.toString(Qt::ISODate) << ")";
}
#endif
} }
} }
} break; } break;
@@ -117,7 +134,7 @@ int CALCULATE_LIBRARY_API get_maximal_parkingprice(Configuration *cfg, PERMIT_TY
if (pv) { if (pv) {
QVector<ATBPaymentRate> const &paymentRate = pv.value(); QVector<ATBPaymentRate> const &paymentRate = pv.value();
if (paymentRate.size() > 0) { if (paymentRate.size() > 0) {
int const price = paymentRate.at(0).pra_price; // price is given per hour int const price = paymentRate.last().pra_price; // price is given per hour
maxPrice = qRound((maxTime * price) / 60.0f); maxPrice = qRound((maxTime * price) / 60.0f);
} }
} }

View File

@@ -1736,6 +1736,9 @@ Calculator::GetDailyTicketPrice(Configuration* cfg,
if (dailyTickets) { if (dailyTickets) {
QVector<ATBDailyTicket> const tickets = dailyTickets.value(); QVector<ATBDailyTicket> const tickets = dailyTickets.value();
switch (permitType) { switch (permitType) {
case PERMIT_TYPE::FOOD_STAMP: {
// TODO
} break;
case PERMIT_TYPE::DAY_TICKET_ADULT: { case PERMIT_TYPE::DAY_TICKET_ADULT: {
std::optional<ATBCustomer> c = cfg->getCustomerForType(ATBCustomer::CustomerType::ADULT); std::optional<ATBCustomer> c = cfg->getCustomerForType(ATBCustomer::CustomerType::ADULT);
if (c) { if (c) {

View File

@@ -34,13 +34,13 @@ 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)
#define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0) #define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (1)
#define NEUHAUSER_BILEXA_GALTUER (0) #define NEUHAUSER_BILEXA_GALTUER (0)
#define NEUHAUSER_KIRCHDORF (1) #define NEUHAUSER_KIRCHDORF (0)
#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) {
@@ -429,13 +429,12 @@ int main() {
QDateTime end2 = QDateTime(); QDateTime end2 = QDateTime();
if (compute_duration_for_parking_ticket(&cfg, start, cost, end2)) { // return value if (compute_duration_for_parking_ticket(&cfg, start, cost, end2)) { // return value
qCritical() << "XXXX start" << start.toString(Qt::ISODate) qCritical() << "start" << start.toString(Qt::ISODate)
<< "offset" << offset << "offset" << offset
<< "cost" << cost << "cost" << cost
<< "end" << end2.toString(Qt::ISODate); << "end" << end2.toString(Qt::ISODate);
if (end != end2) { if (end != end2) {
qCritical() << "YYYY" qCritical() << end.toString(Qt::ISODate)
<< end.toString(Qt::ISODate)
<< end2.toString(Qt::ISODate); << end2.toString(Qt::ISODate);
} }
} }
@@ -570,15 +569,16 @@ int main() {
int Up = 1; int Up = 1;
//compute_next_timestep(&cfg, ) //compute_next_timestep(&cfg, )
QDateTime const start = QDateTime::currentDateTime();
for (int i=0; i<timeSteps.size(); ++i) { for (int i=0; i<timeSteps.size(); ++i) {
int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up); int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up);
qCritical() << "nextTimeStep" << nextTimeStep; qCritical() << "nextTimeStep" << nextTimeStep;
// uint32_t price = calculator.GetPriceForTimeStep(&cfg, timeSteps.at(i)); uint32_t price = Calculator::GetInstance().GetPriceForTimeStep(&cfg, timeSteps.at(i));
// uint32_t duration = calculator.GetDurationForPrice(&cfg, price); uint32_t duration = Calculator::GetInstance().GetDurationForPrice(&cfg, price);
// qCritical() << "nextTimeStep relative to start:" qCritical() << "nextTimeStep relative to start:"
// << duration << start.addSecs(duration * 60) << duration << start.addSecs(duration * 60).toString(Qt::ISODate)
// << "(price so far:" << price << ")"; << "(price so far:" << price << ")";
} }
} }
#endif #endif
@@ -603,39 +603,28 @@ int main() {
int w = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_TEEN); int w = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_TEEN);
qCritical() << "price teen" << w; qCritical() << "price teen" << w;
return 0;
QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime s(QDate(2023, 11, 30), QTime());
QDateTime end; QDateTime end;
struct price_t price; struct price_t price;
#define ADULT 0 #define ADULT 1
#define TEEN 1 //#define TEEN 1
for (int offset = 480; offset < 1200; ++offset) {
QDateTime start = s.addSecs(offset * 60);
CalcState cs = compute_price_for_daily_ticket(&cfg, start, end,
#if ADULT==1 #if ADULT==1
for (int offset = 480; offset < 1080; ++offset) { PERMIT_TYPE::DAY_TICKET_ADULT,
QDateTime start = s.addSecs(offset * 60); #elif TEEN==1
PERMIT_TYPE::DAY_TICKET_TEEN,
// qCritical() << QString(Calculator::GetInstance().isParkingAllowed(&cfg, start)); #endif
&price);
CalcState cs = compute_price_for_daily_ticket(&cfg, start, end,
PERMIT_TYPE::DAY_TICKET_ADULT, &price);
qCritical() << "start=" << start.toString(Qt::ISODate) qCritical() << "start=" << start.toString(Qt::ISODate)
<< "end" << end.toString(Qt::ISODate) << "price" << price.netto; << "end" << end.toString(Qt::ISODate) << "price" << price.netto;
} }
#endif
#if TEEN==1
for (int offset = 480; offset < 1080; ++offset) {
QDateTime start = s.addSecs(offset * 60);
CalcState cs = compute_price_for_daily_ticket(&cfg, start, end,
PERMIT_TYPE::DAY_TICKET_TEEN, &price);
qCritical() << "start=" << start.toString(Qt::ISODate)
<< "end" << end.toString(Qt::ISODate) << "price" << price.netto;
} }
#endif #undef ADULT
} #undef TEEN
#endif #endif
#if NEUHAUSER_LINSINGER_MASCHINENBAU==1 #if NEUHAUSER_LINSINGER_MASCHINENBAU==1
@@ -651,50 +640,19 @@ int main() {
cout << endl; cout << endl;
if (isParsed) { if (isParsed) {
bool nextDay = false; int const price = compute_product_price(&cfg, PERMIT_TYPE::FOOD_STAMP);
bool prePaid = false; qCritical() << "price food stamp" << price;
// 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 <= 360; ++offset) {
// for (int offset = 360; offset < 1080; ++offset) {
QDateTime start = s.addSecs(offset * 60);
//qCritical() << "start" << start.toString(Qt::ISODate);
// note: prepaid == false (!)
// double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 4, start, end, marken[duration], nextDay, prePaid);
struct price_t price;
if (compute_price_for_parking_ticket(&cfg, start, marken[duration], end, &price, prePaid)) {
double cost = price.netto;
qCritical() << "start" << start.toString(Qt::ISODate)
<< "end" << end.toString(Qt::ISODate)
<< "duration" << marken[duration]
<< "cost" << cost;
}
//std::string d = Calculator::GetInstance().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 #endif
#if NEUHAUSER_KORNEUBURG==1 #if NEUHAUSER_KORNEUBURG==1
std::ifstream input("/tmp/tariff_korneuburg.json"); std::ifstream input("/opt/ptu5/opt/customer_714/etc/psa_tariff/tariff01.json");
int pop_max_time; int pop_max_time;
std::stringstream sstr; std::stringstream sstr;
while(input >> sstr.rdbuf()); while(input >> sstr.rdbuf());
std::string json(sstr.str()); std::string json(sstr.str());
Calculator calculator;
Configuration cfg; Configuration cfg;
bool isParsed = cfg.ParseJson(&cfg, json.c_str()); bool isParsed = cfg.ParseJson(&cfg, json.c_str());
@@ -716,19 +674,19 @@ int main() {
QDateTime start = s.addSecs(offset * 60); QDateTime start = s.addSecs(offset * 60);
//qCritical() << "start" << start.toString(Qt::ISODate); //qCritical() << "start" << start.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid); double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid);
//Q_ASSERT(cost == duration*2.5); //Q_ASSERT(cost == duration*2.5);
//qCritical() << ""; //qCritical() << "";
//qCritical() << "start" << start.toString(Qt::ISODate)
// << "end" << end.toString(Qt::ISODate)
// << "duration" << duration
// << "cost" << cost;
std::string duration = calculator.GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
//Q_ASSERT(cost == duration*2.5);
qCritical() << "start" << start.toString(Qt::ISODate) qCritical() << "start" << start.toString(Qt::ISODate)
<< "cost" << cost << "end" << end.toString(Qt::ISODate)
<< "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60; << "duration" << duration
<< "cost" << cost;
//std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
//Q_ASSERT(cost == duration*2.5);
//qCritical() << "start" << start.toString(Qt::ISODate)
// << "cost" << cost
// << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60;
} }
} }
} }