feat(core-flows): create or update payment collections in RMA flows (#8676)

* feat(core-flows): create or update payment collections in RMA flows

* chore: change ui to pick payment link from unpaid payment collection

* Apply suggestions from code review

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>

* chore: fix mathbn

---------

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
Riqwan Thamir
2024-08-20 18:40:58 +02:00
committed by GitHub
co-authored by Carlos R. L. Rodrigues
parent 29830f0077
commit 430d9a38c4
10 changed files with 193 additions and 162 deletions
@@ -32,6 +32,7 @@ import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
export type ConfirmClaimRequestWorkflowInput = {
claim_id: string
@@ -385,6 +386,12 @@ export const confirmClaimRequestWorkflow = createWorkflow(
})
})
createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})
return new WorkflowResponse(orderPreview)
}
)
@@ -0,0 +1,109 @@
import { PaymentCollectionDTO } from "@medusajs/types"
import { MathBN, MedusaError, PaymentCollectionStatus } from "@medusajs/utils"
import {
createWorkflow,
transform,
when,
WorkflowData,
WorkflowResponse,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { updatePaymentCollectionStep } from "../../payment-collection"
import { createOrderPaymentCollectionWorkflow } from "./create-order-payment-collection"
export const createOrUpdateOrderPaymentCollectionWorkflowId =
"create-or-update-order-payment-collection"
/**
* This workflow creates or updates payment collection for an order.
*/
export const createOrUpdateOrderPaymentCollectionWorkflow = createWorkflow(
createOrUpdateOrderPaymentCollectionWorkflowId,
(
input: WorkflowData<{
order_id: string
amount?: number
}>
) => {
const order = useRemoteQueryStep({
entry_point: "order",
fields: ["id", "summary", "currency_code", "region_id"],
variables: { id: input.order_id },
throw_if_key_not_found: true,
list: false,
})
const orderPaymentCollections = useRemoteQueryStep({
entry_point: "order_payment_collection",
fields: ["payment_collection_id"],
variables: { order_id: order.id },
}).config({ name: "order-payment-collection-query" })
const orderPaymentCollectionIds = transform(
{ orderPaymentCollections },
({ orderPaymentCollections }) =>
orderPaymentCollections.map((opc) => opc.payment_collection_id)
)
const existingPaymentCollection = useRemoteQueryStep({
entry_point: "payment_collection",
fields: ["id", "status"],
variables: {
filters: {
id: orderPaymentCollectionIds,
status: [PaymentCollectionStatus.NOT_PAID],
},
},
list: false,
}).config({ name: "payment-collection-query" })
const amountPending = transform({ order, input }, ({ order, input }) => {
const pendingPayment =
order.summary.raw_pending_difference ?? order.summary.pending_difference
if (MathBN.gt(input.amount ?? 0, pendingPayment)) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Amount cannot be greater than ${pendingPayment}`
)
}
return pendingPayment
})
const updatedPaymentCollections = when(
{ existingPaymentCollection, amountPending },
({ existingPaymentCollection, amountPending }) => {
return !!existingPaymentCollection?.id && MathBN.gt(amountPending, 0)
}
).then(() => {
return updatePaymentCollectionStep({
selector: { id: existingPaymentCollection.id },
update: {
amount: amountPending,
},
}) as PaymentCollectionDTO[]
})
const createdPaymentCollection = when(
{ existingPaymentCollection, amountPending },
({ existingPaymentCollection, amountPending }) => {
return !!!existingPaymentCollection?.id && MathBN.gt(amountPending, 0)
}
).then(() => {
return createOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
amount: amountPending,
},
}) as PaymentCollectionDTO[]
})
const paymentCollections = transform(
{ updatedPaymentCollections, createdPaymentCollection },
({ updatedPaymentCollections, createdPaymentCollection }) =>
updatedPaymentCollections || createdPaymentCollection
)
return new WorkflowResponse(paymentCollections)
}
)
@@ -1,35 +1,13 @@
import { PaymentCollectionDTO } from "@medusajs/types"
import {
MathBN,
MedusaError,
Modules,
PaymentCollectionStatus,
} from "@medusajs/utils"
import { Modules } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createStep,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { createRemoteLinkStep, useRemoteQueryStep } from "../../common"
import { createPaymentCollectionsStep } from "../../definition"
/**
* This step validates that the order doesn't have an active payment collection.
*/
export const throwIfActivePaymentCollectionExists = createStep(
"validate-existing-payment-collection",
({ paymentCollection }: { paymentCollection: PaymentCollectionDTO }) => {
if (paymentCollection) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Active payment collections were found. Complete existing ones or delete them before proceeding.`
)
}
}
)
export const createOrderPaymentCollectionWorkflowId =
"create-order-payment-collection"
/**
@@ -40,7 +18,7 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
(
input: WorkflowData<{
order_id: string
amount?: number
amount: number
}>
) => {
const order = useRemoteQueryStep({
@@ -51,57 +29,12 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
list: false,
})
const orderPaymentCollections = useRemoteQueryStep({
entry_point: "order_payment_collection",
fields: ["payment_collection_id"],
variables: { order_id: order.id },
}).config({ name: "order-payment-collection-query" })
const orderPaymentCollectionIds = transform(
{ orderPaymentCollections },
({ orderPaymentCollections }) =>
orderPaymentCollections.map((opc) => opc.payment_collection_id)
)
const paymentCollection = useRemoteQueryStep({
entry_point: "payment_collection",
fields: ["id", "status"],
variables: {
filters: {
id: orderPaymentCollectionIds,
status: [PaymentCollectionStatus.NOT_PAID],
},
},
list: false,
}).config({ name: "payment-collection-query" })
throwIfActivePaymentCollectionExists({ paymentCollection })
const paymentCollectionData = transform(
{ order, input },
({ order, input }) => {
const pendingPayment = order.summary.raw_pending_difference
if (MathBN.lte(pendingPayment, 0)) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Cannot create a payment collection for amount less than 0`
)
}
if (
input.amount &&
MathBN.gt(input.amount ?? pendingPayment, pendingPayment)
) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Cannot create a payment collection for amount greater than ${pendingPayment}`
)
}
return {
currency_code: order.currency_code,
amount: input.amount ?? pendingPayment,
amount: input.amount,
region_id: order.region_id,
}
}
@@ -32,6 +32,7 @@ import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
export type ConfirmExchangeRequestWorkflowInput = {
exchange_id: string
@@ -381,6 +382,12 @@ export const confirmExchangeRequestWorkflow = createWorkflow(
})
})
createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})
return new WorkflowResponse(orderPreview)
}
)
@@ -15,6 +15,7 @@ import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
export type ConfirmOrderEditRequestWorkflowInput = {
order_id: string
@@ -161,6 +162,12 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
reserveInventoryStep(formatedInventoryItems)
createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})
return new WorkflowResponse(orderPreview)
}
)
@@ -28,6 +28,7 @@ import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
export type ConfirmReturnRequestWorkflowInput = {
return_id: string
@@ -259,6 +260,12 @@ export const confirmReturnRequestWorkflow = createWorkflow(
confirmOrderChanges({ changes: [orderChange], orderId: order.id })
)
createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})
return new WorkflowResponse(orderPreview)
}
)