mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(payments): add support for profile aggregates (#5845)
This commit is contained in:
@ -71,6 +71,7 @@ pub trait PaymentIntentInterface {
|
|||||||
async fn get_intent_status_with_count(
|
async fn get_intent_status_with_count(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &id_type::MerchantId,
|
merchant_id: &id_type::MerchantId,
|
||||||
|
profile_id_list: Option<Vec<id_type::ProfileId>>,
|
||||||
constraints: &api_models::payments::TimeRange,
|
constraints: &api_models::payments::TimeRange,
|
||||||
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, errors::StorageError>;
|
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, errors::StorageError>;
|
||||||
|
|
||||||
|
|||||||
@ -3234,11 +3234,12 @@ pub async fn get_payment_filters(
|
|||||||
pub async fn get_aggregates_for_payments(
|
pub async fn get_aggregates_for_payments(
|
||||||
state: SessionState,
|
state: SessionState,
|
||||||
merchant: domain::MerchantAccount,
|
merchant: domain::MerchantAccount,
|
||||||
|
profile_id_list: Option<Vec<id_type::ProfileId>>,
|
||||||
time_range: api::TimeRange,
|
time_range: api::TimeRange,
|
||||||
) -> RouterResponse<api::PaymentsAggregateResponse> {
|
) -> RouterResponse<api::PaymentsAggregateResponse> {
|
||||||
let db = state.store.as_ref();
|
let db = state.store.as_ref();
|
||||||
let intent_status_with_count = db
|
let intent_status_with_count = db
|
||||||
.get_intent_status_with_count(merchant.get_id(), &time_range)
|
.get_intent_status_with_count(merchant.get_id(), profile_id_list, &time_range)
|
||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||||
|
|
||||||
|
|||||||
@ -1640,10 +1640,11 @@ impl PaymentIntentInterface for KafkaStore {
|
|||||||
async fn get_intent_status_with_count(
|
async fn get_intent_status_with_count(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &id_type::MerchantId,
|
merchant_id: &id_type::MerchantId,
|
||||||
|
profile_id_list: Option<Vec<id_type::ProfileId>>,
|
||||||
time_range: &api_models::payments::TimeRange,
|
time_range: &api_models::payments::TimeRange,
|
||||||
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, errors::DataStorageError> {
|
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, errors::DataStorageError> {
|
||||||
self.diesel_store
|
self.diesel_store
|
||||||
.get_intent_status_with_count(merchant_id, time_range)
|
.get_intent_status_with_count(merchant_id, profile_id_list, time_range)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -547,6 +547,10 @@ impl Payments {
|
|||||||
.service(web::resource("/filter").route(web::post().to(get_filters_for_payments)))
|
.service(web::resource("/filter").route(web::post().to(get_filters_for_payments)))
|
||||||
.service(web::resource("/v2/filter").route(web::get().to(get_payment_filters)))
|
.service(web::resource("/v2/filter").route(web::get().to(get_payment_filters)))
|
||||||
.service(web::resource("/aggregate").route(web::get().to(get_payments_aggregates)))
|
.service(web::resource("/aggregate").route(web::get().to(get_payments_aggregates)))
|
||||||
|
.service(
|
||||||
|
web::resource("/profile/aggregate")
|
||||||
|
.route(web::get().to(get_payments_aggregates_profile)),
|
||||||
|
)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/v2/profile/filter")
|
web::resource("/v2/profile/filter")
|
||||||
.route(web::get().to(get_payment_filters_profile)),
|
.route(web::get().to(get_payment_filters_profile)),
|
||||||
|
|||||||
@ -1341,7 +1341,7 @@ pub async fn get_payments_aggregates(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, auth: auth::AuthenticationData, req, _| {
|
|state, auth: auth::AuthenticationData, req, _| {
|
||||||
payments::get_aggregates_for_payments(state, auth.merchant_account, req)
|
payments::get_aggregates_for_payments(state, auth.merchant_account, None, req)
|
||||||
},
|
},
|
||||||
&auth::JWTAuth {
|
&auth::JWTAuth {
|
||||||
permission: Permission::PaymentRead,
|
permission: Permission::PaymentRead,
|
||||||
@ -2074,3 +2074,34 @@ impl GetLockingInput for payment_types::PaymentsManualUpdateRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsAggregate))]
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
pub async fn get_payments_aggregates_profile(
|
||||||
|
state: web::Data<app::AppState>,
|
||||||
|
req: actix_web::HttpRequest,
|
||||||
|
payload: web::Query<payment_types::TimeRange>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let flow = Flow::PaymentsAggregate;
|
||||||
|
let payload = payload.into_inner();
|
||||||
|
Box::pin(api::server_wrap(
|
||||||
|
flow,
|
||||||
|
state,
|
||||||
|
&req,
|
||||||
|
payload,
|
||||||
|
|state, auth: auth::AuthenticationData, req, _| {
|
||||||
|
payments::get_aggregates_for_payments(
|
||||||
|
state,
|
||||||
|
auth.merchant_account,
|
||||||
|
auth.profile_id.map(|profile_id| vec![profile_id]),
|
||||||
|
req,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
&auth::JWTAuth {
|
||||||
|
permission: Permission::PaymentRead,
|
||||||
|
minimum_entity_level: EntityType::Profile,
|
||||||
|
},
|
||||||
|
api_locking::LockAction::NotApplicable,
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ impl PaymentIntentInterface for MockDb {
|
|||||||
async fn get_intent_status_with_count(
|
async fn get_intent_status_with_count(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &common_utils::id_type::MerchantId,
|
_merchant_id: &common_utils::id_type::MerchantId,
|
||||||
|
_profile_id_list: Option<Vec<common_utils::id_type::ProfileId>>,
|
||||||
_time_range: &api_models::payments::TimeRange,
|
_time_range: &api_models::payments::TimeRange,
|
||||||
) -> CustomResult<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
) -> CustomResult<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
||||||
// [#172]: Implement function for `MockDb`
|
// [#172]: Implement function for `MockDb`
|
||||||
|
|||||||
@ -350,10 +350,11 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
|
|||||||
async fn get_intent_status_with_count(
|
async fn get_intent_status_with_count(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
|
profile_id_list: Option<Vec<common_utils::id_type::ProfileId>>,
|
||||||
time_range: &api_models::payments::TimeRange,
|
time_range: &api_models::payments::TimeRange,
|
||||||
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
||||||
self.router_store
|
self.router_store
|
||||||
.get_intent_status_with_count(merchant_id, time_range)
|
.get_intent_status_with_count(merchant_id, profile_id_list, time_range)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,6 +671,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
|
|||||||
async fn get_intent_status_with_count(
|
async fn get_intent_status_with_count(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &common_utils::id_type::MerchantId,
|
merchant_id: &common_utils::id_type::MerchantId,
|
||||||
|
profile_id_list: Option<Vec<common_utils::id_type::ProfileId>>,
|
||||||
time_range: &api_models::payments::TimeRange,
|
time_range: &api_models::payments::TimeRange,
|
||||||
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
) -> error_stack::Result<Vec<(common_enums::IntentStatus, i64)>, StorageError> {
|
||||||
let conn = connection::pg_connection_read(self).await.switch()?;
|
let conn = connection::pg_connection_read(self).await.switch()?;
|
||||||
@ -681,6 +683,10 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
|
|||||||
.filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
|
.filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
|
||||||
.into_boxed();
|
.into_boxed();
|
||||||
|
|
||||||
|
if let Some(profile_id) = profile_id_list {
|
||||||
|
query = query.filter(pi_dsl::profile_id.eq_any(profile_id));
|
||||||
|
}
|
||||||
|
|
||||||
query = query.filter(pi_dsl::created_at.ge(time_range.start_time));
|
query = query.filter(pi_dsl::created_at.ge(time_range.start_time));
|
||||||
|
|
||||||
query = match time_range.end_time {
|
query = match time_range.end_time {
|
||||||
|
|||||||
Reference in New Issue
Block a user