feat(payout_link): return total_count in filtered payouts list API response (#5538)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Kashif
2024-08-14 20:03:10 +05:30
committed by GitHub
parent 92a07cf5e4
commit 34f648e29b
11 changed files with 349 additions and 37 deletions

View File

@ -1,5 +1,9 @@
#[cfg(feature = "olap")]
use api_models::enums::PayoutConnectors;
#[cfg(feature = "olap")]
use async_bb8_diesel::{AsyncConnection, AsyncRunQueryDsl};
#[cfg(feature = "olap")]
use common_utils::errors::ReportSwitchExt;
use common_utils::ext_traits::Encode;
#[cfg(feature = "olap")]
use diesel::{associations::HasTable, ExpressionMethods, QueryDsl};
@ -11,7 +15,7 @@ use diesel::{associations::HasTable, ExpressionMethods, QueryDsl};
use diesel::{JoinOnDsl, NullableExpressionMethods};
#[cfg(feature = "olap")]
use diesel_models::{
customers::Customer as DieselCustomer, query::generics::db_metrics,
customers::Customer as DieselCustomer, enums as storage_enums, query::generics::db_metrics,
schema::payouts::dsl as po_dsl,
};
use diesel_models::{
@ -348,6 +352,39 @@ impl<T: DatabaseStore> PayoutsInterface for KVRouterStore<T> {
.filter_payouts_by_time_range_constraints(merchant_id, time_range, storage_scheme)
.await
}
#[cfg(feature = "olap")]
async fn get_total_count_of_filtered_payouts(
&self,
merchant_id: &common_utils::id_type::MerchantId,
active_payout_ids: &[String],
connector: Option<Vec<PayoutConnectors>>,
currency: Option<Vec<storage_enums::Currency>>,
status: Option<Vec<storage_enums::PayoutStatus>>,
payout_method: Option<Vec<storage_enums::PayoutType>>,
) -> error_stack::Result<i64, StorageError> {
self.router_store
.get_total_count_of_filtered_payouts(
merchant_id,
active_payout_ids,
connector,
currency,
status,
payout_method,
)
.await
}
#[cfg(feature = "olap")]
async fn filter_active_payout_ids_by_constraints(
&self,
merchant_id: &common_utils::id_type::MerchantId,
constraints: &PayoutFetchConstraints,
) -> error_stack::Result<Vec<String>, StorageError> {
self.router_store
.filter_active_payout_ids_by_constraints(merchant_id, constraints)
.await
}
}
#[async_trait::async_trait]
@ -431,8 +468,6 @@ impl<T: DatabaseStore> PayoutsInterface for crate::RouterStore<T> {
filters: &PayoutFetchConstraints,
storage_scheme: MerchantStorageScheme,
) -> error_stack::Result<Vec<Payouts>, StorageError> {
use common_utils::errors::ReportSwitchExt;
let conn = connection::pg_connection_read(self).await.switch()?;
let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
@ -495,18 +530,6 @@ impl<T: DatabaseStore> PayoutsInterface for crate::RouterStore<T> {
query = query.offset(params.offset.into());
query = match &params.currency {
Some(currency) => {
query.filter(po_dsl::destination_currency.eq_any(currency.clone()))
}
None => query,
};
query = match &params.status {
Some(status) => query.filter(po_dsl::status.eq_any(status.clone())),
None => query,
};
if let Some(currency) = &params.currency {
query = query.filter(po_dsl::destination_currency.eq_any(currency.clone()));
}
@ -552,8 +575,6 @@ impl<T: DatabaseStore> PayoutsInterface for crate::RouterStore<T> {
storage_scheme: MerchantStorageScheme,
) -> error_stack::Result<Vec<(Payouts, PayoutAttempt, Option<DieselCustomer>)>, StorageError>
{
use common_utils::errors::ReportSwitchExt;
let conn = connection::pg_connection_read(self).await.switch()?;
let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
let mut query = DieselPayouts::table()
@ -561,7 +582,7 @@ impl<T: DatabaseStore> PayoutsInterface for crate::RouterStore<T> {
diesel_models::schema::payout_attempt::table
.on(poa_dsl::payout_id.eq(po_dsl::payout_id)),
)
.inner_join(
.left_join(
diesel_models::schema::customers::table
.on(cust_dsl::customer_id.nullable().eq(po_dsl::customer_id)),
)
@ -704,6 +725,122 @@ impl<T: DatabaseStore> PayoutsInterface for crate::RouterStore<T> {
self.filter_payouts_by_constraints(merchant_id, &payout_filters, storage_scheme)
.await
}
#[cfg(feature = "olap")]
#[instrument(skip_all)]
async fn get_total_count_of_filtered_payouts(
&self,
merchant_id: &common_utils::id_type::MerchantId,
active_payout_ids: &[String],
connector: Option<Vec<PayoutConnectors>>,
currency: Option<Vec<storage_enums::Currency>>,
status: Option<Vec<storage_enums::PayoutStatus>>,
payout_type: Option<Vec<storage_enums::PayoutType>>,
) -> error_stack::Result<i64, StorageError> {
let conn = self
.db_store
.get_replica_pool()
.get()
.await
.change_context(StorageError::DatabaseConnectionError)?;
let connector_strings = connector.as_ref().map(|connectors| {
connectors
.iter()
.map(|c| c.to_string())
.collect::<Vec<String>>()
});
DieselPayouts::get_total_count_of_payouts(
&conn,
merchant_id,
active_payout_ids,
connector_strings,
currency,
status,
payout_type,
)
.await
.map_err(|er| {
let new_err = diesel_error_to_data_error(er.current_context());
er.change_context(new_err)
})
}
#[cfg(feature = "olap")]
#[instrument(skip_all)]
async fn filter_active_payout_ids_by_constraints(
&self,
merchant_id: &common_utils::id_type::MerchantId,
constraints: &PayoutFetchConstraints,
) -> error_stack::Result<Vec<String>, StorageError> {
let conn = connection::pg_connection_read(self).await.switch()?;
let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
let mut query = DieselPayouts::table()
.inner_join(
diesel_models::schema::payout_attempt::table
.on(poa_dsl::payout_id.eq(po_dsl::payout_id)),
)
.left_join(
diesel_models::schema::customers::table
.on(cust_dsl::customer_id.nullable().eq(po_dsl::customer_id)),
)
.select(po_dsl::payout_id)
.filter(po_dsl::merchant_id.eq(merchant_id.to_owned()))
.order(po_dsl::created_at.desc())
.into_boxed();
query = match constraints {
PayoutFetchConstraints::Single { payout_id } => {
query.filter(po_dsl::payout_id.eq(payout_id.to_owned()))
}
PayoutFetchConstraints::List(params) => {
if let Some(customer_id) = &params.customer_id {
query = query.filter(po_dsl::customer_id.eq(customer_id.clone()));
}
if let Some(profile_id) = &params.profile_id {
query = query.filter(po_dsl::profile_id.eq(profile_id.clone()));
}
query = match params.starting_at {
Some(starting_at) => query.filter(po_dsl::created_at.ge(starting_at)),
None => query,
};
query = match params.ending_at {
Some(ending_at) => query.filter(po_dsl::created_at.le(ending_at)),
None => query,
};
query = match &params.currency {
Some(currency) => {
query.filter(po_dsl::destination_currency.eq_any(currency.clone()))
}
None => query,
};
query = match &params.status {
Some(status) => query.filter(po_dsl::status.eq_any(status.clone())),
None => query,
};
query
}
};
logger::debug!(filter = %diesel::debug_query::<diesel::pg::Pg,_>(&query).to_string());
db_metrics::track_database_call::<<DieselPayouts as HasTable>::Table, _, _>(
query.get_results_async::<String>(conn),
db_metrics::DatabaseOperation::Filter,
)
.await
.map_err(|er| {
StorageError::DatabaseError(
error_stack::report!(diesel_models::errors::DatabaseError::from(er))
.attach_printable("Error filtering payout records"),
)
.into()
})
}
}
impl DataModelExt for Payouts {