Skip to content

Commit

Permalink
feat(core-flows): create or update payment collections in RMA flows
Browse files Browse the repository at this point in the history
  • Loading branch information
riqwan committed Aug 20, 2024
1 parent 5f310c0 commit ae82591
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 92 deletions.
57 changes: 36 additions & 21 deletions integration-tests/http/__tests__/claims/claims.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,11 @@ medusaIntegrationTestRunner({
adminHeaders
)

await api.post(`/admin/claims/${claimId2}/request`, {}, adminHeaders)
const testRes = await api.post(
`/admin/claims/${claimId2}/request`,
{},
adminHeaders
)

claimId = baseClaim.id
item = order.items[0]
Expand Down Expand Up @@ -682,6 +686,17 @@ medusaIntegrationTestRunner({
await api.get(`/admin/orders/${order.id}`, adminHeaders)
).data.order

const paymentCollections = fulfillOrder.payment_collections

expect(paymentCollections).toHaveLength(1)
expect(paymentCollections[0]).toEqual(
expect.objectContaining({
status: "not_paid",
amount: 171.5,
currency_code: "usd",
})
)

const fulfillableItem = fulfillOrder.items.find(
(item) => item.detail.fulfilled_quantity === 0
)
Expand Down Expand Up @@ -721,41 +736,40 @@ medusaIntegrationTestRunner({
})

it("should create a payment collection successfully and throw on multiple", async () => {
const paymentDelta = 171.5
const orderForPayment = (
await api.get(`/admin/orders/${order.id}`, adminHeaders)
).data.order

const paymentCollections = orderForPayment.payment_collections

expect(paymentCollections).toHaveLength(1)
expect(paymentCollections[0]).toEqual(
expect.objectContaining({
status: "not_paid",
amount: 171.5,
currency_code: "usd",
})
)

const paymentCollection = (
await api.post(
`/admin/payment-collections`,
{ order_id: order.id },
{ order_id: order.id, amount: 100 },
adminHeaders
)
).data.payment_collection

expect(paymentCollection).toEqual(
expect.objectContaining({
currency_code: "usd",
amount: paymentDelta,
payment_sessions: [],
amount: 100,
status: "not_paid",
})
)

const { response } = await api
.post(
`/admin/payment-collections`,
{ order_id: order.id },
adminHeaders
)
.catch((e) => e)

expect(response.data).toEqual({
type: "not_allowed",
message:
"Active payment collections were found. Complete existing ones or delete them before proceeding.",
})

const deleted = (
await api.delete(
`/admin/payment-collections/${paymentCollection.id}`,
`/admin/payment-collections/${paymentCollections[0].id}`,
adminHeaders
)
).data
Expand Down Expand Up @@ -973,7 +987,8 @@ medusaIntegrationTestRunner({
},
adminHeaders
)
await api.post(

const { response } = await api.post(
`/admin/claims/${baseClaim.id}/request`,
{},
adminHeaders
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -385,6 +386,12 @@ export const confirmClaimRequestWorkflow = createWorkflow(
})
})

createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})

return new WorkflowResponse(orderPreview)
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { PaymentCollectionDTO } from "@medusajs/types"
import { 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.pending_difference

if (input.amount && input.amount > 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 && amountPending > 0
}
).then(() => {
return updatePaymentCollectionStep({
selector: { id: existingPaymentCollection.id },
update: {
amount: amountPending,
},
}) as PaymentCollectionDTO[]
})

const createdPaymentCollection = when(
{ existingPaymentCollection, amountPending },
({ existingPaymentCollection, amountPending }) => {
return !!!existingPaymentCollection?.id && 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)
}
)
Original file line number Diff line number Diff line change
@@ -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"
/**
Expand All @@ -40,7 +18,7 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
(
input: WorkflowData<{
order_id: string
amount?: number
amount: number
}>
) => {
const order = useRemoteQueryStep({
Expand All @@ -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,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -381,6 +382,12 @@ export const confirmExchangeRequestWorkflow = createWorkflow(
})
})

createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})

return new WorkflowResponse(orderPreview)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -161,6 +162,12 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(

reserveInventoryStep(formatedInventoryItems)

createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
input: {
order_id: order.id,
},
})

return new WorkflowResponse(orderPreview)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
)
Loading

0 comments on commit ae82591

Please sign in to comment.