From 1c0374533349d7b6460ea17648c79c5822b7177a Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Mon, 8 May 2023 12:32:44 +0200 Subject: [PATCH 1/5] Add CalcState to be used as return type of tarif_init and compute_price_for_parking_ticket. --- library/include/mobilisis/calculate_price.h | 77 +++++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/library/include/mobilisis/calculate_price.h b/library/include/mobilisis/calculate_price.h index 5f05367..bbcda42 100644 --- a/library/include/mobilisis/calculate_price.h +++ b/library/include/mobilisis/calculate_price.h @@ -4,6 +4,8 @@ #include #include +#include + #ifdef WIN32 #ifdef CALCULATE_LIBRARY_EXPORTS #define CALCULATE_LIBRARY_API __declspec(dllexport) @@ -30,14 +32,79 @@ struct CALCULATE_LIBRARY_API price_t { double vat; }; -bool CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file); +struct CALCULATE_LIBRARY_API CalcState { + enum class State : uint8_t { + SUCCESS, + ERROR_PARSING_ZONE_NR, + ERROR_LOADING_TARIFF, + ERROR_PARSING_TARIFF, + NEGATIVE_PARING_TIME, + WRONG_PARAM_VALUES, + ABOVE_MAX_PARKING_TIME, + BELOW_MIN_PARKING_TIME, + BELOW_MIN_PARKING_PRICE, + OVERPAID + }; + + State m_status; + QString m_desc; + + explicit CalcState() : m_status(State::SUCCESS), m_desc("") {} + + explicit operator bool() const noexcept { + return (m_status == State::SUCCESS); + } + + explicit operator QString () const noexcept { + 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; + } + return s + ":" + m_desc; + } + + CalcState &set(State s) { m_status = s; return *this; } + CalcState &setDesc(QString s) { m_desc = s; return *this; } +}; + +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, + char const *config_file); void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff); int CALCULATE_LIBRARY_API get_zone_nr(); -bool CALCULATE_LIBRARY_API compute_price_for_parking_ticket(parking_tariff_t *tariff, - time_t start_parking_time, - time_t end_parking_time, - struct price_t *price); +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(parking_tariff_t *tariff, + time_t start_parking_time, + time_t end_parking_time, + struct price_t *price); #ifdef __cplusplus } // extern "C" #endif From c5960a031ea9c22c69934c7444d15a8f6eaeef3d Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Mon, 8 May 2023 12:34:01 +0200 Subject: [PATCH 2/5] init_tariff, compute_price_for_parking_ticket: return instance of CalcState as info for errors or success status. --- library/src/calculate_price.cpp | 101 +++++++++++++++++++------------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/library/src/calculate_price.cpp b/library/src/calculate_price.cpp index a04d82a..0125777 100644 --- a/library/src/calculate_price.cpp +++ b/library/src/calculate_price.cpp @@ -16,19 +16,18 @@ int CALCULATE_LIBRARY_API get_zone_nr() { QFileInfo finfo(zone); if (finfo.size() <= 4) { // decimal 000\n if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&zone); return in.readLine(100).toInt(); - } } } return -1; } -bool CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { +CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) { *tariff = new Configuration(); + CalcState calcState; int const zone = get_zone_nr(); // DEBUG @@ -36,7 +35,7 @@ bool CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *co qCritical() << " ... zone = " << zone; if (zone <= 0) { - return false; + return calcState.set(CalcState::State::ERROR_PARSING_ZONE_NR); } QString confFile(config_file); @@ -53,57 +52,79 @@ bool CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *co qCritical() << " ... confFile = " << confFile; QFile fname(confFile); - if (fname.exists()) { - + if (fname.exists() && + fname.open(QIODevice::ReadOnly | QIODevice::Text)) { // DEBUG - qCritical() << " ... confFile exists"; + qCritical() << " ... confFile is open"; - if (fname.open(QIODevice::ReadOnly | QIODevice::Text)) { - - // DEBUG - qCritical() << " ... confFile is open"; - - QString json = fname.readAll(); - return (*tariff)->ParseJson(*tariff, json.toStdString().c_str()); + QString json = fname.readAll(); + if (! (*tariff)->ParseJson(*tariff, json.toStdString().c_str())) { + calcState.m_status = CalcState::State::ERROR_PARSING_TARIFF; } + } else { + calcState.m_status = CalcState::State::ERROR_LOADING_TARIFF; } qCritical() << "init_tariff: Parsing tariff config (" << confFile << ") failed!"; - return false; + return calcState; } void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) { delete tariff; } -bool CALCULATE_LIBRARY_API compute_price_for_parking_ticket( - parking_tariff_t *tariff, - time_t start_parking_time, // in minutes - time_t end_parking_time, // in minutes - struct price_t *price) { +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, // in minutes + time_t end_parking_time, // in minutes + struct price_t *price) { + CalcState calcState; + double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time; + double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time; + + if (minMin < 0 || maxMin < 0 || maxMin < minMin) { + calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin, maxMin)); + return calcState.set(CalcState::State::WRONG_PARAM_VALUES); + } + int const duration = end_parking_time - start_parking_time; - if (duration > 0) { - QDate const d(1970, 1, 1); - QTime const t(0, 0, 0); - QDateTime start(d, t, Qt::UTC); - start = start.toLocalTime().addSecs(start_parking_time * 60); - if (start.isValid()) { - QString cs = start.toString(Qt::ISODate); - double cost = calculator.GetCostFromDuration( - tariff, PaymentOption::Option1, - cs.toLocal8Bit().constData(), - duration, false, true); - price->units = cost; - price->netto = cost; - return true; - } - } else + if (duration < 0) { + calcState.setDesc(QString("end=%1, start=%2") + .arg(end_parking_time, start_parking_time)); + return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); + } + if (duration > maxMin) { + calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration, maxMin)); + return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); + } + if (duration < minMin) { + calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration, minMin)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); + } if (duration == 0) { memset(price, 0x00, sizeof(*price)); - return true; + return calcState.set(CalcState::State::SUCCESS); } - qCritical() << "ERROR start_parking_time (" << start_parking_time << ") <" - << "end_parking_time (" << end_parking_time << ")"; - return false; + + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + double cost = calculator.GetCostFromDuration( + tariff, PaymentOption::Option1, + cs.toLocal8Bit().constData(), + duration, false, true); + double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price; + if (cost < minCost) { + calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost)); + return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE); + } + price->units = cost; + price->netto = cost; + } + + return calcState.set(CalcState::State::SUCCESS); } From 01f2dc07ce423d9ddc80de1de294bc08b69dc48b Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 9 May 2023 11:38:39 +0200 Subject: [PATCH 3/5] Added INVALID_START_DATE. Added compute_duration_for_parking_ticket(). --- library/include/mobilisis/calculate_price.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/include/mobilisis/calculate_price.h b/library/include/mobilisis/calculate_price.h index bbcda42..8c4dcfb 100644 --- a/library/include/mobilisis/calculate_price.h +++ b/library/include/mobilisis/calculate_price.h @@ -39,6 +39,7 @@ struct CALCULATE_LIBRARY_API CalcState { ERROR_LOADING_TARIFF, ERROR_PARSING_TARIFF, NEGATIVE_PARING_TIME, + INVALID_START_DATE, WRONG_PARAM_VALUES, ABOVE_MAX_PARKING_TIME, BELOW_MIN_PARKING_TIME, @@ -88,6 +89,9 @@ struct CALCULATE_LIBRARY_API CalcState { case State::OVERPAID: s = "OVERPAID"; break; + case State::INVALID_START_DATE: + s = "INVALID_START_DATE"; + break; } return s + ":" + m_desc; } @@ -101,10 +105,17 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff); int CALCULATE_LIBRARY_API get_zone_nr(); -CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(parking_tariff_t *tariff, +CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( + parking_tariff_t *tariff, time_t start_parking_time, time_t end_parking_time, struct price_t *price); + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double cost, + QString &duration); #ifdef __cplusplus } // extern "C" #endif From ceb545b432c82dfce4faa1feefdfaecf270b0f58 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 9 May 2023 11:40:14 +0200 Subject: [PATCH 4/5] Implemented compute_duration_for_parking_ticket(). --- library/src/calculate_price.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/src/calculate_price.cpp b/library/src/calculate_price.cpp index 0125777..58363a6 100644 --- a/library/src/calculate_price.cpp +++ b/library/src/calculate_price.cpp @@ -124,6 +124,30 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( } price->units = cost; price->netto = cost; + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); + } + + return calcState.set(CalcState::State::SUCCESS); +} + +CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( + parking_tariff_t *tariff, + time_t start_parking_time, + double price, + QString &duration) { + CalcState calcState; + QDate const d(1970, 1, 1); + QTime const t(0, 0, 0); + QDateTime start(d, t, Qt::UTC); + start = start.toLocalTime().addSecs(start_parking_time * 60); + if (start.isValid()) { + QString cs = start.toString(Qt::ISODate); + duration = calculator.GetDurationFromCost(tariff, PaymentOption::Option1, + cs.toLocal8Bit().constData(), + price, false, true).c_str(); + } else { + return calcState.set(CalcState::State::INVALID_START_DATE); } return calcState.set(CalcState::State::SUCCESS); From b02115bf75b3394a8cc0e234ffac1c7bdb698aa1 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 9 May 2023 11:41:41 +0200 Subject: [PATCH 5/5] Prepare the use of ceil() instead of floor(). --- library/src/calculator_functions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/src/calculator_functions.cpp b/library/src/calculator_functions.cpp index f7cb568..97e0b2e 100644 --- a/library/src/calculator_functions.cpp +++ b/library/src/calculator_functions.cpp @@ -509,5 +509,6 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio double ret_val = total_cost; total_cost = 0.0f; - return floor(ret_val); + // return ceil(ret_val); + return floor(ret_val); }