Compare commits
39 Commits
4a076e1dad
...
1.0.0
Author | SHA1 | Date | |
---|---|---|---|
d15c9dad29
|
|||
cb8cd5dead
|
|||
9d64350e4f
|
|||
1a71edc274 | |||
51d8beda2a | |||
7bab9d6ba2 | |||
8b4d64bd0c | |||
eefdde4693 | |||
6157861d62 | |||
23748966de
|
|||
7bd7f66666 | |||
268d43cdea
|
|||
a453886f0a
|
|||
eef94a3fb3
|
|||
88a0b6ebe2
|
|||
3097819c01
|
|||
acf799da7e
|
|||
3bf71f84d5
|
|||
73f5eca656
|
|||
b8753cc2ed
|
|||
29986e0451
|
|||
1146db743c
|
|||
c6302edec5
|
|||
617eee39ed | |||
6b3c1cbf0c | |||
1142efaec2 | |||
90eae152bf
|
|||
6d001f1501
|
|||
de32022b89
|
|||
1e2f1589ac
|
|||
2f8c8cab4c | |||
ee1f7eca44
|
|||
1069c5ad90
|
|||
46bffc250d
|
|||
2599513ef9 | |||
ef66c1f0c0 | |||
219d820104 | |||
ed9166c226 | |||
818c67ad63 |
@@ -107,9 +107,9 @@ struct CALCULATE_LIBRARY_API CalcState {
|
|||||||
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
|
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
|
||||||
char const *config_file);
|
char const *config_file);
|
||||||
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 CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
|
||||||
|
|
||||||
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,
|
||||||
@@ -118,10 +118,11 @@ 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,
|
||||||
QDateTime const &end_parking_time,
|
int netto_parking_time,
|
||||||
struct price_t *price);
|
QDateTime &end_parking_time, // return value
|
||||||
|
struct price_t *price); // return value
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket( // deprecated
|
||||||
parking_tariff_t *tariff,
|
parking_tariff_t *tariff,
|
||||||
time_t start_parking_time,
|
time_t start_parking_time,
|
||||||
double cost,
|
double cost,
|
||||||
@@ -131,6 +132,11 @@ 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,7 +23,11 @@ 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, char const* start_datetime, double durationMin, bool nextDay = false, bool prepaid = false);
|
double GetCostFromDuration(Configuration* cfg, uint8_t vehicle_type, const QDateTime start_datetime, QDateTime & end_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);
|
||||||
|
};
|
||||||
|
@@ -55,4 +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);
|
||||||
};
|
};
|
||||||
|
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
enum DayOfWeek
|
enum DayOfWeek
|
||||||
{
|
{
|
||||||
Saturday = 0x06,
|
Monday = 0x01,
|
||||||
Sunday = 0x01,
|
Tuesday = 0x02,
|
||||||
Monday = 0x02,
|
Wednesday = 0x03,
|
||||||
Tuesday = 0x02,
|
Thursday = 0x04,
|
||||||
Wednesday = 0x03,
|
Friday = 0x05,
|
||||||
Thursday = 0x04,
|
Saturday = 0x06,
|
||||||
Friday = 0x05,
|
Sunday = 0x07,
|
||||||
UndefinedDay = 0xFF
|
UndefinedDay = 0xFF
|
||||||
};
|
};
|
||||||
|
@@ -14,4 +14,5 @@ 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;
|
||||||
|
};
|
||||||
|
@@ -68,5 +68,6 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pra_price"></param>
|
/// <param name="pra_price"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
static double CalculatePricePerUnit(double pra_price);
|
static double CalculatePricePerUnit(double pra_price, double durationUnit = -1);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -10,24 +10,31 @@
|
|||||||
|
|
||||||
static Calculator calculator;
|
static Calculator calculator;
|
||||||
|
|
||||||
int CALCULATE_LIBRARY_API get_zone_nr() {
|
int CALCULATE_LIBRARY_API get_zone_nr(int zone)
|
||||||
QFile zone("/etc/zone_nr");
|
{
|
||||||
if (zone.exists()) {
|
if(zone > -1) return zone;
|
||||||
QFileInfo finfo(zone);
|
else
|
||||||
if (finfo.size() <= 4) { // decimal 000\n
|
{
|
||||||
if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
QFile zone("/etc/zone_nr");
|
||||||
QTextStream in(&zone);
|
if (zone.exists()) {
|
||||||
return in.readLine(100).toInt();
|
QFileInfo finfo(zone);
|
||||||
|
if (finfo.size() <= 4) { // decimal 000\n
|
||||||
|
if (zone.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream in(&zone);
|
||||||
|
return in.readLine(100).toInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) {
|
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char const *config_file) {
|
||||||
*tariff = new Configuration();
|
*tariff = new Configuration();
|
||||||
|
|
||||||
CalcState calcState;
|
CalcState calcState;
|
||||||
|
#if __linux__
|
||||||
|
|
||||||
int const zone = get_zone_nr();
|
int const zone = get_zone_nr();
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
@@ -49,13 +56,16 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char cons
|
|||||||
memset(buffer, 0x00, sizeof(buffer));
|
memset(buffer, 0x00, sizeof(buffer));
|
||||||
snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone);
|
snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone);
|
||||||
confFile += buffer;
|
confFile += buffer;
|
||||||
|
#else // windows
|
||||||
|
QString confFile(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
qCritical() << " ... confFile = " << confFile;
|
qCritical() << " ... confFile = " << confFile;
|
||||||
|
|
||||||
QFile fname(confFile);
|
QFile fname(confFile);
|
||||||
if (fname.exists() &&
|
if (fname.exists() &&
|
||||||
fname.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
fname.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
qCritical() << " ... confFile is open";
|
qCritical() << " ... confFile is open";
|
||||||
|
|
||||||
@@ -82,11 +92,13 @@ 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, // in minutes
|
time_t end_parking_time, // netto 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;
|
||||||
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
|
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
|
||||||
@@ -99,7 +111,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
|
|||||||
int const duration = end_parking_time - start_parking_time;
|
int const duration = end_parking_time - start_parking_time;
|
||||||
if (duration < 0) {
|
if (duration < 0) {
|
||||||
calcState.setDesc(QString("end=%1, start=%2")
|
calcState.setDesc(QString("end=%1, start=%2")
|
||||||
.arg(end_parking_time, start_parking_time));
|
.arg(end_parking_time, start_parking_time));
|
||||||
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME);
|
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME);
|
||||||
}
|
}
|
||||||
if (duration > maxMin) {
|
if (duration > maxMin) {
|
||||||
@@ -119,12 +131,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, PaymentOption::Option1,
|
tariff, PaymentOption::Option1,
|
||||||
cs.toLocal8Bit().constData(),
|
start,
|
||||||
duration, false, true);
|
end,
|
||||||
|
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) {
|
||||||
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost));
|
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost));
|
||||||
@@ -140,10 +153,12 @@ 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,
|
||||||
QDateTime const &end_parking_time,
|
int netto_parking_time,
|
||||||
struct price_t *price) {
|
QDateTime &end_parking_time,
|
||||||
|
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;
|
||||||
@@ -151,39 +166,37 @@ 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
|
||||||
<< " end_parking_time: " << end_parking_time << endl
|
<< " netto_parking_time: " << netto_parking_time << endl
|
||||||
<< " minMin: " << minMin << endl
|
<< " minMin: " << minMin << endl
|
||||||
<< " maxMin: " << maxMin;
|
<< " maxMin: " << maxMin;
|
||||||
|
|
||||||
|
|
||||||
int const duration = (end_parking_time.toSecsSinceEpoch() -
|
if (netto_parking_time < 0) {
|
||||||
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 (duration > maxMin) {
|
if (netto_parking_time > maxMin) {
|
||||||
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration, maxMin));
|
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin));
|
||||||
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
|
||||||
}
|
}
|
||||||
if (duration < minMin) {
|
if (netto_parking_time < minMin) {
|
||||||
calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration, minMin));
|
calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin));
|
||||||
return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME);
|
return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME);
|
||||||
}
|
}
|
||||||
if (duration == 0) {
|
if (netto_parking_time == 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,
|
||||||
cs.toLocal8Bit().constData(),
|
start_parking_time, // starting time
|
||||||
duration, false, true);
|
end_parking_time, // return value: end time
|
||||||
|
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));
|
||||||
@@ -203,10 +216,10 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
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 price,
|
double price,
|
||||||
QString &duration) {
|
QString &duration) {
|
||||||
CalcState calcState;
|
CalcState calcState;
|
||||||
QDate const d(1970, 1, 1);
|
QDate const d(1970, 1, 1);
|
||||||
QTime const t(0, 0, 0);
|
QTime const t(0, 0, 0);
|
||||||
@@ -223,7 +236,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);
|
QDateTime d = QDateTime::fromString(duration, Qt::ISODate);
|
||||||
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);
|
||||||
@@ -236,17 +249,18 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
|
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, PaymentOption::Option1,
|
tariff, PaymentOption::Option1,
|
||||||
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);
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
@@ -264,3 +278,30 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -154,6 +154,7 @@ 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();
|
||||||
@@ -209,7 +210,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_unit_id, PaymentRate));
|
cfg->PaymentRate.insert(pair<int, ATBPaymentRate>(PaymentRate.pra_payment_option_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));
|
||||||
|
@@ -8,12 +8,15 @@ 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 Utilities::CalculatePricePerUnit(double pra_price, double durationUnit)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double price_per_unit = pra_price;
|
double price_per_unit = pra_price;
|
||||||
price_per_unit /= 60.0f; // Divided by 60 because price per unit is set per hour and we are using minutes
|
double unit = durationUnit;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -33,7 +36,7 @@ time_t Utilities::GetCurrentLocalTime()
|
|||||||
memset(&tm_curr_time, '\0', sizeof(struct tm));
|
memset(&tm_curr_time, '\0', sizeof(struct tm));
|
||||||
|
|
||||||
tm_curr_time = *localtime(&curr_time);
|
tm_curr_time = *localtime(&curr_time);
|
||||||
curr_time = mktime(&tm_curr_time) - timezone;
|
curr_time = mktime(&tm_curr_time); //- timezone;
|
||||||
return curr_time;
|
return curr_time;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
198
main/main.cpp
198
main/main.cpp
@@ -1,10 +1,9 @@
|
|||||||
#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,
|
||||||
@@ -27,88 +26,135 @@ 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, "/etc/psa_tariff/")) {
|
||||||
struct price_t price;
|
struct price_t price;
|
||||||
memset(&price, 0x00, sizeof(price));
|
memset(&price, 0x00, sizeof(price));
|
||||||
QDateTime start = 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 + 60;
|
time_t end_parking_time = start_parking_time + 615;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests
|
QString duration;
|
||||||
struct tm now;
|
if(compute_duration_for_parking_ticket(tariff,start_parking_time,3090,duration))
|
||||||
memset(&now, 0, sizeof(now));
|
{
|
||||||
|
qDebug() << "GetDurationFromCost() => duration=" << duration;
|
||||||
// 3.Jan 2023 -> Tuesday
|
|
||||||
strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
|
||||||
for (int i = 0; i < 600; ++i) {
|
|
||||||
start_parking_time = mktime(&now);
|
|
||||||
end_parking_time = start_parking_time + 240; // duration == 240
|
|
||||||
|
|
||||||
if (compute_price_for_parking_ticket(tariff,
|
|
||||||
start_parking_time,
|
|
||||||
end_parking_time,
|
|
||||||
&price)) {
|
|
||||||
int const zone = get_zone_nr();
|
|
||||||
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,
|
// Daily ticket
|
||||||
start_parking_time,
|
//compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
||||||
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;
|
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over
|
||||||
now = *localtime(&t);
|
// // tests
|
||||||
}
|
// struct tm now;
|
||||||
|
// memset(&now, 0, sizeof(now));
|
||||||
|
|
||||||
|
// // 3.Jan 2023 -> Tuesday
|
||||||
|
// strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
||||||
|
// for (int i = 0; i < 600; ++i) {
|
||||||
|
// start_parking_time = mktime(&now);
|
||||||
|
// end_parking_time = start_parking_time + 240; // duration == 240
|
||||||
|
|
||||||
|
// if (compute_price_for_parking_ticket(tariff,
|
||||||
|
// start_parking_time,
|
||||||
|
// end_parking_time,
|
||||||
|
// &price)) {
|
||||||
|
// 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,
|
||||||
|
// start_parking_time,
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
@@ -145,7 +191,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) {
|
||||||
@@ -220,8 +266,8 @@ int main() {
|
|||||||
|
|
||||||
int const duration = 120;
|
int const duration = 120;
|
||||||
double cost = calculator.GetCostFromDuration(&cfg,
|
double cost = calculator.GetCostFromDuration(&cfg,
|
||||||
PaymentOption::Option1, buffer, duration,
|
PaymentOption::Option1, buffer, duration,
|
||||||
false, true);
|
false, true);
|
||||||
|
|
||||||
switch (zone) {
|
switch (zone) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -259,8 +305,8 @@ int main() {
|
|||||||
|
|
||||||
int const duration = 120;
|
int const duration = 120;
|
||||||
double cost = calculator.GetCostFromDuration(&cfg,
|
double cost = calculator.GetCostFromDuration(&cfg,
|
||||||
PaymentOption::Option1, buffer, duration,
|
PaymentOption::Option1, buffer, duration,
|
||||||
false, true);
|
false, true);
|
||||||
|
|
||||||
switch (zone) {
|
switch (zone) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -293,8 +339,8 @@ int main() {
|
|||||||
|
|
||||||
double const compCost = (duration < 15) ? 0 : duration * ((zone == 1) ? 3.6666 : 8.0);
|
double const compCost = (duration < 15) ? 0 : duration * ((zone == 1) ? 3.6666 : 8.0);
|
||||||
double cost = calculator.GetCostFromDuration(&cfg,
|
double cost = calculator.GetCostFromDuration(&cfg,
|
||||||
PaymentOption::Option1, buffer, duration,
|
PaymentOption::Option1, buffer, duration,
|
||||||
false, true);
|
false, true);
|
||||||
if (fabs(cost - compCost) > 1.0) { // zone 1 has rounding errors
|
if (fabs(cost - compCost) > 1.0) { // zone 1 has rounding errors
|
||||||
cout << "ERROR ===> [" << i << "] " << asctime(&now)
|
cout << "ERROR ===> [" << i << "] " << asctime(&now)
|
||||||
<< " - Total cost is: " << cost << " FT (computed="
|
<< " - Total cost is: " << cost << " FT (computed="
|
||||||
|
@@ -7,6 +7,8 @@ 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 {
|
||||||
|
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
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user