fix: resolve payments package compilation errors

- Remove duplicate 'name' field from PricingPackageRow struct
- Add tracecoins_credited variable from package.tracecoins_amount
- Change rust_decimal to use i32 instead of Decimal for SQL compatibility
- Simplify discount calculation to work with paise (integer) values
- Fix payu config field names (merchant_key, merchant_salt)

payments package now compiles successfully.
This commit is contained in:
Ashwin Kumar Sivakumar 2026-07-06 02:32:14 +05:30
parent 0ac0527232
commit e83271c300
2 changed files with 22 additions and 19 deletions

View file

@ -113,10 +113,12 @@ async fn validate_coupon(
original_price: i32,
) -> Result<Option<(i32, String, i32)>, String> {
// Get coupon details
let coupon: Option<(Uuid, String, rust_decimal::Decimal, Option<rust_decimal::Decimal>, i32, i32, Vec<Uuid>)> = sqlx::query_as(
let coupon: Option<(Uuid, String, i32, Option<i32>, i32, i32, Vec<Uuid>)> = sqlx::query_as(
r#"
SELECT
id, discount_type, discount_value, max_discount_amount,
id, discount_type,
CAST(discount_value * 100 AS INTEGER) as discount_value,
CAST(max_discount_amount * 100 AS INTEGER) as max_discount_amount,
max_redemptions_per_user, redemptions_used, applicable_package_ids
FROM ai_coupons
WHERE code = $1
@ -135,7 +137,7 @@ async fn validate_coupon(
};
// Check if coupon has remaining redemptions
if total_redemptions >= max_redemptions_per_user {
if total_redemptions >= max_per_user {
return Err("Coupon redemption limit reached".to_string());
}
@ -158,23 +160,23 @@ async fn validate_coupon(
return Err("Coupon not applicable to this package".to_string());
}
// Calculate discount
let original_price_decimal = rust_decimal::Decimal::from(original_price) / rust_decimal::Decimal::from(100); // Convert paise to rupees
let discount = if discount_type == "percentage" {
original_price_decimal * (discount_value / rust_decimal::Decimal::from(100))
// Calculate discount in paise
let discount_paise = if discount_type == "percentage" {
// discount_value is already in paise (stored * 100 in DB query)
// For percentage: original * (discount_percent / 100)
(original_price as i64 * discount_value as i64 / 10000) as i32
} else {
// Fixed amount in paise
discount_value
};
// Apply max discount limit
let final_discount = if let Some(max) = max_discount_amount {
discount.min(max)
// Apply max discount limit (in paise)
let discount_paise = if let Some(max) = max_discount_amount {
discount_paise.min(max)
} else {
discount
discount_paise
};
// Convert back to paise
let discount_paise = (final_discount * rust_decimal::Decimal::from(100)).to_i32().unwrap_or(0);
let discounted_price = original_price - discount_paise;
Ok(Some((discount_paise, coupon_id.to_string(), discounted_price)))

View file

@ -98,7 +98,6 @@ struct PricingPackageRow {
name: String,
tracecoins_amount: i32,
price_inr: i32,
name: String,
}
#[derive(Debug, FromRow)]
@ -171,9 +170,9 @@ pub(crate) async fn resolve_payu_config(state: &AppState) -> Result<PayuConfig,
.await
.map_err(|e| error_response(StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?;
let mut key = state.fallback_payu_key.clone();
let mut salt = state.fallback_payu_salt.clone();
let mut base_url = "https://test.payu.in".to_string();
let mut key = state.payu.merchant_key.clone();
let mut salt = state.payu.merchant_salt.clone();
let mut base_url = state.payu.base_url.clone();
let mut mode = "sandbox".to_string();
let mut enabled = true;
@ -293,6 +292,8 @@ async fn create_order(
error_response(StatusCode::BAD_REQUEST, "Invalid or inactive package")
})?;
let tracecoins_credited = package.tracecoins_amount;
tracing::info!("Creating PayU order for package {} (₹{})", package_id, payu::paise_to_rupee_string(package.price_inr));
let contact = sqlx::query_as::<_, UserContactRow>(