#ifdef WIN32 #include #include #include #include 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 #include #include #include #include #include #include #include "calculator_functions.h" #include "calculate_price.h" #define SZEGED (1) #define SCHOENAU_KOENIGSEE (0) #define NEUHAUSER_KORNEUBURG (0) #define NEUHAUSER_LINSINGER_MASCHINENBAU (0) #define NEUHAUSER_NORDISCHES_AUSBILDUNGSZENTRUM (0) #define NEUHAUSER_BILEXA_GALTUER (0) #define NEUHAUSER_KIRCHDORF (1) #if NEUHAUSER_KIRCHDORF==1 static bool test_neuhauser_kirchdorf(int step, double cost) { switch (step) { case 30: if (cost != 30) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 30; return false; } break; case 35: if (cost != 40) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 40; return false; } break; case 40: if (cost != 50) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 50; return false; } break; case 45: if (cost != 60) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 60; return false; } break; case 50: if (cost != 70) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 70; return false; } break; case 55: if (cost != 80) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 80; return false; } break; case 60: if (cost != 90) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 90; return false; } break; case 65: if (cost != 100) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 100; return false; } break; case 70: if (cost != 110) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 110; return false; } break; case 75: if (cost != 120) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 120; return false; } break; case 80: if (cost != 130) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 130; return false; } break; case 85: if (cost != 140) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 140; return false; } break; case 90: if (cost != 150) { qCritical() << "ERROR COMPUTING COST" << "HAVE" << cost << "SHOULD" << 150; return false; } break; default: break; } return true; } #endif int main() { #if SCHOENAU_KOENIGSEE==1 QString f("/opt/ptu5/opt/customer_332/etc/psa_tariff/tariff01.json"); //QString f("/opt/ptu5/opt/customer_332/etc/psa_tariff/tariff02.json"); std::ifstream input(f.toUtf8().constData()); std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; if (isParsed) { qCritical() << "parsed" << f; int minParkingTime = get_minimal_parkingtime(&cfg); qCritical() << "minimal_parking_time" << minParkingTime; QDateTime start = QDateTime::currentDateTime(); // zone 1 //int timeSteps[9] = {60, 180, 1440, 2880, 4320, 5670, 7200, 8640, 10080}; // zone 2 //int timeSteps[3] = {60, 180, 1440}; static QList const timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); qCritical() << "TimeSteps" << timeSteps; // for (int i = 0 ; i < timeSteps.size(); ++i) { // QDateTime end = start.addSecs(timeSteps.at(i)*60); // // double price = Calculator::GetInstance().GetCostFromDuration( // &cfg, // start, // timeSteps.at(i)); // qDebug() << "GetCostFromDuration() time: " << timeSteps.at(i) << "price=" << price; //} } #endif #if NEUHAUSER_KIRCHDORF==1 //if (QDir("/opt/app/tools/atbupdate/customer_743").exists()) { // if(QFileInfo::exists("/etc/psa_tariff/tariff01.json")) { if (true) { if(true) { // const char *f = "/etc/psa_tariff/tariff01.json"; const char *f = "/opt/ptu5/opt/customer_743/etc/psa_tariff/tariff01.json"; std::ifstream input(f); std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); if (!isParsed) { qCritical() << "ERROR: CANNOT PARSE" << f; return -1; } qCritical() << "Successfully parsed" << f; int const minParkingTime = get_minimal_parkingtime(&cfg); int const maxParkingTime = get_maximal_parkingtime(&cfg); int const minParkingPrice = get_minimal_parkingprice(&cfg); if (minParkingTime != 30) { qCritical() << "ERROR: WRONG MIN_PARKING_TIME" << minParkingTime; return -1; } qCritical() << "min_parking_time " << minParkingTime; if (maxParkingTime != 90) { qCritical() << "ERROR: WRONG MAX_PARKING_TIME" << maxParkingTime; return -1; } qCritical() << "max_parking_time " << maxParkingTime; if (minParkingPrice != 30) { qCritical() << "ERROR: WRONG MIN_PARKING_PRICE" << minParkingPrice; return -1; } qCritical() << "min_parking_price" << minParkingPrice; QList const stepsConfigured = QList(std::initializer_list{ 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90}); QList const steps = Calculator::GetInstance().GetTimeSteps(&cfg); if (stepsConfigured != steps) { qCritical() << "ERROR: WRONG TIME-STEP-LIST" << steps; qCritical() << "SHOULD BE" << stepsConfigured; return -1; } qCritical() << "time steps" << steps; QDateTime s(QDate(2024, 2, 21), QTime()); QDateTime end; struct price_t price; QList::const_iterator step; for (step = steps.cbegin(); step != steps.cend(); ++step) { qCritical() << QString("*** NEXT STEP: %1 ***").arg(*step); //for (int offset = 691; offset < 692; ++offset) { for (int offset = 480; offset < 1080; ++offset) { //for (int offset = 7*60; offset < (18*60)-90; ++offset) { //for (int offset = (18*60)-90; offset < 18*60; ++offset) { //for (int offset = 1046; offset < 1047; ++offset) { QDateTime start = s.addSecs(offset * 60); QDateTime const firstStart = start; //if (*step != 30) continue; double cost = 0; if (compute_price_for_parking_ticket(&cfg, start, *step, end, &price)) { cost = price.netto; qCritical() << "****" << offset << *step << "****"; qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate); qCritical() << " start :" << start.toString(Qt::ISODate); qCritical() << " end :" << end.toString(Qt::ISODate); qCritical() << " cost :" << cost; if (offset < 8*60) { // [7:00 - 8:00[ double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 9*60) { // [8:00 - 9:00[ double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 10*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 11*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 12*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 13*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 14*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 15*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 16*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { new_cost += ((*step-30)/5)*10; qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 17*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { double const f = ((*step-30)/5)*10; new_cost += f; new_cost = std::min(new_cost, f+30); qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; //return -1; } } else if (offset < 18*60) { double new_cost = cost; if (offset > (18*60)-(*step)) { double const f = ((*step-30)/5)*10; new_cost += f; new_cost = std::min(new_cost, f+30); qCritical() << __LINE__ << "new_cost" << new_cost << "(cost" << cost << ")"; } if (!test_neuhauser_kirchdorf(*step, new_cost)) { qCritical() << "ERROR AT OFFSET" << offset; // return -1; } } else { qCritical() << "ERROR OFFSET TOO HIGH" << offset; return -1; } } else { qCritical() << "ERROR COMPUTING PRICE FOR" << "start" << start.toString(Qt::ISODate) << "step" << *step << "end" << end.toString(Qt::ISODate); return -1; } QDateTime end2 = QDateTime(); if (compute_duration_for_parking_ticket(&cfg, start, cost, end2)) { // return value qCritical() << "XXXX start" << start.toString(Qt::ISODate) << "offset" << offset << "cost" << cost << "end" << end2.toString(Qt::ISODate); if (end != end2) { qCritical() << "YYYY" << end.toString(Qt::ISODate) << end2.toString(Qt::ISODate); } } } } } return 0; } #if 0 const char *f = "/opt/ptu5/opt/customer_743/etc/psa_tariff/tariff01.json"; std::ifstream input(f); std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); if (isParsed) { qCritical() << "Parsed" << f; int minParkingTime = get_minimal_parkingtime(&cfg); int maxParkingTime = get_maximal_parkingtime(&cfg); int minParkingPrice = get_minimal_parkingprice(&cfg); qCritical() << "min_parking_time " << minParkingTime; qCritical() << "max_parking_time " << maxParkingTime; qCritical() << "min_parking_price" << minParkingPrice; bool nextDay = false; bool prePaid = true; // bool carryOver = false; //QDateTime s = QDateTime::currentDateTime(); QDateTime s(QDate(2024, 2, 21), QTime()); QDateTime end; for (int duration = 30; duration <= 90; duration += 5) { // for (int duration = 30; duration <= maxParkingTime; duration += 5) { qCritical() << ""; for (int offset = 420; offset <= 1080; ++offset) { //for (int offset = 0; offset <= 0; ++offset) { //for (int offset = 420; offset <= 1080; ++offset) { //if (offset > 720 && offset < 840) { // continue; //} QDateTime start = s.addSecs(offset * 60); QDateTime const firstStart = start; // qCritical() << "start" << start.toString(Qt::ISODate); // double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 1, start, end, duration, nextDay, prePaid); struct price_t price; compute_price_for_parking_ticket(&cfg, start, duration, end, &price); double cost = price.netto; //#if COST_FROM_DURATION==0 double cost_soll = 30 + ((duration-30)/5 * 10); uint32_t duration_ist = start.secsTo(end) / 60; if (duration_ist >= 120) { duration_ist = duration_ist - 120; } qCritical() << "****" << offset << duration << "****"; qCritical() << " firstStart :" << firstStart.toString(Qt::ISODate); qCritical() << " start :" << start.toString(Qt::ISODate); qCritical() << " end :" << end.toString(Qt::ISODate); //qCritical() << "duration (soll):" << duration; //qCritical() << "duration (ist) :" << duration_ist; //qCritical() << " cost (soll):" << cost_soll; //qCritical() << " cost (ist) :" << cost; // if (cost_soll != cost) { //qCritical() << "ERROR" << __func__ << ":" << __LINE__ // << "cost_soll" << cost_soll << "cost_ist" << cost; //break; // } // if (duration != duration_ist) { //qCritical() << "ERROR" << __func__ << ":" << __LINE__ // << "duration_soll" << duration << "duration_ist" << duration_ist; //break; // } //#else //start = s.addSecs(offset * 60); //std::string duration = Calculator::GetInstance().GetDurationFromCost(&cfg, 1, // start.toString(Qt::ISODate).toStdString().c_str(), // cost, false, true); //if (end.toString(Qt::ISODate) != QString(duration.c_str())) { //qCritical() << "ERROR" << end.toString(Qt::ISODate) // << QString(duration.c_str()); //break; //} //qCritical() << "start" << start.toString(Qt::ISODate) // << "cost" << cost // << "until" << duration.c_str() // << "end" << end.toString(Qt::ISODate) // << ":" << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60 // << (end.toString(Qt::ISODate) == QString(duration.c_str())); //#endif // COST_FROM_DURATION } } #endif // 0 #endif #if NEUHAUSER_BILEXA_GALTUER==1 std::ifstream input("/opt/ptu5/opt/customer_745/etc/psa_tariff/tariff01.json"); std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; if (isParsed) { int minParkingTime = get_minimal_parkingtime(&cfg); QList timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg); qCritical() << timeSteps; int Down = 0; int Up = 1; //compute_next_timestep(&cfg, ) for (int i=0; i> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; if (isParsed) { int v = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_ADULT); qCritical() << "price adult" << v; int w = compute_product_price(&cfg, PERMIT_TYPE::DAY_TICKET_TEEN); qCritical() << "price teen" << w; return 0; QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime end; struct price_t price; #define ADULT 0 #define TEEN 1 #if ADULT==1 for (int offset = 480; offset < 1080; ++offset) { QDateTime start = s.addSecs(offset * 60); // qCritical() << QString(Calculator::GetInstance().isParkingAllowed(&cfg, start)); CalcState cs = compute_price_for_daily_ticket(&cfg, start, end, PERMIT_TYPE::DAY_TICKET_ADULT, &price); qCritical() << "start=" << start.toString(Qt::ISODate) << "end" << end.toString(Qt::ISODate) << "price" << price.netto; } #endif #if TEEN==1 for (int offset = 480; offset < 1080; ++offset) { QDateTime start = s.addSecs(offset * 60); CalcState cs = compute_price_for_daily_ticket(&cfg, start, end, PERMIT_TYPE::DAY_TICKET_TEEN, &price); qCritical() << "start=" << start.toString(Qt::ISODate) << "end" << end.toString(Qt::ISODate) << "price" << price.netto; } #endif } #endif #if NEUHAUSER_LINSINGER_MASCHINENBAU==1 std::ifstream input("/opt/ptu5/opt/customer_741/etc/psa_tariff/tariff01.json"); std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; if (isParsed) { bool nextDay = false; bool prePaid = false; // zone 1 (lila) QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime end; int marken[] = { 3*60, 5*60, 10*60}; for (int duration = 0; duration < 3; ++duration) { for (int offset = 360; offset <= 360; ++offset) { // for (int offset = 360; offset < 1080; ++offset) { QDateTime start = s.addSecs(offset * 60); //qCritical() << "start" << start.toString(Qt::ISODate); // note: prepaid == false (!) // double cost = Calculator::GetInstance().GetCostFromDuration(&cfg, 4, start, end, marken[duration], nextDay, prePaid); struct price_t price; if (compute_price_for_parking_ticket(&cfg, start, marken[duration], end, &price, prePaid)) { double cost = price.netto; qCritical() << "start" << start.toString(Qt::ISODate) << "end" << end.toString(Qt::ISODate) << "duration" << marken[duration] << "cost" << cost; } //std::string d = Calculator::GetInstance().GetDurationFromCost(&cfg, 4, start.toString(Qt::ISODate).toStdString().c_str(), cost); //qCritical() << "start" << start.toString(Qt::ISODate) // << "cost" << cost // << "until" << d.c_str() << start.secsTo(QDateTime::fromString(d.c_str(), Qt::ISODate)) / 60; } } } #endif #if NEUHAUSER_KORNEUBURG==1 std::ifstream input("/tmp/tariff_korneuburg.json"); int pop_max_time; 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; if (isParsed) { { pop_max_time = 3*60; bool nextDay = false; bool prePaid = true; // zone 1 (lila) QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime end; for (int duration = 30; duration <= pop_max_time; duration += 5) { for (int offset = 420; offset < 1140; ++offset) { if (offset > 720 && offset < 840) { continue; } QDateTime start = s.addSecs(offset * 60); //qCritical() << "start" << start.toString(Qt::ISODate); double cost = calculator.GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid); //Q_ASSERT(cost == duration*2.5); //qCritical() << ""; //qCritical() << "start" << start.toString(Qt::ISODate) // << "end" << end.toString(Qt::ISODate) // << "duration" << duration // << "cost" << cost; std::string duration = calculator.GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost); //Q_ASSERT(cost == duration*2.5); qCritical() << "start" << start.toString(Qt::ISODate) << "cost" << cost << "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60; } } } } return 0; #endif #if SZEGED==1 std::ifstream input; int pop_min_time; int pop_max_time; int pop_min_price; int pop_max_price; int pop_daily_card_price; for (int zone=6; zone < 7; ++zone) { //for (int t=6; t < 7; t+=20) { switch (zone) { case 1: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff01.json"); //pop_max_time = 6*60; } break; case 2: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff02.json"); //pop_max_time = 5*60; } break; case 3: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff03.json"); //pop_max_time = 6*60; } break; case 4: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff04.json"); //pop_max_time = 4*60; } break; case 5: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff05.json"); //pop_max_time = 6*60; } break; case 6: { input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff06.json"); //pop_max_time = 4*60; } break; default: continue; } std::stringstream sstr; while(input >> sstr.rdbuf()); std::string json(sstr.str()); Configuration cfg; bool isParsed = cfg.ParseJson(&cfg, json.c_str()); cout << endl; if (isParsed) { // test library functions pop_min_time = get_minimal_parkingtime(&cfg); pop_max_time = get_maximal_parkingtime(&cfg); pop_min_price = get_minimal_parkingprice(&cfg); pop_max_price = get_maximal_parkingprice(&cfg); pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price; qCritical() << " pop_min_time: " << pop_min_time; qCritical() << " pop_max_time: " << pop_max_time; qCritical() << " pop_min_price: " << pop_min_price; qCritical() << " pop_max_price: " << pop_max_price; qCritical() << "pop_daily_card_price: " << pop_daily_card_price; if (pop_min_time > pop_max_time) { qCritical() << "ERROR pop_min_time > pop_max_time" << pop_min_time << pop_max_time; return -1; } if (pop_min_price > pop_max_price) { qCritical() << "ERROR pop_min_price > pop_max_price" << pop_min_price << pop_max_price; return -1; } if (pop_daily_card_price < pop_max_price) { qCritical() << "ERROR pop_daily_card_price < pop_max_price" << pop_daily_card_price << pop_max_price; return -1; } QMap m; { // zone 1 (lila) QDateTime s(QDate(2023, 11, 30), QTime()); QDateTime end; int cnt = 1; if (zone == 1) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 42 m.insert(pop_min_time, pop_min_price); m.insert(20, 55); m.insert(25, 69); m.insert(30, 83); m.insert(35, 97); m.insert(40, 110); m.insert(45, 124); m.insert(50, 138); m.insert(55, 152); m.insert(60, 165); m.insert(65, 179); m.insert(70, 193); m.insert(75, 207); m.insert(80, 220); m.insert(85, 234); m.insert(90, 248); m.insert(95, 262); m.insert(100, 275); m.insert(105, 289); m.insert(110, 303); m.insert(115, 317); m.insert(120, 330); m.insert(125, 344); m.insert(130, 358); m.insert(135, 372); m.insert(140, 385); m.insert(145, 399); m.insert(150, 413); m.insert(155, 427); m.insert(160, 440); m.insert(165, 454); m.insert(170, 468); m.insert(175, 482); m.insert(180, 495); m.insert(185, 509); m.insert(190, 523); m.insert(195, 537); m.insert(200, 550); m.insert(205, 564); m.insert(210, 578); m.insert(215, 592); m.insert(220, 605); m.insert(225, 619); m.insert(230, 633); m.insert(235, 647); m.insert(240, 660); m.insert(245, 674); m.insert(250, 688); m.insert(255, 702); m.insert(260, 715); m.insert(265, 729); m.insert(270, 743); m.insert(275, 757); m.insert(280, 770); m.insert(285, 784); m.insert(290, 798); m.insert(295, 812); m.insert(300, 825); m.insert(305, 839); m.insert(310, 853); m.insert(315, 867); m.insert(320, 880); m.insert(325, 894); m.insert(330, 908); m.insert(335, 922); m.insert(340, 935); m.insert(345, 949); m.insert(350, 963); m.insert(355, 977); m.insert(360, pop_max_price); // 990 m.insert(365, pop_max_price); m.insert(370, pop_max_price); m.insert(375, pop_max_price); m.insert(380, pop_max_price); m.insert(385, pop_max_price); m.insert(390, pop_max_price); m.insert(395, pop_max_price); m.insert(400, pop_max_price); m.insert(405, pop_max_price); m.insert(410, pop_max_price); m.insert(415, pop_max_price); m.insert(420, pop_max_price); } else if (zone == 2) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 65 m.insert(pop_min_time, pop_min_price); m.insert(20, 87); m.insert(25, 109); m.insert(30, 130); m.insert(35, 152); m.insert(40, 174); m.insert(45, 195); m.insert(50, 217); m.insert(55, 239); m.insert(60, 260); m.insert(65, 282); m.insert(70, 304); m.insert(75, 325); m.insert(80, 347); m.insert(85, 369); m.insert(90, 390); m.insert(95, 412); m.insert(100, 434); m.insert(105, 455); m.insert(110, 477); m.insert(115, 499); m.insert(120, 520); m.insert(125, 524); m.insert(130, 564); m.insert(135, 585); m.insert(140, 607); m.insert(145, 629); m.insert(150, 650); m.insert(155, 672); m.insert(160, 694); m.insert(165, 715); m.insert(170, 737); m.insert(175, 759); m.insert(180, 780); m.insert(185, 802); m.insert(190, 824); m.insert(195, 845); m.insert(200, 867); m.insert(205, 889); m.insert(210, 910); m.insert(215, 932); m.insert(220, 954); m.insert(225, 975); m.insert(230, 997); m.insert(235, 1019); m.insert(240, 1040); m.insert(245, 1062); m.insert(250, 1084); m.insert(255, 1105); m.insert(260, 1127); m.insert(265, 1149); m.insert(270, 1170); m.insert(275, 1192); m.insert(280, 1214); m.insert(285, 1235); m.insert(290, 1257); m.insert(295, 1279); m.insert(300, 1300); m.insert(305, 1322); m.insert(310, 1344); m.insert(315, 1365); m.insert(320, 1387); m.insert(325, 1409); m.insert(330, 1430); m.insert(335, 1452); m.insert(340, 1474); m.insert(345, 1495); m.insert(350, 1517); m.insert(355, 1539); m.insert(360, pop_max_price); // 1560 m.insert(365, pop_max_price); m.insert(370, pop_max_price); m.insert(375, pop_max_price); m.insert(380, pop_max_price); m.insert(385, pop_max_price); m.insert(390, pop_max_price); m.insert(395, pop_max_price); m.insert(400, pop_max_price); m.insert(405, pop_max_price); m.insert(410, pop_max_price); m.insert(415, pop_max_price); m.insert(420, pop_max_price); } else if (zone == 3) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 90 m.insert(pop_min_time, pop_min_price); m.insert(20, 120); m.insert(25, 150); m.insert(30, 180); m.insert(35, 210); m.insert(40, 240); m.insert(45, 270); m.insert(50, 300); m.insert(55, 330); m.insert(60, 360); m.insert(65, 390); m.insert(70, 420); m.insert(75, 450); m.insert(80, 480); m.insert(85, 510); m.insert(90, 540); m.insert(95, 570); m.insert(100, 600); m.insert(105, 630); m.insert(110, 660); m.insert(115, 690); m.insert(120, 720); m.insert(125, 750); m.insert(130, 780); m.insert(135, 810); m.insert(140, 840); m.insert(145, 870); m.insert(150, 900); m.insert(155, 930); m.insert(160, 960); m.insert(165, 990); m.insert(170, 1020); m.insert(175, 1050); m.insert(180, 1080); m.insert(185, 1110); m.insert(190, 1140); m.insert(195, 1170); m.insert(200, 1200); m.insert(205, 1230); m.insert(210, 1260); m.insert(215, 1290); m.insert(220, 1320); m.insert(225, 1350); m.insert(230, 1380); m.insert(235, 1410); m.insert(240, 1440); m.insert(245, 1470); m.insert(250, 1500); m.insert(255, 1530); m.insert(260, 1560); m.insert(265, 1590); m.insert(270, 1620); m.insert(275, 1650); m.insert(280, 1680); m.insert(285, 1710); m.insert(290, 1740); m.insert(295, 1770); m.insert(300, 1800); m.insert(305, 1830); m.insert(310, 1860); m.insert(315, 1890); m.insert(320, 1920); m.insert(325, 1950); m.insert(330, 1980); m.insert(335, 2010); m.insert(340, 2040); m.insert(345, 2070); m.insert(350, 2100); m.insert(355, 2130); m.insert(360, pop_max_price); // 2160 m.insert(365, pop_max_price); m.insert(370, pop_max_price); m.insert(375, pop_max_price); m.insert(380, pop_max_price); m.insert(385, pop_max_price); m.insert(390, pop_max_price); m.insert(395, pop_max_price); m.insert(400, pop_max_price); m.insert(405, pop_max_price); m.insert(410, pop_max_price); m.insert(415, pop_max_price); m.insert(420, pop_max_price); } else if (zone == 4) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 163 m.insert(pop_min_time, pop_min_price); m.insert(20, 217); m.insert(25, 271); m.insert(30, 325); m.insert(35, 380); m.insert(40, 434); m.insert(45, 488); m.insert(50, 542); m.insert(55, 596); m.insert(60, 650); m.insert(65, 705); m.insert(70, 759); m.insert(75, 813); m.insert(80, 867); m.insert(85, 921); m.insert(90, 975); m.insert(95, 1030); m.insert(100, 1084); m.insert(105, 1138); m.insert(110, 1192); m.insert(115, 1246); m.insert(120, 1300); m.insert(125, 1355); m.insert(130, 1409); m.insert(135, 1463); m.insert(140, 1517); m.insert(145, 1571); m.insert(150, 1625); m.insert(155, 1680); m.insert(160, 1734); m.insert(165, 1788); m.insert(170, 1842); m.insert(175, 1896); m.insert(180, 1950); m.insert(185, 2005); m.insert(190, 2059); m.insert(195, 2113); m.insert(200, 2167); m.insert(205, 2221); m.insert(210, 2275); m.insert(215, 2330); m.insert(220, 2384); m.insert(225, 2438); m.insert(230, 2492); m.insert(235, 2546); m.insert(240, pop_max_price); // 2600 m.insert(245, pop_max_price); m.insert(250, pop_max_price); m.insert(255, pop_max_price); m.insert(260, pop_max_price); m.insert(270, pop_max_price); m.insert(280, pop_max_price); m.insert(290, pop_max_price); m.insert(300, pop_max_price); } else if (zone == 5) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 90 m.insert(pop_min_time, pop_min_price); m.insert(20, 120); m.insert(25, 150); m.insert(30, 180); m.insert(35, 210); m.insert(40, 240); m.insert(45, 270); m.insert(50, 300); m.insert(55, 330); m.insert(60, 360); m.insert(65, 390); m.insert(70, 420); m.insert(75, 450); m.insert(80, 480); m.insert(85, 510); m.insert(90, 540); m.insert(95, 570); m.insert(100, 600); m.insert(105, 630); m.insert(110, 660); m.insert(115, 690); m.insert(120, 720); m.insert(125, 750); m.insert(130, 780); m.insert(135, 810); m.insert(140, 840); m.insert(145, 870); m.insert(150, 900); m.insert(155, 930); m.insert(160, 960); m.insert(165, 990); m.insert(170, 1020); m.insert(175, 1050); m.insert(180, 1080); m.insert(185, 1110); m.insert(190, 1140); m.insert(195, 1170); m.insert(200, 1200); m.insert(205, 1230); m.insert(210, 1260); m.insert(215, 1290); m.insert(220, 1320); m.insert(225, 1350); m.insert(230, 1380); m.insert(235, 1410); m.insert(240, 1440); m.insert(245, 1470); m.insert(250, 1500); m.insert(255, 1530); m.insert(260, 1560); m.insert(265, 1590); m.insert(270, 1620); m.insert(275, 1650); m.insert(280, 1680); m.insert(285, 1710); m.insert(290, 1740); m.insert(295, 1770); m.insert(300, 1800); m.insert(305, 1830); m.insert(310, 1860); m.insert(315, 1890); m.insert(320, 1920); m.insert(325, 1950); m.insert(330, 1980); m.insert(335, 2010); m.insert(340, 2040); m.insert(345, 2070); m.insert(350, 2100); m.insert(355, 2130); m.insert(360, pop_max_price); // 2160 m.insert(365, pop_max_price); m.insert(370, pop_max_price); m.insert(375, pop_max_price); m.insert(380, pop_max_price); m.insert(385, pop_max_price); m.insert(390, pop_max_price); m.insert(395, pop_max_price); m.insert(400, pop_max_price); m.insert(405, pop_max_price); m.insert(410, pop_max_price); m.insert(415, pop_max_price); m.insert(420, pop_max_price); } else if (zone == 6) { m.insert(5, pop_min_price); m.insert(10, pop_min_price); // 163 m.insert(pop_min_time, pop_min_price); m.insert(20, 217); m.insert(25, 271); m.insert(30, 325); m.insert(35, 380); m.insert(40, 434); m.insert(45, 488); m.insert(50, 542); m.insert(55, 596); m.insert(60, 650); m.insert(65, 705); m.insert(70, 759); m.insert(75, 813); m.insert(80, 867); m.insert(85, 921); m.insert(90, 975); m.insert(95, 1030); m.insert(100, 1084); m.insert(105, 1138); m.insert(110, 1192); m.insert(115, 1246); m.insert(120, 1300); m.insert(125, 1355); m.insert(130, 1409); m.insert(135, 1463); m.insert(140, 1517); m.insert(145, 1571); m.insert(150, 1625); m.insert(155, 1680); m.insert(160, 1734); m.insert(165, 1788); m.insert(170, 1842); m.insert(175, 1896); m.insert(180, 1950); m.insert(185, 2005); m.insert(190, 2059); m.insert(195, 2113); m.insert(200, 2167); m.insert(205, 2221); m.insert(210, 2275); m.insert(215, 2330); m.insert(220, 2384); m.insert(225, 2438); m.insert(230, 2492); m.insert(235, 2546); m.insert(240, pop_max_price); // 2600 m.insert(245, pop_max_price); m.insert(250, pop_max_price); m.insert(255, pop_max_price); m.insert(260, pop_max_price); m.insert(270, pop_max_price); m.insert(280, pop_max_price); m.insert(290, pop_max_price); m.insert(300, pop_max_price); } struct price_t price; for (int duration = pop_min_time; duration <= pop_max_time; duration += 5) { for (int offset = 480; offset < 1080; ++offset) { QDateTime start = s.addSecs(offset * 60); end = QDateTime(); price.netto = 0; if (compute_price_for_parking_ticket(&cfg, start, duration, end, &price)) { double cost = price.netto; //qCritical() << start.toString(Qt::ISODate) << end.toString(Qt::ISODate) // << duration << cost; if (cost != m[duration]) { qCritical() << "ERROR computing_price_for_parking_ticket" << "duration" << duration << "HAVE cost" << cost << "SHOULD HAVE cost" << m[duration]; return -1; } } else { qCritical() << "ERROR computing_price_for_parking_ticket AT" << cnt << "duration" << duration << "start" << start.toString(Qt::ISODate); return -1; } start = s.addSecs(offset * 60); end = QDateTime(); price.netto = 0; if (compute_price_for_daily_ticket(&cfg, start, end, PERMIT_TYPE::DAY_TICKET, &price)) { if (price.netto != pop_daily_card_price) { qCritical() << "ERROR computing_price_for_daily_ticket" << "duration" << duration << "HAVE cost" << price.netto << "SHOULD HAVE cost" << pop_daily_card_price; return -1; } } else { qCritical() << "ERROR computing_price_for_daily_ticket AT" << "start" << start.toString(Qt::ISODate); return -1; } // start = s.addSecs(offset * 60); // end = QDateTime(); //if (compute_duration_for_daily_ticket(&cfg, start, end)) { // // } else { // qCritical() << "ERROR computing_duration_for_daily_ticket AT" // << "start" << start.toString(Qt::ISODate); // return -1; // } ++cnt; } } } } } return 0; #endif #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_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2182,\"pedwt_period_exc_day_id\":2019,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2183,\"pedwt_period_exc_day_id\":2020,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2184,\"pedwt_period_exc_day_id\":2021,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2185,\"pedwt_period_exc_day_id\":2023,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2188,\"pedwt_period_exc_day_id\":2031,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2189,\"pedwt_period_exc_day_id\":2029,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2191,\"pedwt_period_exc_day_id\":2016,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2192,\"pedwt_period_exc_day_id\":2033,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2194,\"pedwt_period_exc_day_id\":2034,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2196,\"pedwt_period_exc_day_id\":2035,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2198,\"pedwt_period_exc_day_id\":2036,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2200,\"pedwt_period_exc_day_id\":2037,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2202,\"pedwt_period_exc_day_id\":2038,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2204,\"pedwt_period_exc_day_id\":2039,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2206,\"pedwt_period_exc_day_id\":2040,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2219,\"pedwt_period_exc_day_id\":2041,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2220,\"pedwt_period_exc_day_id\":2042,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2221,\"pedwt_period_exc_day_id\":2043,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2222,\"pedwt_period_exc_day_id\":2044,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2223,\"pedwt_period_exc_day_id\":2045,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"01:00:00\",\"pedwt_price\":0},{\"pedwt_id\":2224,\"pedwt_period_exc_day_id\":2046,\"pedwt_time_from\":\"00:00:00\",\"pedwt_time_to\":\"00:00:00\",\"pedwt_price\":0}],\"SpecialDays\":[{\"ped_id\":11,\"ped_label\":\"Christmas 1st day\",\"ped_date_start\":\"2022-12-25\",\"ped_date_end\":\"2022-12-25\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":13,\"ped_label\":\"Christmas 2nd day\",\"ped_date_start\":\"2022-12-26\",\"ped_date_end\":\"2022-12-26\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":14,\"ped_label\":\"Republic Day (Hungary)\",\"ped_date_start\":\"2022-10-23\",\"ped_date_end\":\"2022-10-23\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2016,\"ped_label\":\"Christmas (Sunday)\",\"ped_date_start\":\"2022-12-24\",\"ped_date_end\":\"2022-12-24\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2017,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-27\",\"ped_date_end\":\"2022-12-27\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2018,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-28\",\"ped_date_end\":\"2022-12-28\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2019,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-29\",\"ped_date_end\":\"2022-12-29\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2020,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-30\",\"ped_date_end\":\"2022-12-30\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2021,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2022-12-31\",\"ped_date_end\":\"2022-12-31\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2022,\"ped_label\":\"NewYear\",\"ped_date_start\":\"2023-01-01\",\"ped_date_end\":\"2023-01-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2023,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2023-01-02\",\"ped_date_end\":\"2023-01-02\",\"ped_period_special_day_id\":1,\"ped_year\":2024},{\"ped_id\":2024,\"ped_label\":\"Good Friday\",\"ped_date_start\":\"2023-04-07\",\"ped_date_end\":\"2023-04-07\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2025,\"ped_label\":\"Easter Sunday\",\"ped_date_start\":\"2023-04-09\",\"ped_date_end\":\"2023-04-09\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2026,\"ped_label\":\"Easter Monday\",\"ped_date_start\":\"2023-04-10\",\"ped_date_end\":\"2023-04-10\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2027,\"ped_label\":\"Whit Sunday\",\"ped_date_start\":\"2023-05-28\",\"ped_date_end\":\"2023-05-28\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2028,\"ped_label\":\"Whit Monday\",\"ped_date_start\":\"2023-05-29\",\"ped_date_end\":\"2023-05-29\",\"ped_period_special_day_id\":2,\"ped_year\":2023},{\"ped_id\":2029,\"ped_label\":\"Revolution Day (Hungary)\",\"ped_date_start\":\"2023-03-15\",\"ped_date_end\":\"2023-03-15\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2030,\"ped_label\":\"Labour Day\",\"ped_date_start\":\"2023-05-01\",\"ped_date_end\":\"2023-05-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2031,\"ped_label\":\"Saint Stephens Day (Hungary)\",\"ped_date_start\":\"2023-08-20\",\"ped_date_end\":\"2023-08-20\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2032,\"ped_label\":\"All Saints Day\",\"ped_date_start\":\"2023-11-01\",\"ped_date_end\":\"2023-11-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2033,\"ped_label\":\"Christmas (Tuesday)\",\"ped_date_start\":\"2024-12-24\",\"ped_date_end\":\"2024-12-24\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2034,\"ped_label\":\"Good Friday\",\"ped_date_start\":\"2024-03-29\",\"ped_date_end\":\"2024-03-29\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2035,\"ped_label\":\"Easter\",\"ped_date_start\":\"2024-03-31\",\"ped_date_end\":\"2024-03-31\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2036,\"ped_label\":\"Easter Monday\",\"ped_date_start\":\"2024-04-01\",\"ped_date_end\":\"2024-04-01\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2037,\"ped_label\":\"Whit Monday\",\"ped_date_start\":\"2024-05-20\",\"ped_date_end\":\"2024-05-20\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2038,\"ped_label\":\"Whit Sunday\",\"ped_date_start\":\"2024-05-19\",\"ped_date_end\":\"2024-05-19\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2039,\"ped_label\":\"Christmas 1st Day\",\"ped_date_start\":\"2024-12-25\",\"ped_date_end\":\"2024-12-25\",\"ped_period_special_day_id\":2,\"ped_year\":2024},{\"ped_id\":2040,\"ped_label\":\"Christmas 2nd Day\",\"ped_date_start\":\"2024-12-26\",\"ped_date_end\":\"2024-12-26\",\"ped_period_special_day_id\":2,\"ped_year\":0},{\"ped_id\":2041,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-27\",\"ped_date_end\":\"2024-12-27\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2042,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-28\",\"ped_date_end\":\"2024-12-28\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2043,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-29\",\"ped_date_end\":\"2024-12-29\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2044,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-30\",\"ped_date_end\":\"2024-12-30\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2045,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2024-12-31\",\"ped_date_end\":\"2024-12-31\",\"ped_period_special_day_id\":1,\"ped_year\":0},{\"ped_id\":2046,\"ped_label\":\"Holiday (Hungary)\",\"ped_date_start\":\"2025-01-02\",\"ped_date_end\":\"2025-01-02\",\"ped_period_special_day_id\":1,\"ped_year\":2025}]}"; 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]; //#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) { 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, PaymentOption::Option1, buffer, duration, false, true); 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, PaymentOption::Option1, buffer, duration, false, true); 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, 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=" << compCost << ")" << endl; // assert (cost == compCost); } if (++duration > 240) { duration = 0; } } } } #endif }