#include "tariff_calc.h" #include "tariff_utils.h" /// /// Helper function /// /// /// double CalculatePricePerUnit(double pra_price) { try { double price_per_unit = pra_price; price_per_unit /= 60.0f; // Divided by 60 because price per unit is set per hour and we are using minutes printf("Price per unit (min) is: %lf EUR\n", price_per_unit); return price_per_unit; } catch (...) { printf("An error has occurred in CalculatePricePerUnit() function\n"); return 0.0f; } } /// double TariffCalculator::GetDurationFromCost(TariffConfiguration* tariff_cfg, uint8_t vehicle_type, char const* start_datetime, double price) { uint8_t pay_method = PaymentMethod::Undefined; double cost = 0.0f; // Payment method is automatically selected by vehicle type // (vehicle type byte actually represents payment type according to documentation) // e.g. car (0x03) in tariff_vehicles_type == linear payment method (0x03) // tariff_payment_method pay_method = vehicle_type; // car = 0x03 printf("Payment method: %d\n", pay_method); double price_per_unit = 0; double durationMin = 0; bool isSpecialDay = false; int spec_day_id = -1; for (size_t i = 0; i <= tariff_cfg->PaymentRate.size(); i++) { if (pay_method == tariff_cfg->PaymentRate.at(i).pra_payment_option_id) { double pra_price = tariff_cfg->PaymentRate.at(i).pra_price; // If is special day, pra_price will be overriden with special day's price if ((isSpecialDay = TariffUtils::IsSpecialDay(tariff_cfg, start_datetime, spec_day_id))) { if (TariffUtils::PriceForSpecialDay(tariff_cfg, spec_day_id, &pra_price)) { printf("Date %s is special day\n", start_datetime); printf("Setting new price per hour: %f EUR\n", pra_price); } } price_per_unit = CalculatePricePerUnit(pra_price); if (price_per_unit <= 0) price_per_unit = 1; // Division by zero protection durationMin = price / price_per_unit; break; } } // Check active hours for parking (override with special day active hours if special day flag is set) ActiveTimeRange active_time_range = TariffUtils::isParkingTimeRangeActive(tariff_cfg, start_datetime, isSpecialDay, spec_day_id); printf("Is active parking payment: %d\n", active_time_range.isActive); // TODO: CHECK struct tm initial_tm; TariffUtils::DateTimeToStructTm(start_datetime, &initial_tm); time_t initial = mktime(&initial_tm); TariffUtils::ValidateParkingTicket(tariff_cfg, initial, durationMin, price, active_time_range.timeRange, isSpecialDay, spec_day_id); // If parking payment active hours have passed, do not calculate duration if (!active_time_range.isActive) return 0.0f; return durationMin; } /// double TariffCalculator::GetCostFromDuration(TariffConfiguration* tariff_cfg, uint8_t vehicle_type, char const* start_datetime, double durationMin) { uint8_t pay_method = PaymentMethod::Undefined; double cost = 0.0f; // Payment method is automatically selected by vehicle type // (vehicle type byte actually represents payment type according to documentation) // e.g. car (0x03) in tariff_vehicles_type == linear payment method (0x03) // tariff_payment_method pay_method = vehicle_type; // car = 0x03 printf("Payment method: %d\n", pay_method); int unit = 1.0f; // Unit factor, as parameter 'durationMin' // represents minutes, this should stay 1 double price_per_unit = 0; bool isSpecialDay = false; int spec_day_id = -1; for (size_t i = 0; i <= tariff_cfg->PaymentRate.size(); i++) { if (pay_method == tariff_cfg->PaymentRate.at(i).pra_payment_option_id) { double pra_price = tariff_cfg->PaymentRate.at(i).pra_price; if ((isSpecialDay = TariffUtils::IsSpecialDay(tariff_cfg, start_datetime, spec_day_id))) { // If is special day, pra_price will be // overriden with special day's price if (TariffUtils::PriceForSpecialDay(tariff_cfg, spec_day_id, &pra_price)) { printf("Date %s is special day\n", start_datetime); printf("Setting new price per hour: %f EUR\n", pra_price); } } price_per_unit = CalculatePricePerUnit(pra_price); break; } } cost = durationMin * price_per_unit; // Check active hours for parking (override with special day active hours // if special day flag is set) ActiveTimeRange active_time_range = TariffUtils::isParkingTimeRangeActive(tariff_cfg, start_datetime, isSpecialDay, spec_day_id); printf("Is active parking payment: %d\n", active_time_range.isActive); // TODO: CHECK struct tm initial_tm; TariffUtils::DateTimeToStructTm(start_datetime, &initial_tm); time_t initial = mktime(&initial_tm); TariffUtils::ValidateParkingTicket(tariff_cfg, initial, durationMin, cost, active_time_range.timeRange, isSpecialDay, spec_day_id); // If parking payment active hours have passed, do not calculate price if (!active_time_range.isActive) return 0.0f; return cost; }