feat(core-flows,dashboard,types,medusa): delete shipping methods when all inbound/outbound items are deleted (#9106)
* feat(core-flows,dashboard,types,medusa): delete shipping methods when all inbound/outbound items are deleted * chore: fix specs
This commit is contained in:
@@ -838,6 +838,8 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
|
||||
describe("with only outbound items", () => {
|
||||
let orderResult
|
||||
|
||||
beforeEach(async () => {
|
||||
await api.post(
|
||||
`/admin/orders/${order.id}/fulfillments`,
|
||||
@@ -906,7 +908,7 @@ medusaIntegrationTestRunner({
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
const { data } = await api.post(
|
||||
`/admin/claims/${claimId}/outbound/items`,
|
||||
{
|
||||
items: [
|
||||
@@ -965,7 +967,7 @@ medusaIntegrationTestRunner({
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
let orderResult = (
|
||||
orderResult = (
|
||||
await api.get(`/admin/orders/${order.id}`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
@@ -1040,9 +1042,55 @@ medusaIntegrationTestRunner({
|
||||
|
||||
expect(orderResult.fulfillment_status).toEqual("shipped")
|
||||
})
|
||||
|
||||
it("should remove outbound shipping method when outbound items are completely removed", async () => {
|
||||
orderResult = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const claimItems = orderResult.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "ITEM_ADD")
|
||||
)
|
||||
|
||||
const claimShippingMethods = orderResult.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "SHIPPING_ADD")
|
||||
)
|
||||
|
||||
expect(claimItems).toHaveLength(1)
|
||||
expect(claimShippingMethods).toHaveLength(1)
|
||||
|
||||
await api.delete(
|
||||
`/admin/claims/${claimId}/outbound/items/${claimItems[0].actions[0].id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
orderResult = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const updatedClaimItems = orderResult.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "ITEM_ADD")
|
||||
)
|
||||
|
||||
const updatedClaimShippingMethods =
|
||||
orderResult.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) => action.action === "SHIPPING_ADD"
|
||||
)
|
||||
)
|
||||
|
||||
expect(updatedClaimItems).toHaveLength(0)
|
||||
expect(updatedClaimShippingMethods).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("with only inbound items", () => {
|
||||
let orderResult
|
||||
|
||||
beforeEach(async () => {
|
||||
await api.post(
|
||||
`/admin/orders/${order.id}/fulfillments`,
|
||||
@@ -1072,7 +1120,7 @@ medusaIntegrationTestRunner({
|
||||
claimId = baseClaim.id
|
||||
item = order.items[0]
|
||||
|
||||
let result = await api.post(
|
||||
await api.post(
|
||||
`/admin/claims/${claimId}/inbound/items`,
|
||||
{
|
||||
items: [
|
||||
@@ -1091,7 +1139,9 @@ medusaIntegrationTestRunner({
|
||||
{ shipping_option_id: returnShippingOption.id },
|
||||
adminHeaders
|
||||
)
|
||||
})
|
||||
|
||||
it("test inbound only", async () => {
|
||||
// Claim Items
|
||||
await api.post(
|
||||
`/admin/claims/${claimId}/claim-items`,
|
||||
@@ -1109,20 +1159,18 @@ medusaIntegrationTestRunner({
|
||||
|
||||
await api.post(`/admin/claims/${claimId}/request`, {}, adminHeaders)
|
||||
|
||||
result = (
|
||||
const claims = (
|
||||
await api.get(
|
||||
`/admin/claims?fields=*claim_items,*additional_items`,
|
||||
adminHeaders
|
||||
)
|
||||
).data.claims
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
expect(result[0].additional_items).toHaveLength(0)
|
||||
expect(result[0].claim_items).toHaveLength(1)
|
||||
expect(result[0].canceled_at).toBeNull()
|
||||
})
|
||||
expect(claims).toHaveLength(1)
|
||||
expect(claims[0].additional_items).toHaveLength(0)
|
||||
expect(claims[0].claim_items).toHaveLength(1)
|
||||
expect(claims[0].canceled_at).toBeNull()
|
||||
|
||||
it("test inbound only", async () => {
|
||||
const orderCheck = (
|
||||
await api.get(`/admin/orders/${order.id}`, adminHeaders)
|
||||
).data.order
|
||||
@@ -1137,6 +1185,49 @@ medusaIntegrationTestRunner({
|
||||
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
|
||||
it("should remove inbound shipping method when inbound items are completely removed", async () => {
|
||||
orderResult = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const returnItems = orderResult.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "RETURN_ITEM")
|
||||
)
|
||||
const returnShippingMethods = orderResult.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "SHIPPING_ADD")
|
||||
)
|
||||
|
||||
expect(returnItems).toHaveLength(1)
|
||||
expect(returnShippingMethods).toHaveLength(1)
|
||||
|
||||
await api.delete(
|
||||
`/admin/claims/${claimId}/inbound/items/${returnItems[0].actions[0].id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
orderResult = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const updatedReturnItems = orderResult.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "RETURN_ITEM")
|
||||
)
|
||||
|
||||
const updatedReturnShippingMethods =
|
||||
orderResult.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) => action.action === "SHIPPING_ADD"
|
||||
)
|
||||
)
|
||||
|
||||
expect(updatedReturnItems).toHaveLength(0)
|
||||
expect(updatedReturnShippingMethods).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ medusaIntegrationTestRunner({
|
||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||
let order, order2
|
||||
let returnShippingOption
|
||||
let outboundShippingOption
|
||||
let shippingProfile
|
||||
let fulfillmentSet
|
||||
let returnReason
|
||||
@@ -345,6 +346,44 @@ medusaIntegrationTestRunner({
|
||||
],
|
||||
}
|
||||
|
||||
const outboundShippingOptionPayload = {
|
||||
name: "Oubound shipping",
|
||||
service_zone_id: fulfillmentSet.service_zones[0].id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: shippingProviderId,
|
||||
price_type: "flat",
|
||||
type: {
|
||||
label: "Test type",
|
||||
description: "Test description",
|
||||
code: "test-code",
|
||||
},
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
amount: 20,
|
||||
},
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "is_return",
|
||||
value: "false",
|
||||
},
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "enabled_in_store",
|
||||
value: "true",
|
||||
},
|
||||
],
|
||||
}
|
||||
outboundShippingOption = (
|
||||
await api.post(
|
||||
"/admin/shipping-options",
|
||||
outboundShippingOptionPayload,
|
||||
adminHeaders
|
||||
)
|
||||
).data.shipping_option
|
||||
|
||||
returnShippingOption = (
|
||||
await api.post(
|
||||
"/admin/shipping-options",
|
||||
@@ -541,6 +580,165 @@ medusaIntegrationTestRunner({
|
||||
).data.exchanges
|
||||
expect(result[0].canceled_at).toBeDefined()
|
||||
})
|
||||
|
||||
describe("with inbound and outbound items", () => {
|
||||
let exchange
|
||||
let orderPreview
|
||||
|
||||
beforeEach(async () => {
|
||||
exchange = (
|
||||
await api.post(
|
||||
"/admin/exchanges",
|
||||
{
|
||||
order_id: order.id,
|
||||
description: "Test",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.exchange
|
||||
|
||||
const item = order.items[0]
|
||||
|
||||
await api.post(
|
||||
`/admin/exchanges/${exchange.id}/inbound/items`,
|
||||
{
|
||||
items: [
|
||||
{
|
||||
id: item.id,
|
||||
reason_id: returnReason.id,
|
||||
quantity: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/exchanges/${exchange.id}/inbound/shipping-method`,
|
||||
{ shipping_option_id: returnShippingOption.id },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/exchanges/${exchange.id}/outbound/items`,
|
||||
{
|
||||
items: [
|
||||
{
|
||||
variant_id: productExtra.variants[0].id,
|
||||
quantity: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/exchanges/${exchange.id}/outbound/shipping-method`,
|
||||
{ shipping_option_id: outboundShippingOption.id },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
orderPreview = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
})
|
||||
|
||||
it("should remove outbound shipping method when outbound items are completely removed", async () => {
|
||||
orderPreview = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const exchangeItems = orderPreview.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "ITEM_ADD")
|
||||
)
|
||||
|
||||
const exchangeShippingMethods = orderPreview.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) =>
|
||||
action.action === "SHIPPING_ADD" && !action.return_id
|
||||
)
|
||||
)
|
||||
|
||||
expect(exchangeItems).toHaveLength(1)
|
||||
expect(exchangeShippingMethods).toHaveLength(1)
|
||||
|
||||
await api.delete(
|
||||
`/admin/exchanges/${exchange.id}/outbound/items/${exchangeItems[0].actions[0].id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
orderPreview = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const updatedExchangeItems = orderPreview.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "ITEM_ADD")
|
||||
)
|
||||
|
||||
const updatedClaimShippingMethods =
|
||||
orderPreview.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) =>
|
||||
action.action === "SHIPPING_ADD" && !action.return_id
|
||||
)
|
||||
)
|
||||
|
||||
expect(updatedExchangeItems).toHaveLength(0)
|
||||
expect(updatedClaimShippingMethods).toHaveLength(0)
|
||||
})
|
||||
|
||||
it("should remove inbound shipping method when inbound items are completely removed", async () => {
|
||||
orderPreview = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const exchangeItems = orderPreview.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "RETURN_ITEM")
|
||||
)
|
||||
|
||||
const exchangeShippingMethods = orderPreview.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) =>
|
||||
action.action === "SHIPPING_ADD" && !!action.return_id
|
||||
)
|
||||
)
|
||||
|
||||
expect(exchangeItems).toHaveLength(1)
|
||||
expect(exchangeShippingMethods).toHaveLength(1)
|
||||
|
||||
await api.delete(
|
||||
`/admin/exchanges/${exchange.id}/inbound/items/${exchangeItems[0].actions[0].id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
orderPreview = (
|
||||
await api.get(`/admin/orders/${order.id}/preview`, adminHeaders)
|
||||
).data.order
|
||||
|
||||
const updatedExchangeItems = orderPreview.items.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find((action) => action.action === "RETURN_ITEM")
|
||||
)
|
||||
|
||||
const updatedClaimShippingMethods =
|
||||
orderPreview.shipping_methods.filter(
|
||||
(item) =>
|
||||
!!item.actions?.find(
|
||||
(action) =>
|
||||
action.action === "SHIPPING_ADD" && !!action.return_id
|
||||
)
|
||||
)
|
||||
|
||||
expect(updatedExchangeItems).toHaveLength(0)
|
||||
expect(updatedClaimShippingMethods).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
QueryKey,
|
||||
useMutation,
|
||||
@@ -307,6 +307,10 @@ export const useRemoveClaimInboundItem = (
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: returnsQueryKeys.details(),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
QueryKey,
|
||||
@@ -6,7 +7,6 @@ import {
|
||||
useQuery,
|
||||
UseQueryOptions,
|
||||
} from "@tanstack/react-query"
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
@@ -280,11 +280,16 @@ export const useRemoveExchangeInboundItem = (
|
||||
mutationFn: (actionId: string) =>
|
||||
sdk.admin.exchange.removeInboundItem(id, actionId),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.details(),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.details(),
|
||||
queryKey: returnsQueryKeys.details(),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
@@ -356,6 +361,7 @@ export const useDeleteExchangeInboundShipping = (
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -423,9 +429,14 @@ export const useRemoveExchangeOutboundItem = (
|
||||
mutationFn: (actionId: string) =>
|
||||
sdk.admin.exchange.removeOutboundItem(id, actionId),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.details(),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
|
||||
@@ -7,11 +7,11 @@ import {
|
||||
UseQueryOptions,
|
||||
} from "@tanstack/react-query"
|
||||
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import { ordersQueryKeys } from "./orders"
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
|
||||
const RETURNS_QUERY_KEY = "returns" as const
|
||||
export const returnsQueryKeys = queryKeysFactory(RETURNS_QUERY_KEY)
|
||||
@@ -169,9 +169,11 @@ export const useCancelReturnRequest = (
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: returnsQueryKeys.details(),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: returnsQueryKeys.lists(),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -257,6 +259,10 @@ export const useRemoveReturnItem = (
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: returnsQueryKeys.details(),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -369,6 +375,10 @@ export const useDeleteReturnShipping = (
|
||||
queryKey: ordersQueryKeys.preview(orderId),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: returnsQueryKeys.details(),
|
||||
})
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
|
||||
@@ -323,22 +323,26 @@ export const ClaimCreateForm = ({
|
||||
}, [previewItems])
|
||||
|
||||
useEffect(() => {
|
||||
let method = preview.shipping_methods.find(
|
||||
const inboundShipping = preview.shipping_methods.find(
|
||||
(s) =>
|
||||
!!s.actions?.find((a) => a.action === "SHIPPING_ADD" && !!a.return_id)
|
||||
)
|
||||
|
||||
if (method) {
|
||||
form.setValue("inbound_option_id", method.shipping_option_id)
|
||||
if (inboundShipping) {
|
||||
form.setValue("inbound_option_id", inboundShipping.shipping_option_id)
|
||||
} else {
|
||||
form.setValue("inbound_option_id", null)
|
||||
}
|
||||
|
||||
method = preview.shipping_methods.find(
|
||||
const outboundShipping = preview.shipping_methods.find(
|
||||
(s) =>
|
||||
!!s.actions?.find((a) => a.action === "SHIPPING_ADD" && !a.return_id)
|
||||
)
|
||||
|
||||
if (method) {
|
||||
form.setValue("outbound_option_id", method.shipping_option_id)
|
||||
if (outboundShipping) {
|
||||
form.setValue("outbound_option_id", outboundShipping.shipping_option_id)
|
||||
} else {
|
||||
form.setValue("outbound_option_id", null)
|
||||
}
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
@@ -420,10 +424,25 @@ export const ClaimCreateForm = ({
|
||||
}
|
||||
|
||||
const onShippingOptionChange = async (selectedOptionId: string) => {
|
||||
const promises = preview.shipping_methods
|
||||
.map((s) => s.actions?.find((a) => a.action === "SHIPPING_ADD")?.id)
|
||||
const inboundShippingMethods = preview.shipping_methods.filter((s) => {
|
||||
const action = s.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD" && !!a.return_id
|
||||
)
|
||||
|
||||
return action && !!!action?.return_id
|
||||
})
|
||||
|
||||
const promises = inboundShippingMethods
|
||||
.filter(Boolean)
|
||||
.map(deleteInboundShipping)
|
||||
.map((inboundShippingMethod) => {
|
||||
const action = inboundShippingMethod.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD" && !!a.return_id
|
||||
)
|
||||
|
||||
if (action) {
|
||||
return deleteInboundShipping(action.id)
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
|
||||
@@ -191,20 +191,22 @@ export const ClaimOutboundSection = ({
|
||||
|
||||
const onShippingOptionChange = async (selectedOptionId: string) => {
|
||||
const outboundShippingMethods = preview.shipping_methods.filter((s) => {
|
||||
const action = s.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
const action = s.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD" && !a.return_id
|
||||
)
|
||||
|
||||
return action && !!!action?.return?.id
|
||||
return action && !!!action?.return_id
|
||||
})
|
||||
|
||||
const promises = outboundShippingMethods
|
||||
.filter(Boolean)
|
||||
.map((outboundShippingMethod) => {
|
||||
const action = outboundShippingMethod.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD"
|
||||
(a) => a.action === "SHIPPING_ADD" && !a.return_id
|
||||
)
|
||||
|
||||
if (action) {
|
||||
deleteOutboundShipping(action.id)
|
||||
return deleteOutboundShipping(action.id)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -188,17 +188,17 @@ export const ExchangeInboundSection = ({
|
||||
}, [previewInboundItems])
|
||||
|
||||
useEffect(() => {
|
||||
const inboundShippingMethod = preview.shipping_methods.find((s) => {
|
||||
const action = s.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
|
||||
return !!action?.return?.id
|
||||
})
|
||||
const inboundShippingMethod = preview.shipping_methods.find((s) =>
|
||||
s.actions?.find((a) => a.action === "SHIPPING_ADD" && !!a.return_id)
|
||||
)
|
||||
|
||||
if (inboundShippingMethod) {
|
||||
form.setValue(
|
||||
"inbound_option_id",
|
||||
inboundShippingMethod.shipping_option_id
|
||||
)
|
||||
} else {
|
||||
form.setValue("inbound_option_id", null)
|
||||
}
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
@@ -246,21 +246,19 @@ export const ExchangeInboundSection = ({
|
||||
}
|
||||
|
||||
const onShippingOptionChange = async (selectedOptionId: string) => {
|
||||
const inboundShippingMethods = preview.shipping_methods.filter((s) => {
|
||||
const action = s.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
|
||||
return action && !!action?.return?.id
|
||||
})
|
||||
const inboundShippingMethods = preview.shipping_methods.filter((s) =>
|
||||
s.actions?.find((a) => a.action === "SHIPPING_ADD" && !!a.return_id)
|
||||
)
|
||||
|
||||
const promises = inboundShippingMethods
|
||||
.filter(Boolean)
|
||||
.map((inboundShippingMethod) => {
|
||||
const action = inboundShippingMethod.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD"
|
||||
(a) => a.action === "SHIPPING_ADD" && !!a.return_id
|
||||
)
|
||||
|
||||
if (action) {
|
||||
deleteInboundShipping(action.id)
|
||||
return deleteInboundShipping(action.id)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -188,22 +188,34 @@ export const ExchangeOutboundSection = ({
|
||||
setIsOpen("outbound-items", false)
|
||||
}
|
||||
|
||||
const onShippingOptionChange = async (selectedOptionId: string) => {
|
||||
const outboundShippingMethods = preview.shipping_methods.filter((s) => {
|
||||
const action = s.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
useEffect(() => {
|
||||
const outboundShipping = preview.shipping_methods.find(
|
||||
(s) =>
|
||||
!!s.actions?.find((a) => a.action === "SHIPPING_ADD" && !a.return_id)
|
||||
)
|
||||
|
||||
return !action?.return_id
|
||||
})
|
||||
if (outboundShipping) {
|
||||
form.setValue("outbound_option_id", outboundShipping.shipping_option_id)
|
||||
} else {
|
||||
form.setValue("outbound_option_id", null)
|
||||
}
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
const onShippingOptionChange = async (selectedOptionId: string) => {
|
||||
const outboundShippingMethods = preview.shipping_methods.filter(
|
||||
(s) =>
|
||||
!!s.actions?.find((a) => a.action === "SHIPPING_ADD" && !a.return_id)
|
||||
)
|
||||
|
||||
const promises = outboundShippingMethods
|
||||
.filter(Boolean)
|
||||
.map((outboundShippingMethod) => {
|
||||
const action = outboundShippingMethod.actions?.find(
|
||||
(a) => a.action === "SHIPPING_ADD"
|
||||
(a) => a.action === "SHIPPING_ADD" && !a.return_id
|
||||
)
|
||||
|
||||
if (action) {
|
||||
deleteOutboundShipping(action.id)
|
||||
return deleteOutboundShipping(action.id)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { AdminOrder, InventoryLevelDTO, ReturnDTO } from "@medusajs/types"
|
||||
import {
|
||||
AdminOrder,
|
||||
AdminOrderPreview,
|
||||
AdminReturn,
|
||||
InventoryLevelDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
@@ -47,8 +52,8 @@ import { ReturnCreateSchema, ReturnCreateSchemaType } from "./schema"
|
||||
|
||||
type ReturnCreateFormProps = {
|
||||
order: AdminOrder
|
||||
activeReturn: ReturnDTO // TODO: AdminReturn
|
||||
preview: AdminOrder // TODO
|
||||
activeReturn: AdminReturn
|
||||
preview: AdminOrderPreview
|
||||
}
|
||||
|
||||
let selectedItems: string[] = []
|
||||
@@ -62,7 +67,7 @@ export const ReturnCreateForm = ({
|
||||
const { handleSuccess } = useRouteModal()
|
||||
|
||||
const itemsMap = useMemo(
|
||||
() => new Map(order.items.map((i) => [i.id, i])),
|
||||
() => new Map((order.items || []).map((i) => [i.id, i])),
|
||||
[order.items]
|
||||
)
|
||||
|
||||
@@ -171,7 +176,7 @@ export const ReturnCreateForm = ({
|
||||
?.reason_id,
|
||||
})),
|
||||
option_id: method ? method.shipping_option_id : "",
|
||||
location_id: "",
|
||||
location_id: activeReturn?.location_id,
|
||||
send_notification: false,
|
||||
})
|
||||
},
|
||||
@@ -189,7 +194,7 @@ export const ReturnCreateForm = ({
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const existingItemsMap = {}
|
||||
const existingItemsMap: Record<string, boolean> = {}
|
||||
|
||||
previewItems.forEach((i) => {
|
||||
const ind = items.findIndex((field) => field.item_id === i.id)
|
||||
@@ -229,12 +234,14 @@ export const ReturnCreateForm = ({
|
||||
}, [previewItems])
|
||||
|
||||
useEffect(() => {
|
||||
const method = preview.shipping_methods.find(
|
||||
const method = preview.shipping_methods?.find(
|
||||
(s) => !!s.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
)
|
||||
|
||||
if (method) {
|
||||
form.setValue("option_id", method.shipping_option_id)
|
||||
form.setValue("option_id", method.shipping_option_id!)
|
||||
} else {
|
||||
form.setValue("option_id", "")
|
||||
}
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
@@ -300,6 +307,10 @@ export const ReturnCreateForm = ({
|
||||
}
|
||||
}, [isShippingPriceEdit])
|
||||
|
||||
useEffect(() => {
|
||||
form.setValue("location_id", activeReturn?.location_id || "")
|
||||
}, [activeReturn])
|
||||
|
||||
const showLevelsWarning = useMemo(() => {
|
||||
if (!locationId) {
|
||||
return false
|
||||
|
||||
@@ -8,10 +8,12 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
@@ -22,6 +24,7 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { removeClaimShippingMethodWorkflow } from "./remove-claim-shipping-method"
|
||||
|
||||
/**
|
||||
* This step validates that new items can be removed from a claim.
|
||||
@@ -104,6 +107,62 @@ export const removeAddItemClaimActionWorkflow = createWorkflow(
|
||||
|
||||
deleteOrderChangeActionsStep({ ids: [input.action_id] })
|
||||
|
||||
const updatedOrderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: [
|
||||
"actions.action",
|
||||
"actions.claim_id",
|
||||
"actions.id",
|
||||
"actions.return_id",
|
||||
],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderClaim.order_id,
|
||||
claim_id: orderClaim.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "updated-order-change-query" })
|
||||
|
||||
const actionIdToDelete = transform(
|
||||
{ updatedOrderChange, orderClaim },
|
||||
({
|
||||
updatedOrderChange: { actions = [] },
|
||||
orderClaim: { id: orderClaimId },
|
||||
}) => {
|
||||
const itemActions = actions.filter((c) => c.action === "ITEM_ADD")
|
||||
|
||||
if (itemActions.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const shippingAction = actions.find(
|
||||
(c) =>
|
||||
c.action === "SHIPPING_ADD" &&
|
||||
c.claim_id === orderClaimId &&
|
||||
!c.return_id
|
||||
)
|
||||
|
||||
if (!shippingAction) {
|
||||
return null
|
||||
}
|
||||
|
||||
return shippingAction.id
|
||||
}
|
||||
)
|
||||
|
||||
when({ actionIdToDelete }, ({ actionIdToDelete }) => {
|
||||
return !!actionIdToDelete
|
||||
}).then(() => {
|
||||
removeClaimShippingMethodWorkflow.runAsStep({
|
||||
input: {
|
||||
claim_id: orderClaim.id!,
|
||||
action_id: actionIdToDelete,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
@@ -22,6 +24,7 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { removeExchangeShippingMethodWorkflow } from "./remove-exchange-shipping-method"
|
||||
|
||||
/**
|
||||
* This step validates that a new item can be removed from an exchange.
|
||||
@@ -104,6 +107,62 @@ export const removeItemExchangeActionWorkflow = createWorkflow(
|
||||
|
||||
deleteOrderChangeActionsStep({ ids: [input.action_id] })
|
||||
|
||||
const updatedOrderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: [
|
||||
"actions.action",
|
||||
"actions.id",
|
||||
"actions.exchange_id",
|
||||
"actions.return_id",
|
||||
],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "updated-order-change-query" })
|
||||
|
||||
const actionIdToDelete = transform(
|
||||
{ updatedOrderChange, orderExchange },
|
||||
({
|
||||
updatedOrderChange: { actions = [] },
|
||||
orderExchange: { id: orderExchangeId },
|
||||
}) => {
|
||||
const itemActions = actions.filter((c) => c.action === "ITEM_ADD")
|
||||
|
||||
if (itemActions.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const shippingAction = actions.find(
|
||||
(c) =>
|
||||
c.action === "SHIPPING_ADD" &&
|
||||
c.exchange_id === orderExchangeId &&
|
||||
!c.return_id
|
||||
)
|
||||
|
||||
if (!shippingAction) {
|
||||
return null
|
||||
}
|
||||
|
||||
return shippingAction.id
|
||||
}
|
||||
)
|
||||
|
||||
when({ actionIdToDelete }, ({ actionIdToDelete }) => {
|
||||
return !!actionIdToDelete
|
||||
}).then(() => {
|
||||
removeExchangeShippingMethodWorkflow.runAsStep({
|
||||
input: {
|
||||
exchange_id: orderExchange.id!,
|
||||
action_id: actionIdToDelete,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
@@ -22,6 +24,8 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { removeReturnShippingMethodWorkflow } from "./remove-return-shipping-method"
|
||||
import { updateReturnWorkflow } from "./update-return"
|
||||
|
||||
/**
|
||||
* This step validates that a return item can be removed.
|
||||
@@ -116,6 +120,61 @@ export const removeItemReturnActionWorkflow = createWorkflow(
|
||||
|
||||
deleteOrderChangeActionsStep({ ids: [input.action_id] })
|
||||
|
||||
const updatedOrderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["actions.action", "actions.return_id", "actions.id"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderReturn.order_id,
|
||||
return_id: orderReturn.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "updated-order-change-query" })
|
||||
|
||||
const actionIdToDelete = transform(
|
||||
{ updatedOrderChange, orderReturn },
|
||||
({
|
||||
updatedOrderChange: { actions = [] },
|
||||
orderReturn: { id: returnId },
|
||||
}) => {
|
||||
const itemActions = actions.filter((c) => c.action === "RETURN_ITEM")
|
||||
|
||||
if (itemActions.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const shippingAction = actions.find(
|
||||
(c) => c.action === "SHIPPING_ADD" && c.return_id === returnId
|
||||
)
|
||||
|
||||
if (!shippingAction) {
|
||||
return null
|
||||
}
|
||||
|
||||
return shippingAction.id
|
||||
}
|
||||
)
|
||||
|
||||
when({ actionIdToDelete }, ({ actionIdToDelete }) => {
|
||||
return !!actionIdToDelete
|
||||
}).then(() => {
|
||||
removeReturnShippingMethodWorkflow.runAsStep({
|
||||
input: {
|
||||
return_id: orderReturn.id!,
|
||||
action_id: actionIdToDelete,
|
||||
},
|
||||
})
|
||||
|
||||
updateReturnWorkflow.runAsStep({
|
||||
input: {
|
||||
return_id: orderReturn.id,
|
||||
location_id: null,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1566,7 +1566,7 @@ export interface UpdateReturnDTO {
|
||||
/**
|
||||
* The ID of the location to return the items to.
|
||||
*/
|
||||
location_id?: string
|
||||
location_id?: string | null
|
||||
|
||||
/**
|
||||
* The refund amount of the return.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export interface UpdateReturnWorkflowInput {
|
||||
return_id: string
|
||||
location_id?: string
|
||||
location_id?: string | null
|
||||
no_notification?: boolean
|
||||
metadata?: Record<string, any> | null
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
removeAddItemClaimActionWorkflow,
|
||||
updateClaimAddItemWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
@@ -11,7 +12,6 @@ import {
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
import { AdminPostClaimsItemsActionReqSchemaType } from "../../../../validators"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostClaimsItemsActionReqSchemaType>,
|
||||
@@ -55,7 +55,6 @@ export const DELETE = async (
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const { id, action_id } = req.params
|
||||
|
||||
const { result: orderPreview } = await removeAddItemClaimActionWorkflow(
|
||||
req.scope
|
||||
).run({
|
||||
|
||||
@@ -86,12 +86,10 @@ export const DELETE = async (
|
||||
entryPoint: "return",
|
||||
variables: {
|
||||
id: exchange.return_id,
|
||||
filters: {
|
||||
...req.filterableFields,
|
||||
},
|
||||
},
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
fields: defaultAdminDetailsReturnFields,
|
||||
})
|
||||
|
||||
const [orderReturn] = await remoteQuery(queryObject)
|
||||
|
||||
res.json({
|
||||
|
||||
Reference in New Issue
Block a user