From e839ffb519ce9deb52cb9f74ee8ac9da5b319e6c Mon Sep 17 00:00:00 2001 From: nutcas3 Date: Sat, 25 Apr 2026 05:28:43 +0300 Subject: [PATCH] feat: Add precision handling and overflow protection to monthly fee billing - Add rounding to monthly fee conversion to cents to prevent precision loss - Replace direct subtraction with saturating_sub to prevent i64 underflow - Add fee_cents variable for clearer monthly fee calculation in billing cycle --- apps/charging-engine/src/charging/rating_billing.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/charging-engine/src/charging/rating_billing.rs b/apps/charging-engine/src/charging/rating_billing.rs index a40bf9b..df9bac1 100644 --- a/apps/charging-engine/src/charging/rating_billing.rs +++ b/apps/charging-engine/src/charging/rating_billing.rs @@ -246,7 +246,9 @@ impl super::ChargingEngine { if let Ok(Some(mut account)) = redis::AsyncCommands::get::<_, Option>(&mut conn, &key).await { // Get rating plan from Postgres and apply monthly fee. if let Ok(Some(plan)) = self.get_rating_plan("basic").await { - account.balance -= (plan.monthly_fee * 100.0) as i64; // Convert to cents + // Use rounding to avoid precision loss when converting to cents + let fee_cents = (plan.monthly_fee * 100.0).round() as i64; + account.balance = account.balance.saturating_sub(fee_cents); account.last_updated = Utc::now(); let _: () = redis::AsyncCommands::set(&mut conn, &key, &account).await.unwrap_or(());