2023-04-28 11:00:01 +02:00
|
|
|
#ifdef WIN32
|
|
|
|
#include <time.h>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
2023-05-15 14:05:55 +02:00
|
|
|
#include <calculate_price.h>
|
|
|
|
|
2023-04-28 11:00:01 +02:00
|
|
|
|
|
|
|
extern "C" char* strptime(const char* s,
|
|
|
|
const char* f,
|
|
|
|
struct tm* tm) {
|
|
|
|
// Isn't the C++ standard lib nice? std::get_time is defined such that its
|
|
|
|
// format parameters are the exact same as strptime. Of course, we have to
|
|
|
|
// create a string stream first, and imbue it with the current C locale, and
|
|
|
|
// we also have to make sure we return the right things if it fails, or
|
|
|
|
// if it succeeds, but this is still far simpler an implementation than any
|
|
|
|
// of the versions in any of the C standard libraries.
|
|
|
|
std::istringstream input(s);
|
|
|
|
input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
|
|
|
|
input >> std::get_time(tm, f);
|
|
|
|
if (input.fail()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return (char*)(s + input.tellg());
|
|
|
|
}
|
|
|
|
#endif
|
2023-04-24 15:31:46 +02:00
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QDateTime>
|
|
|
|
int main() {
|
|
|
|
|
|
|
|
parking_tariff_t *tariff = 0;
|
2023-08-22 12:16:25 +02:00
|
|
|
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"))
|
2023-05-15 14:05:55 +02:00
|
|
|
{
|
2023-04-24 15:31:46 +02:00
|
|
|
struct price_t price;
|
|
|
|
memset(&price, 0x00, sizeof(price));
|
2023-08-22 12:16:25 +02:00
|
|
|
QDateTime start = QDateTime::fromString("2023-06-02T13:03:00.000Z",Qt::ISODate); //QDateTime::currentDateTime();
|
2023-04-24 15:31:46 +02:00
|
|
|
time_t start_parking_time = start.toSecsSinceEpoch() / 60;
|
2023-08-22 12:16:25 +02:00
|
|
|
time_t end_parking_time = start_parking_time + 1230;
|
|
|
|
|
|
|
|
// if (compute_price_for_parking_ticket(tariff,
|
|
|
|
// start_parking_time,
|
|
|
|
// end_parking_time,
|
|
|
|
// &price))
|
|
|
|
// {
|
|
|
|
// qDebug() << "GetCostFromDuration() => price=" << price.netto;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// QString duration;
|
|
|
|
// if(compute_duration_for_parking_ticket(tariff,start_parking_time,1650,duration))
|
|
|
|
// {
|
|
|
|
// qDebug() << "GetDurationFromCost() => duration=" << duration;
|
|
|
|
// }
|
2023-05-12 09:20:46 +02:00
|
|
|
|
2023-05-15 14:05:55 +02:00
|
|
|
// Daily ticket
|
2023-08-22 12:16:25 +02:00
|
|
|
// compute_duration_for_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
|
|
|
|
|
|
|
compute_duration_for_24hour_daily_ticket(tariff,start.toString(Qt::ISODate),3);
|
2023-05-15 14:05:55 +02:00
|
|
|
|
|
|
|
//Configuration* cfg, QString start_datetime, uint8_t payment_option, bool carry_over
|
2023-05-14 17:19:24 +02:00
|
|
|
// // 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);
|
|
|
|
// }
|
2023-04-24 15:31:46 +02:00
|
|
|
|
|
|
|
free_tariff(tariff);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
//std::string json = "{\"Currency\":[{\"pcu_id\":2,\"pcu_sign\":\"Ft\",\"pcu_major\":\"HUF\",\"pcu_minor\":\"\",\"pcu_active\":true}],\"PaymentMethod\":[{\"pme_id\":1,\"pme_label\":\"progressive\"},{\"pme_id\":2,\"pme_label\":\"degressive\"},{\"pme_id\":3,\"pme_label\":\"linear\"},{\"pme_id\":4,\"pme_label\":\"steps\"}],\"PaymentOption\":[{\"pop_id\":17,\"pop_label\":\"Zone 1\",\"pop_payment_method_id\":3,\"pop_day_end_time\":\"00:00:00\",\"pop_day_night_end_time\":\"00:00:00\",\"pop_price_night\":0,\"pop_min_time\":15,\"pop_max_time\":240,\"pop_min_price\":120,\"pop_carry_over\":1}],\"PaymentRate\":[{\"pra_payment_option_id\":17,\"pra_payment_unit_id\":3,\"pra_price\":480}],\"Duration\":[{\"pun_id\":1,\"pun_label\":\"1h\",\"pun_duration\":60},{\"pun_id\":2,\"pun_label\":\"1 min\",\"pun_duration\":1},{\"pun_id\":3,\"pun_label\":\"15 min\",\"pun_duration\":15},{\"pun_id\":4,\"pun_label\":\"1d\",\"pun_duration\":1440},{\"pun_id\":6,\"pun_label\":\"2h\",\"pun_duration\":120},{\"pun_id\":7,\"pun_label\":\"3h\",\"pun_duration\":180},{\"pun_id\":11,\"pun_label\":\"4h\",\"pun_duration\":240},{\"pun_id\":17,\"pun_label\":\"30 min\",\"pun_duration\":30},{\"pun_id\":18,\"pun_label\":\"1.5h\",\"pun_duration\":90},{\"pun_id\":20,\"pun_label\":\"10min\",\"pun_duration\":10}],\"WeekDaysWorktime\":[{\"pwd_id\":540,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":1,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":541,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":2,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":542,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":3,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":543,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":4,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"},{\"pwd_id\":544,\"pwd_period_week_day_id\":32,\"pwd_period_day_in_week_id\":5,\"pwd_time_from\":\"08:00:00\",\"pwd_time_to\":\"18:00:00\"}],\"PeriodYear\":[{\"pye_id\":1,\"pye_label\":\"Summer\",\"pye_start_month\":6,\"pye_start_day\":1,\"pye_end_month\":9,\"pye_end_day\":30},{\"pye_id\":2,\"pye_label\":\"Winter\",\"pye_start_month\":10,\"pye_start_day\":1,\"pye_end_month\":5,\"pye_end_day\":31},{\"pye_id\":8,\"pye_label\":\"Whole year\",\"pye_start_month\":1,\"pye_start_day\":1,\"pye_end_month\":12,\"pye_end_day\":31}],\"SpecialDaysWorktime\":[{\"pedwt_id\":2156,\"pedwt_period_exc_day_id\":2024,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2158,\"pedwt_period_exc_day_id\":2025,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2160,\"pedwt_period_exc_day_id\":2026,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2162,\"pedwt_period_exc_day_id\":2027,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2164,\"pedwt_period_exc_day_id\":2028,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2170,\"pedwt_period_exc_day_id\":2030,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2172,\"pedwt_period_exc_day_id\":2032,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2174,\"pedwt_period_exc_day_id\":11,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2175,\"pedwt_period_exc_day_id\":13,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2178,\"pedwt_period_exc_day_id\":2022,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2179,\"pedwt_period_exc_day_id\":14,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2180,\"pedwt_period_exc_day_id\":2017,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2181,\"pedwt_period_exc_day_id\":2018,\"pedwt_time_
|
|
|
|
|
|
|
|
for (int zone = 3; zone < 4; ++zone) {
|
|
|
|
// std::string fname("/opt/ptu5/opt/customer_281/szeged/tariff/szeged_winter_sale_zone");
|
|
|
|
std::string fname("/opt/ptu5/opt/ATB-CalculatorLinux_21.12.2022/tariff/szeged_winter_sale_zone");
|
|
|
|
|
|
|
|
fname += std::to_string(zone) + ".json";
|
|
|
|
|
|
|
|
std::cout << fname << std::endl;
|
|
|
|
|
|
|
|
std::ifstream input(fname);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
struct tm now; // = Utilities::DateTimeToStructTm("2023-03-01T16:00:00");
|
|
|
|
memset(&now, 0, sizeof(now));
|
|
|
|
char buffer[64];
|
2023-05-14 17:19:24 +02:00
|
|
|
//#if 0
|
2023-04-24 15:31:46 +02:00
|
|
|
// 3.Jan 2023 -> Tuesday
|
|
|
|
strptime("2023-01-03T14:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
|
|
|
for (int i = 0; i < 600; ++i) {
|
|
|
|
|
|
|
|
time_t now_t = mktime(&now);
|
|
|
|
now_t += 60;
|
|
|
|
now = *localtime(&now_t);
|
|
|
|
|
|
|
|
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d", now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
|
|
|
double cost = calculator.GetCostFromDuration(&cfg, PaymentOption::Option1, buffer, 240, false, true);
|
|
|
|
memset(buffer, 0, 64);
|
|
|
|
|
|
|
|
// cout << "======================================================" << endl;
|
|
|
|
// cout << "zone " << zone << " ===> " << i << " " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
switch (zone) {
|
|
|
|
case 1:
|
|
|
|
assert(cost == 879); // expected value: 880
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* fall through */
|
|
|
|
case 3:
|
|
|
|
assert(cost == 1920);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// cout << "======================================================" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// zone 3 has problems
|
|
|
|
for (int i = 112; i <= 128; ++i)
|
|
|
|
{
|
|
|
|
startDate = "2022-12-23T17:00:00";
|
|
|
|
std::string validity = calculator.GetDurationFromCost(&cfg, PaymentOption::Option1, (char *)startDate, i, false, true);
|
|
|
|
cout << "zone " << zone << ", startDate " << startDate << " _price_ "
|
|
|
|
<< i << " Total duration is: " << validity << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 112; i <= 128; ++i)
|
|
|
|
{
|
|
|
|
startDate = "2022-12-09T18:00:00";
|
|
|
|
std::string validity = calculator.GetDurationFromCost(&cfg, PaymentOption::Option1, (char *)startDate, i, false, true);
|
|
|
|
cout << "zone " << zone << ", startDate " << startDate << " _price_ "
|
|
|
|
<< i << " Total duration is: " << validity << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 112; i <= 128; ++i) {
|
|
|
|
startDate = "2022-12-26T17:00:00";
|
|
|
|
std::string validity = calculator.GetDurationFromCost(&cfg, PaymentOption::Option1, (char *)startDate, i, false, true);
|
|
|
|
cout << "zone " << zone << ", startDate " << startDate << " _price_ "
|
|
|
|
<< i << " Total duration is: " << validity << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
//std::string validity = calculator.GetDurationFromCost(&cfg, PaymentOption::Option1, (char*)"2022-12-22T05:00:00", 75, false, true);
|
|
|
|
//cout << "_price_ " << " Total duration is: " << validity << " min" << endl;
|
|
|
|
|
|
|
|
startDate = "2022-12-22T05:00:00";
|
|
|
|
std::string validity = calculator.GetDurationFromCost(&cfg, PaymentOption::Option1, (char*)startDate, 120, false, true);
|
|
|
|
cout << "zone " << zone << ", startDate " << startDate << " _price_ "
|
|
|
|
<< " Total duration is: " << validity << " min" << endl;
|
|
|
|
// working for all zones
|
|
|
|
//
|
|
|
|
// test Easter 2023
|
|
|
|
//
|
|
|
|
memset(&now, 0, sizeof(now));
|
|
|
|
strptime("2023-04-07T06:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
|
|
|
for (int i=0; i<6*24; ++i) {
|
|
|
|
time_t now_t = mktime(&now);
|
|
|
|
now_t += 60*60;
|
|
|
|
now = *localtime(&now_t);
|
|
|
|
|
|
|
|
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d", now.tm_year + 1900,
|
|
|
|
now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
|
|
|
|
|
|
|
int const duration = 120;
|
|
|
|
double cost = calculator.GetCostFromDuration(&cfg,
|
2023-05-14 17:19:24 +02:00
|
|
|
PaymentOption::Option1, buffer, duration,
|
|
|
|
false, true);
|
2023-04-24 15:31:46 +02:00
|
|
|
|
|
|
|
switch (zone) {
|
|
|
|
case 1:
|
|
|
|
cout << "===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
assert(cost == 440);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* fall through */
|
|
|
|
case 3:
|
|
|
|
assert(cost == 960);
|
|
|
|
cout << "===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//if (cost == 960) {
|
|
|
|
// cout << "===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
//} else {
|
|
|
|
// cout << "ERROR ===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
// assert(cost == 960);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
// working for all zones
|
|
|
|
//
|
|
|
|
// test May 1st 2023
|
|
|
|
//
|
|
|
|
memset(&now, 0, sizeof(now));
|
|
|
|
strptime("2023-04-30T06:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
|
|
|
for (int i=0; i<6*24; ++i) {
|
|
|
|
time_t now_t = mktime(&now);
|
|
|
|
now_t += 60*60;
|
|
|
|
now = *localtime(&now_t);
|
|
|
|
|
|
|
|
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d", now.tm_year + 1900,
|
|
|
|
now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
|
|
|
|
|
|
|
int const duration = 120;
|
|
|
|
double cost = calculator.GetCostFromDuration(&cfg,
|
2023-05-14 17:19:24 +02:00
|
|
|
PaymentOption::Option1, buffer, duration,
|
|
|
|
false, true);
|
2023-04-24 15:31:46 +02:00
|
|
|
|
|
|
|
switch (zone) {
|
|
|
|
case 1:
|
|
|
|
cout << "===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
assert(cost == 440);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* fall through */
|
|
|
|
case 3:
|
|
|
|
assert(cost == 960);
|
|
|
|
cout << "===> [" << i << "] " << asctime(&now) << " - Total cost is: " << cost << " FT" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// only zone 1 has some minor problems
|
|
|
|
//
|
|
|
|
// test 17/04/2023 - 27/04/2023
|
|
|
|
//
|
|
|
|
memset(&now, 0, sizeof(now));
|
|
|
|
strptime("2023-04-17T06:00:00", "%Y-%m-%dT%H:%M:%S", &now);
|
|
|
|
int duration = 0;
|
|
|
|
//for (int i=0; i<1440; ++i) {
|
|
|
|
for (int i=0; i<1440; ++i) {
|
|
|
|
time_t now_t = mktime(&now);
|
|
|
|
now_t += 600; // 10 minutes
|
|
|
|
now = *localtime(&now_t);
|
|
|
|
|
|
|
|
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d", now.tm_year + 1900,
|
|
|
|
now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
|
|
|
|
|
|
|
double const compCost = (duration < 15) ? 0 : duration * ((zone == 1) ? 3.6666 : 8.0);
|
|
|
|
double cost = calculator.GetCostFromDuration(&cfg,
|
2023-05-14 17:19:24 +02:00
|
|
|
PaymentOption::Option1, buffer, duration,
|
|
|
|
false, true);
|
2023-04-24 15:31:46 +02:00
|
|
|
if (fabs(cost - compCost) > 1.0) { // zone 1 has rounding errors
|
|
|
|
cout << "ERROR ===> [" << i << "] " << asctime(&now)
|
|
|
|
<< " - Total cost is: " << cost << " FT (computed="
|
|
|
|
<< compCost << ")" << endl;
|
|
|
|
// assert (cost == compCost);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (++duration > 240) {
|
|
|
|
duration = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|