Compare commits

..

56 Commits

Author SHA1 Message Date
9bfea0f46d Add compute_next_timestep() 2023-11-27 08:59:51 +01:00
7ee90a9e8a Fix: GetDurationForPrice return proper value not only '0' 2023-11-23 15:06:57 +01:00
8f2609c4ae Fix: GetDurationFromCost for PaymentMethod::Steps 2023-11-23 11:14:21 +01:00
453ca266a5 Merge remote-tracking branch 'origin/schoenau_23112023' 2023-11-23 09:46:42 +01:00
0217bb8918 GetTimeStep() and GetPriceForTimeStep(): use getPaymentOptions(). 2023-11-23 09:41:40 +01:00
4b35b1ffb7 Implement GetDurationForPrice(). 2023-11-23 09:41:02 +01:00
80e228b498 GetCostFromDuration(): don't use condiftion PaymentMethod::Steps,
but the multimap YearPeriod, which must be empty.
2023-11-23 09:39:26 +01:00
574161ff76 Call getDurationForPrice() in GetDurationForCost(). 2023-11-23 09:38:34 +01:00
b80cd5e6ef Remove parameter paymentMethod.
Add GetDurationForPrice().
2023-11-23 09:36:50 +01:00
ccbf07a654 Use new getPaymentOptions interface 2023-11-23 08:42:35 +01:00
3a2e521345 Add interface to access 'PaymentOptions' 2023-11-22 16:27:41 +01:00
cd77e380ef Read project/version-info from tariff-config ...
... if available
2023-11-22 11:27:09 +01:00
aaa4348a9a Add ATBProject to configuration 2023-11-22 11:14:48 +01:00
17c4aac452 Add header file atb_project.h 2023-11-22 11:14:38 +01:00
68c438bfe0 Add header file for project-variables 2023-11-22 11:13:37 +01:00
509bc29d7e Fix: read tariff configuration file 2023-11-22 10:17:40 +01:00
f7e462188f Add methods for PaymentMethod::Steps 2023-11-22 09:53:07 +01:00
d15c9dad29 Update tariff04 (virtual dayticket) 2023-06-27 17:43:58 +02:00
cb8cd5dead Merge branch 'moransBranch' 2023-06-14 11:28:27 +02:00
9d64350e4f Merge branch 'moransBranch' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into moransBranch 2023-06-14 11:27:43 +02:00
1a71edc274 max_time=300, unit_id=1 2023-06-13 13:32:16 +02:00
51d8beda2a max_time=300, unit_id=1 2023-06-13 13:32:12 +02:00
7bab9d6ba2 max_time=300, unit_id=1 2023-06-13 13:32:08 +02:00
8b4d64bd0c max_time=300, unit_id=1 2023-06-13 13:31:42 +02:00
eefdde4693 Removed section whith superfluous 'price_per_unit < 0' check.
Removed calc_price-caculation followed by shift of inputDate.
2023-06-13 12:12:23 +02:00
6157861d62 Monday starts with 1 2023-06-13 12:11:09 +02:00
23748966de Merge branch 'moransBranch' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into moransBranch 2023-05-19 15:49:38 +02:00
7bd7f66666 Fixed pra_payment_unit_id 2023-05-17 10:08:02 +02:00
268d43cdea GetDailyTicketDuration: use QDateTime for timestamps 2023-05-16 16:43:45 +02:00
a453886f0a Merge branch 'master' into moransBranch 2023-05-16 15:35:47 +02:00
eef94a3fb3 Change interface: use QDateTime
- use QDateTime instead of char*-string
 - GetCostFromDuration: add end_datetime as a return value
2023-05-16 15:31:53 +02:00
88a0b6ebe2 Make main.c compile again 2023-05-16 11:10:49 +02:00
3097819c01 Update interface for 'compute_duration_for_daily_ticket() 2023-05-16 11:07:21 +02:00
acf799da7e Add explaining comments 2023-05-15 17:37:51 +02:00
3bf71f84d5 Merge branch 'moransBranch' 2023-05-15 17:33:51 +02:00
73f5eca656 Tariff config: add day ticket 2023-05-15 17:23:10 +02:00
b8753cc2ed Update tariff config for test 2023-05-15 17:06:57 +02:00
29986e0451 Merge branch 'moransBranch' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into moransBranch 2023-05-15 16:58:48 +02:00
1146db743c Add explaining comments 2023-05-15 16:58:28 +02:00
c6302edec5 Format all json files 2023-05-15 16:57:45 +02:00
617eee39ed Daily ticket 2023-05-15 14:05:55 +02:00
6b3c1cbf0c Fix with min time in GetDurationFromCost 2023-05-14 17:19:24 +02:00
1142efaec2 Rounding minutes seems to be fixed ... 2023-05-14 16:15:37 +02:00
90eae152bf Merge branch 'moransBranch' 2023-05-12 14:48:19 +02:00
6d001f1501 Fix: QDateTime.addSecs() creates a new object 2023-05-12 14:28:30 +02:00
de32022b89 Merge branch 'moransBranch' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator into moransBranch 2023-05-12 14:10:57 +02:00
1e2f1589ac Fix: QDateTime::fromString() 2023-05-12 14:10:16 +02:00
2f8c8cab4c Another small fix on GetDurationFromCost() 2023-05-12 13:02:10 +02:00
ee1f7eca44 Merge branch 'master' of git.mimbach49.de:GerhardHoffmann/MOBILISIS-Calculator 2023-05-12 12:43:49 +02:00
1069c5ad90 main: add test for GetDurationFromCost 2023-05-12 12:43:07 +02:00
46bffc250d Fix: includepath for main 2023-05-12 12:41:37 +02:00
2599513ef9 Minor fixes with +/- 1 minute offset. 2023-05-12 12:40:25 +02:00
ef66c1f0c0 Fixed GetDurationFromCost() 2023-05-12 11:55:35 +02:00
219d820104 GetCostFromDuration fixed 2023-05-12 09:20:46 +02:00
ed9166c226 Windows: set timezone as -3600. 2023-05-11 13:58:33 +02:00
818c67ad63 Windows debug: for init-Tariff, do not read zone_ne, but use the path given directly. 2023-05-11 13:57:31 +02:00
18 changed files with 4232 additions and 683 deletions

View File

@@ -0,0 +1,13 @@
#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

View File

@@ -107,9 +107,11 @@ struct CALCULATE_LIBRARY_API CalcState {
CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
char const *config_file);
void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff);
int CALCULATE_LIBRARY_API get_zone_nr();
int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated
parking_tariff_t *tariff,
time_t start_parking_time,
time_t end_parking_time,
@@ -118,10 +120,11 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime const &end_parking_time,
struct price_t *price);
int netto_parking_time,
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,
time_t start_parking_time,
double cost,
@@ -131,6 +134,11 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
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);
//#ifdef __cplusplus
//} // extern "C"

View File

@@ -1,7 +1,8 @@
#pragma once
#include <iostream>
#include "configuration.h"
#include "payment_method.h"
#include <QDateTime>
using namespace std;
class Calculator
@@ -23,7 +24,25 @@ public:
/// <param name="tariff_cfg">Pointer to configuration</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="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>
/// <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);
//
// helper function to find time steps for a tariff with PaymentMethod::Steps
// (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;
};

View File

@@ -20,6 +20,7 @@
#include "member_type.h"
#include "period_year.h"
#include "payment_rate.h"
#include "atb_project.h"
using namespace std;
using namespace rapidjson;
@@ -27,8 +28,8 @@ using namespace rapidjson;
class Configuration
{
public:
ATBCurrency Currency;
ATBProject project;
ATBCurrency Currency;
ATBDuration duration;
multimap<int, ATBDuration> Duration;
@@ -48,6 +49,8 @@ public:
/// <returns>Returns operation status bool (OK | FAIL) </returns>
bool ParseJson(Configuration* cfg, const char* json);
ATBPaymentOption const & getPaymentOptions();
private:
/// <summary>
/// Identify type of JSON member
@@ -55,4 +58,6 @@ private:
/// <param name="member_name"></param>
/// <returns></returns>
MemberType IdentifyJsonMember(const char* member_name);
ATBPaymentOption currentPaymentOptions;
};

View File

@@ -2,12 +2,12 @@
enum DayOfWeek
{
Saturday = 0x06,
Sunday = 0x01,
Monday = 0x02,
Tuesday = 0x02,
Wednesday = 0x03,
Thursday = 0x04,
Friday = 0x05,
UndefinedDay = 0xFF
Monday = 0x01,
Tuesday = 0x02,
Wednesday = 0x03,
Thursday = 0x04,
Friday = 0x05,
Saturday = 0x06,
Sunday = 0x07,
UndefinedDay = 0xFF
};

View File

@@ -14,4 +14,5 @@ public:
double pop_max_time;
double pop_min_price;
int pop_carry_over;
int pop_daily_card_price;
};

View File

@@ -68,5 +68,6 @@ public:
/// </summary>
/// <param name="pra_price"></param>
/// <returns></returns>
static double CalculatePricePerUnit(double pra_price);
static double CalculatePricePerUnit(double pra_price, double durationUnit = -1);
};

View File

@@ -1,6 +1,6 @@
TEMPLATE = lib
TARGET = mobilisis_calc
# CONFIG += staticlib
#CONFIG += staticlib
QMAKE_CXXFLAGS += -std=c++17 -g -O0
@@ -65,7 +65,8 @@ HEADERS += \
include/mobilisis/tariff_period_year.h \
include/mobilisis/tariff_payment_rate.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

View File

@@ -10,24 +10,31 @@
static Calculator calculator;
int CALCULATE_LIBRARY_API get_zone_nr() {
QFile zone("/etc/zone_nr");
if (zone.exists()) {
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();
int CALCULATE_LIBRARY_API get_zone_nr(int zone)
{
if(zone > -1) return zone;
else
{
QFile zone("/etc/zone_nr");
if (zone.exists()) {
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) {
*tariff = new Configuration();
CalcState calcState;
#if __linux__
int const zone = get_zone_nr();
// DEBUG
@@ -49,13 +56,16 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff, char cons
memset(buffer, 0x00, sizeof(buffer));
snprintf(buffer, sizeof(buffer)-1, "tariff%02d.json", zone);
confFile += buffer;
#else // windows
QString confFile(config_file);
#endif
// DEBUG
qCritical() << " ... confFile = " << confFile;
QFile fname(confFile);
if (fname.exists() &&
fname.open(QIODevice::ReadOnly | QIODevice::Text)) {
fname.open(QIODevice::ReadOnly | QIODevice::Text)) {
// DEBUG
qCritical() << " ... confFile is open";
@@ -82,14 +92,54 @@ 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(
parking_tariff_t *tariff,
time_t start_parking_time, // in minutes
time_t end_parking_time, // in minutes
struct price_t *price) {
parking_tariff_t *tariff,
time_t start_parking_time, // in minutes
time_t end_parking_time, // netto time in minutes
struct price_t *price) {
CalcState calcState;
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
double minMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_time;
double maxMin = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_max_time;
if (minMin < 0 || maxMin < 0 || maxMin < minMin) {
calcState.setDesc(QString("minMin=%1, maxMin=%2").arg(minMin).arg(maxMin));
@@ -99,7 +149,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
int const duration = end_parking_time - start_parking_time;
if (duration < 0) {
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);
}
if (duration > maxMin) {
@@ -119,13 +169,15 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
QTime const t(0, 0, 0);
QDateTime start(d, t, Qt::UTC);
start = start.toLocalTime().addSecs(start_parking_time * 60);
QDateTime end(start);
if (start.isValid()) {
QString cs = start.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration(
tariff, PaymentOption::Option1,
cs.toLocal8Bit().constData(),
duration, false, true);
double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price;
tariff,
tariff->getPaymentOptions().pop_payment_method_id,
start,
end,
duration, false, true);
double minCost = tariff->PaymentOption.find(tariff->getPaymentOptions().pop_payment_method_id)->second.pop_min_price;
if (cost < minCost) {
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost).arg(cost));
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
@@ -140,51 +192,52 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
}
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
QDateTime const &end_parking_time,
struct price_t *price) {
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
int netto_parking_time,
QDateTime &end_parking_time,
struct price_t *price)
{
CalcState calcState;
double minMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_time;
double maxMin = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_max_time;
double minMin = tariff->getPaymentOptions().pop_min_time;
double maxMin = tariff->getPaymentOptions().pop_max_time;
// DEBUG
qCritical() << "compute_price_for_parking_ticket() " << 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
<< " maxMin: " << maxMin;
int const duration = (end_parking_time.toSecsSinceEpoch() -
start_parking_time.toSecsSinceEpoch()) / 60;
if (duration < 0) {
if (netto_parking_time < 0) {
calcState.setDesc(QString("end=%1, start=%2")
.arg(end_parking_time.toString(Qt::ISODate),
start_parking_time.toString(Qt::ISODate)));
.arg(end_parking_time.toString(Qt::ISODate),
start_parking_time.toString(Qt::ISODate)));
return calcState.set(CalcState::State::NEGATIVE_PARING_TIME);
}
if (duration > maxMin) {
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(duration, maxMin));
if (netto_parking_time > maxMin) {
calcState.setDesc(QString("duration=%1, maxMin=%2").arg(netto_parking_time).arg(maxMin));
return calcState.set(CalcState::State::ABOVE_MAX_PARKING_TIME);
}
if (duration < minMin) {
calcState.setDesc(QString("duration=%1, minMin=%2").arg(duration, minMin));
if (netto_parking_time < minMin) {
calcState.setDesc(QString("duration=%1, minMin=%2").arg(netto_parking_time).arg(minMin));
return calcState.set(CalcState::State::BELOW_MIN_PARKING_TIME);
}
if (duration == 0) {
if (netto_parking_time == 0) {
memset(price, 0x00, sizeof(*price));
return calcState.set(CalcState::State::SUCCESS);
}
if (start_parking_time.isValid()) {
QString cs = start_parking_time.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration(
tariff, PaymentOption::Option1,
cs.toLocal8Bit().constData(),
duration, false, true);
double minCost = tariff->PaymentOption.find(PaymentOption::Option1)->second.pop_min_price;
tariff,
tariff->getPaymentOptions().pop_payment_method_id,
start_parking_time, // starting time
end_parking_time, // return value: end time
netto_parking_time, // minutes, netto
false, true);
double minCost = tariff->getPaymentOptions().pop_min_price;
if (cost < minCost) {
calcState.setDesc(QString("minCost=%1, cost=%2").arg(minCost, cost));
return calcState.set(CalcState::State::BELOW_MIN_PARKING_PRICE);
@@ -203,10 +256,10 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
}
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff,
time_t start_parking_time,
double price,
QString &duration) {
parking_tariff_t *tariff,
time_t start_parking_time,
double price,
QString &duration) {
CalcState calcState;
QDate const d(1970, 1, 1);
QTime const t(0, 0, 0);
@@ -220,10 +273,11 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
qCritical() << " start (cs): " << cs;
qCritical() << " price: " << price;
duration = calculator.GetDurationFromCost(tariff, PaymentOption::Option1,
duration = calculator.GetDurationFromCost(tariff,
tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(),
price, false, true).c_str();
QDateTime d = QDateTime::fromString(duration);
QDateTime d = QDateTime::fromString(duration, Qt::ISODate);
if (!d.isValid()) {
calcState.setDesc(QString("ticketEndTime=%1").arg(duration));
return calcState.set(CalcState::State::WRONG_ISO_TIME_FORMAT);
@@ -236,17 +290,19 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
}
CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
double price,
QDateTime &ticketEndTime) {
parking_tariff_t *tariff,
QDateTime const &start_parking_time,
double price,
QDateTime &ticketEndTime)
{
CalcState calcState;
if (start_parking_time.isValid()) {
QString cs = start_parking_time.toString(Qt::ISODate);
QString endTime = calculator.GetDurationFromCost(
tariff, PaymentOption::Option1,
cs.toLocal8Bit().constData(),
price, false, true).c_str();
tariff,
tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(),
price, false, true).c_str();
ticketEndTime = QDateTime::fromString(endTime,Qt::ISODate);
// DEBUG
@@ -264,3 +320,30 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
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,
tariff->getPaymentOptions().pop_payment_method_id,
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

View File

@@ -59,8 +59,9 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
|| !document.HasMember("PaymentRate")
|| !document.HasMember("Duration")
//|| !document.HasMember("WeekDays")
|| !document.HasMember("SpecialDaysWorktime")
|| !document.HasMember("SpecialDays"))
//|| !document.HasMember("SpecialDaysWorktime")
//|| !document.HasMember("SpecialDays")
)
{
printf("%s", "Error: not a valid configuration JSON\n");
return false;
@@ -87,13 +88,26 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
const char* mb_name = i->name.GetString();
if (mb_name == NULL) continue;
// if (!document[mb_name].IsArray()) {
std::string const _mb_name(mb_name);
if (_mb_name == "version" || _mb_name == "project" ||
_mb_name == "zone" || _mb_name == "info") {
if (document[mb_name].IsString()) {
QString const _mb_name(mb_name);
if (_mb_name.startsWith("Project", Qt::CaseInsensitive)) {
cfg->project.project = document[mb_name].GetString();
continue;
}
if (_mb_name.startsWith("Version", Qt::CaseInsensitive)) {
cfg->project.version = document[mb_name].GetString();
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);
@@ -154,7 +168,9 @@ 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_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();
break;
else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) PaymentOption.pop_daily_card_price = k->value.GetInt();
this->currentPaymentOptions = PaymentOption;
break;
case MemberType::DurationType:
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();
@@ -209,7 +225,7 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
cfg->PaymentMethod.insert(pair<int, ATBPaymentMethod>(PaymentMethod.pme_id, PaymentMethod));
break;
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;
case MemberType::PaymentOptionType:
cfg->PaymentOption.insert(pair<int, ATBPaymentOption>(PaymentOption.pop_payment_method_id, PaymentOption));
@@ -244,3 +260,10 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
return false;
}
}
const ATBPaymentOption & Configuration::getPaymentOptions()
{
return this->currentPaymentOptions;
}

View File

@@ -8,12 +8,15 @@ static int protection_counter = 0;
/// </summary>
/// <param name="pra_price"></param>
/// <returns></returns>
double Utilities::CalculatePricePerUnit(double pra_price)
double Utilities::CalculatePricePerUnit(double pra_price, double durationUnit)
{
try
{
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);
return price_per_unit;
}
@@ -33,7 +36,7 @@ time_t Utilities::GetCurrentLocalTime()
memset(&tm_curr_time, '\0', sizeof(struct tm));
tm_curr_time = *localtime(&curr_time);
curr_time = mktime(&tm_curr_time) - timezone;
curr_time = mktime(&tm_curr_time); //- timezone;
return curr_time;
}
catch (...)

View File

@@ -1,10 +1,9 @@
#include <calculate_price.h>
#ifdef WIN32
#include <time.h>
#include <iomanip>
#include <sstream>
#include <calculate_price.h>
extern "C" char* strptime(const char* s,
const char* f,
@@ -27,88 +26,135 @@ extern "C" char* strptime(const char* s,
#include <QDebug>
#include <QDateTime>
#include <QDir>
#include <fstream>
#include <sstream>
#include "calculator_functions.h"
#include <calculate_price.h>
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;
if (init_tariff(&tariff, "/etc/psa_tariff/")) {
struct price_t 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 end_parking_time = start_parking_time + 60;
time_t end_parking_time = start_parking_time + 615;
if (compute_price_for_parking_ticket(tariff,
start_parking_time,
end_parking_time,
&price)) {
qDebug() << "price=" << price.netto;
&price))
{
qDebug() << "GetCostFromDuration() => price=" << price.netto;
}
// 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();
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);
QString duration;
if(compute_duration_for_parking_ticket(tariff,start_parking_time,3090,duration))
{
qDebug() << "GetDurationFromCost() => duration=" << duration;
}
//
// 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;
}
}
// Daily ticket
//compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3);
t = (start_parking_time + 60)*60;
now = *localtime(&t);
}
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over
// // 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);
}
@@ -145,7 +191,7 @@ int main() {
struct tm now; // = Utilities::DateTimeToStructTm("2023-03-01T16:00:00");
memset(&now, 0, sizeof(now));
char buffer[64];
//#if 0
//#if 0
// 3.Jan 2023 -> Tuesday
strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
for (int i = 0; i < 600; ++i) {
@@ -220,8 +266,8 @@ int main() {
int const duration = 120;
double cost = calculator.GetCostFromDuration(&cfg,
PaymentOption::Option1, buffer, duration,
false, true);
PaymentOption::Option1, buffer, duration,
false, true);
switch (zone) {
case 1:
@@ -259,8 +305,8 @@ int main() {
int const duration = 120;
double cost = calculator.GetCostFromDuration(&cfg,
PaymentOption::Option1, buffer, duration,
false, true);
PaymentOption::Option1, buffer, duration,
false, true);
switch (zone) {
case 1:
@@ -293,8 +339,8 @@ int main() {
double const compCost = (duration < 15) ? 0 : duration * ((zone == 1) ? 3.6666 : 8.0);
double cost = calculator.GetCostFromDuration(&cfg,
PaymentOption::Option1, buffer, duration,
false, true);
PaymentOption::Option1, buffer, duration,
false, true);
if (fabs(cost - compCost) > 1.0) { // zone 1 has rounding errors
cout << "ERROR ===> [" << i << "] " << asctime(&now)
<< " - Total cost is: " << cost << " FT (computed="

View File

@@ -7,6 +7,8 @@ QMAKE_CFLAGS = -c -pipe -std=c11 -g -O0 -Wall -Wno-attributes -W -DDEBUG -D_REEN
QMAKE_CXX_FLAGS += -std=c11
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 += .
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