Compare commits
2 Commits
master
...
moransBran
Author | SHA1 | Date | |
---|---|---|---|
6ea58be34d | |||
8a7828c1e6 |
@ -1,13 +0,0 @@
|
|||||||
#ifndef ATB_PROJECT_H_INCLUDED
|
|
||||||
#define ATB_PROJECT_H_INCLUDED
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class ATBProject {
|
|
||||||
public:
|
|
||||||
QString project;
|
|
||||||
QString version;
|
|
||||||
QString info;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ATB_PROJECT_H_INCLUDED
|
|
@ -109,9 +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);
|
||||||
|
|
||||||
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown);
|
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated
|
|
||||||
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,
|
||||||
@ -120,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,
|
||||||
@ -134,12 +131,17 @@ 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
|
QDateTime &ticketEndTime);
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(
|
CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(
|
||||||
parking_tariff_t *tariff,
|
parking_tariff_t *tariff,
|
||||||
QDateTime const &start_parking_time,
|
QString const &start_parking_time,
|
||||||
QDateTime &ticketEndTime);
|
uint8_t paymentMethod);
|
||||||
|
|
||||||
|
CalcState CALCULATE_LIBRARY_API compute_duration_for_24hour_daily_ticket(
|
||||||
|
parking_tariff_t *tariff,
|
||||||
|
QString const &start_parking_time,
|
||||||
|
uint8_t paymentMethod);
|
||||||
//#ifdef __cplusplus
|
//#ifdef __cplusplus
|
||||||
//} // extern "C"
|
//} // extern "C"
|
||||||
//#endif
|
//#endif
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "payment_method.h"
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -24,25 +23,13 @@ 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
|
// Daily ticket
|
||||||
QDateTime GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over);
|
QString GetDailyTicketDuration(Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over);
|
||||||
|
|
||||||
//
|
// 24-hour daily ticket
|
||||||
// helper function to find time steps for a tariff with PaymentMethod::Steps
|
QString Get24HourTicketDuration(Configuration* cfg, QString start_datetime, uint8_t payment_option);
|
||||||
// (e.g. Schoenau/Koenigsee)
|
|
||||||
//
|
|
||||||
QList<int> GetTimeSteps(Configuration *cfg) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Introduced for PaymentMethod::Steps (e.g. Schoenau)
|
|
||||||
// For tariff of following structure: only steps, no special days, nonstop.
|
|
||||||
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, quint64 durationMinutes) const;
|
|
||||||
uint32_t GetCostFromDuration(Configuration *cfg, QDateTime const &start, QDateTime const &end) const;
|
|
||||||
uint32_t GetPriceForTimeStep(Configuration *cfg, int timeStep) const;
|
|
||||||
uint32_t GetDurationForPrice(Configuration *cfg, int price) const;
|
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "member_type.h"
|
#include "member_type.h"
|
||||||
#include "period_year.h"
|
#include "period_year.h"
|
||||||
#include "payment_rate.h"
|
#include "payment_rate.h"
|
||||||
#include "atb_project.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
@ -28,8 +27,8 @@ using namespace rapidjson;
|
|||||||
class Configuration
|
class Configuration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ATBProject project;
|
|
||||||
ATBCurrency Currency;
|
ATBCurrency Currency;
|
||||||
ATBDuration duration;
|
ATBDuration duration;
|
||||||
|
|
||||||
multimap<int, ATBDuration> Duration;
|
multimap<int, ATBDuration> Duration;
|
||||||
@ -49,8 +48,6 @@ public:
|
|||||||
/// <returns>Returns operation status bool (OK | FAIL) </returns>
|
/// <returns>Returns operation status bool (OK | FAIL) </returns>
|
||||||
bool ParseJson(Configuration* cfg, const char* json);
|
bool ParseJson(Configuration* cfg, const char* json);
|
||||||
|
|
||||||
ATBPaymentOption const & getPaymentOptions();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identify type of JSON member
|
/// Identify type of JSON member
|
||||||
@ -58,6 +55,4 @@ private:
|
|||||||
/// <param name="member_name"></param>
|
/// <param name="member_name"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
MemberType IdentifyJsonMember(const char* member_name);
|
MemberType IdentifyJsonMember(const char* member_name);
|
||||||
|
|
||||||
ATBPaymentOption currentPaymentOptions;
|
|
||||||
};
|
};
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
enum DayOfWeek
|
enum DayOfWeek
|
||||||
{
|
{
|
||||||
Monday = 0x01,
|
Saturday = 0x06,
|
||||||
Tuesday = 0x02,
|
Sunday = 0x01,
|
||||||
Wednesday = 0x03,
|
Monday = 0x02,
|
||||||
Thursday = 0x04,
|
Tuesday = 0x02,
|
||||||
Friday = 0x05,
|
Wednesday = 0x03,
|
||||||
Saturday = 0x06,
|
Thursday = 0x04,
|
||||||
Sunday = 0x07,
|
Friday = 0x05,
|
||||||
UndefinedDay = 0xFF
|
UndefinedDay = 0xFF
|
||||||
};
|
};
|
@ -15,4 +15,5 @@ public:
|
|||||||
double pop_min_price;
|
double pop_min_price;
|
||||||
int pop_carry_over;
|
int pop_carry_over;
|
||||||
int pop_daily_card_price;
|
int pop_daily_card_price;
|
||||||
|
int pop_multi_hour_price;
|
||||||
};
|
};
|
||||||
|
@ -65,8 +65,7 @@ HEADERS += \
|
|||||||
include/mobilisis/tariff_period_year.h \
|
include/mobilisis/tariff_period_year.h \
|
||||||
include/mobilisis/tariff_payment_rate.h \
|
include/mobilisis/tariff_payment_rate.h \
|
||||||
include/mobilisis/tariff_log.h \
|
include/mobilisis/tariff_log.h \
|
||||||
include/mobilisis/calculate_price.h \
|
include/mobilisis/calculate_price.h
|
||||||
include/mobilisis/atb_project.h
|
|
||||||
|
|
||||||
OTHER_FILES += src/main.cpp
|
OTHER_FILES += src/main.cpp
|
||||||
|
|
||||||
|
@ -92,54 +92,14 @@ void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// UpDown 1 -> up; 0 -> down
|
|
||||||
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown)
|
|
||||||
{
|
|
||||||
static const QList<int> stepList = calculator.GetTimeSteps(tariff);
|
|
||||||
|
|
||||||
int currentStepIndex = stepList.indexOf(currentTimeMinutes);
|
|
||||||
|
|
||||||
if (currentStepIndex == -1) {
|
|
||||||
qCritical() << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
|
|
||||||
return currentTimeMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UpDown == 1) { // UP
|
|
||||||
if (stepList[currentStepIndex] == stepList.last()) {
|
|
||||||
qCritical() << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
|
|
||||||
return currentTimeMinutes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return stepList[currentStepIndex + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (UpDown == 0) { // DOWN
|
|
||||||
if (stepList[currentStepIndex] == stepList.first()) {
|
|
||||||
qCritical() << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
|
|
||||||
return currentTimeMinutes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return stepList[currentStepIndex - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")";
|
|
||||||
return currentTimeMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_time;
|
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
|
||||||
double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_max_time;
|
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
|
||||||
|
|
||||||
if (minMin < 0 || maxMin < 0 || maxMin < minMin) {
|
if (minMin < 0 || maxMin < 0 || maxMin < minMin) {
|
||||||
calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin));
|
calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin));
|
||||||
@ -169,15 +129,13 @@ 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,
|
tariff, PaymentOption::Option1,
|
||||||
tariff->getPaymentOptions().pop_payment_method_id,
|
cs.toLocal8Bit().constData(),
|
||||||
start,
|
|
||||||
end,
|
|
||||||
duration, false, true);
|
duration, false, true);
|
||||||
double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->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).arg(cost));
|
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost));
|
||||||
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
|
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
|
||||||
@ -194,50 +152,49 @@ 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->getPaymentOptions().pop_min_time;
|
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
|
||||||
double maxMin = tariff->getPaymentOptions().pop_max_time;
|
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
|
||||||
|
|
||||||
// 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,
|
tariff, PaymentOption::Option1,
|
||||||
tariff->getPaymentOptions().pop_payment_method_id,
|
cs.toLocal8Bit().constData(),
|
||||||
start_parking_time, // starting time
|
duration, false, true);
|
||||||
end_parking_time, // return value: end time
|
double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price;
|
||||||
netto_parking_time, // minutes, netto
|
|
||||||
false, true);
|
|
||||||
double minCost = tariff->getPaymentOptions().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));
|
||||||
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
|
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
|
||||||
@ -273,11 +230,10 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
|||||||
qCritical() << " start (cs): " << cs;
|
qCritical() << " start (cs): " << cs;
|
||||||
qCritical() << " price: " << price;
|
qCritical() << " price: " << price;
|
||||||
|
|
||||||
duration = calculator.GetDurationFromCost(tariff,
|
duration = calculator.GetDurationFromCost(tariff, PaymentOption::Option1,
|
||||||
tariff->getPaymentOptions().pop_payment_method_id,
|
|
||||||
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);
|
||||||
@ -293,14 +249,12 @@ 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);
|
||||||
QString endTime = calculator.GetDurationFromCost(
|
QString endTime = calculator.GetDurationFromCost(
|
||||||
tariff,
|
tariff, PaymentOption::Option1,
|
||||||
tariff->getPaymentOptions().pop_payment_method_id,
|
|
||||||
cs.toLocal8Bit().constData(),
|
cs.toLocal8Bit().constData(),
|
||||||
price, false, true).c_str();
|
price, false, true).c_str();
|
||||||
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
|
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
|
||||||
@ -321,28 +275,20 @@ 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 CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff_t *tariff, QString const &start_parking_time,uint8_t paymentMethod)
|
||||||
{
|
{
|
||||||
CalcState calcState;
|
CalcState calcState;
|
||||||
if (start_parking_time.isValid()) {
|
QString result = calculator.GetDailyTicketDuration(tariff, start_parking_time, PaymentOption::Option1,false);
|
||||||
|
qDebug() << "DailyTicket() => " + result;
|
||||||
ticketEndTime = calculator.GetDailyTicketDuration(tariff,
|
|
||||||
start_parking_time,
|
return calcState.set(CalcState::State::SUCCESS);
|
||||||
tariff->getPaymentOptions().pop_payment_method_id,
|
}
|
||||||
false); // carry over
|
|
||||||
|
CalcState CALCULATE_LIBRARY_API compute_duration_for_24hour_daily_ticket(parking_tariff_t *tariff, QString const &start_parking_time,uint8_t paymentMethod)
|
||||||
// DEBUG
|
{
|
||||||
qCritical() << "compute_duration_for_daily_ticket(): ";
|
CalcState calcState;
|
||||||
qCritical() << " ticketEndTime: " << ticketEndTime;
|
QString result = calculator.Get24HourTicketDuration(tariff, start_parking_time, PaymentOption::Option1,false);
|
||||||
|
qDebug() << "24HourDailyTicket() => " + result;
|
||||||
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);
|
return calcState.set(CalcState::State::SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "calculator_functions.h"
|
#include "calculator_functions.h"
|
||||||
#include "payment_option.h"
|
#include "payment_method.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "tariff_log.h"
|
#include "tariff_log.h"
|
||||||
|
|
||||||
@ -10,6 +10,7 @@
|
|||||||
double total_duration_min = 0.0f;
|
double total_duration_min = 0.0f;
|
||||||
double total_cost = 0.0f;
|
double total_cost = 0.0f;
|
||||||
bool overtime = false;
|
bool overtime = false;
|
||||||
|
int protection_counter = 0;
|
||||||
|
|
||||||
#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){
|
||||||
@ -19,25 +20,55 @@ inline struct tm* localtime_r(const time_t *clock, struct tm* result){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime start_datetime, uint8_t payment_option, bool carry_over)
|
QString Calculator::Get24HourTicketDuration(Configuration *cfg, QString start_datetime, uint8_t payment_option)
|
||||||
{
|
{
|
||||||
if(!start_datetime.isValid()) {
|
if(start_datetime.isNull() || start_datetime.isEmpty()) return "Invalid date-time";
|
||||||
return QDateTime();
|
protection_counter = 0;
|
||||||
}
|
|
||||||
|
double day_price = 0.0f;
|
||||||
|
int current_special_day_id = -1;
|
||||||
|
|
||||||
|
QDateTime inputDateTime = QDateTime::fromString(start_datetime, Qt::ISODate);
|
||||||
|
QTime worktime_from;
|
||||||
|
QTime worktime_to;
|
||||||
|
|
||||||
|
int daily_24hour_card_price = cfg->PaymentOption.find(payment_option)->second.pop_multi_hour_price;
|
||||||
|
if(daily_24hour_card_price <= 0) return "24-hour daily ticket: price zero or less";
|
||||||
|
|
||||||
|
bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toStdString().c_str(), ¤t_special_day_id, &day_price);
|
||||||
|
|
||||||
|
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);
|
||||||
|
return "24-hour ticket cannot be bought on special day";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check next special day
|
||||||
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
|
while(Utilities::CheckSpecialDay(cfg, inputDateTime.toString(Qt::ISODate).toLocal8Bit(), ¤t_special_day_id, &day_price))
|
||||||
|
{
|
||||||
|
protection_counter++;
|
||||||
|
if(protection_counter >=7) return NULL;
|
||||||
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
|
}
|
||||||
|
return inputDateTime.toString(Qt::ISODate) + ", price = " + to_string(daily_24hour_card_price).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Calculator::GetDailyTicketDuration(Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over)
|
||||||
|
{
|
||||||
|
if(start_datetime.isNull() || start_datetime.isEmpty()) return NULL;
|
||||||
|
|
||||||
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, start_datetime.toString(Qt::ISODate).toStdString().c_str(), ¤t_special_day_id, &day_price);
|
bool is_special_day = Utilities::CheckSpecialDay(cfg, start_datetime.toStdString().c_str(), ¤t_special_day_id, &day_price);
|
||||||
|
|
||||||
QDateTime inputDateTime = start_datetime;
|
QDateTime inputDateTime = QDateTime::fromString(start_datetime, Qt::ISODate);
|
||||||
QTime worktime_from;
|
QTime worktime_from;
|
||||||
QTime worktime_to;
|
QTime worktime_to;
|
||||||
|
|
||||||
int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price;
|
int daily_card_price = cfg->PaymentOption.find(payment_option)->second.pop_daily_card_price;
|
||||||
if(daily_card_price <= 0) {
|
if(daily_card_price <= 0) return "Daily ticket price zero or less";
|
||||||
LOG_ERROR("Calculator::GetDailyTicketDuration(): Daily ticket price zero or less");
|
|
||||||
return QDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_special_day)
|
if(is_special_day)
|
||||||
{
|
{
|
||||||
@ -51,21 +82,21 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
|
|||||||
{
|
{
|
||||||
// Go to next day if outside worktime
|
// Go to next day if outside worktime
|
||||||
inputDateTime = inputDateTime.addSecs(86400);
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
|
return GetDailyTicketDuration(cfg,inputDateTime.toString(Qt::ISODate), payment_option,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(day_price <=0)
|
if(day_price <=0)
|
||||||
{
|
{
|
||||||
// Go to next day if special day price is 0
|
// Go to next day if special day price is 0
|
||||||
inputDateTime = inputDateTime.addSecs(86400);
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
|
return GetDailyTicketDuration(cfg,inputDateTime.toString(Qt::ISODate), payment_option,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int diff = abs(inputDateTime.time().secsTo(worktime_to));
|
int diff = abs(inputDateTime.time().secsTo(worktime_to));
|
||||||
inputDateTime = inputDateTime.addSecs(diff);
|
inputDateTime = inputDateTime.addSecs(diff);
|
||||||
|
|
||||||
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
|
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
|
||||||
return inputDateTime;
|
return inputDateTime.toString(Qt::ISODate) + ", price = " + to_string(daily_card_price).c_str() + ", duration = " + to_string((diff/60)).c_str();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -81,7 +112,7 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
|
|||||||
if(found <=0)
|
if(found <=0)
|
||||||
{
|
{
|
||||||
inputDateTime = inputDateTime.addSecs(86400);
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
|
return GetDailyTicketDuration(cfg,inputDateTime.toString(Qt::ISODate), payment_option,true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -97,18 +128,18 @@ QDateTime Calculator::GetDailyTicketDuration(Configuration* cfg, const QDateTime
|
|||||||
{
|
{
|
||||||
// Go to next day if outside worktime
|
// Go to next day if outside worktime
|
||||||
inputDateTime = inputDateTime.addSecs(86400);
|
inputDateTime = inputDateTime.addSecs(86400);
|
||||||
return GetDailyTicketDuration(cfg,inputDateTime, payment_option,true);
|
return GetDailyTicketDuration(cfg,inputDateTime.toString(Qt::ISODate), payment_option,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int diff = abs(inputDateTime.time().secsTo(worktime_to));
|
int diff = abs(inputDateTime.time().secsTo(worktime_to));
|
||||||
inputDateTime = inputDateTime.addSecs(diff);
|
inputDateTime = inputDateTime.addSecs(diff);
|
||||||
|
|
||||||
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
|
//qDebug() << "Ticket is valid until: " << inputDateTime.toString(Qt::ISODate) << "price = " << daily_card_price << ", duration = " << diff / 60;
|
||||||
return inputDateTime;
|
return inputDateTime.toString(Qt::ISODate) + ", price = " + to_string(daily_card_price).c_str() + ", duration = " + to_string((diff/60)).c_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QDateTime();
|
return NULL;
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
||||||
@ -122,31 +153,19 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
// Get input date
|
// Get input date
|
||||||
QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate);
|
QDateTime inputDate = QDateTime::fromString(start_datetime,Qt::ISODate);
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get day of week
|
// Get day of week
|
||||||
int weekdayId = 0;
|
int weekdayId = 0;
|
||||||
weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year());
|
weekdayId = Utilities::ZellersAlgorithm(inputDate.date().day(),inputDate.date().month(),inputDate.date().year());
|
||||||
|
|
||||||
//Get min and max time defined in JSON
|
//Get min and max time defined in JSON
|
||||||
double minMin = 0;
|
double minMin = 0;
|
||||||
minMin = cfg->getPaymentOptions().pop_min_time;
|
minMin = cfg->PaymentOption.find(payment_option)->second.pop_min_time;
|
||||||
|
|
||||||
double maxMin = 0;
|
double maxMin = 0;
|
||||||
maxMin = cfg->getPaymentOptions().pop_max_time;
|
maxMin = cfg->PaymentOption.find(payment_option)->second.pop_max_time;
|
||||||
|
|
||||||
double min_price = 0;
|
double min_price = 0;
|
||||||
min_price = cfg->getPaymentOptions().pop_min_price;
|
min_price = cfg->PaymentOption.find(payment_option)->second.pop_min_price;
|
||||||
|
|
||||||
if(price < min_price)
|
if(price < min_price)
|
||||||
{
|
{
|
||||||
@ -219,9 +238,19 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
|
|
||||||
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";
|
// Commented on 07.06.2023
|
||||||
|
//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);
|
||||||
|
|
||||||
|
if (price_per_unit < 0)
|
||||||
|
{
|
||||||
|
inputDate = inputDate.addDays(1);
|
||||||
|
inputDate.setTime(worktime_from);
|
||||||
|
return GetDurationFromCost(cfg, payment_option, inputDate.toString(Qt::ISODate).toStdString().c_str(), money_left, true);
|
||||||
|
}
|
||||||
|
|
||||||
// If overtime flag is set
|
// If overtime flag is set
|
||||||
if (overtime || nextDay)
|
if (overtime || nextDay)
|
||||||
{
|
{
|
||||||
@ -325,15 +354,15 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
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);
|
inputDate.addSecs(-(int)ceil(calc_price) * 60);
|
||||||
//}
|
}
|
||||||
|
|
||||||
if(price >= min_price && total_duration_min >= minMin)
|
if(price >= min_price && total_duration_min >= minMin)
|
||||||
qDebug() << "GetDurationFromCost(): Valid until: " << inputDate.toString(Qt::ISODate);
|
qDebug() << "Valid until: " << inputDate.toString(Qt::ISODate);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "Parking not allowed";
|
qDebug() << "Parking not allowed";
|
||||||
@ -352,52 +381,10 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
///
|
double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_option, const char* start_datetime, double durationMin, bool nextDay, bool prepaid)
|
||||||
|
|
||||||
uint32_t Calculator::GetCostFromDuration(Configuration *cfg,
|
|
||||||
QDateTime const &start,
|
|
||||||
quint64 timeStepInMinutes) const {
|
|
||||||
// for instance, a tariff as used in Schoenau, Koenigssee: only steps, no
|
|
||||||
// special days, nonstop.
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Calculator::GetCostFromDuration(Configuration * cfg,
|
|
||||||
QDateTime const &start,
|
|
||||||
QDateTime const &end) const {
|
|
||||||
if (cfg->YearPeriod.size() == 0
|
|
||||||
&& cfg->SpecialDays.size() == 0
|
|
||||||
&& cfg->SpecialDaysWorktime.size() == 0) {
|
|
||||||
int const timeStepInMinutes = start.secsTo(end) / 60;
|
|
||||||
return GetPriceForTimeStep(cfg, timeStepInMinutes);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_option, const QDateTime start_datetime, QDateTime & end_datetime, double durationMin, bool nextDay, bool prepaid)
|
|
||||||
{
|
{
|
||||||
if (cfg->YearPeriod.size() == 0
|
|
||||||
&& cfg->SpecialDays.size() == 0
|
|
||||||
&& cfg->SpecialDaysWorktime.size() == 0)
|
|
||||||
{
|
|
||||||
end_datetime = start_datetime.addSecs(durationMin*60);
|
|
||||||
return GetCostFromDuration(cfg, start_datetime, end_datetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
||||||
@ -456,13 +443,11 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
|
|||||||
double price_per_unit = 0.0f;
|
double price_per_unit = 0.0f;
|
||||||
QTime worktime_from;
|
QTime worktime_from;
|
||||||
QTime worktime_to;
|
QTime worktime_to;
|
||||||
double durationUnit = 60.0;
|
|
||||||
|
|
||||||
if(is_special_day)
|
if(is_special_day)
|
||||||
{
|
{
|
||||||
// Set price_per_unit to special day price: at the end of the calculation
|
// Set special day price
|
||||||
// divide by durationUnit to get correct price.
|
price_per_unit = Utilities::CalculatePricePerUnit(day_price);
|
||||||
price_per_unit = day_price;
|
|
||||||
worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str());
|
worktime_from = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_from.c_str());
|
||||||
worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str());
|
worktime_to = QTime::fromString(cfg->SpecialDaysWorktime.find(current_special_day_id)->second.pedwt_time_to.c_str());
|
||||||
}
|
}
|
||||||
@ -474,13 +459,8 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
|
|||||||
day_price = cfg->PaymentRate.find(pop_id)->second.pra_price;
|
day_price = cfg->PaymentRate.find(pop_id)->second.pra_price;
|
||||||
|
|
||||||
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
|
int durationId = cfg->PaymentRate.find(pop_id)->second.pra_payment_unit_id;
|
||||||
durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
|
double durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
|
||||||
if (durationUnit == 0) {
|
price_per_unit = Utilities::CalculatePricePerUnit(day_price,durationUnit);
|
||||||
durationUnit = 60.0;
|
|
||||||
}
|
|
||||||
// Set price_per_unit to day price: at the end of the calculation
|
|
||||||
// divide by durationUnit to get correct price.
|
|
||||||
price_per_unit = day_price;
|
|
||||||
|
|
||||||
// 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;
|
||||||
@ -491,7 +471,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 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());
|
||||||
@ -504,7 +484,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
|
||||||
@ -534,7 +514,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +566,7 @@ double Calculator::GetCostFromDuration(Configuration* cfg, uint8_t payment_optio
|
|||||||
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
|
||||||
@ -595,75 +575,8 @@ 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 round(ret_val / durationUnit);
|
return ceil(ret_val);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
|
|
||||||
QList<int> timeSteps;
|
|
||||||
|
|
||||||
int const pop_id = cfg->getPaymentOptions().pop_id;
|
|
||||||
|
|
||||||
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr)
|
|
||||||
{
|
|
||||||
int const durationId = itr->second.pra_payment_unit_id;
|
|
||||||
int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
|
|
||||||
timeSteps << durationUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return timeSteps;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep) const {
|
|
||||||
|
|
||||||
int const pop_id = cfg->getPaymentOptions().pop_id;
|
|
||||||
|
|
||||||
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr)
|
|
||||||
{
|
|
||||||
int const payment_unit_id = itr->second.pra_payment_unit_id;
|
|
||||||
int const pun_id = cfg->Duration.find(payment_unit_id)->second.pun_id;
|
|
||||||
|
|
||||||
Q_ASSERT(pun_id == payment_unit_id);
|
|
||||||
|
|
||||||
int const pun_duration = cfg->Duration.find(payment_unit_id)->second.pun_duration;
|
|
||||||
if (timeStep == pun_duration) {
|
|
||||||
return (uint32_t)(itr->second.pra_price);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* private: read price directly from config file (used with PaymentMethod::Steps)
|
|
||||||
*
|
|
||||||
* return duration in minutes for greatest pra_price < price
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint32_t Calculator::GetDurationForPrice(Configuration *cfg, int price) const {
|
|
||||||
int const pop_id = cfg->getPaymentOptions().pop_id;
|
|
||||||
uint32_t duration = 0;
|
|
||||||
|
|
||||||
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr)
|
|
||||||
{
|
|
||||||
int const durationId = itr->second.pra_payment_unit_id;
|
|
||||||
int const pra_price = itr->second.pra_price;
|
|
||||||
uint32_t const durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
|
|
||||||
|
|
||||||
if (price == pra_price) {
|
|
||||||
return durationUnit;
|
|
||||||
}
|
|
||||||
if (pra_price < price) {
|
|
||||||
duration = durationUnit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return duration;
|
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,8 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
|| !document.HasMember("PaymentRate")
|
|| !document.HasMember("PaymentRate")
|
||||||
|| !document.HasMember("Duration")
|
|| !document.HasMember("Duration")
|
||||||
//|| !document.HasMember("WeekDays")
|
//|| !document.HasMember("WeekDays")
|
||||||
//|| !document.HasMember("SpecialDaysWorktime")
|
|| !document.HasMember("SpecialDaysWorktime")
|
||||||
//|| !document.HasMember("SpecialDays")
|
|| !document.HasMember("SpecialDays"))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
printf("%s", "Error: not a valid configuration JSON\n");
|
printf("%s", "Error: not a valid configuration JSON\n");
|
||||||
return false;
|
return false;
|
||||||
@ -88,26 +87,13 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
const char* mb_name = i->name.GetString();
|
const char* mb_name = i->name.GetString();
|
||||||
if (mb_name == NULL) continue;
|
if (mb_name == NULL) continue;
|
||||||
|
|
||||||
if (document[mb_name].IsString()) {
|
// if (!document[mb_name].IsArray()) {
|
||||||
QString const _mb_name(mb_name);
|
std::string const _mb_name(mb_name);
|
||||||
if (_mb_name.startsWith("Project", Qt::CaseInsensitive)) {
|
if (_mb_name == "version" || _mb_name == "project" ||
|
||||||
cfg->project.project = document[mb_name].GetString();
|
_mb_name == "zone" || _mb_name == "info") {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (_mb_name.startsWith("Version", Qt::CaseInsensitive)) {
|
|
||||||
cfg->project.version = document[mb_name].GetString();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_mb_name.startsWith("Info", Qt::CaseInsensitive)) {
|
// }
|
||||||
cfg->project.info = document[mb_name].GetString();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... everything else should be an array
|
|
||||||
if (!document[mb_name].IsArray()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf(" -%s\n", mb_name);
|
//printf(" -%s\n", mb_name);
|
||||||
|
|
||||||
@ -169,8 +155,8 @@ 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_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();
|
else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) PaymentOption.pop_daily_card_price = k->value.GetInt();
|
||||||
this->currentPaymentOptions = PaymentOption;
|
else if (strcmp(inner_obj_name, "pop_multi_hour_price") == 0) PaymentOption.pop_multi_hour_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();
|
||||||
else if (strcmp(inner_obj_name, "pun_label") == 0) Duration.pun_label = k->value.GetString();
|
else if (strcmp(inner_obj_name, "pun_label") == 0) Duration.pun_label = k->value.GetString();
|
||||||
@ -260,10 +246,3 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ATBPaymentOption & Configuration::getPaymentOptions()
|
|
||||||
{
|
|
||||||
return this->currentPaymentOptions;
|
|
||||||
}
|
|
||||||
|
@ -26,69 +26,35 @@ 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\\Old\\build-MOBILISIS-Calculator-Desktop_Qt_5_12_12_MSVC2017_32bit-Debug\\main\\etc\\psa_tariff\\tariff01.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-06-01T07:50:00.000Z",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() << "GetCostFromDuration() => 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,1650,duration))
|
||||||
{
|
// {
|
||||||
qDebug() << "GetDurationFromCost() => duration=" << duration;
|
// qDebug() << "GetDurationFromCost() => duration=" << duration;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Daily ticket
|
// Daily ticket
|
||||||
//compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
// compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
||||||
|
|
||||||
|
compute_duration_for_24hour_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
||||||
|
|
||||||
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over
|
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over
|
||||||
// // tests
|
// // tests
|
||||||
|
@ -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 {
|
||||||
|
@ -38,7 +38,9 @@
|
|||||||
"pop_max_time": 300,
|
"pop_max_time": 300,
|
||||||
"pop_min_price": 0,
|
"pop_min_price": 0,
|
||||||
"pop_carry_over": 1,
|
"pop_carry_over": 1,
|
||||||
"pop_daily_card_price": 900
|
"pop_daily_card_price": 900,
|
||||||
|
"pop_multi_hour_price":500
|
||||||
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"PaymentRate": [
|
"PaymentRate": [
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user