use common_enums::MerchantStorageScheme; use common_utils::pii; use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable}; use masking::Secret; use time::PrimitiveDateTime; use crate::{enums as storage_enums, schema::mandate}; #[derive( Clone, Debug, Identifiable, Queryable, Selectable, serde::Serialize, serde::Deserialize, )] #[diesel(table_name = mandate, primary_key(mandate_id), check_for_backend(diesel::pg::Pg))] pub struct Mandate { pub mandate_id: String, pub customer_id: common_utils::id_type::CustomerId, pub merchant_id: common_utils::id_type::MerchantId, pub payment_method_id: String, pub mandate_status: storage_enums::MandateStatus, pub mandate_type: storage_enums::MandateType, pub customer_accepted_at: Option, pub customer_ip_address: Option>, pub customer_user_agent: Option, pub network_transaction_id: Option, pub previous_attempt_id: Option, pub created_at: PrimitiveDateTime, pub mandate_amount: Option, pub mandate_currency: Option, pub amount_captured: Option, pub connector: String, pub connector_mandate_id: Option, pub start_date: Option, pub end_date: Option, pub metadata: Option, pub connector_mandate_ids: Option, pub original_payment_id: Option, pub merchant_connector_id: Option, pub updated_by: Option, } #[derive( router_derive::Setter, Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay, serde::Serialize, serde::Deserialize, )] #[diesel(table_name = mandate)] pub struct MandateNew { pub mandate_id: String, pub customer_id: common_utils::id_type::CustomerId, pub merchant_id: common_utils::id_type::MerchantId, pub payment_method_id: String, pub mandate_status: storage_enums::MandateStatus, pub mandate_type: storage_enums::MandateType, pub customer_accepted_at: Option, pub customer_ip_address: Option>, pub customer_user_agent: Option, pub network_transaction_id: Option, pub previous_attempt_id: Option, pub created_at: Option, pub mandate_amount: Option, pub mandate_currency: Option, pub amount_captured: Option, pub connector: String, pub connector_mandate_id: Option, pub start_date: Option, pub end_date: Option, pub metadata: Option, pub connector_mandate_ids: Option, pub original_payment_id: Option, pub merchant_connector_id: Option, pub updated_by: Option, } impl MandateNew { pub fn update_storage_scheme(&mut self, storage_scheme: MerchantStorageScheme) { self.updated_by = Some(storage_scheme.to_string()); } } #[derive(Debug)] pub enum MandateUpdate { StatusUpdate { mandate_status: storage_enums::MandateStatus, }, CaptureAmountUpdate { amount_captured: Option, }, ConnectorReferenceUpdate { connector_mandate_ids: Option, }, ConnectorMandateIdUpdate { connector_mandate_id: Option, connector_mandate_ids: Option, payment_method_id: String, original_payment_id: Option, }, } impl MandateUpdate { pub fn convert_to_mandate_update( self, storage_scheme: MerchantStorageScheme, ) -> MandateUpdateInternal { let mut updated_object = MandateUpdateInternal::from(self); updated_object.updated_by = Some(storage_scheme.to_string()); updated_object } } #[derive(Clone, Eq, PartialEq, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] pub struct SingleUseMandate { pub amount: i64, pub currency: storage_enums::Currency, } #[derive( Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay, serde::Serialize, serde::Deserialize, )] #[diesel(table_name = mandate)] pub struct MandateUpdateInternal { mandate_status: Option, amount_captured: Option, connector_mandate_ids: Option, connector_mandate_id: Option, payment_method_id: Option, original_payment_id: Option, updated_by: Option, } impl From for MandateUpdateInternal { fn from(mandate_update: MandateUpdate) -> Self { match mandate_update { MandateUpdate::StatusUpdate { mandate_status } => Self { mandate_status: Some(mandate_status), connector_mandate_ids: None, amount_captured: None, connector_mandate_id: None, payment_method_id: None, original_payment_id: None, updated_by: None, }, MandateUpdate::CaptureAmountUpdate { amount_captured } => Self { mandate_status: None, amount_captured, connector_mandate_ids: None, connector_mandate_id: None, payment_method_id: None, original_payment_id: None, updated_by: None, }, MandateUpdate::ConnectorReferenceUpdate { connector_mandate_ids, } => Self { connector_mandate_ids, ..Default::default() }, MandateUpdate::ConnectorMandateIdUpdate { connector_mandate_id, connector_mandate_ids, payment_method_id, original_payment_id, } => Self { connector_mandate_id, connector_mandate_ids, payment_method_id: Some(payment_method_id), original_payment_id, ..Default::default() }, } } } impl MandateUpdateInternal { pub fn apply_changeset(self, source: Mandate) -> Mandate { let Self { mandate_status, amount_captured, connector_mandate_ids, connector_mandate_id, payment_method_id, original_payment_id, updated_by, } = self; Mandate { mandate_status: mandate_status.unwrap_or(source.mandate_status), amount_captured: amount_captured.map_or(source.amount_captured, Some), connector_mandate_ids: connector_mandate_ids.map_or(source.connector_mandate_ids, Some), connector_mandate_id: connector_mandate_id.map_or(source.connector_mandate_id, Some), payment_method_id: payment_method_id.unwrap_or(source.payment_method_id), original_payment_id: original_payment_id.map_or(source.original_payment_id, Some), updated_by: updated_by.map_or(source.updated_by, Some), ..source } } } impl From<&MandateNew> for Mandate { fn from(mandate_new: &MandateNew) -> Self { Self { mandate_id: mandate_new.mandate_id.clone(), customer_id: mandate_new.customer_id.clone(), merchant_id: mandate_new.merchant_id.clone(), payment_method_id: mandate_new.payment_method_id.clone(), mandate_status: mandate_new.mandate_status, mandate_type: mandate_new.mandate_type, customer_accepted_at: mandate_new.customer_accepted_at, customer_ip_address: mandate_new.customer_ip_address.clone(), customer_user_agent: mandate_new.customer_user_agent.clone(), network_transaction_id: mandate_new.network_transaction_id.clone(), previous_attempt_id: mandate_new.previous_attempt_id.clone(), created_at: mandate_new .created_at .unwrap_or_else(common_utils::date_time::now), mandate_amount: mandate_new.mandate_amount, mandate_currency: mandate_new.mandate_currency, amount_captured: mandate_new.amount_captured, connector: mandate_new.connector.clone(), connector_mandate_id: mandate_new.connector_mandate_id.clone(), start_date: mandate_new.start_date, end_date: mandate_new.end_date, metadata: mandate_new.metadata.clone(), connector_mandate_ids: mandate_new.connector_mandate_ids.clone(), original_payment_id: mandate_new.original_payment_id.clone(), merchant_connector_id: mandate_new.merchant_connector_id.clone(), updated_by: mandate_new.updated_by.clone(), } } }