diff --git a/library/src/configuration.cpp b/library/src/configuration.cpp index 6c13daf..30f0b73 100644 --- a/library/src/configuration.cpp +++ b/library/src/configuration.cpp @@ -1,769 +1,844 @@ -#include "configuration.h" -#include "tariff_timebase.h" -#include "time_range_header.h" -#include "tariff_timestep_config.h" -#include "tariff_permit_type.h" -#include "tariff_business_hours.h" - -#include -#include - -/// -MemberType Configuration::IdentifyJsonMember(const char* member_name) -{ - if (strcmp(member_name, "Currency") == 0) return MemberType::CurrencyType; - if (strcmp(member_name, "PaymentMethod") == 0) return MemberType::PaymentMethodType; - if (strcmp(member_name, "PaymentRate") == 0) return MemberType::PaymentRateType; - if (strcmp(member_name, "PaymentOption") == 0) return MemberType::PaymentOptionType; - if (strcmp(member_name, "Duration") == 0) return MemberType::DurationType; - //if (strcmp(member_name, "WeekDays") == 0) return MemberType::WeekDaysType; - if (strcmp(member_name, "WeekDaysWorktime") == 0) return MemberType::WeekDaysWorkTimeType; - if (strcmp(member_name, "SpecialDaysWorktime") == 0) return MemberType::SpecialDaysWorktimeType; - if (strcmp(member_name, "SpecialDays") == 0) return MemberType::SpecialDaysType; - if (strcmp(member_name, "PeriodYear") == 0) return MemberType::PeriodYearType; - if (strcmp(member_name, "DailyTicket") == 0) return MemberType::DailyTicketType; - if (strcmp(member_name, "TimeBase") == 0) return MemberType::TimeBaseType; - if (strcmp(member_name, "Customer") == 0) return MemberType::CustomerType; - if (strcmp(member_name, "TimeRange") == 0) return MemberType::TimeRangeType; - if (strcmp(member_name, "TimeStepConfig") == 0) return MemberType::TimeStepConfigType; - if (strcmp(member_name, "Product") == 0) return MemberType::ProductType; - else return MemberType::UnknownType; -} - -/// -bool Configuration::ParseJson(Configuration* cfg, const char* json) -{ - try - { - if (cfg == nullptr) - { - printf("TariffConfiguration pointer not set\n"); - return false; - } - if (json == NULL) - { - printf("%s", "Input JSON string is NULL\n"); - return false; - } - - // Parse JSON to document - Document document; - document.Parse(json); - - // Return if parse error has been found - ParseErrorCode err = document.GetParseError(); - if (err != 0) - { - printf("%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err)); - return false; - } - - // Validate JSON, check if it's a JSON object - qCritical() << "JSON parsing has been successful"; - if (!document.IsObject()) { - printf("%s", "Error: not a (valid) JSON object\n"); - return false; - } - qCritical() << "Valid JSON object identified"; - - // Validate JSON, check configuration members - if (!document.HasMember("Currency") - || !document.HasMember("PaymentMethod") - || !document.HasMember("PaymentOption") - || !document.HasMember("PaymentRate") - || !document.HasMember("Duration") - //|| !document.HasMember("WeekDays") - //|| !document.HasMember("SpecialDaysWorktime") - //|| !document.HasMember("SpecialDays") - ) - { - printf("%s", "Error: not a valid configuration JSON\n"); - return false; - } - qCritical() << "Valid JSON configuration identified"; - - ATBCurrency Currency; - ATBDuration Duration; - ATBPaymentMethod PaymentMethod; - ATBPaymentRate PaymentRate; - ATBSpecialDaysWorktime SpecialDaysWorktime; - ATBSpecialDays SpecialDays; - ATBWeekDays WeekDays; - ATBWeekDaysWorktime WeekDaysWorktime; - ATBPeriodYear YearPeriod; - ATBDailyTicket DailyTicket; - ATBTimeBase TimeBase; - ATBCustomer Customer; - ATBTimeRange TimeRange; - ATBTimeStepConfig TimeStepConfig; - ATBTariffProduct TariffProduct; - - MemberType mb_type = MemberType::UnknownType; - this->currentPaymentOptions.clear(); - - // Get all JSON object members - // This code should run only once (to load JSON variables into memory) - for (auto i = document.MemberBegin(); i != document.MemberEnd(); i++) - { - // Get name of all general members of JSON, don't print name if NULL - const char* mb_name = i->name.GetString(); - if (mb_name == NULL) continue; - - 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; - } - - qCritical() << " -" << mb_name; - - // Get array for each JSON object member - auto mb_array = document[mb_name].GetArray(); - if (mb_array.Size() <= 0) break; - - //Iterate over provided array - for (rapidjson::SizeType j = 0; j < mb_array.Size(); j++) - { - // Get all inner objects, don't print name if NULL - auto inner_obj = mb_array[j].GetObject(); - if (inner_obj.MemberCount() <= 0) break; - - // Iterate over inner object JSON members - for (auto k = inner_obj.MemberBegin(); k != inner_obj.MemberEnd(); k++) - { - // Get inner object JSON member, don't print name if NULL - const char* inner_obj_name = k->name.GetString(); - if (inner_obj_name == NULL) - { - printf("Inner object name is NULL\n"); - continue; - } - - // Identify member type - mb_type = IdentifyJsonMember(mb_name); - - switch (mb_type) - { - case MemberType::UnknownType: - break; - case MemberType::ProductType: { - if (QString(inner_obj_name) == QString("tariff_product_id")) { - if (k->value.IsInt()) { - int const x = k->value.GetInt(); - TariffProduct.m_tariff_product_id = PermitType(x); - } - } else - if (QString(inner_obj_name) == QString("tariff_product_price")) { - if (k->value.IsInt()) { - int const x = k->value.GetInt(); - TariffProduct.m_tariff_product_price = x; - } - } else - if (QString(inner_obj_name) == QString("tariff_product_name")) { - if (k->value.IsString()) { - std::string const &s = k->value.GetString(); - TariffProduct.m_tariff_product_name = QString::fromStdString(s); - } - } else - if (QString(inner_obj_name) == QString("tariff_product_start")) { - if (k->value.IsString()) { - std::string const &s = k->value.GetString(); - TariffProduct.m_tariff_product_start = QTime::fromString(QString::fromStdString(s), Qt::ISODate); - } - } else - if (QString(inner_obj_name) == QString("tariff_product_end")) { - if (k->value.IsString()) { - std::string const &s = k->value.GetString(); - TariffProduct.m_tariff_product_end = QTime::fromString(QString::fromStdString(s), Qt::ISODate); - } - } else - if (QString(inner_obj_name) == QString("tariff_product_from_in_minutes_from_start")) { - if (k->value.IsInt()) { - int const x = k->value.GetInt(); - TariffProduct.m_tariff_product_from_in_minutes_from_start = x; - } - } else - if (QString(inner_obj_name) == QString("tariff_product_to_in_minutes_from_start")) { - if (k->value.IsInt()) { - int const x = k->value.GetInt(); - TariffProduct.m_tariff_product_to_in_minutes_from_start = x; - } - } - } break; - case MemberType::TimeRangeType: - if (QString(inner_obj_name) == QString("time_range_id")) { - if (k->value.IsInt()) { - TimeRange.time_range_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("time_range_from")) { - if (k->value.IsString()) { - QTime timeRangeFrom = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); - TimeRange.time_range_from = timeRangeFrom; - } else - if (k->value.IsInt()) { - int timeRangeFrom = k->value.GetInt(); - TimeRange.time_range_from_in_minutes_from_start = timeRangeFrom; - } - } else - if (QString(inner_obj_name) == QString("time_range_to")) { - if (k->value.IsString()) { - QTime timeRangeTo = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); - TimeRange.time_range_to = timeRangeTo; - } else - if (k->value.IsInt()) { - int timeRangeTo = k->value.GetInt(); - TimeRange.time_range_to_in_minutes_from_start = timeRangeTo; - } - } else - if (QString(inner_obj_name) == QString("time_range_tbase_id")) { - if (k->value.IsInt()) { - int tbase = k->value.GetInt(); - TimeRange.time_range_tbase_id = tbase; - } - } else - if (QString(inner_obj_name) == QString("time_range_payment_rate_id")) { - if (k->value.IsInt()) { - int ptype = k->value.GetInt(); - TimeRange.time_range_payment_type_id = ptype; - } - } - break; - case MemberType::TimeBaseType: - if (QString(inner_obj_name) == QString("tbase_id")) { - if (k->value.IsInt()) { - TimeBase.tbase_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("tbase_type")) { - if (k->value.IsInt()) { - int timeBase = k->value.GetInt(); - switch (timeBase) { - case (int)ATBTimeBase::TimeBaseType::ABSOLUTE: - TimeBase.tbase_type = ATBTimeBase::TimeBaseType::ABSOLUTE; - break; - case (int)ATBTimeBase::TimeBaseType::RELATIVE: - TimeBase.tbase_type = ATBTimeBase::TimeBaseType::RELATIVE; - break; - } - } - } - break; - case MemberType::TimeStepConfigType: - if (QString(inner_obj_name) == QString("tsconfig_id")) { - if (k->value.IsInt()) { - TimeStepConfig.tsconfig_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("tsconfig_label")) { - if (k->value.IsString()) { - TimeStepConfig.tsconfig_label = QString::fromStdString(k->value.GetString()); - } - } - break; - case MemberType::DailyTicketType: - if (QString(inner_obj_name) == QString("daily_ticket_payment_option_id")) { - if (k->value.IsInt()) { - DailyTicket.daily_ticket_payment_option_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_id")) { - if (k->value.IsInt()) { - DailyTicket.daily_ticket_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_price_id")) { - if (k->value.IsInt()) { - DailyTicket.daily_ticket_price_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_tb_id")) { - if (k->value.IsInt()) { - DailyTicket.daily_ticket_tb_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_clearance_customer_ids")) { - if (k->value.IsArray()) { - auto customerIds = k->value.GetArray(); - for (rapidjson::SizeType i=0; i < customerIds.Size(); ++i) { - if (customerIds[i].IsInt()) { - DailyTicket.daily_ticket_clearance_customer_ids.append(customerIds[i].GetInt()); - } - } - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_from_min")) { - if (k->value.IsString()) { - std::string const from_min = k->value.GetString(); - char const *from_min_c_str = from_min.c_str(); // for debugging - DailyTicket.daily_ticket_from_min = QTime::fromString(from_min_c_str, Qt::ISODate); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_to_max")) { - if (k->value.IsString()) { - std::string const to_max = k->value.GetString(); - char const *to_max_c_str = to_max.c_str(); - DailyTicket.daily_ticket_to_max = QTime::fromString(to_max_c_str, Qt::ISODate); - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_from_offset_min")) { - if (k->value.IsInt()) { - int const from_offset_min = k->value.GetInt(); - DailyTicket.daily_ticket_from_offset_min = from_offset_min; - } - } else - if (QString(inner_obj_name) == QString("daily_ticket_to_offset_max")) { - if (k->value.IsInt()) { - int to_offset_max = k->value.GetInt(); - DailyTicket.daily_ticket_to_offset_max = to_offset_max; - } - } - break; - case MemberType::CustomerType: - if (QString(inner_obj_name) == QString("cust_id")) { - if (k->value.IsInt()) { - Customer.cust_id = k->value.GetInt(); - } - } else - if (QString(inner_obj_name) == QString("cust_type")) { - if (k->value.IsInt()) { - int cust_type = k->value.GetInt(); - switch (cust_type) { - case (int)ATBCustomer::CustomerType::ADULT: - Customer.cust_type = ATBCustomer::CustomerType::ADULT; - break; - case (int)ATBCustomer::CustomerType::CHILD: - Customer.cust_type = ATBCustomer::CustomerType::CHILD; - break; - case (int)ATBCustomer::CustomerType::TEEN: - Customer.cust_type = ATBCustomer::CustomerType::TEEN; - break; - } - } - } else - if (QString(inner_obj_name) == QString("cust_label")) { - if (k->value.IsString()) { - QString label(QString::fromStdString(k->value.GetString())); - if (label.contains("ADULT", Qt::CaseInsensitive)) { - Customer.cust_label = label; - } else - if (label.contains("CHILD", Qt::CaseInsensitive)) { - Customer.cust_label = label; - } else - if (label.contains("TEEN", Qt::CaseInsensitive)) { - Customer.cust_label = label; - } - } - } - break; - case MemberType::CurrencyType: - if (strcmp(inner_obj_name, "pcu_id") == 0) Currency.pcu_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pcu_sign") == 0) Currency.pcu_sign = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_major") == 0) Currency.pcu_major = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString(); - else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool(); - break; - case MemberType::PaymentMethodType: - if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString(); - break; - case MemberType::PaymentRateType: - if (strcmp(inner_obj_name, "pra_payment_option_id") == 0) PaymentRate.pra_payment_option_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pra_payment_unit_id") == 0) PaymentRate.pra_payment_unit_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pra_price") == 0) PaymentRate.pra_price = k->value.GetDouble(); - break; - case MemberType::PaymentOptionType: - if (strcmp(inner_obj_name, "pop_id") == 0) { - this->currentPaymentOptions.append(ATBPaymentOption()); - this->currentPaymentOptions.last().reset(); - this->currentPaymentOptions.last().pop_id = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_label") == 0) { - this->currentPaymentOptions.last().pop_label = k->value.GetString(); - } else if (strcmp(inner_obj_name, "pop_payment_method_id") == 0) { - this->currentPaymentOptions.last().pop_payment_method_id = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_day_end_time") == 0) { - this->currentPaymentOptions.last().pop_day_end_time = k->value.GetString(); - } else if (strcmp(inner_obj_name, "pop_day_night_end_time") == 0) { - this->currentPaymentOptions.last().pop_day_night_end_time = k->value.GetString(); - } else if (strcmp(inner_obj_name, "pop_price_night") == 0) { - this->currentPaymentOptions.last().pop_price_night = k->value.GetDouble(); - } else if (strcmp(inner_obj_name, "pop_min_time") == 0) { - this->currentPaymentOptions.last().pop_min_time = k->value.GetDouble(); - } else if (strcmp(inner_obj_name, "pop_max_price") == 0) { - this->currentPaymentOptions.last().pop_max_price = k->value.GetDouble(); - } else if (strcmp(inner_obj_name, "pop_max_time") == 0) { - this->currentPaymentOptions.last().pop_max_time = k->value.GetDouble(); - } else if (strcmp(inner_obj_name, "pop_min_price") == 0) { - this->currentPaymentOptions.last().pop_min_price = k->value.GetDouble(); - } else if (strcmp(inner_obj_name, "pop_carry_over") == 0) { - this->currentPaymentOptions.last().pop_carry_over = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_carry_over_time_range_id") == 0) { - this->currentPaymentOptions.last().pop_carry_over_time_range_id = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) { - this->currentPaymentOptions.last().pop_daily_card_price = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_business_hours") == 0) { - this->currentPaymentOptions.last().pop_business_hours = k->value.GetInt(); - } else if (strcmp(inner_obj_name, "pop_time_step_config") == 0) { - this->currentPaymentOptions.last().pop_time_step_config = k->value.GetInt(); - } - 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(); - else if (strcmp(inner_obj_name, "pun_duration") == 0) Duration.pun_duration = k->value.GetDouble(); - else if (strcmp(inner_obj_name, "pun_duration_min") == 0) Duration.pun_duration_min = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pun_duration_max") == 0) Duration.pun_duration_max = k->value.GetInt(); - break; - case MemberType::SpecialDaysWorktimeType: - if (strcmp(inner_obj_name, "pedwt_id") == 0) SpecialDaysWorktime.pedwt_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pedwt_period_exc_day_id") == 0) SpecialDaysWorktime.pedwt_period_exc_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pedwt_time_from") == 0) SpecialDaysWorktime.pedwt_time_from = k->value.GetString(); - else if (strcmp(inner_obj_name, "pedwt_time_to") == 0) SpecialDaysWorktime.pedwt_time_to = k->value.GetString(); - else if (strcmp(inner_obj_name, "pedwt_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble(); - break; - /*case MemberType::WeekDaysType: - if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pdiw_label") == 0) WeekDays.pdiw_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pdiw_index") == 0) WeekDays.pdiw_index = k->value.GetInt(); - break;*/ - case MemberType::WeekDaysWorkTimeType: - if (strcmp(inner_obj_name, "pwd_id") == 0) WeekDaysWorktime.pwd_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_period_week_day_id") == 0) WeekDaysWorktime.pwd_period_week_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_period_day_in_week_id") == 0) WeekDaysWorktime.pwd_period_day_in_week_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pwd_time_from") == 0) WeekDaysWorktime.pwd_time_from = k->value.GetString(); - else if (strcmp(inner_obj_name, "pwd_time_to") == 0) WeekDaysWorktime.pwd_time_to = k->value.GetString(); - break; - case MemberType::SpecialDaysType: - if (strcmp(inner_obj_name, "ped_id") == 0) SpecialDays.ped_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "ped_label") == 0) SpecialDays.ped_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_date_start") == 0) SpecialDays.ped_date_start = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_date_end") == 0) SpecialDays.ped_date_end = k->value.GetString(); - else if (strcmp(inner_obj_name, "ped_period_special_day_id") == 0) SpecialDays.ped_period_special_day_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "ped_year") == 0) SpecialDays.ped_year = k->value.GetInt(); - break; - case MemberType::PeriodYearType: - if (strcmp(inner_obj_name, "pye_id") == 0) YearPeriod.pye_id = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_label") == 0) YearPeriod.pye_label = k->value.GetString(); - else if (strcmp(inner_obj_name, "pye_start_month") == 0) YearPeriod.pye_start_month = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_start_day") == 0) YearPeriod.pye_start_day = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_end_month") == 0) YearPeriod.pye_end_month = k->value.GetInt(); - else if (strcmp(inner_obj_name, "pye_end_day") == 0) YearPeriod.pye_end_day = k->value.GetInt(); - break; - default: - break; - } -//#pragma endregion - } - - // Push to specific list depending on member type - switch (mb_type) - { - case MemberType::UnknownType: - break; - case MemberType::PaymentMethodType: - cfg->PaymentMethod.insert(pair(PaymentMethod.pme_id, PaymentMethod)); - break; - case MemberType::PaymentRateType: - // qCritical() << "PaymentRate" << PaymentRate; - cfg->PaymentRate.insert(pair(PaymentRate.pra_payment_option_id, PaymentRate)); - break; - case MemberType::PaymentOptionType: { - if (!this->currentPaymentOptions.isEmpty()) { - ATBPaymentOption const &PaymentOption = this->currentPaymentOptions.last(); - cfg->PaymentOption.insert(pair(PaymentOption.pop_payment_method_id, PaymentOption)); - } - } break; - case MemberType::DurationType: - cfg->Duration.insert(pair(Duration.pun_id, Duration)); - break; - case MemberType::SpecialDaysWorktimeType: - cfg->SpecialDaysWorktime.insert(pair(SpecialDaysWorktime.pedwt_period_exc_day_id, SpecialDaysWorktime)); - break; - //case MemberType::WeekDaysType: - // cfg->WeekDays.insert(pair(WeekDays.pdiw_index, WeekDays)); - // break; - case MemberType::WeekDaysWorkTimeType: - cfg->WeekDaysWorktime.insert(pair(WeekDaysWorktime.pwd_period_day_in_week_id, WeekDaysWorktime)); - break; - case MemberType::SpecialDaysType: - cfg->SpecialDays.insert(pair(SpecialDays.ped_id, SpecialDays)); - break; - case MemberType::PeriodYearType: - cfg->YearPeriod.insert(pair(YearPeriod.pye_id, YearPeriod)); - break; - case MemberType::DailyTicketType: - cfg->DailyTicket.insert(pair(DailyTicket.daily_ticket_id, DailyTicket)); - qCritical() << DailyTicket; - DailyTicket.reset(); - break; - case MemberType::CustomerType: - cfg->Customer.insert(pair(Customer.cust_id, Customer)); - qCritical() << Customer; - break; - case MemberType::TimeBaseType: - cfg->TimeBase.insert(pair(TimeBase.tbase_id, TimeBase)); - qCritical() << TimeBase; - break; - case MemberType::TimeRangeType: - cfg->TimeRange.insert(pair(TimeRange.time_range_id, TimeRange)); - //qCritical() << TimeRange; - break; - case MemberType::TimeStepConfigType: - cfg->TimeStepConfig.insert(pair(TimeStepConfig.tsconfig_id, TimeStepConfig)); - // qCritical() << TimeStepConfig; - break; - case MemberType::ProductType: - cfg->TariffProduct.insert(pair(TariffProduct.m_tariff_product_id, TariffProduct)); - qCritical() << TariffProduct; - default: - break; - } - } - } - return true; - } - catch (...) { - printf("%s\n", "General exception has occurred while parsing JSON\n"); - return false; - } -} - -int Configuration::getCurrentPaymentOptionIndex(QDateTime const &dt) const { - int const numOptions = getAllPaymentOptions().size(); - - for (int opt=0; opt < numOptions; ++opt) { - uint64_t const pop_business_hours = getPaymentOptions(opt).pop_business_hours; - uint64_t p = 0; - switch (dt.date().dayOfWeek()) { - case (int)Qt::Monday: { - p = BusinessHours::MON; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Tuesday: { - p = BusinessHours::TUE; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Wednesday: { - p = BusinessHours::WED; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Thursday: { - p = BusinessHours::THU; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Friday: { - p = BusinessHours::FRI; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Saturday: { - p = BusinessHours::SAT; - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - case (int)Qt::Sunday: { - p = BusinessHours::SUN; - if (isHoliday(dt)) { - p |= BusinessHours::OFFICIAL_HOLIDAY; - } - if ((pop_business_hours & p) == p) { - return opt; - } - } break; - } - } - - return -1; -} - -bool Configuration::isHoliday(QDateTime const &dt) const { - return false; -} - -ATBPaymentOption const &Configuration::getPaymentOptions(int paymentOptionsIndex) const { - Q_ASSERT(!this->currentPaymentOptions.isEmpty()); - return this->currentPaymentOptions.at(paymentOptionsIndex); -} - -ATBPaymentOption &Configuration::getPaymentOptions(int paymentOptionsIndex) { - Q_ASSERT(!this->currentPaymentOptions.isEmpty()); - return this->currentPaymentOptions[paymentOptionsIndex]; -} - -QVector const &Configuration::getAllPaymentOptions() const { - return this->currentPaymentOptions; -} - -QVector &Configuration::getAllPaymentOptions() { - return this->currentPaymentOptions; -} - -std::optional> -Configuration::getTariffProductForAllKeys() const { - QVector products; - std::optional> value; - - products.clear(); - - for (std::multimap::const_iterator it = this->TariffProduct.cbegin(); - it != this->TariffProduct.cend(); ++it) { - products.append(it->second); - } - - if (products.size() > 0) { - value = value.value_or(products); - } - - return value; -} - -std::optional> -Configuration::getTariffProductForProductId(PermitType permitType) const { - QVector products; - std::optional> value; - - products.clear(); - - for (auto[it, rangeEnd] = this->TariffProduct.equal_range(permitType); it != rangeEnd; ++it) { - products.append(it->second); - } - - if (products.size() > 0) { - value = value.value_or(products); - } - - return value; -} - -std::optional> -Configuration::getTariffProductForProductId(int id) const { - return getTariffProductForProductId(PermitType(id)); -} - -std::optional> -Configuration::getDailyTicketsForAllKeys() const { - QVector tickets; - std::optional> value; - - for (std::multimap::const_iterator it = this->DailyTicket.cbegin(); - it != this->DailyTicket.cend(); ++it) { - tickets.append(it->second); - } - - if (tickets.size() > 0) { - value = value.value_or(tickets); - } - - return value; -} - -std::optional> -Configuration::getDailyTicketsForKey(int key) const { - QVector tickets; - std::optional> value; - - tickets.clear(); - - for (auto[it, rangeEnd] = this->DailyTicket.equal_range(key); it != rangeEnd; ++it) { - tickets.append(it->second); - } - - if (tickets.size() > 0) { - value = value.value_or(tickets); - } - - return value; -} - -std::optional> -Configuration::getPaymentRateForAllKeys() const { - QVector paymentRates; - std::optional> value; - - for (std::multimap::const_iterator it = this->PaymentRate.cbegin(); - it != this->PaymentRate.cend(); ++it) { - paymentRates.append(it->second); - } - - if (paymentRates.size() > 0) { - value = value.value_or(paymentRates); - } - - return value; - -} - -std::optional> -Configuration::getPaymentRateForKey(int key) const { - QVector paymentRate; - std::optional> value; - - paymentRate.clear(); - - for (auto[it, rangeEnd] = this->PaymentRate.equal_range(key); it != rangeEnd; ++it) { - paymentRate.append(it->second); - } - - if (paymentRate.size() > 0) { - value = value.value_or(paymentRate); - } - - return value; -} - -std::optional -Configuration::getCustomerForType(ATBCustomer::CustomerType customerType) { - for (std::multimap::const_iterator it = this->Customer.cbegin(); - it != this->Customer.cend(); ++it) { - ATBCustomer const &customer = it->second; - if (customer.cust_type == customerType) { - return customer; - } - } - - return std::nullopt; -} - -std::optional -Configuration::getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek) { - ATBWeekDaysWorktime worktime; - std::optional value; - - std::multimap::const_iterator it = this->WeekDaysWorktime.find((int)dayOfWeek); - if (it != this->WeekDaysWorktime.cend()) { - - ATBWeekDaysWorktime const &wt = it->second; - - if (time >= QTime::fromString(wt.pwd_time_from.c_str(), Qt::ISODate) - && time < QTime::fromString(wt.pwd_time_to.c_str(), Qt::ISODate)) { - value = value.value_or(wt); - } - } - - return value; -} +#include "configuration.h" +#include "utilities.h" +#include "tariff_timebase.h" +#include "time_range_header.h" +#include "tariff_timestep_config.h" +#include "tariff_permit_type.h" +#include "tariff_business_hours.h" +#include "tariff_global_defines.h" + +#include +#include + +/// +MemberType Configuration::IdentifyJsonMember(const char* member_name) +{ + if (strcmp(member_name, "Currency") == 0) return MemberType::CurrencyType; + if (strcmp(member_name, "PaymentMethod") == 0) return MemberType::PaymentMethodType; + if (strcmp(member_name, "PaymentRate") == 0) return MemberType::PaymentRateType; + if (strcmp(member_name, "PaymentOption") == 0) return MemberType::PaymentOptionType; + if (strcmp(member_name, "Duration") == 0) return MemberType::DurationType; + //if (strcmp(member_name, "WeekDays") == 0) return MemberType::WeekDaysType; + if (strcmp(member_name, "WeekDaysWorktime") == 0) return MemberType::WeekDaysWorkTimeType; + if (strcmp(member_name, "SpecialDaysWorktime") == 0) return MemberType::SpecialDaysWorktimeType; + if (strcmp(member_name, "SpecialDays") == 0) return MemberType::SpecialDaysType; + if (strcmp(member_name, "PeriodYear") == 0) return MemberType::PeriodYearType; + if (strcmp(member_name, "DailyTicket") == 0) return MemberType::DailyTicketType; + if (strcmp(member_name, "TimeBase") == 0) return MemberType::TimeBaseType; + if (strcmp(member_name, "Customer") == 0) return MemberType::CustomerType; + if (strcmp(member_name, "TimeRange") == 0) return MemberType::TimeRangeType; + if (strcmp(member_name, "TimeStepConfig") == 0) return MemberType::TimeStepConfigType; + if (strcmp(member_name, "Product") == 0) return MemberType::ProductType; + else return MemberType::UnknownType; +} + +/// +bool Configuration::ParseJson(Configuration* cfg, const char* json) +{ + try + { + if (cfg == nullptr) + { + printf("TariffConfiguration pointer not set\n"); + return false; + } + if (json == NULL) + { + printf("%s", "Input JSON string is NULL\n"); + return false; + } + + // Parse JSON to document + Document document; + document.Parse(json); + + // Return if parse error has been found + ParseErrorCode err = document.GetParseError(); + if (err != 0) + { + printf("%s %d (%s)\n", "Unable to parse JSON, error code:", err, GetParseError_En(err)); + return false; + } + + // Validate JSON, check if it's a JSON object + qCritical() << "JSON parsing has been successful"; + if (!document.IsObject()) { + printf("%s", "Error: not a (valid) JSON object\n"); + return false; + } + qCritical() << "Valid JSON object identified"; + + // Validate JSON, check configuration members + if (!document.HasMember("Currency") + || !document.HasMember("PaymentMethod") + || !document.HasMember("PaymentOption") + || !document.HasMember("PaymentRate") + || !document.HasMember("Duration") + //|| !document.HasMember("WeekDays") + //|| !document.HasMember("SpecialDaysWorktime") + //|| !document.HasMember("SpecialDays") + ) + { + printf("%s", "Error: not a valid configuration JSON\n"); + return false; + } + qCritical() << "Valid JSON configuration identified"; + + ATBCurrency Currency; + ATBDuration Duration; + ATBPaymentMethod PaymentMethod; + ATBPaymentRate PaymentRate; + ATBSpecialDaysWorktime SpecialDaysWorktime; + ATBSpecialDays SpecialDays; + ATBWeekDays WeekDays; + ATBWeekDaysWorktime WeekDaysWorktime; + ATBPeriodYear YearPeriod; + ATBDailyTicket DailyTicket; + ATBTimeBase TimeBase; + ATBCustomer Customer; + ATBTimeRange TimeRange; + ATBTimeStepConfig TimeStepConfig; + ATBTariffProduct TariffProduct; + + MemberType mb_type = MemberType::UnknownType; + this->currentPaymentOptions.clear(); + + // Get all JSON object members + // This code should run only once (to load JSON variables into memory) + for (auto i = document.MemberBegin(); i != document.MemberEnd(); i++) + { + // Get name of all general members of JSON, don't print name if NULL + const char* mb_name = i->name.GetString(); + if (mb_name == NULL) continue; + + 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; + } + + qCritical() << " -" << mb_name; + + // Get array for each JSON object member + auto mb_array = document[mb_name].GetArray(); + if (mb_array.Size() <= 0) break; + + //Iterate over provided array + for (rapidjson::SizeType j = 0; j < mb_array.Size(); j++) + { + // Get all inner objects, don't print name if NULL + auto inner_obj = mb_array[j].GetObject(); + if (inner_obj.MemberCount() <= 0) break; + + // Iterate over inner object JSON members + for (auto k = inner_obj.MemberBegin(); k != inner_obj.MemberEnd(); k++) + { + // Get inner object JSON member, don't print name if NULL + const char* inner_obj_name = k->name.GetString(); + if (inner_obj_name == NULL) + { + printf("Inner object name is NULL\n"); + continue; + } + + // Identify member type + mb_type = IdentifyJsonMember(mb_name); + + switch (mb_type) + { + case MemberType::UnknownType: + break; + case MemberType::ProductType: { + if (QString(inner_obj_name) == QString("tariff_product_id")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_id = PermitType(x); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_price")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_price = x; + } + } else + if (QString(inner_obj_name) == QString("tariff_product_name")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_name = QString::fromStdString(s); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_start")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_start = QTime::fromString(QString::fromStdString(s), Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_end")) { + if (k->value.IsString()) { + std::string const &s = k->value.GetString(); + TariffProduct.m_tariff_product_end = QTime::fromString(QString::fromStdString(s), Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("tariff_product_from_in_minutes_from_start")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_from_in_minutes_from_start = x; + } + } else + if (QString(inner_obj_name) == QString("tariff_product_to_in_minutes_from_start")) { + if (k->value.IsInt()) { + int const x = k->value.GetInt(); + TariffProduct.m_tariff_product_to_in_minutes_from_start = x; + } + } + } break; + case MemberType::TimeRangeType: + if (QString(inner_obj_name) == QString("time_range_id")) { + if (k->value.IsInt()) { + TimeRange.time_range_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("time_range_from")) { + if (k->value.IsString()) { + QTime timeRangeFrom = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); + TimeRange.time_range_from = timeRangeFrom; + } else + if (k->value.IsInt()) { + int timeRangeFrom = k->value.GetInt(); + TimeRange.time_range_from_in_minutes_from_start = timeRangeFrom; + } + } else + if (QString(inner_obj_name) == QString("time_range_to")) { + if (k->value.IsString()) { + QTime timeRangeTo = QTime::fromString(QString::fromStdString(k->value.GetString()), Qt::ISODate); + TimeRange.time_range_to = timeRangeTo; + } else + if (k->value.IsInt()) { + int timeRangeTo = k->value.GetInt(); + TimeRange.time_range_to_in_minutes_from_start = timeRangeTo; + } + } else + if (QString(inner_obj_name) == QString("time_range_tbase_id")) { + if (k->value.IsInt()) { + int tbase = k->value.GetInt(); + TimeRange.time_range_tbase_id = tbase; + } + } else + if (QString(inner_obj_name) == QString("time_range_payment_rate_id")) { + if (k->value.IsInt()) { + int ptype = k->value.GetInt(); + TimeRange.time_range_payment_type_id = ptype; + } + } + break; + case MemberType::TimeBaseType: + if (QString(inner_obj_name) == QString("tbase_id")) { + if (k->value.IsInt()) { + TimeBase.tbase_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("tbase_type")) { + if (k->value.IsInt()) { + int timeBase = k->value.GetInt(); + switch (timeBase) { + case (int)ATBTimeBase::TimeBaseType::ABSOLUTE: + TimeBase.tbase_type = ATBTimeBase::TimeBaseType::ABSOLUTE; + break; + case (int)ATBTimeBase::TimeBaseType::RELATIVE: + TimeBase.tbase_type = ATBTimeBase::TimeBaseType::RELATIVE; + break; + } + } + } + break; + case MemberType::TimeStepConfigType: + if (QString(inner_obj_name) == QString("tsconfig_id")) { + if (k->value.IsInt()) { + TimeStepConfig.tsconfig_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("tsconfig_label")) { + if (k->value.IsString()) { + TimeStepConfig.tsconfig_label = QString::fromStdString(k->value.GetString()); + } + } + break; + case MemberType::DailyTicketType: + if (QString(inner_obj_name) == QString("daily_ticket_payment_option_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_payment_option_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_price_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_price_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_tb_id")) { + if (k->value.IsInt()) { + DailyTicket.daily_ticket_tb_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_clearance_customer_ids")) { + if (k->value.IsArray()) { + auto customerIds = k->value.GetArray(); + for (rapidjson::SizeType i=0; i < customerIds.Size(); ++i) { + if (customerIds[i].IsInt()) { + DailyTicket.daily_ticket_clearance_customer_ids.append(customerIds[i].GetInt()); + } + } + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_from_min")) { + if (k->value.IsString()) { + std::string const from_min = k->value.GetString(); + char const *from_min_c_str = from_min.c_str(); // for debugging + DailyTicket.daily_ticket_from_min = QTime::fromString(from_min_c_str, Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_to_max")) { + if (k->value.IsString()) { + std::string const to_max = k->value.GetString(); + char const *to_max_c_str = to_max.c_str(); + DailyTicket.daily_ticket_to_max = QTime::fromString(to_max_c_str, Qt::ISODate); + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_from_offset_min")) { + if (k->value.IsInt()) { + int const from_offset_min = k->value.GetInt(); + DailyTicket.daily_ticket_from_offset_min = from_offset_min; + } + } else + if (QString(inner_obj_name) == QString("daily_ticket_to_offset_max")) { + if (k->value.IsInt()) { + int to_offset_max = k->value.GetInt(); + DailyTicket.daily_ticket_to_offset_max = to_offset_max; + } + } + break; + case MemberType::CustomerType: + if (QString(inner_obj_name) == QString("cust_id")) { + if (k->value.IsInt()) { + Customer.cust_id = k->value.GetInt(); + } + } else + if (QString(inner_obj_name) == QString("cust_type")) { + if (k->value.IsInt()) { + int cust_type = k->value.GetInt(); + switch (cust_type) { + case (int)ATBCustomer::CustomerType::ADULT: + Customer.cust_type = ATBCustomer::CustomerType::ADULT; + break; + case (int)ATBCustomer::CustomerType::CHILD: + Customer.cust_type = ATBCustomer::CustomerType::CHILD; + break; + case (int)ATBCustomer::CustomerType::TEEN: + Customer.cust_type = ATBCustomer::CustomerType::TEEN; + break; + } + } + } else + if (QString(inner_obj_name) == QString("cust_label")) { + if (k->value.IsString()) { + QString label(QString::fromStdString(k->value.GetString())); + if (label.contains("ADULT", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } else + if (label.contains("CHILD", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } else + if (label.contains("TEEN", Qt::CaseInsensitive)) { + Customer.cust_label = label; + } + } + } + break; + case MemberType::CurrencyType: + if (strcmp(inner_obj_name, "pcu_id") == 0) Currency.pcu_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pcu_sign") == 0) Currency.pcu_sign = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_major") == 0) Currency.pcu_major = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_minor") == 0) Currency.pcu_minor = k->value.GetString(); + else if (strcmp(inner_obj_name, "pcu_active") == 0) Currency.pcu_active = k->value.GetBool(); + break; + case MemberType::PaymentMethodType: + if (strcmp(inner_obj_name, "pme_id") == 0) PaymentMethod.pme_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pme_label") == 0) PaymentMethod.pme_label = k->value.GetString(); + break; + case MemberType::PaymentRateType: + if (strcmp(inner_obj_name, "pra_payment_option_id") == 0) PaymentRate.pra_payment_option_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pra_payment_unit_id") == 0) PaymentRate.pra_payment_unit_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pra_price") == 0) PaymentRate.pra_price = k->value.GetDouble(); + break; + case MemberType::PaymentOptionType: + if (strcmp(inner_obj_name, "pop_id") == 0) { + this->currentPaymentOptions.append(ATBPaymentOption()); + this->currentPaymentOptions.last().reset(); + this->currentPaymentOptions.last().pop_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_label") == 0) { + this->currentPaymentOptions.last().pop_label = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_payment_method_id") == 0) { + this->currentPaymentOptions.last().pop_payment_method_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_day_end_time") == 0) { + this->currentPaymentOptions.last().pop_day_end_time = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_day_night_end_time") == 0) { + this->currentPaymentOptions.last().pop_day_night_end_time = k->value.GetString(); + } else if (strcmp(inner_obj_name, "pop_price_night") == 0) { + this->currentPaymentOptions.last().pop_price_night = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_min_time") == 0) { + this->currentPaymentOptions.last().pop_min_time = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_max_price") == 0) { + this->currentPaymentOptions.last().pop_max_price = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_max_time") == 0) { + this->currentPaymentOptions.last().pop_max_time = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_min_price") == 0) { + this->currentPaymentOptions.last().pop_min_price = k->value.GetDouble(); + } else if (strcmp(inner_obj_name, "pop_carry_over") == 0) { + this->currentPaymentOptions.last().pop_carry_over = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_time_range_id") == 0) { + this->currentPaymentOptions.last().pop_carry_over_time_range_id = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_start_time_range") == 0) { + this->currentPaymentOptions.last().pop_carry_over_start_time_range = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_carry_over_end_time_range") == 0) { + this->currentPaymentOptions.last().pop_carry_over_end_time_range = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_daily_card_price") == 0) { + this->currentPaymentOptions.last().pop_daily_card_price = k->value.GetInt(); + } else if (strcmp(inner_obj_name, "pop_business_hours") == 0) { + if (k->value.IsInt()) { + int const v = k->value.GetInt(); + this->currentPaymentOptions.last().pop_business_hours = v; + } else + if (k->value.IsString()) { + bool ok; + uint64_t const v = QString::fromStdString(k->value.GetString()).toLongLong(&ok); + if (ok) { + this->currentPaymentOptions.last().pop_business_hours = v; + } + } + } else if (strcmp(inner_obj_name, "pop_time_step_config") == 0) { + this->currentPaymentOptions.last().pop_time_step_config = k->value.GetInt(); + } + 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(); + else if (strcmp(inner_obj_name, "pun_duration") == 0) Duration.pun_duration = k->value.GetDouble(); + else if (strcmp(inner_obj_name, "pun_duration_min") == 0) Duration.pun_duration_min = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pun_duration_max") == 0) Duration.pun_duration_max = k->value.GetInt(); + break; + case MemberType::SpecialDaysWorktimeType: + if (strcmp(inner_obj_name, "pedwt_id") == 0) SpecialDaysWorktime.pedwt_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pedwt_period_exc_day_id") == 0) SpecialDaysWorktime.pedwt_period_exc_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pedwt_time_from") == 0) SpecialDaysWorktime.pedwt_time_from = k->value.GetString(); + else if (strcmp(inner_obj_name, "pedwt_time_to") == 0) SpecialDaysWorktime.pedwt_time_to = k->value.GetString(); + else if (strcmp(inner_obj_name, "pedwt_price") == 0) SpecialDaysWorktime.pedwt_price = k->value.GetDouble(); + break; + /*case MemberType::WeekDaysType: + if (strcmp(inner_obj_name, "pdiw_id") == 0) WeekDays.pdiw_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pdiw_label") == 0) WeekDays.pdiw_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "pdiw_index") == 0) WeekDays.pdiw_index = k->value.GetInt(); + break;*/ + case MemberType::WeekDaysWorkTimeType: + if (strcmp(inner_obj_name, "pwd_id") == 0) WeekDaysWorktime.pwd_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_period_week_day_id") == 0) WeekDaysWorktime.pwd_period_week_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_period_day_in_week_id") == 0) WeekDaysWorktime.pwd_period_day_in_week_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pwd_time_from") == 0) WeekDaysWorktime.pwd_time_from = k->value.GetString(); + else if (strcmp(inner_obj_name, "pwd_time_to") == 0) WeekDaysWorktime.pwd_time_to = k->value.GetString(); + break; + case MemberType::SpecialDaysType: + if (strcmp(inner_obj_name, "ped_id") == 0) SpecialDays.ped_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_label") == 0) SpecialDays.ped_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_date_start") == 0) SpecialDays.ped_date_start = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_date_end") == 0) SpecialDays.ped_date_end = k->value.GetString(); + else if (strcmp(inner_obj_name, "ped_period_special_day_id") == 0) SpecialDays.ped_period_special_day_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_payment_option_id") == 0) SpecialDays.ped_payment_option_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "ped_year") == 0) SpecialDays.ped_year = k->value.GetInt(); + break; + case MemberType::PeriodYearType: + if (strcmp(inner_obj_name, "pye_id") == 0) YearPeriod.pye_id = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_label") == 0) YearPeriod.pye_label = k->value.GetString(); + else if (strcmp(inner_obj_name, "pye_start_month") == 0) YearPeriod.pye_start_month = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_start_day") == 0) YearPeriod.pye_start_day = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_end_month") == 0) YearPeriod.pye_end_month = k->value.GetInt(); + else if (strcmp(inner_obj_name, "pye_end_day") == 0) YearPeriod.pye_end_day = k->value.GetInt(); + break; + default: + break; + } +//#pragma endregion + } + + // Push to specific list depending on member type + switch (mb_type) + { + case MemberType::UnknownType: + break; + case MemberType::PaymentMethodType: + cfg->PaymentMethod.insert(pair(PaymentMethod.pme_id, PaymentMethod)); + break; + case MemberType::PaymentRateType: + // qCritical() << "PaymentRate" << PaymentRate; + cfg->PaymentRate.insert(pair(PaymentRate.pra_payment_option_id, PaymentRate)); + break; + case MemberType::PaymentOptionType: { + if (!this->currentPaymentOptions.isEmpty()) { + ATBPaymentOption const &PaymentOption = this->currentPaymentOptions.last(); + cfg->PaymentOption.insert(pair(PaymentOption.pop_payment_method_id, PaymentOption)); + } + } break; + case MemberType::DurationType: + cfg->Duration.insert(pair(Duration.pun_id, Duration)); + break; + case MemberType::SpecialDaysWorktimeType: + cfg->SpecialDaysWorktime.insert(pair(SpecialDaysWorktime.pedwt_period_exc_day_id, SpecialDaysWorktime)); + break; + //case MemberType::WeekDaysType: + // cfg->WeekDays.insert(pair(WeekDays.pdiw_index, WeekDays)); + // break; + case MemberType::WeekDaysWorkTimeType: + cfg->WeekDaysWorktime.insert(pair(WeekDaysWorktime.pwd_period_day_in_week_id, WeekDaysWorktime)); + break; + case MemberType::SpecialDaysType: + cfg->SpecialDays.insert(pair(SpecialDays.ped_id, SpecialDays)); + break; + case MemberType::PeriodYearType: + cfg->YearPeriod.insert(pair(YearPeriod.pye_id, YearPeriod)); + break; + case MemberType::DailyTicketType: + cfg->DailyTicket.insert(pair(DailyTicket.daily_ticket_id, DailyTicket)); + qCritical() << DailyTicket; + DailyTicket.reset(); + break; + case MemberType::CustomerType: + cfg->Customer.insert(pair(Customer.cust_id, Customer)); + qCritical() << Customer; + break; + case MemberType::TimeBaseType: + cfg->TimeBase.insert(pair(TimeBase.tbase_id, TimeBase)); + qCritical() << TimeBase; + break; + case MemberType::TimeRangeType: + cfg->TimeRange.insert(pair(TimeRange.time_range_id, TimeRange)); + //qCritical() << TimeRange; + break; + case MemberType::TimeStepConfigType: + cfg->TimeStepConfig.insert(pair(TimeStepConfig.tsconfig_id, TimeStepConfig)); + // qCritical() << TimeStepConfig; + break; + case MemberType::ProductType: + cfg->TariffProduct.insert(pair(TariffProduct.m_tariff_product_id, TariffProduct)); + qCritical() << TariffProduct; + default: + break; + } + } + } + return true; + } + catch (...) { + printf("%s\n", "General exception has occurred while parsing JSON\n"); + return false; + } +} + +int Configuration::getPaymentOptionIndexIfSpecialDay(QDateTime const &dt) const { + if (isSpecialDay(dt)) { + int const numOptions = getAllPaymentOptions().size(); + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_business_hours = getPaymentOptions(opt).pop_business_hours; + if ((pop_business_hours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY) { + return opt; + } + } + } + return -1; +} + +int Configuration::getPaymentOptionIndex(QDateTime const &dt) const { + int const numOptions = getAllPaymentOptions().size(); + + // special days are handled before usual week days + int const sid = specialDayId(dt); + if (sid > 0) { + ATBSpecialDays const sd = specialDay(dt); + if (sd.ped_id != 0) { + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_id = getPaymentOptions(opt).pop_id; + if (pop_id == sd.ped_payment_option_id) { + return opt; + } + } + } + } + + for (int opt=0; opt < numOptions; ++opt) { + uint64_t const pop_business_hours = getPaymentOptions(opt).pop_business_hours; + + + uint64_t p = 0; + int const dayOfWeek = dt.date().dayOfWeek(); + + switch (dayOfWeek) { + case (int)Qt::Monday: { + p = BusinessHours::MON; + } break; + case (int)Qt::Tuesday: { + p = BusinessHours::TUE; + } break; + case (int)Qt::Wednesday: { + p = BusinessHours::WED; + } break; + case (int)Qt::Thursday: { + p = BusinessHours::THU; + } break; + case (int)Qt::Friday: { + p = BusinessHours::FRI; + } break; + case (int)Qt::Saturday: { + p = BusinessHours::SAT; + } break; + case (int)Qt::Sunday: { + p = BusinessHours::SUN; + qCritical() << DBG_HEADER << Utilities::dumpBusinessHours(pop_business_hours) << pop_business_hours << p; + } break; + } + + if ((pop_business_hours & p) == p) { + return opt; + } + } + + return -1; +} + +ATBSpecialDays Configuration::specialDay(QDateTime const &dt) const { + SpecialDaysType::const_iterator it; + for (it = SpecialDays.cbegin(); it != SpecialDays.cend(); ++it) { + if (dt.date().toString(Qt::ISODate) == QString::fromStdString(it->second.ped_date_start)) { + return it->second; + } + } + + return ATBSpecialDays(); +} + +int Configuration::specialDayId(QDateTime const &dt) const { + SpecialDaysType::const_iterator it; + for (it = SpecialDays.cbegin(); it != SpecialDays.cend(); ++it) { + if (dt.date().toString(Qt::ISODate) == QString::fromStdString(it->second.ped_date_start)) { + int const specialDayId = it->second.ped_id; + return specialDayId; // must be > 0 + } + } + return 0; +} + +bool Configuration::isSpecialDay(QDateTime const &dt) const { + return (specialDayId(dt) > 0); +} + +bool Configuration::isDayIncludedAsSpecialDay(uint64_t businessHours, int specialDayId) const { + if (specialDayId > 0) { + bool const &r = ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY); + return r; + } + return false; +} + +bool Configuration::isDayIncludedAsSpecialDay(uint64_t businessHours, QDateTime const &dt) const { + // included in 'businessHours' + + if (isSpecialDay(dt)) { + bool const &r = ((businessHours & BusinessHours::OFFICIAL_HOLIDAY) == BusinessHours::OFFICIAL_HOLIDAY); + qCritical() << "XXXXXXXXXXXXXXXXXX r" << r << businessHours; + return r; + } + + return false; +} + +bool Configuration::isDayIncluded(uint64_t businessHours, QDateTime const &dt) const { + return Utilities::isDayIncluded(businessHours, dt); +} + +ATBPaymentOption const &Configuration::getPaymentOptions(int paymentOptionsIndex) const { + Q_ASSERT(!this->currentPaymentOptions.isEmpty()); + return this->currentPaymentOptions.at(paymentOptionsIndex); +} + +ATBPaymentOption &Configuration::getPaymentOptions(int paymentOptionsIndex) { + Q_ASSERT(!this->currentPaymentOptions.isEmpty()); + return this->currentPaymentOptions[paymentOptionsIndex]; +} + +QVector const &Configuration::getAllPaymentOptions() const { + return this->currentPaymentOptions; +} + +QVector &Configuration::getAllPaymentOptions() { + return this->currentPaymentOptions; +} + +std::optional> +Configuration::getTariffProductForAllKeys() const { + QVector products; + std::optional> value; + + products.clear(); + + for (std::multimap::const_iterator it = this->TariffProduct.cbegin(); + it != this->TariffProduct.cend(); ++it) { + products.append(it->second); + } + + if (products.size() > 0) { + value = value.value_or(products); + } + + return value; +} + +std::optional> +Configuration::getTariffProductForProductId(PermitType permitType) const { + QVector products; + std::optional> value; + + products.clear(); + + for (auto[it, rangeEnd] = this->TariffProduct.equal_range(permitType); it != rangeEnd; ++it) { + products.append(it->second); + } + + if (products.size() > 0) { + value = value.value_or(products); + } + + return value; +} + +std::optional> +Configuration::getTariffProductForProductId(int id) const { + return getTariffProductForProductId(PermitType(id)); +} + +std::optional> +Configuration::getDailyTicketsForAllKeys() const { + QVector tickets; + std::optional> value; + + for (std::multimap::const_iterator it = this->DailyTicket.cbegin(); + it != this->DailyTicket.cend(); ++it) { + tickets.append(it->second); + } + + if (tickets.size() > 0) { + value = value.value_or(tickets); + } + + return value; +} + +std::optional> +Configuration::getDailyTicketsForKey(int key) const { + QVector tickets; + std::optional> value; + + tickets.clear(); + + for (auto[it, rangeEnd] = this->DailyTicket.equal_range(key); it != rangeEnd; ++it) { + tickets.append(it->second); + } + + if (tickets.size() > 0) { + value = value.value_or(tickets); + } + + return value; +} + +std::optional> +Configuration::getPaymentRateForAllKeys() const { + QVector paymentRates; + std::optional> value; + + for (std::multimap::const_iterator it = this->PaymentRate.cbegin(); + it != this->PaymentRate.cend(); ++it) { + paymentRates.append(it->second); + } + + if (paymentRates.size() > 0) { + value = value.value_or(paymentRates); + } + + return value; + +} + +std::optional> +Configuration::getPaymentRateForKey(int key) const { + QVector paymentRate; + std::optional> value; + + paymentRate.clear(); + + for (auto[it, rangeEnd] = this->PaymentRate.equal_range(key); it != rangeEnd; ++it) { + paymentRate.append(it->second); + } + + if (paymentRate.size() > 0) { + value = value.value_or(paymentRate); + } + + return value; +} + +std::optional +Configuration::getCustomerForType(ATBCustomer::CustomerType customerType) { + for (std::multimap::const_iterator it = this->Customer.cbegin(); + it != this->Customer.cend(); ++it) { + ATBCustomer const &customer = it->second; + if (customer.cust_type == customerType) { + return customer; + } + } + + return std::nullopt; +} + +std::optional +Configuration::getWeekDayWorkTime(QTime const &time, Qt::DayOfWeek dayOfWeek) { + ATBWeekDaysWorktime worktime; + std::optional value; + + std::multimap::const_iterator it = this->WeekDaysWorktime.find((int)dayOfWeek); + if (it != this->WeekDaysWorktime.cend()) { + + ATBWeekDaysWorktime const &wt = it->second; + + if (time >= QTime::fromString(wt.pwd_time_from.c_str(), Qt::ISODate) + && time < QTime::fromString(wt.pwd_time_to.c_str(), Qt::ISODate)) { + value = value.value_or(wt); + } + } + + return value; +}