Skip to content

Commit

Permalink
feat(router): add profile id and extra filters in lists (#2379)
Browse files Browse the repository at this point in the history
  • Loading branch information
apoorvdixit88 authored Oct 4, 2023
1 parent 409913f commit ab2cde7
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 108 deletions.
2 changes: 2 additions & 0 deletions crates/api_models/src/disputes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub struct DisputeEvidenceBlock {
pub struct DisputeListConstraints {
/// limit on the number of objects to return
pub limit: Option<i64>,
/// The identifier for business profile
pub profile_id: Option<String>,
/// status of the dispute
pub dispute_status: Option<DisputeStatus>,
/// stage of the dispute
Expand Down
17 changes: 14 additions & 3 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1999,10 +1999,13 @@ pub struct PaymentListResponseV2 {
}

#[derive(Clone, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PaymentListFilterConstraints {
/// The identifier for payment
pub payment_id: Option<String>,
/// The identifier for business profile
pub profile_id: Option<String>,
/// The identifier for customer
pub customer_id: Option<String>,
/// The limit on the number of objects. The default limit is 10 and max limit is 20
#[serde(default = "default_limit")]
pub limit: u32,
Expand All @@ -2015,10 +2018,14 @@ pub struct PaymentListFilterConstraints {
pub connector: Option<Vec<api_enums::Connector>>,
/// The list of currencies to filter payments list
pub currency: Option<Vec<enums::Currency>>,
/// The list of payment statuses to filter payments list
/// The list of payment status to filter payments list
pub status: Option<Vec<enums::IntentStatus>>,
/// The list of payment methods to filter payments list
pub payment_methods: Option<Vec<enums::PaymentMethod>>,
pub payment_method: Option<Vec<enums::PaymentMethod>>,
/// The list of payment method types to filter payments list
pub payment_method_type: Option<Vec<enums::PaymentMethodType>>,
/// The list of authentication types to filter payments list
pub authentication_type: Option<Vec<enums::AuthenticationType>>,
}
#[derive(Clone, Debug, serde::Serialize)]
pub struct PaymentListFilters {
Expand All @@ -2030,6 +2037,10 @@ pub struct PaymentListFilters {
pub status: Vec<enums::IntentStatus>,
/// The list of available payment method filters
pub payment_method: Vec<enums::PaymentMethod>,
/// The list of available payment method types
pub payment_method_type: Vec<enums::PaymentMethodType>,
/// The list of available authentication types
pub authentication_type: Vec<enums::AuthenticationType>,
}

#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
Expand Down
2 changes: 2 additions & 0 deletions crates/api_models/src/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ pub struct RefundListRequest {
pub payment_id: Option<String>,
/// The identifier for the refund
pub refund_id: Option<String>,
/// The identifier for business profile
pub profile_id: Option<String>,
/// Limit on the number of objects to return
pub limit: Option<i64>,
/// The starting point within a list of objects
Expand Down
7 changes: 6 additions & 1 deletion crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,15 @@ pub trait PaymentAttemptInterface {
storage_scheme: MerchantStorageScheme,
) -> error_stack::Result<PaymentListFilters, errors::StorageError>;

#[allow(clippy::too_many_arguments)]
async fn get_total_count_of_filtered_payment_attempts(
&self,
merchant_id: &str,
active_attempt_ids: &[String],
connector: Option<Vec<Connector>>,
payment_methods: Option<Vec<storage_enums::PaymentMethod>>,
payment_method: Option<Vec<storage_enums::PaymentMethod>>,
payment_method_type: Option<Vec<storage_enums::PaymentMethodType>>,
authentication_type: Option<Vec<storage_enums::AuthenticationType>>,
storage_scheme: MerchantStorageScheme,
) -> error_stack::Result<i64, errors::StorageError>;
}
Expand Down Expand Up @@ -147,6 +150,8 @@ pub struct PaymentListFilters {
pub currency: Vec<storage_enums::Currency>,
pub status: Vec<storage_enums::IntentStatus>,
pub payment_method: Vec<storage_enums::PaymentMethod>,
pub payment_method_type: Vec<storage_enums::PaymentMethodType>,
pub authentication_type: Vec<storage_enums::AuthenticationType>,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
Expand Down
64 changes: 38 additions & 26 deletions crates/data_models/src/payments/payment_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,57 +391,66 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
}

pub enum PaymentIntentFetchConstraints {
Single {
payment_intent_id: String,
},
List {
offset: u32,
starting_at: Option<PrimitiveDateTime>,
ending_at: Option<PrimitiveDateTime>,
connector: Option<Vec<api_models::enums::Connector>>,
currency: Option<Vec<storage_enums::Currency>>,
status: Option<Vec<storage_enums::IntentStatus>>,
payment_methods: Option<Vec<storage_enums::PaymentMethod>>,
customer_id: Option<String>,
starting_after_id: Option<String>,
ending_before_id: Option<String>,
limit: Option<u32>,
},
Single { payment_intent_id: String },
List(Box<PaymentIntentListParams>),
}

pub struct PaymentIntentListParams {
pub offset: u32,
pub starting_at: Option<PrimitiveDateTime>,
pub ending_at: Option<PrimitiveDateTime>,
pub connector: Option<Vec<api_models::enums::Connector>>,
pub currency: Option<Vec<storage_enums::Currency>>,
pub status: Option<Vec<storage_enums::IntentStatus>>,
pub payment_method: Option<Vec<storage_enums::PaymentMethod>>,
pub payment_method_type: Option<Vec<storage_enums::PaymentMethodType>>,
pub authentication_type: Option<Vec<storage_enums::AuthenticationType>>,
pub profile_id: Option<String>,
pub customer_id: Option<String>,
pub starting_after_id: Option<String>,
pub ending_before_id: Option<String>,
pub limit: Option<u32>,
}

impl From<api_models::payments::PaymentListConstraints> for PaymentIntentFetchConstraints {
fn from(value: api_models::payments::PaymentListConstraints) -> Self {
Self::List {
Self::List(Box::new(PaymentIntentListParams {
offset: 0,
starting_at: value.created_gte.or(value.created_gt).or(value.created),
ending_at: value.created_lte.or(value.created_lt).or(value.created),
connector: None,
currency: None,
status: None,
payment_methods: None,
payment_method: None,
payment_method_type: None,
authentication_type: None,
profile_id: None,
customer_id: value.customer_id,
starting_after_id: value.starting_after,
ending_before_id: value.ending_before,
limit: Some(std::cmp::min(value.limit, PAYMENTS_LIST_MAX_LIMIT_V1)),
}
}))
}
}

impl From<api_models::payments::TimeRange> for PaymentIntentFetchConstraints {
fn from(value: api_models::payments::TimeRange) -> Self {
Self::List {
Self::List(Box::new(PaymentIntentListParams {
offset: 0,
starting_at: Some(value.start_time),
ending_at: value.end_time,
connector: None,
currency: None,
status: None,
payment_methods: None,
payment_method: None,
payment_method_type: None,
authentication_type: None,
profile_id: None,
customer_id: None,
starting_after_id: None,
ending_before_id: None,
limit: None,
}
}))
}
}

Expand All @@ -450,19 +459,22 @@ impl From<api_models::payments::PaymentListFilterConstraints> for PaymentIntentF
if let Some(payment_intent_id) = value.payment_id {
Self::Single { payment_intent_id }
} else {
Self::List {
Self::List(Box::new(PaymentIntentListParams {
offset: value.offset.unwrap_or_default(),
starting_at: value.time_range.map(|t| t.start_time),
ending_at: value.time_range.and_then(|t| t.end_time),
connector: value.connector,
currency: value.currency,
status: value.status,
payment_methods: value.payment_methods,
customer_id: None,
payment_method: value.payment_method,
payment_method_type: value.payment_method_type,
authentication_type: value.authentication_type,
profile_id: value.profile_id,
customer_id: value.customer_id,
starting_after_id: None,
ending_before_id: None,
limit: Some(std::cmp::min(value.limit, PAYMENTS_LIST_MAX_LIMIT_V2)),
}
}))
}
}
}
38 changes: 38 additions & 0 deletions crates/diesel_models/src/query/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ impl PaymentAttempt {
Vec<enums::Currency>,
Vec<IntentStatus>,
Vec<enums::PaymentMethod>,
Vec<enums::PaymentMethodType>,
Vec<enums::AuthenticationType>,
)> {
let active_attempts: Vec<String> = pi
.iter()
Expand Down Expand Up @@ -272,11 +274,39 @@ impl PaymentAttempt {
.flatten()
.collect::<Vec<enums::PaymentMethod>>();

let filter_payment_method_type = filter
.clone()
.select(dsl::payment_method_type)
.distinct()
.get_results_async::<Option<enums::PaymentMethodType>>(conn)
.await
.into_report()
.change_context(DatabaseError::Others)
.attach_printable("Error filtering records by payment method type")?
.into_iter()
.flatten()
.collect::<Vec<enums::PaymentMethodType>>();

let filter_authentication_type = filter
.clone()
.select(dsl::authentication_type)
.distinct()
.get_results_async::<Option<enums::AuthenticationType>>(conn)
.await
.into_report()
.change_context(DatabaseError::Others)
.attach_printable("Error filtering records by authentication type")?
.into_iter()
.flatten()
.collect::<Vec<enums::AuthenticationType>>();

Ok((
filter_connector,
filter_currency,
intent_status,
filter_payment_method,
filter_payment_method_type,
filter_authentication_type,
))
}
pub async fn get_total_count_of_attempts(
Expand All @@ -285,6 +315,8 @@ impl PaymentAttempt {
active_attempt_ids: &[String],
connector: Option<Vec<String>>,
payment_method: Option<Vec<enums::PaymentMethod>>,
payment_method_type: Option<Vec<enums::PaymentMethodType>>,
authentication_type: Option<Vec<enums::AuthenticationType>>,
) -> StorageResult<i64> {
let mut filter = <Self as HasTable>::table()
.count()
Expand All @@ -299,6 +331,12 @@ impl PaymentAttempt {
if let Some(payment_method) = payment_method.clone() {
filter = filter.filter(dsl::payment_method.eq_any(payment_method));
}
if let Some(payment_method_type) = payment_method_type.clone() {
filter = filter.filter(dsl::payment_method_type.eq_any(payment_method_type));
}
if let Some(authentication_type) = authentication_type.clone() {
filter = filter.filter(dsl::authentication_type.eq_any(authentication_type));
}
router_env::logger::debug!(query = %debug_query::<Pg, _>(&filter).to_string());

db_metrics::track_database_call::<<Self as HasTable>::Table, _, _>(
Expand Down
6 changes: 5 additions & 1 deletion crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1651,7 +1651,9 @@ pub async fn apply_filters_on_payments(
&merchant.merchant_id,
&active_attempt_ids,
constraints.connector,
constraints.payment_methods,
constraints.payment_method,
constraints.payment_method_type,
constraints.authentication_type,
merchant.storage_scheme,
)
.await
Expand Down Expand Up @@ -1698,6 +1700,8 @@ pub async fn get_filters_for_payments(
currency: filters.currency,
status: filters.status,
payment_method: filters.payment_method,
payment_method_type: filters.payment_method_type,
authentication_type: filters.authentication_type,
},
))
}
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/db/dispute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ mod tests {
received_time_gt: None,
received_time_lte: None,
received_time_gte: None,
profile_id: None,
},
)
.await
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/db/refund.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ impl RefundInterface for MockDb {
.clone()
.map_or(true, |id| id == refund.refund_id)
})
.filter(|refund| refund_details.profile_id == refund.profile_id)
.filter(|refund| {
refund.created_at
>= refund_details.time_range.map_or(
Expand Down Expand Up @@ -1025,6 +1026,7 @@ impl RefundInterface for MockDb {
.clone()
.map_or(true, |id| id == refund.refund_id)
})
.filter(|refund| refund_details.profile_id == refund.profile_id)
.filter(|refund| {
refund.created_at
>= refund_details.time_range.map_or(
Expand Down
3 changes: 3 additions & 0 deletions crates/router/src/types/storage/dispute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ impl DisputeDbExt for Dispute {
.order(dsl::modified_at.desc())
.into_boxed();

if let Some(profile_id) = dispute_list_constraints.profile_id {
filter = filter.filter(dsl::profile_id.eq(profile_id));
}
if let Some(received_time) = dispute_list_constraints.received_time {
filter = filter.filter(dsl::created_at.eq(received_time));
}
Expand Down
14 changes: 14 additions & 0 deletions crates/router/src/types/storage/refund.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ impl RefundDbExt for Refund {
filter = filter.limit(limit).offset(offset);
}
};
match &refund_list_details.profile_id {
Some(profile_id) => {
filter = filter
.filter(dsl::profile_id.eq(profile_id.to_owned()))
.limit(limit)
.offset(offset);
}
None => {
filter = filter.limit(limit).offset(offset);
}
};

if let Some(time_range) = refund_list_details.time_range {
filter = filter.filter(dsl::created_at.ge(time_range.start_time));
Expand Down Expand Up @@ -175,6 +186,9 @@ impl RefundDbExt for Refund {
if let Some(ref_id) = &refund_list_details.refund_id {
filter = filter.filter(dsl::refund_id.eq(ref_id.to_owned()));
}
if let Some(profile_id) = &refund_list_details.profile_id {
filter = filter.filter(dsl::profile_id.eq(profile_id.to_owned()));
}

if let Some(time_range) = refund_list_details.time_range {
filter = filter.filter(dsl::created_at.ge(time_range.start_time));
Expand Down
6 changes: 4 additions & 2 deletions crates/storage_impl/src/mock_db/payment_attempt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use api_models::enums::{Connector, PaymentMethod};
use api_models::enums::{AuthenticationType, Connector, PaymentMethod, PaymentMethodType};
use common_utils::errors::CustomResult;
use data_models::{
errors::StorageError,
Expand Down Expand Up @@ -39,7 +39,9 @@ impl PaymentAttemptInterface for MockDb {
_merchant_id: &str,
_active_attempt_ids: &[String],
_connector: Option<Vec<Connector>>,
_payment_methods: Option<Vec<PaymentMethod>>,
_payment_method: Option<Vec<PaymentMethod>>,
_payment_method_type: Option<Vec<PaymentMethodType>>,
_authentication_type: Option<Vec<AuthenticationType>>,
_storage_scheme: MerchantStorageScheme,
) -> CustomResult<i64, StorageError> {
Err(StorageError::MockDbError)?
Expand Down
Loading

0 comments on commit ab2cde7

Please sign in to comment.