Compare commits

..

2 Commits

Author SHA1 Message Date
GerhardHoffmann 124eb64018 Use fprintf instead of printf. 2023-05-12 10:04:04 +02:00
GerhardHoffmann 4bc343c5b2 Add tariff Zone_1. unit_id set to 3. 2023-05-12 10:03:30 +02:00
17 changed files with 434 additions and 3776 deletions
+4 -10
View File
@@ -109,7 +109,7 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff); void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff);
int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1); int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
time_t start_parking_time, time_t start_parking_time,
time_t end_parking_time, time_t end_parking_time,
@@ -118,11 +118,10 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // depre
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
QDateTime const &start_parking_time, QDateTime const &start_parking_time,
int netto_parking_time, QDateTime const &end_parking_time,
QDateTime &end_parking_time, // return value struct price_t *price);
struct price_t *price); // return value
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( // deprecated CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
time_t start_parking_time, time_t start_parking_time,
double cost, double cost,
@@ -132,11 +131,6 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
QDateTime const &start_parking_time, QDateTime const &start_parking_time,
double cost, double cost,
QDateTime &ticketEndTime); // return value
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime &ticketEndTime); QDateTime &ticketEndTime);
//#ifdef __cplusplus //#ifdef __cplusplus
//} // extern "C" //} // extern "C"
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include "configuration.h" #include "configuration.h"
#include <QDateTime>
using namespace std; using namespace std;
class Calculator class Calculator
@@ -23,11 +23,7 @@ public:
/// <param name="tariff_cfg">Pointer to configuration</param> /// <param name="tariff_cfg">Pointer to configuration</param>
/// <param name="vehicle_type">Type of vehicle</param> /// <param name="vehicle_type">Type of vehicle</param>
/// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param> /// <param name="start_datetime">Date/time of payment to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param>
/// <param name="end_datetime">Date/time of park end to be conducted in ISO8601 format (e.g. 2022-12-25T08:00:00Z) </param>
/// <param name="durationMin">Duration of parking in minutes</param> /// <param name="durationMin">Duration of parking in minutes</param>
/// <returns>Returns cost (data type: double)</returns> /// <returns>Returns cost (data type: double)</returns>
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, const QDateTime start_datetime, QDateTime & end_datetime, double durationMin, bool nextDay = false, bool prepaid = false); double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, char const* start_datetime, double durationMin, bool nextDay = false, bool prepaid = false);
// Daily ticket
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
}; };
+3 -3
View File
@@ -2,12 +2,12 @@
enum DayOfWeek enum DayOfWeek
{ {
Monday = 0x01, Saturday = 0x06,
Sunday = 0x01,
Monday = 0x02,
Tuesday = 0x02, Tuesday = 0x02,
Wednesday = 0x03, Wednesday = 0x03,
Thursday = 0x04, Thursday = 0x04,
Friday = 0x05, Friday = 0x05,
Saturday = 0x06,
Sunday = 0x07,
UndefinedDay = 0xFF UndefinedDay = 0xFF
}; };
-1
View File
@@ -14,5 +14,4 @@ public:
double pop_max_time; double pop_max_time;
double pop_min_price; double pop_min_price;
int pop_carry_over; int pop_carry_over;
int pop_daily_card_price;
}; };
+1 -2
View File
@@ -68,6 +68,5 @@ public:
/// </summary> /// </summary>
/// <param name="pra_price"></param> /// <param name="pra_price"></param>
/// <returns></returns> /// <returns></returns>
static double CalculatePricePerUnit(double pra_price, double durationUnit = -1); static double CalculatePricePerUnit(double pra_price);
}; };
+1 -1
View File
@@ -1,6 +1,6 @@
TEMPLATE = lib TEMPLATE = lib
TARGET = mobilisis_calc TARGET = mobilisis_calc
#CONFIG += staticlib # CONFIG += staticlib
QMAKE_CXXFLAGS += -std=c++17 -g -O0 QMAKE_CXXFLAGS += -std=c++17 -g -O0
+20 -51
View File
@@ -92,12 +92,10 @@ void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) {
} }
} }
// this is currently not used
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
time_t start_parking_time, // in minutes time_t start_parking_time, // in minutes
time_t end_parking_time, // netto time in minutes time_t end_parking_time, // in minutes
struct price_t *price) { struct price_t *price) {
CalcState calcState; CalcState calcState;
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time; double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
@@ -131,12 +129,11 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
QTime const t(0, 0, 0); QTime const t(0, 0, 0);
QDateTime start(d, t, Qt::UTC); QDateTime start(d, t, Qt::UTC);
start = start.toLocalTime().addSecs(start_parking_time * 60); start = start.toLocalTime().addSecs(start_parking_time * 60);
QDateTime end(start);
if (start.isValid()) { if (start.isValid()) {
QString cs = start.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration( double cost = calculator.GetCostFromDuration(
tariff, PaymentOption::Option1, tariff, PaymentOption::Option1,
start, cs.toLocal8Bit().constData(),
end,
duration, false, true); duration, false, true);
double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price; double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price;
if (cost < minCost) { if (cost < minCost) {
@@ -155,10 +152,8 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
QDateTime const &start_parking_time, QDateTime const &start_parking_time,
int netto_parking_time, QDateTime const &end_parking_time,
QDateTime &end_parking_time, struct price_t *price) {
struct price_t *price)
{
CalcState calcState; CalcState calcState;
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time; double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time; double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
@@ -166,37 +161,39 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
// DEBUG // DEBUG
qCritical() << "compute_price_for_parking_ticket() " << endl qCritical() << "compute_price_for_parking_ticket() " << endl
<< " start_parking_time: " << start_parking_time << endl << " start_parking_time: " << start_parking_time << endl
<< " netto_parking_time: " << netto_parking_time << endl << " end_parking_time: " << end_parking_time << endl
<< " minMin: " << minMin << endl << " minMin: " << minMin << endl
<< " maxMin: " << maxMin; << " maxMin: " << maxMin;
if (netto_parking_time < 0) { int const duration = (end_parking_time.toSecsSinceEpoch() -
start_parking_time.toSecsSinceEpoch()) / 60;
if (duration < 0) {
calcState.setDesc(QString("end=%1, start=%2") calcState.setDesc(QString("end=%1, start=%2")
.arg(end_parking_time.toString(Qt::ISODate), .arg(end_parking_time.toString(Qt::ISODate),
start_parking_time.toString(Qt::ISODate))); start_parking_time.toString(Qt::ISODate)));
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME); return calcState.set(CalcState::State::NEGATIVE_PARING_TIME);
} }
if (netto_parking_time > maxMin) { if (duration > maxMin) {
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin)); calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration, maxMin));
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME); return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
} }
if (netto_parking_time < minMin) { if (duration < minMin) {
calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin)); calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration, minMin));
return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME); return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME);
} }
if (netto_parking_time == 0) { if (duration == 0) {
memset(price, 0x00, sizeof(*price)); memset(price, 0x00, sizeof(*price));
return calcState.set(CalcState::State::SUCCESS); return calcState.set(CalcState::State::SUCCESS);
} }
if (start_parking_time.isValid()) { if (start_parking_time.isValid()) {
QString cs = start_parking_time.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration( double cost = calculator.GetCostFromDuration(
tariff, PaymentOption::Option1, tariff, PaymentOption::Option1,
start_parking_time, // starting time cs.toLocal8Bit().constData(),
end_parking_time, // return value: end time duration, false, true);
netto_parking_time, // minutes, netto
false, true);
double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price; double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price;
if (cost < minCost) { if (cost < minCost) {
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost)); calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost));
@@ -236,7 +233,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
duration = calculator.GetDurationFromCost(tariff, PaymentOption::Option1, duration = calculator.GetDurationFromCost(tariff, PaymentOption::Option1,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
price, false, true).c_str(); price, false, true).c_str();
QDateTime d = QDateTime::fromString(duration, Qt::ISODate); QDateTime d = QDateTime::fromString(duration);
if (!d.isValid()) { if (!d.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(duration)); calcState.setDesc(QString("ticketEndTime=%1").arg(duration));
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT); return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
@@ -252,8 +249,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff, parking_tariff_t *tariff,
QDateTime const &start_parking_time, QDateTime const &start_parking_time,
double price, double price,
QDateTime &ticketEndTime) QDateTime &ticketEndTime) {
{
CalcState calcState; CalcState calcState;
if (start_parking_time.isValid()) { if (start_parking_time.isValid()) {
QString cs = start_parking_time.toString(Qt::ISODate); QString cs = start_parking_time.toString(Qt::ISODate);
@@ -278,30 +274,3 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
return calcState.set(CalcState::State::SUCCESS); return calcState.set(CalcState::State::SUCCESS);
} }
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, QDateTime const &start_parking_time, QDateTime &ticketEndTime)
{
CalcState calcState;
if (start_parking_time.isValid()) {
ticketEndTime = calculator.GetDailyTicketDuration(tariff,
start_parking_time,
PaymentOption::Option1,
false); // carry over
// DEBUG
qCritical() << "compute_duration_for_daily_ticket(): ";
qCritical() << " ticketEndTime: " << ticketEndTime;
if (!ticketEndTime.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(ticketEndTime.toString(Qt::ISODate)));
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
}
} else {
return calcState.set(CalcState::State::INVALID_START_DATE);
}
return calcState.set(CalcState::State::SUCCESS);
}
+193 -223
View File
@@ -12,104 +12,13 @@ double total_cost = 0.0f;
bool overtime = false; bool overtime = false;
#ifdef _WIN32 #ifdef _WIN32
inline struct tm* localtime_r(const time_t *clock, struct tm* result){ inline struct tm* localtime_r(const time_t *clock, struct tm* result){
if(!clock || !result) return NULL; if(!clock || !result) return NULL;
memcpy(result,localtime(clock),sizeof(*result)); memcpy(result,localtime(clock),sizeof(*result));
return result; return result;
} }
#endif #endif
QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over)
{
if(!start_datetime.isValid()) {
return QDateTime();
}
double day_price = 0.0f;
int current_special_day_id = -1;
bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toString(Qt::ISODate).toStdString().c_str(), &current_special_day_id, &day_price);
QDateTime inputDateTime = start_datetime;
QTime worktime_from;
QTime worktime_to;
int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price;
if(daily_card_price <= 0) {
LOG_ERROR("Calculator::GetDailyTicketDuration(): Daily ticket price zero or less");
return QDateTime();
}
if(is_special_day)
{
worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str(), Qt::ISODate);
worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str(),Qt::ISODate);
if(inputDateTime.time() < worktime_from) inputDateTime.setTime(worktime_from);
if(carry_over) inputDateTime.setTime(worktime_from);
if(inputDateTime.time() >= worktime_to)
{
// Go to next day if outside worktime
inputDateTime = inputDateTime.addSecs(86400);
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
}
if(day_price <=0)
{
// Go to next day if special day price is 0
inputDateTime = inputDateTime.addSecs(86400);
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
}
int diff = abs(inputDateTime.time().secsTo(worktime_to));
inputDateTime = inputDateTime.addSecs(diff);
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
return inputDateTime;
}
else
{
// Get day of week
int weekdayId = 0;
weekdayId = Utilities::ZellersAlgorithm(inputDateTime.date().day(),inputDateTime.date().month(),inputDateTime.date().year());
// If no working day found, skip it (recursively call method again)
size_t found = 0;
found = cfg->WeekDaysWorktime.count(weekdayId);
// When no workday found, go to next available day
if(found <=0)
{
inputDateTime = inputDateTime.addSecs(86400);
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
}
else
{
worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str(),Qt::ISODate);
worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str(),Qt::ISODate);
if(inputDateTime.time() < worktime_from)
inputDateTime.setTime(worktime_from);
if(carry_over)
inputDateTime.setTime(worktime_from);
if(inputDateTime.time() >= worktime_to)
{
// Go to next day if outside worktime
inputDateTime = inputDateTime.addSecs(86400);
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
}
int diff = abs(inputDateTime.time().secsTo(worktime_to));
inputDateTime = inputDateTime.addSecs(diff);
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
return inputDateTime;
}
}
return QDateTime();
}
/// <inheritdoc/> /// <inheritdoc/>
std::string Calculator::GetDurationFromCost(Configuration* cfg, std::string Calculator::GetDurationFromCost(Configuration* cfg,
uint8_t payment_option, uint8_t payment_option,
@@ -118,30 +27,27 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
bool nextDay, bool nextDay,
bool prepaid) bool prepaid)
{ {
// Get input date // Get current date time from input
QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate); struct tm current_datetime = Utilities::DateTimeToStructTm(start_datetime);
time_t current_datetime_t;
// Get day of week // Get day of week
int weekdayId = 0; DayOfWeek weekdayId = DayOfWeek::UndefinedDay;
weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year()); weekdayId = Utilities::GetDayOfWeek(&current_datetime);
//std::stringstream ss;
// ss << "*** Input date is: " << start_datetime << " [weekday id = " << weekdayId << "]" << endl;
LOG_DEBUG("*** Input date is: ", start_datetime, " [weekday id = ", weekdayId, "]");
//Get min and max time defined in JSON
double minMin = 0; double minMin = 0;
minMin = cfg->PaymentOption.find(payment_option)->second.pop_min_time; minMin = cfg->PaymentOption.find(payment_option)->second.pop_min_time;
if (minMin < 0) minMin = 0;
double maxMin = 0; double maxMin = 0;
maxMin = cfg->PaymentOption.find(payment_option)->second.pop_max_time; maxMin = cfg->PaymentOption.find(payment_option)->second.pop_max_time;
if (maxMin <= 0) maxMin = 60;
double min_price = 0;
min_price = cfg->PaymentOption.find(payment_option)->second.pop_min_price;
if(price < min_price)
{
return "PARKING NOT ALLOWED";
}
if (minMin < 0) minMin = 0;
if (maxMin < 0) maxMin = 0;
if (minMin >= maxMin) if (minMin >= maxMin)
{ {
LOG_ERROR("Error: min_min cannot be greater or equal to max_min"); LOG_ERROR("Error: min_min cannot be greater or equal to max_min");
@@ -154,72 +60,106 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
return "PARKING NOT ALLOWED"; return "PARKING NOT ALLOWED";
} }
// Get payment method
uint8_t p_method = PaymentMethod::Undefined; uint8_t p_method = PaymentMethod::Undefined;
p_method = payment_option; p_method = payment_option;
LOG_DEBUG("Payment method id: ", (unsigned)p_method); LOG_DEBUG("Payment method id: ", (unsigned)p_method);
// Check special day
double day_price = 0.0f; double day_price = 0.0f;
int current_special_day_id = -1; int current_special_day_id = -1;
bool is_special_day = Utilities::CheckSpecialDay(cfg, inputDate.toString(Qt::ISODate).toStdString().c_str(), &current_special_day_id, &day_price); bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime, &current_special_day_id, &day_price);
LOG_DEBUG("Special day: ", is_special_day); LOG_DEBUG("Special day: ", is_special_day);
double money_left = price; double money_left = price;
LOG_DEBUG("Total money:", money_left);
double price_per_unit = 0.0f; double price_per_unit = 0.0f;
QTime worktime_from; string worktime_from = "";
QTime worktime_to; string worktime_to = "";
if(is_special_day) if (is_special_day)
{ {
// Set special day price // Set special day price
price_per_unit = Utilities::CalculatePricePerUnit(day_price); price_per_unit = Utilities::CalculatePricePerUnit(day_price);
worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str()); worktime_from = cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from;
worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str()); worktime_to = cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to;
} }
else else
{ {
// Set new price for the normal day // Set new price for the normal day
int pop_id = cfg->PaymentOption.find(payment_option)->second.pop_id; day_price = cfg->PaymentRate.find(payment_option)->second.pra_price;
day_price = cfg->PaymentRate.find(pop_id)->second.pra_price; price_per_unit = Utilities::CalculatePricePerUnit(day_price);
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
double durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
price_per_unit = Utilities::CalculatePricePerUnit(day_price,durationUnit);
// If no working day found, skip it (recursively call method again) // If no working day found, skip it (recursively call method again)
size_t found = 0; size_t found = 0;
found = cfg->WeekDaysWorktime.count(weekdayId); found = cfg->WeekDaysWorktime.count(weekdayId);
// When no workday found, go to next available day if (found <= 0)
if(found <=0)
{ {
LOG_DEBUG("- No workday found, trying to find next available day"); LOG_DEBUG("- No workday found, trying to find next available day");
inputDate = inputDate.addDays(1); current_datetime_t = mktime(&current_datetime);
return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left,true,prepaid); current_datetime_t += 86400;
current_datetime = *localtime(&current_datetime_t);
char buffer_datetime[80];
strftime(buffer_datetime, 80, "%Y-%m-%dT%H:%M:%S", &current_datetime);
// Make new datetime string and call function again recursively
start_datetime = buffer_datetime;
return GetDurationFromCost(cfg, payment_option, start_datetime, price, true);
} }
worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str());
worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str()); worktime_from = cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from;
worktime_to = cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to;
} }
if (price_per_unit < 0) price_per_unit = 1.0f; if (price_per_unit < 0) price_per_unit = 1.0f;
// if((price/price_per_unit) < minMin) return "PARKING NOT ALLOWED";
LOG_DEBUG("Calculated price per minute: ", price_per_unit); LOG_DEBUG("Calculated price per minute: ", price_per_unit);
LOG_DEBUG("Worktime from: ", worktime_from);
LOG_DEBUG("Worktime to: ", worktime_to);
struct tm from_tm;
struct tm to_tm;
from_tm = Utilities::TimeToStructTm(worktime_from.c_str(), current_datetime.tm_year, current_datetime.tm_mon, current_datetime.tm_mday, current_datetime.tm_wday);
from_tm.tm_year = current_datetime.tm_year;
from_tm.tm_mon = current_datetime.tm_mon;
from_tm.tm_wday = current_datetime.tm_wday;
from_tm.tm_mday = current_datetime.tm_mday;
to_tm = Utilities::TimeToStructTm(worktime_to.c_str(), current_datetime.tm_year, current_datetime.tm_mon, current_datetime.tm_mday, current_datetime.tm_wday);
to_tm.tm_year = current_datetime.tm_year;
to_tm.tm_mon = current_datetime.tm_mon;
to_tm.tm_wday = current_datetime.tm_wday;
to_tm.tm_mday = current_datetime.tm_mday;
// Convert tm structures to time_t
current_datetime_t = mktime(&current_datetime);
time_t from_datetime_t = mktime(&from_tm);
time_t to_datetime_t = mktime(&to_tm);
/*Newly added */
//current_datetime.tm_hour = from_tm.tm_hour;
//current_datetime.tm_min = from_tm.tm_min;
//current_datetime.tm_sec = from_tm.tm_sec;
//current_datetime_t = mktime(&current_datetime);
// If overtime flag is set // If overtime flag is set
if (overtime || nextDay) if (overtime || nextDay)
{ {
inputDate.setTime(worktime_from); current_datetime.tm_hour = from_tm.tm_hour;
current_datetime.tm_min = from_tm.tm_min;
current_datetime.tm_sec = from_tm.tm_sec;
current_datetime_t = mktime(&current_datetime);
LOG_DEBUG(" *** New input date set according to worktime: ", asctime(&current_datetime));
overtime = false; overtime = false;
} }
// Check prepaid // Validate ticket
if (!prepaid) if (!prepaid)
{ {
if ((inputDate.time() < worktime_from) || (inputDate.time() > worktime_to)) if ((current_datetime_t < from_datetime_t) || (current_datetime_t > to_datetime_t))
{ {
LOG_DEBUG("[STOP] * Ticket is not valid * "); LOG_DEBUG("[STOP] * Ticket is not valid * ");
return "PARKING NOT ALLOWED"; return "PARKING NOT ALLOWED";
@@ -228,121 +168,160 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
else else
{ {
LOG_DEBUG("* PREPAID MODE ACTIVE *"); LOG_DEBUG("* PREPAID MODE ACTIVE *");
if (inputDate.time() < worktime_from)
if (current_datetime_t < from_datetime_t)
{ {
inputDate.setTime(worktime_from); current_datetime.tm_hour = from_tm.tm_hour;
current_datetime.tm_min = from_tm.tm_min;
current_datetime.tm_sec = from_tm.tm_sec;
current_datetime_t = mktime(&current_datetime);
LOG_DEBUG(" *** PREPAID *** Current time is before the time range start, adjusting time to: ", asctime(&current_datetime));
} }
else if(inputDate.time() > worktime_to) else if (current_datetime_t > to_datetime_t)
{ {
LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day"); LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day");
inputDate = inputDate.addDays(1); current_datetime_t = mktime(&current_datetime);
return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left, true); current_datetime_t += 86400;
current_datetime = *localtime(&current_datetime_t);
char buffer_datetime[80];
strftime(buffer_datetime, 80, "%Y-%m-%dT%H:%M:%S", &current_datetime);
//Make new datetime string and call function again recursively
start_datetime = buffer_datetime;
return GetDurationFromCost(cfg, payment_option, start_datetime, price, true, prepaid);
} }
} }
while(true) while (true)
{ {
if((int)money_left <= 0) break; if (!Utilities::IsYearPeriodActive(cfg, &current_datetime))
// Check year period
bool isYearPeriodActive = false;
//// Parse input date
int dayCurrent = inputDate.date().day();
int monthCurrent = inputDate.date().month();
// Current date time
int cdt = (monthCurrent * 100) + dayCurrent;
multimap<int, ATBPeriodYear>::iterator year_period_itr;
for (year_period_itr = cfg->YearPeriod.begin(); year_period_itr != cfg->YearPeriod.end(); ++year_period_itr)
{
int dStart = year_period_itr->second.pye_start_day;
int dEnd = year_period_itr->second.pye_end_day;
int mStart = year_period_itr->second.pye_start_month;
int mEnd = year_period_itr->second.pye_end_month;
int start = (mStart * 100) + dStart;
int end = (mEnd * 100) + dEnd;
if (cdt >= start && cdt <= end) {
isYearPeriodActive = true;
break;
}
}
if (!isYearPeriodActive)
{ {
LOG_DEBUG("Year period is not valid"); LOG_DEBUG("Year period is not valid");
return "PARKING NOT ALLOWED"; return "PARKING NOT ALLOWED";
} }
if(total_duration_min > maxMin) // Increment by 1 minute
current_datetime_t = mktime(&current_datetime);
current_datetime_t += 60;
current_datetime = *localtime(&current_datetime_t);
total_duration_min += 1.0f;
money_left -= price_per_unit;
// If no money left (e.g. spent all of the money before reaching end of worktime)
if (money_left <= 0)
{ {
LOG_DEBUG("No money left ");
break;
}
else
{
if (total_duration_min >= maxMin)
{
LOG_DEBUG("Total duration is greater or equal to max_min");
current_datetime_t = mktime(&current_datetime);
current_datetime_t -= 60;
current_datetime = *localtime(&current_datetime_t);
total_duration_min = maxMin; total_duration_min = maxMin;
break; break;
} }
// If reached end of worktime go to next day // If money has left but the end of worktime has been reached (go to next day)
if(inputDate.time() >= worktime_to) if (current_datetime_t >= to_datetime_t)
{ {
total_duration_min -= 1.0f;
int carry_over_status = 0; int carry_over_status = 0;
carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over; carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over;
LOG_DEBUG("Carry over status: ", carry_over_status);
if (carry_over_status < 1) break; if (carry_over_status < 1) break;
inputDate = inputDate.addDays(1); LOG_DEBUG("Reached end of worktime");
LOG_DEBUG("Trying to find next available day, money left = ", money_left);
current_datetime_t = mktime(&current_datetime);
current_datetime_t += 86400;
current_datetime = *localtime(&current_datetime_t);
char buffer_datetime[80];
strftime(buffer_datetime, 80, "%Y-%m-%dT%H:%M:%S", &current_datetime);
// Make new datetime string and call function again recursively
start_datetime = buffer_datetime;
overtime = true; overtime = true;
return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left ,true, prepaid); return GetDurationFromCost(cfg, payment_option, start_datetime, price);
}
}
} }
if(money_left > 1) time_t valid_until_datetime_t = current_datetime_t;
inputDate = inputDate.addSecs(60);
if(price_per_unit > 0) total_duration_min +=1; if ((total_duration_min < minMin) || (price / price_per_unit) < minMin)
money_left -= price_per_unit; {
LOG_DEBUG("Total duration is lower than min_min");
//valid_until_datetime_t += (minMin - total_duration_min) * 60;
//total_duration_min = minMin;
//return "PARKING NOT ALLOWED";
//qDebug() <<"Timestamp:" << inputDate << ", total duration min: " << total_duration_min << ", money left = " << money_left; valid_until_datetime_t = from_datetime_t;
total_duration_min = 0;
} }
// if ((total_duration_min < minMin) || (price / price_per_unit) < minMin)
// {
// LOG_DEBUG("Total duration is lower than min_min");
// inputDate.time() = worktime_from;
// total_duration_min = 0;
// }
double ret_val = 0; double ret_val = 0;
// double calc_price = (int)total_duration_min - (int)price / price_per_unit; double calc_price = (int)total_duration_min - (int)price / price_per_unit;
//if (calc_price > 0 && total_duration_min > 0) if (calc_price > 0 && total_duration_min > 0)
//{
// inputDate = inputDate.addSecs(-(int)ceil(calc_price) * 60);
//}
if(price >= min_price && total_duration_min >= minMin)
qDebug() << "GetDurationFromCost(): Valid until: " << inputDate.toString(Qt::ISODate);
else
{ {
qDebug() << "Parking not allowed"; valid_until_datetime_t -= (int)ceil(calc_price) * 60;
total_duration_min = 0; ret_val = total_duration_min - calc_price;
} }
else ret_val = total_duration_min;
ret_val = total_duration_min; cout << "Total minutes: " << (int)ret_val << endl;
if(ret_val < 0) ret_val = 0;
qDebug() << "Duration: " << ret_val;
if (ret_val <= 0) return "PARKING NOT ALLOWED"; if (ret_val <= 0) return "PARKING NOT ALLOWED";
total_duration_min = 0; #ifdef __linux__
return inputDate.toString(Qt::ISODate).toStdString(); #if !defined(_SVID_SOURCE) && !defined(_XOPEN_SOURCE)
// needed for timezone-correction
#error "!defined(_SVID_SOURCE) && !defined(_XOPEN_SOURCE)"
#else
// timezone correction: localtime() needs argument in UTC-timezone
// The global variable 'timezone' is set by tzset(), see
// https://linux.die.net/man/3/tzset, so I change of the timezone will
// also change the value of the variable 'timezone'.
valid_until_datetime_t += timezone;
#endif
#else // windows, only for testing
static const long timezone = -3600;
valid_until_datetime_t += timezone;
#endif
struct tm valid_until_datetime;
memset(&valid_until_datetime, 0x00, sizeof(valid_until_datetime));
if (!localtime_r(&valid_until_datetime_t, &valid_until_datetime)) {
return "LOCALTIME_R() ERROR";
}
// return in ISO-format: "%Y-%m-%dT%H:%M:%S"
char buf[128];
memset(buf, 0x00, sizeof(buf));
strftime(buf, sizeof(buf)-1, "%Y-%m-%dT%H:%M:%S", &valid_until_datetime);
LOG_DEBUG("Ticket is valid until ", buf);
total_duration_min = 0.0f;
return std::string(buf);
} }
/////////////////////////////////////// ///////////////////////////////////////
/// <inheritdoc/> /// <inheritdoc/>
double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_option, const QDateTime start_datetime, QDateTime & end_datetime, double durationMin, bool nextDay, bool prepaid) double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_option, const char* start_datetime, double durationMin, bool nextDay, bool prepaid)
{ {
// Get input date // Get input date
QDateTime inputDate = start_datetime; QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate);
// Get day of week // Get day of week
int weekdayId = 0; int weekdayId = 0;
@@ -412,13 +391,8 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
else else
{ {
// Set new price for the normal day // Set new price for the normal day
day_price = cfg->PaymentRate.find(payment_option)->second.pra_price;
int pop_id = cfg->PaymentOption.find(payment_option)->second.pop_id; price_per_unit = Utilities::CalculatePricePerUnit(day_price);
day_price = cfg->PaymentRate.find(pop_id)->second.pra_price;
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
double durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
price_per_unit = Utilities::CalculatePricePerUnit(day_price,durationUnit);
// If no working day found, skip it (recursively call method again) // If no working day found, skip it (recursively call method again)
size_t found = 0; size_t found = 0;
@@ -429,7 +403,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
{ {
LOG_DEBUG("- No workday found, trying to find next available day"); LOG_DEBUG("- No workday found, trying to find next available day");
inputDate = inputDate.addDays(1); inputDate = inputDate.addDays(1);
return floor(GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid)); return floor(GetCostFromDuration(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), durationMin, true, prepaid));
} }
worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str()); worktime_from = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_from.c_str());
worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str()); worktime_to = QTime::fromString(cfg->WeekDaysWorktime.find(weekdayId)->second.pwd_time_to.c_str());
@@ -442,7 +416,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
{ {
inputDate = inputDate.addDays(1); inputDate = inputDate.addDays(1);
inputDate.setTime(worktime_from); inputDate.setTime(worktime_from);
return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid); return GetCostFromDuration(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), durationMin, true, prepaid);
} }
// If overtime flag is set // If overtime flag is set
@@ -472,7 +446,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
{ {
LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day"); LOG_DEBUG(" *** PREPAID *** Current time is past the time range end, searching for next available day");
inputDate = inputDate.addDays(1); inputDate = inputDate.addDays(1);
return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, durationMin, true, prepaid); return GetCostFromDuration(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), durationMin, true, prepaid);
} }
} }
@@ -513,18 +487,17 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
return 0.0f; return 0.0f;
} }
int carry_over_status = 0;
carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over;
// Go to next day if minutes not spent // Go to next day if minutes not spent
if(inputDate.time() >= worktime_to) if(inputDate.time() >= worktime_to)
{ {
int carry_over_status = 0;
carry_over_status = cfg->PaymentOption.find(payment_option)->second.pop_carry_over;
if (carry_over_status < 1) break; if (carry_over_status < 1) break;
LOG_DEBUG("Reached end of worktime, searching for the next working day"); LOG_DEBUG("Reached end of worktime, searching for the next working day");
inputDate = inputDate.addDays(1); inputDate = inputDate.addDays(1);
overtime = true; overtime = true;
return GetCostFromDuration(cfg, payment_option, inputDate, end_datetime, total_duration_min); return GetCostFromDuration(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), total_duration_min);
} }
// Increment input date minutes for each monetary unit // Increment input date minutes for each monetary unit
@@ -533,10 +506,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
total_cost += price_per_unit; total_cost += price_per_unit;
} }
qDebug() << "GetCostFromDuration(): Valid until:" << inputDate.toString(Qt::ISODate).toStdString().c_str(); qDebug() << "Valid until:" << inputDate.toString(Qt::ISODate).toStdString().c_str();
end_datetime = inputDate;
double ret_val = total_cost; double ret_val = total_cost;
total_cost = 0.0f; total_cost = 0.0f;
return ceil(ret_val); return ceil(ret_val);
+10 -11
View File
@@ -23,12 +23,12 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
{ {
if (cfg == nullptr) if (cfg == nullptr)
{ {
printf("TariffConfiguration pointer not set\n"); fprintf(stderr, "TariffConfiguration pointer not set\n");
return false; return false;
} }
if (json == NULL) if (json == NULL)
{ {
printf("%s", "Input JSON string is NULL\n"); fprintf(stderr, "%s", "Input JSON string is NULL\n");
return false; return false;
} }
@@ -40,17 +40,17 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
ParseErrorCode err = document.GetParseError(); ParseErrorCode err = document.GetParseError();
if (err != 0) if (err != 0)
{ {
printf("%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err)); fprintf(stderr, "%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err));
return false; return false;
} }
// Validate JSON, check if it's a JSON object // Validate JSON, check if it's a JSON object
printf("%s", "JSON parsing has been successful\n"); fprintf(stderr, "%s", "JSON parsing has been successful\n");
if (!document.IsObject()) { if (!document.IsObject()) {
printf("%s", "Error: not a (valid) JSON object\n"); fprintf(stderr, "%s", "Error: not a (valid) JSON object\n");
return false; return false;
} }
printf("%s", "Valid JSON object identified\n"); fprintf(stderr, "%s", "Valid JSON object identified\n");
// Validate JSON, check configuration members // Validate JSON, check configuration members
if (!document.HasMember("Currency") if (!document.HasMember("Currency")
@@ -65,7 +65,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
printf("%s", "Error: not a valid configuration JSON\n"); printf("%s", "Error: not a valid configuration JSON\n");
return false; return false;
} }
printf("%s", "Valid JSON configuration identified\n"); fprintf(stderr, "%s", "Valid JSON configuration identified\n");
ATBCurrency Currency; ATBCurrency Currency;
ATBDuration Duration; ATBDuration Duration;
@@ -115,7 +115,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
const char* inner_obj_name = k->name.GetString(); const char* inner_obj_name = k->name.GetString();
if (inner_obj_name == NULL) if (inner_obj_name == NULL)
{ {
printf("Inner object name is NULL\n"); fprintf(stderr, "Inner object name is NULL\n");
continue; continue;
} }
@@ -154,7 +154,6 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
else if (strcmp(inner_obj_name, "pop_max_time") == 0) PaymentOption.pop_max_time = k->value.GetDouble(); else if (strcmp(inner_obj_name, "pop_max_time") == 0) PaymentOption.pop_max_time = k->value.GetDouble();
else if (strcmp(inner_obj_name, "pop_min_price") == 0) PaymentOption.pop_min_price = k->value.GetDouble(); 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_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();
break; break;
case MemberType::DurationType: case MemberType::DurationType:
if (strcmp(inner_obj_name, "pun_id") == 0) Duration.pun_id = k->value.GetInt(); if (strcmp(inner_obj_name, "pun_id") == 0) Duration.pun_id = k->value.GetInt();
@@ -210,7 +209,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
cfg->PaymentMethod.insert(pair<int, ATBPaymentMethod>(PaymentMethod.pme_id, PaymentMethod)); cfg->PaymentMethod.insert(pair<int, ATBPaymentMethod>(PaymentMethod.pme_id, PaymentMethod));
break; break;
case MemberType::PaymentRateType: case MemberType::PaymentRateType:
cfg->PaymentRate.insert(pair<int, ATBPaymentRate>(PaymentRate.pra_payment_option_id, PaymentRate)); cfg->PaymentRate.insert(pair<int, ATBPaymentRate>(PaymentRate.pra_payment_unit_id, PaymentRate));
break; break;
case MemberType::PaymentOptionType: case MemberType::PaymentOptionType:
cfg->PaymentOption.insert(pair<int, ATBPaymentOption>(PaymentOption.pop_payment_method_id, PaymentOption)); cfg->PaymentOption.insert(pair<int, ATBPaymentOption>(PaymentOption.pop_payment_method_id, PaymentOption));
@@ -241,7 +240,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
return true; return true;
} }
catch (...) { catch (...) {
printf("%s\n", "General exception has occurred while parsing JSON\n"); fprintf(stderr, "%s\n", "General exception has occurred while parsing JSON\n");
return false; return false;
} }
} }
+2 -5
View File
@@ -8,15 +8,12 @@ static int protection_counter = 0;
/// </summary> /// </summary>
/// <param name="pra_price"></param> /// <param name="pra_price"></param>
/// <returns></returns> /// <returns></returns>
double Utilities::CalculatePricePerUnit(double pra_price, double durationUnit) double Utilities::CalculatePricePerUnit(double pra_price)
{ {
try try
{ {
double price_per_unit = pra_price; double price_per_unit = pra_price;
double unit = durationUnit; price_per_unit /= 60.0f; // Divided by 60 because price per unit is set per hour and we are using minutes
if(unit < 0 || unit > 65535 ) unit = 60.0f;
price_per_unit /= unit; // Divided by 60 because price per unit is set per hour and we are using minutes
//printf("Price per unit (min) is: %lf\n", price_per_unit); //printf("Price per unit (min) is: %lf\n", price_per_unit);
return price_per_unit; return price_per_unit;
} }
+73 -113
View File
@@ -1,9 +1,10 @@
#include <calculate_price.h>
#ifdef WIN32 #ifdef WIN32
#include <time.h> #include <time.h>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <calculate_price.h>
extern "C" char* strptime(const char* s, extern "C" char* strptime(const char* s,
const char* f, const char* f,
@@ -26,135 +27,94 @@ extern "C" char* strptime(const char* s,
#include <QDebug> #include <QDebug>
#include <QDateTime> #include <QDateTime>
#include <QDir>
#include <fstream>
#include <sstream>
#include "calculator_functions.h"
#include <calculate_price.h>
int main() { int main() {
std::ifstream input(QDir::homePath().append("/tariff01.json").toStdString());
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;
char const *startDate = "";
if (isParsed)
{
startDate = "2023-05-10T13:52:18.665Z";
std::string duration = calculator.GetDurationFromCost(&cfg, 3, (char *)startDate, 33, false, true);
cout << "---> startDate " << startDate << " _price_ = " << 33
<< " Total duration is: " << duration << endl;
}
return 0;
parking_tariff_t *tariff = 0; parking_tariff_t *tariff = 0;
if (init_tariff(&tariff, "/etc/psa_tariff/")) { if (init_tariff(&tariff, "C:\\Users\\MROD\\Documents\\QtCreator\\build-MOBILISIS-Calculator-Desktop_Qt_5_12_12_MSVC2017_32bit-Debug\\main\\etc\\psa_tariff\\zone1.json")) {
struct price_t price; struct price_t price;
memset(&price, 0x00, sizeof(price)); memset(&price, 0x00, sizeof(price));
QDateTime start = QDateTime::fromString("2023-05-11T07:50:00",Qt::ISODate); //QDateTime::currentDateTime(); QDateTime start = QDateTime::fromString("2023-05-11T07:50:00",Qt::ISODate); //QDateTime::currentDateTime();
time_t start_parking_time = start.toSecsSinceEpoch() / 60; time_t start_parking_time = start.toSecsSinceEpoch() / 60;
time_t end_parking_time = start_parking_time + 615; time_t end_parking_time = start_parking_time + 1230;
if (compute_price_for_parking_ticket(tariff, if (compute_price_for_parking_ticket(tariff,
start_parking_time, start_parking_time,
end_parking_time, end_parking_time,
&price)) &price)) {
{ qDebug() << "price=" << price.netto;
qDebug() << "GetCostFromDuration() => price=" << price.netto;
} }
QString duration; // QString duration;
if(compute_duration_for_parking_ticket(tariff,start_parking_time,3090,duration)) // if(compute_duration_for_parking_ticket(tariff,start_parking_time,3090,duration))
{ // {
qDebug() << "GetDurationFromCost() => duration=" << duration; // qDebug() << "duration=" << duration;
} // }
// Daily ticket // // tests
//compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3); // struct tm now;
// memset(&now, 0, sizeof(now));
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over // // 3.Jan 2023 -> Tuesday
// // tests // strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
// struct tm now; // for (int i = 0; i < 600; ++i) {
// memset(&now, 0, sizeof(now)); // start_parking_time = mktime(&now);
// end_parking_time = start_parking_time + 240; // duration == 240
// // 3.Jan 2023 -> Tuesday // if (compute_price_for_parking_ticket(tariff,
// strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now); // start_parking_time,
// for (int i = 0; i < 600; ++i) { // end_parking_time,
// start_parking_time = mktime(&now); // &price)) {
// end_parking_time = start_parking_time + 240; // duration == 240 // int const zone = get_zone_nr(1);
// switch (zone) {
// case 1:
// assert(price.netto == 879); // expected value: 880
// break;
// case 2:
// /* fall through */
// case 3:
// assert(price.netto == 1920);
// break;
// }
// }
// time_t t = start_parking_time + 60;
// now = *localtime(&t);
// }
// //
// // test May 1st 2023
// //
// memset(&now, 0, sizeof(now));
// strptime("2023-04-30T06:00:00", "%Y-%m-%dT%H:%M:%S", &now);
// now.tm_hour -= 1; // for ctime
// // for (int i=0; i<6*24; ++i) {
// for (int i=0; i<1; ++i) {
// int const duration = 120;
// time_t t = mktime(&now);
// start_parking_time = t / 60;
// end_parking_time = start_parking_time + duration;
// if (compute_price_for_parking_ticket(tariff, // if (compute_price_for_parking_ticket(tariff,
// start_parking_time, // start_parking_time,
// end_parking_time, // end_parking_time,
// &price)) { // &price)) {
// int const zone = get_zone_nr(1); // int const zone = get_zone_nr();
// switch (zone) { // switch (zone) {
// case 1: // case 1:
// assert(price.netto == 879); // expected value: 880 // qDebug() << i << zone << ctime(&t) << price.netto << " FT";
// break; // assert(price.netto == 440);
// case 2: // break;
// /* fall through */ // case 2:
// case 3: // /* fall through */
// assert(price.netto == 1920); // case 3:
// break; // qDebug() << i << zone << ctime(&t) << price.netto << " FT";
// } // assert(price.netto == 960);
// } // break;
// time_t t = start_parking_time + 60; // }
// now = *localtime(&t); // }
// }
// //
// // test May 1st 2023
// //
// memset(&now, 0, sizeof(now));
// strptime("2023-04-30T06:00:00", "%Y-%m-%dT%H:%M:%S", &now);
// now.tm_hour -= 1; // for ctime
// // for (int i=0; i<6*24; ++i) {
// for (int i=0; i<1; ++i) {
// int const duration = 120;
// time_t t = mktime(&now);
// start_parking_time = t / 60;
// end_parking_time = start_parking_time + duration;
// if (compute_price_for_parking_ticket(tariff, // t = (start_parking_time + 60)*60;
// start_parking_time, // now = *localtime(&t);
// end_parking_time, // }
// &price)) {
// int const zone = get_zone_nr();
// switch (zone) {
// case 1:
// qDebug() << i << zone << ctime(&t) << price.netto << " FT";
// assert(price.netto == 440);
// break;
// case 2:
// /* fall through */
// case 3:
// qDebug() << i << zone << ctime(&t) << price.netto << " FT";
// assert(price.netto == 960);
// break;
// }
// }
// t = (start_parking_time + 60)*60;
// now = *localtime(&t);
// }
free_tariff(tariff); free_tariff(tariff);
} }
@@ -191,7 +151,7 @@ int main() {
struct tm now; // = Utilities::DateTimeToStructTm("2023-03-01T16:00:00"); struct tm now; // = Utilities::DateTimeToStructTm("2023-03-01T16:00:00");
memset(&now, 0, sizeof(now)); memset(&now, 0, sizeof(now));
char buffer[64]; char buffer[64];
//#if 0 //#if 0
// 3.Jan 2023 -> Tuesday // 3.Jan 2023 -> Tuesday
strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now); strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
for (int i = 0; i < 600; ++i) { for (int i = 0; i < 600; ++i) {
-2
View File
@@ -7,8 +7,6 @@ QMAKE_CFLAGS = -c -pipe -std=c11 -g -O0 -Wall -Wno-attributes -W -DDEBUG -D_REEN
QMAKE_CXX_FLAGS += -std=c11 QMAKE_CXX_FLAGS += -std=c11
INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/mobilisis/ INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/mobilisis/
INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/rapidjson/
INCLUDEPATH += $$_PRO_FILE_PWD_/../../MOBILISIS-Calculator/library/include/
INCLUDEPATH += . INCLUDEPATH += .
unix { unix {
+1 -805
View File
File diff suppressed because one or more lines are too long
+1 -805
View File
File diff suppressed because one or more lines are too long
+1 -812
View File
File diff suppressed because one or more lines are too long
+1 -805
View File
File diff suppressed because one or more lines are too long