Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(router): add profile id and extra filters in lists #2379

Merged
merged 7 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading