use crate::discount::calculate_discount;
use crate::error::PromoError;
use crate::promotion::Promotion;
use crate::rule_engine::PromoContext;
pub fn apply_promotion(
promo: &Promotion,
transaction_amount: f64,
now: u64,
) -> Result<f64, PromoError> {
let ctx = PromoContext {
current_time: now,
transaction_amount,
promo,
};
if ctx.promo.valid_from >= ctx.promo.valid_until {
return Err(PromoError::InvalidPeriod);
}
if ctx.current_time < ctx.promo.valid_from || ctx.current_time > ctx.promo.valid_until {
return Err(PromoError::InvalidTime);
}
if let Some(min_tx) = ctx.promo.min_transaction {
if ctx.transaction_amount < min_tx {
return Err(PromoError::BelowMinimumTransaction);
}
}
if let Some(limit) = ctx.promo.usage_limit {
if ctx.promo.used >= limit {
return Err(PromoError::UsageLimitReached);
}
}
Ok(calculate_discount(ctx.promo, ctx.transaction_amount))
}
pub fn increment_usage(promo: &mut Promotion) {
promo.used += 1;
}
pub fn reset_usage(promo: &mut Promotion) {
promo.used = 0;
}