Skip to content

Commit

Permalink
refactor: create separate struct for surcharge details response
Browse files Browse the repository at this point in the history
  • Loading branch information
hrithikesh026 committed Nov 30, 2023
1 parent bc79d52 commit cd8d96a
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 220 deletions.
120 changes: 8 additions & 112 deletions crates/api_models/src/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ use std::collections::HashMap;

use cards::CardNumber;
use common_utils::{
consts::SURCHARGE_PERCENTAGE_PRECISION_LENGTH, crypto::OptionalEncryptableName, pii,
types::Percentage,
consts::SURCHARGE_PERCENTAGE_PRECISION_LENGTH,
crypto::OptionalEncryptableName,
pii,
types::{Percentage, Surcharge},
};
use serde::de;
use utoipa::ToSchema;
Expand All @@ -14,7 +16,7 @@ use crate::{
admin,
customers::CustomerId,
enums as api_enums,
payments::{self, BankCodeResponse, RequestSurchargeDetails},
payments::{self, BankCodeResponse},
};

#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
Expand Down Expand Up @@ -337,117 +339,11 @@ pub struct SurchargeDetailsResponse {
/// tax on surcharge value
pub tax_on_surcharge: Option<Percentage<SURCHARGE_PERCENTAGE_PRECISION_LENGTH>>,
/// surcharge amount for this payment
pub surcharge_amount: i64,
pub display_surcharge_amount: f64,
/// tax on surcharge amount for this payment
pub tax_on_surcharge_amount: i64,
pub display_tax_on_surcharge_amount: f64,
/// sum of original amount,
pub final_amount: i64,
}

impl SurchargeDetailsResponse {
pub fn is_request_surcharge_matching(
&self,
request_surcharge_details: RequestSurchargeDetails,
) -> bool {
request_surcharge_details.surcharge_amount == self.surcharge_amount
&& request_surcharge_details.tax_amount.unwrap_or(0) == self.tax_on_surcharge_amount
}
pub fn get_total_surcharge_amount(&self) -> i64 {
self.surcharge_amount + self.tax_on_surcharge_amount
}
}

#[derive(Clone, Debug)]
pub struct SurchargeMetadata {
surcharge_results: HashMap<
(
common_enums::PaymentMethod,
common_enums::PaymentMethodType,
Option<common_enums::CardNetwork>,
),
SurchargeDetailsResponse,
>,
pub payment_attempt_id: String,
}

impl SurchargeMetadata {
pub fn new(payment_attempt_id: String) -> Self {
Self {
surcharge_results: HashMap::new(),
payment_attempt_id,
}
}
pub fn is_empty_result(&self) -> bool {
self.surcharge_results.is_empty()
}
pub fn get_surcharge_results_size(&self) -> usize {
self.surcharge_results.len()
}
pub fn insert_surcharge_details(
&mut self,
payment_method: &common_enums::PaymentMethod,
payment_method_type: &common_enums::PaymentMethodType,
card_network: Option<&common_enums::CardNetwork>,
surcharge_details: SurchargeDetailsResponse,
) {
let key = (
payment_method.to_owned(),
payment_method_type.to_owned(),
card_network.cloned(),
);
self.surcharge_results.insert(key, surcharge_details);
}
pub fn get_surcharge_details(
&self,
payment_method: &common_enums::PaymentMethod,
payment_method_type: &common_enums::PaymentMethodType,
card_network: Option<&common_enums::CardNetwork>,
) -> Option<&SurchargeDetailsResponse> {
let key = &(
payment_method.to_owned(),
payment_method_type.to_owned(),
card_network.cloned(),
);
self.surcharge_results.get(key)
}
pub fn get_surcharge_metadata_redis_key(payment_attempt_id: &str) -> String {
format!("surcharge_metadata_{}", payment_attempt_id)
}
pub fn get_individual_surcharge_key_value_pairs(
&self,
) -> Vec<(String, SurchargeDetailsResponse)> {
self.surcharge_results
.iter()
.map(|((pm, pmt, card_network), surcharge_details)| {
let key =
Self::get_surcharge_details_redis_hashset_key(pm, pmt, card_network.as_ref());
(key, surcharge_details.to_owned())
})
.collect()
}
pub fn get_surcharge_details_redis_hashset_key(
payment_method: &common_enums::PaymentMethod,
payment_method_type: &common_enums::PaymentMethodType,
card_network: Option<&common_enums::CardNetwork>,
) -> String {
if let Some(card_network) = card_network {
format!(
"{}_{}_{}",
payment_method, payment_method_type, card_network
)
} else {
format!("{}_{}", payment_method, payment_method_type)
}
}
}

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
pub enum Surcharge {
/// Fixed Surcharge value
Fixed(i64),
/// Surcharge percentage
Rate(Percentage<SURCHARGE_PERCENTAGE_PRECISION_LENGTH>),
pub display_final_amount: f64,
}

/// Required fields info used while listing the payment_method_data
Expand Down
12 changes: 0 additions & 12 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::{
admin, disputes,
enums::{self as api_enums},
ephemeral_key::EphemeralKeyCreateResponse,
payment_methods::{Surcharge, SurchargeDetailsResponse},
refunds,
};

Expand Down Expand Up @@ -339,17 +338,6 @@ impl RequestSurchargeDetails {
pub fn is_surcharge_zero(&self) -> bool {
self.surcharge_amount == 0 && self.tax_amount.unwrap_or(0) == 0
}
pub fn get_surcharge_details_object(&self, original_amount: i64) -> SurchargeDetailsResponse {
let surcharge_amount = self.surcharge_amount;
let tax_on_surcharge_amount = self.tax_amount.unwrap_or(0);
SurchargeDetailsResponse {
surcharge: Surcharge::Fixed(self.surcharge_amount),
tax_on_surcharge: None,
surcharge_amount,
tax_on_surcharge_amount,
final_amount: original_amount + surcharge_amount + tax_on_surcharge_amount,
}
}
pub fn get_total_surcharge_amount(&self) -> i64 {
self.surcharge_amount + self.tax_amount.unwrap_or(0)
}
Expand Down
10 changes: 5 additions & 5 deletions crates/api_models/src/surcharge_decision_configs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct SurchargeDetails {
pub surcharge: Surcharge,
pub struct SurchargeDetailsOutput {
pub surcharge: SurchargeOutput,
pub tax_on_surcharge: Option<Percentage<SURCHARGE_PERCENTAGE_PRECISION_LENGTH>>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
pub enum Surcharge {
Fixed(i64),
pub enum SurchargeOutput {
Fixed { amount: i64 },
Rate(Percentage<SURCHARGE_PERCENTAGE_PRECISION_LENGTH>),
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct SurchargeDecisionConfigs {
pub surcharge_details: Option<SurchargeDetails>,
pub surcharge_details: Option<SurchargeDetailsOutput>,
}
impl EuclidDirFilter for SurchargeDecisionConfigs {
const ALLOWED: &'static [DirKeyKind] = &[
Expand Down
15 changes: 14 additions & 1 deletion crates/common_utils/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
use error_stack::{IntoReport, ResultExt};
use serde::{de::Visitor, Deserialize, Deserializer};

use crate::errors::{CustomResult, PercentageError};
use crate::{
consts,
errors::{CustomResult, PercentageError},
};

/// Represents Percentage Value between 0 and 100 both inclusive
#[derive(Clone, Default, Debug, PartialEq, serde::Serialize)]
Expand Down Expand Up @@ -136,3 +139,13 @@ impl<'de, const PRECISION: u8> Deserialize<'de> for Percentage<PRECISION> {
data.deserialize_map(PercentageVisitor::<PRECISION> {})
}
}

/// represents surcharge type and value
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
pub enum Surcharge {
/// Fixed Surcharge value
Fixed(i64),
/// Surcharge percentage
Rate(Percentage<{ consts::SURCHARGE_PERCENTAGE_PRECISION_LENGTH }>),
}
1 change: 0 additions & 1 deletion crates/diesel_models/src/payment_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ pub struct PaymentIntentNew {
pub merchant_decision: Option<String>,
pub payment_link_id: Option<String>,
pub payment_confirm_source: Option<storage_enums::PaymentSource>,

pub updated_by: String,
pub surcharge_applicable: Option<bool>,
pub request_incremental_authorization: RequestIncrementalAuthorization,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
use api_models::{
payment_methods::{self, SurchargeDetailsResponse, SurchargeMetadata},
payment_methods::SurchargeDetailsResponse,
payments::Address,
routing,
surcharge_decision_configs::{
self, SurchargeDecisionConfigs, SurchargeDecisionManagerRecord, SurchargeDetails,
},
surcharge_decision_configs::{self, SurchargeDecisionConfigs, SurchargeDecisionManagerRecord},
};
use common_utils::{ext_traits::StringExt, static_cache::StaticCache};
use common_utils::{ext_traits::StringExt, static_cache::StaticCache, types as common_utils_types};
use error_stack::{self, IntoReport, ResultExt};
use euclid::{
backend,
backend::{inputs as dsl_inputs, EuclidBackend},
};
use router_env::{instrument, tracing};

use crate::{core::payments::PaymentData, db::StorageInterface, types::storage as oss_storage};
use crate::{
core::payments::{types, PaymentData},
db::StorageInterface,
types::{storage as oss_storage, transformers::ForeignTryFrom},
};
static CONF_CACHE: StaticCache<VirInterpreterBackendCacheWrapper> = StaticCache::new();
use crate::{
core::{
Expand Down Expand Up @@ -55,10 +57,10 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list(
billing_address: Option<Address>,
response_payment_method_types: &mut [api_models::payment_methods::ResponsePaymentMethodsEnabled],
) -> ConditionalConfigResult<(
SurchargeMetadata,
types::SurchargeMetadata,
surcharge_decision_configs::MerchantSurchargeConfigs,
)> {
let mut surcharge_metadata = SurchargeMetadata::new(payment_attempt.attempt_id.clone());
let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone());
let algorithm_id = if let Some(id) = algorithm_ref.surcharge_config_algo_id {
id
} else {
Expand Down Expand Up @@ -101,20 +103,25 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list(
Some(card_network_type.card_network.clone());
let surcharge_output =
execute_dsl_and_get_conditional_config(backend_input.clone(), interpreter)?;
// let surcharge_details =
card_network_type.surcharge_details = surcharge_output
.surcharge_details
.map(|surcharge_details| {
get_surcharge_details_response(surcharge_details, payment_attempt).map(
|surcharge_details_response| {
surcharge_metadata.insert_surcharge_details(
&payment_methods_enabled.payment_method,
&payment_method_type_response.payment_method_type,
Some(&card_network_type.card_network),
surcharge_details_response.clone(),
);
surcharge_details_response
},
)
let surcharge_details =
get_surcharge_details_response(surcharge_details, payment_attempt)?;
surcharge_metadata.insert_surcharge_details(
&payment_methods_enabled.payment_method,
&payment_method_type_response.payment_method_type,
Some(&card_network_type.card_network),
surcharge_details.clone(),
);
SurchargeDetailsResponse::foreign_try_from((
&surcharge_details,
&payment_attempt,
))
.into_report()
.change_context(ConfigError::DslExecutionError)
.attach_printable("Error while constructing Surcharge response type")
})
.transpose()?;
}
Expand All @@ -124,17 +131,21 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list(
payment_method_type_response.surcharge_details = surcharge_output
.surcharge_details
.map(|surcharge_details| {
get_surcharge_details_response(surcharge_details, payment_attempt).map(
|surcharge_details_response| {
surcharge_metadata.insert_surcharge_details(
&payment_methods_enabled.payment_method,
&payment_method_type_response.payment_method_type,
None,
surcharge_details_response.clone(),
);
surcharge_details_response
},
)
let surcharge_details =
get_surcharge_details_response(surcharge_details, payment_attempt)?;
surcharge_metadata.insert_surcharge_details(
&payment_methods_enabled.payment_method,
&payment_method_type_response.payment_method_type,
None,
surcharge_details.clone(),
);
SurchargeDetailsResponse::foreign_try_from((
&surcharge_details,
&payment_attempt,
))
.into_report()
.change_context(ConfigError::DslExecutionError)
.attach_printable("Error while constructing Surcharge response type")
})
.transpose()?;
}
Expand All @@ -148,12 +159,12 @@ pub async fn perform_surcharge_decision_management_for_session_flow<O>(
algorithm_ref: routing::RoutingAlgorithmRef,
payment_data: &mut PaymentData<O>,
payment_method_type_list: &Vec<common_enums::PaymentMethodType>,
) -> ConditionalConfigResult<SurchargeMetadata>
) -> ConditionalConfigResult<types::SurchargeMetadata>
where
O: Send + Clone,
{
let mut surcharge_metadata =
SurchargeMetadata::new(payment_data.payment_attempt.attempt_id.clone());
types::SurchargeMetadata::new(payment_data.payment_attempt.attempt_id.clone());
let algorithm_id = if let Some(id) = algorithm_ref.surcharge_config_algo_id {
id
} else {
Expand Down Expand Up @@ -200,12 +211,12 @@ where
}

fn get_surcharge_details_response(
surcharge_details: SurchargeDetails,
surcharge_details: surcharge_decision_configs::SurchargeDetailsOutput,
payment_attempt: &oss_storage::PaymentAttempt,
) -> ConditionalConfigResult<SurchargeDetailsResponse> {
) -> ConditionalConfigResult<types::SurchargeDetails> {
let surcharge_amount = match surcharge_details.surcharge.clone() {
surcharge_decision_configs::Surcharge::Fixed(value) => value,
surcharge_decision_configs::Surcharge::Rate(percentage) => percentage
surcharge_decision_configs::SurchargeOutput::Fixed { amount } => amount,
surcharge_decision_configs::SurchargeOutput::Rate(percentage) => percentage
.apply_and_ceil_result(payment_attempt.amount)
.change_context(ConfigError::DslExecutionError)
.attach_printable("Failed to Calculate surcharge amount by applying percentage")?,
Expand All @@ -221,13 +232,13 @@ fn get_surcharge_details_response(
})
.transpose()?
.unwrap_or(0);
Ok(SurchargeDetailsResponse {
Ok(types::SurchargeDetails {
surcharge: match surcharge_details.surcharge {
surcharge_decision_configs::Surcharge::Fixed(surcharge_amount) => {
payment_methods::Surcharge::Fixed(surcharge_amount)
surcharge_decision_configs::SurchargeOutput::Fixed { amount } => {
common_utils_types::Surcharge::Fixed(amount)
}
surcharge_decision_configs::Surcharge::Rate(percentage) => {
payment_methods::Surcharge::Rate(percentage)
surcharge_decision_configs::SurchargeOutput::Rate(percentage) => {
common_utils_types::Surcharge::Rate(percentage)
}
},
tax_on_surcharge: surcharge_details.tax_on_surcharge,
Expand Down
Loading

0 comments on commit cd8d96a

Please sign in to comment.