MOBILISIS-Calculator/library/src/tariff_calc.cpp

151 lines
5.3 KiB
C++

#include "tariff_calc.h"
#include "tariff_utils.h"
/// <summary>
/// Helper function
/// </summary>
/// <param name="pra_price"></param>
/// <returns></returns>
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;
}
}
/// <inheritdoc/>
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;
}
/// <inheritdoc/>
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;
}