filter payment methods based on obtainment type

This commit is contained in:
Djkáťo 2024-04-10 16:59:10 +02:00
parent 31eac1d7ab
commit b257d18c95
4 changed files with 116 additions and 12 deletions

View file

@ -1,4 +1,3 @@
[toolchain]
channel = "nightly"
channel = "nightly-2024-03-23"
targets = ["x86_64-unknown-linux-gnu"]
components = ["clippy"]

View file

@ -11,7 +11,7 @@ use tracing_subscriber::EnvFilter;
use saleor_app_sdk::{config::Config, locales::LocaleCode, manifest::AppManifest, SaleorApp};
use serde::{Deserialize, Serialize};
// Make our own error that wraps `anyhow::Error`.
pub struct AppError(anyhow::Error);
pub struct AppError(pub anyhow::Error);
// Tell axum how to convert `AppError` into a response.
impl IntoResponse for AppError {
@ -49,7 +49,7 @@ pub fn trace_to_std(config: &Config) -> anyhow::Result<()> {
Ok(())
}
#[derive(Debug, Clone, Sequence, Serialize, Deserialize)]
#[derive(Debug, Clone, Sequence, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum PaymentMethodType {
Accreditation,

View file

@ -2,6 +2,23 @@ use const_format::concatcp;
#[cynic::schema("saleor")]
mod schema {}
pub const fragment_checkout_details: &str = r#"
fragment CheckoutDetails on Checkout {
id
isShippingRequired
deliveryMethod {
... on Warehouse {
name
id
}
... on ShippingMethod {
id
name
}
}
}
"#;
pub const fragment_transaction_details: &str = r#"
fragment TransactionDetails on TransactionItem {
id
@ -48,6 +65,8 @@ fragment OrderDetails on Order {
paymentStatus
chargeStatus
canFinalize
shippingMethodName
collectionPointName
totalBalance {
currency
amount
@ -75,14 +94,20 @@ subscription PaymentGatewayInitializeSession {
data
amount
sourceObject {
...OrderDetails
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails
}
}
amount
}
}
}
"#,
fragment_order_details
fragment_order_details,
fragment_checkout_details
);
pub const sub_transaction_initialize_session: &str = concatcp!(
@ -92,7 +117,12 @@ subscription transactionInitializeSession {
... on TransactionInitializeSession {
data
sourceObject {
...OrderDetails
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails
}
}
transaction {
...TransactionDetails
@ -107,7 +137,8 @@ subscription transactionInitializeSession {
}
"#,
fragment_order_details,
fragment_transaction_details
fragment_transaction_details,
fragment_checkout_details
);
pub const sub_transaction_process_session: &str = concatcp!(
@ -120,7 +151,12 @@ subscription transactionProcessSession {
actionType
}
sourceObject {
...OrderDetails
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails
}
}
transaction {
...TransactionDetails
@ -131,7 +167,8 @@ subscription transactionProcessSession {
}
"#,
fragment_order_details,
fragment_transaction_details
fragment_transaction_details,
fragment_checkout_details,
);
pub const sub_transaction_charge_requested: &str = concatcp!(
@ -191,6 +228,12 @@ subscription transactionCancelationRequested {
fragment_transaction_details
);
#[derive(cynic::QueryFragment, Debug)]
pub struct Warehouse {
pub name: String,
pub id: cynic::Id,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "TransactionRefundRequested")]
pub struct TransactionRefundRequested2 {
@ -301,6 +344,12 @@ pub struct PaymentGatewayInitializeSession {
pub event: Option<Event6>,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct ShippingMethod {
pub id: cynic::Id,
pub name: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PaymentGatewayInitializeSession")]
pub struct PaymentGatewayInitializeSession2 {
@ -318,6 +367,8 @@ pub struct Order {
pub payment_status: PaymentChargeStatusEnum,
pub charge_status: OrderChargeStatusEnum,
pub can_finalize: bool,
pub shipping_method_name: Option<String>,
pub collection_point_name: Option<String>,
pub total_balance: Money,
}
@ -327,6 +378,13 @@ pub struct Money {
pub amount: f64,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct Checkout {
pub id: cynic::Id,
pub is_shipping_required: bool,
pub delivery_method: Option<DeliveryMethod>,
}
#[derive(cynic::InlineFragments, Debug)]
#[cynic(graphql_type = "Event")]
pub enum Event6 {
@ -374,8 +432,17 @@ pub enum Event {
Unknown,
}
#[derive(cynic::InlineFragments, Debug)]
pub enum DeliveryMethod {
Warehouse(Warehouse),
ShippingMethod(ShippingMethod),
#[cynic(fallback)]
Unknown,
}
#[derive(cynic::InlineFragments, Debug)]
pub enum OrderOrCheckout {
Checkout(Checkout),
Order(Order),
#[cynic(fallback)]
Unknown,

View file

@ -22,10 +22,12 @@ use tracing::{debug, error, info};
use crate::{
app::{
AppError, AppState, PaymentGatewayInitializeSessionData, TransactionInitializeSessionData,
AppError, AppState, PaymentGatewayInitializeSessionData, PaymentMethodType,
TransactionInitializeSessionData,
},
queries::{
event_transactions::{
DeliveryMethod, OrderOrCheckout, PaymentGatewayInitializeSession2,
TransactionCancelationRequested2, TransactionChargeRequested2,
TransactionFlowStrategyEnum, TransactionInitializeSession2, TransactionProcessSession2,
TransactionRefundRequested2,
@ -63,8 +65,44 @@ pub async fn webhooks(
// Json::from(serde_json::to_value(PaymentListGatewaysResponse(gateways))?)
// }
SyncWebhookEventType::PaymentGatewayInitializeSession => {
let session_data = serde_json::from_str::<PaymentGatewayInitializeSession2>(&body)?;
let mut filtered_payment_methods = state.active_payment_methods.clone();
//If obtainment method is via some sort of shipping, remove PaymentMethodType::Cash
//If obtainment method is collection in person at warehouse, remove PaymentMethodType::CODv
match session_data.source_object {
OrderOrCheckout::Order(o) => {
if o.shipping_method_name.is_some() {
filtered_payment_methods.retain(|p| p.typ != PaymentMethodType::Cash)
} else if o.collection_point_name.is_some() {
filtered_payment_methods.retain(|p| p.typ != PaymentMethodType::COD)
} else {
error!("Order has neither shipping_method_name or collection_point_name, how is it being payed for?");
}
}
OrderOrCheckout::Checkout(c) => {
if let Some(d) = c.delivery_method {
match d {
DeliveryMethod::Warehouse(_) => {
filtered_payment_methods
.retain(|p| p.typ != PaymentMethodType::COD);
}
DeliveryMethod::ShippingMethod(_) => {
filtered_payment_methods
.retain(|p| p.typ != PaymentMethodType::Cash);
}
DeliveryMethod::Unknown => {
error!("DeliveryMethod is neither");
}
}
}
}
OrderOrCheckout::Unknown => {
error!("OrderOrCheckout is neither");
}
}
let data = serde_json::to_value(PaymentGatewayInitializeSessionData {
payment_methods: state.active_payment_methods,
payment_methods: filtered_payment_methods,
})?;
Json::from(serde_json::to_value(
PaymentGatewayInitializeSessionResponse::<Value> { data: Some(data) },