fix(dashboard, js-sdk): undefined RMA activity items (#9649)
**What** - fix for showing removed items in rma flows --- DEPENDS ON https://github.com/medusajs/medusa/pull/9646 FIXES CC-597
This commit is contained in:
@@ -56,6 +56,10 @@ export const useRequestOrderEdit = (
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.changes(id),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.lineItems(id),
|
||||
})
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -85,6 +89,10 @@ export const useConfirmOrderEdit = (
|
||||
queryKey: ordersQueryKeys.changes(id),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.lineItems(id),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: reservationItemsQueryKeys.lists(),
|
||||
})
|
||||
@@ -121,6 +129,10 @@ export const useCancelOrderEdit = (
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.changes(orderId),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersQueryKeys.lineItems(id),
|
||||
})
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { AdminOrderItemsFilters, HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
QueryKey,
|
||||
useMutation,
|
||||
@@ -12,13 +12,10 @@ import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory, TQueryKey } from "../../lib/query-key-factory"
|
||||
|
||||
const ORDERS_QUERY_KEY = "orders" as const
|
||||
const _orderKeys = queryKeysFactory(ORDERS_QUERY_KEY) as TQueryKey<
|
||||
"orders",
|
||||
any,
|
||||
string
|
||||
> & {
|
||||
const _orderKeys = queryKeysFactory(ORDERS_QUERY_KEY) as TQueryKey<"orders"> & {
|
||||
preview: (orderId: string) => any
|
||||
changes: (orderId: string) => any
|
||||
lineItems: (orderId: string) => any
|
||||
}
|
||||
|
||||
_orderKeys.preview = function (id: string) {
|
||||
@@ -29,6 +26,10 @@ _orderKeys.changes = function (id: string) {
|
||||
return [this.detail(id), "changes"]
|
||||
}
|
||||
|
||||
_orderKeys.lineItems = function (id: string) {
|
||||
return [this.detail(id), "lineItems"]
|
||||
}
|
||||
|
||||
export const ordersQueryKeys = _orderKeys
|
||||
|
||||
export const useOrder = (
|
||||
@@ -97,7 +98,7 @@ export const useOrderChanges = (
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminOrderChangesResponse,
|
||||
Error,
|
||||
FetchError,
|
||||
HttpTypes.AdminOrderChangesResponse,
|
||||
QueryKey
|
||||
>,
|
||||
@@ -113,6 +114,28 @@ export const useOrderChanges = (
|
||||
return { ...data, ...rest }
|
||||
}
|
||||
|
||||
export const useOrderLineItems = (
|
||||
id: string,
|
||||
query?: HttpTypes.AdminOrderItemsFilters,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminOrderLineItemsListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminOrderLineItemsListResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: async () => sdk.admin.order.listLineItems(id, query),
|
||||
queryKey: ordersQueryKeys.lineItems(id),
|
||||
...options,
|
||||
})
|
||||
|
||||
return { ...data, ...rest }
|
||||
}
|
||||
|
||||
export const useCreateOrderFulfillment = (
|
||||
orderId: string,
|
||||
options?: UseMutationOptions<
|
||||
|
||||
@@ -54,7 +54,7 @@ function ActivityItems(props: ActivityItemsProps) {
|
||||
<Popover.Content
|
||||
align="center"
|
||||
side="top"
|
||||
className="bg-ui-bg-component p-0 max-w-[200px] focus-visible:outline-none"
|
||||
className="bg-ui-bg-component max-w-[200px] p-0 focus-visible:outline-none"
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
{!!itemsToSend?.length && (
|
||||
@@ -73,12 +73,10 @@ function ActivityItems(props: ActivityItemsProps) {
|
||||
{item.quantity}x
|
||||
</Text>
|
||||
|
||||
<Thumbnail
|
||||
src={originalItem?.variant?.product?.thumbnail}
|
||||
/>
|
||||
<Thumbnail src={originalItem?.thumbnail} />
|
||||
|
||||
<Text className="txt-compact-small text-ui-fg-subtle truncate">
|
||||
{`${originalItem?.variant?.title} · ${originalItem?.variant?.product?.title}`}
|
||||
{`${originalItem?.variant_title} · ${originalItem?.product_title}`}
|
||||
</Text>
|
||||
</div>
|
||||
)
|
||||
@@ -105,12 +103,10 @@ function ActivityItems(props: ActivityItemsProps) {
|
||||
{item.quantity}x
|
||||
</Text>
|
||||
|
||||
<Thumbnail
|
||||
src={originalItem?.variant?.product?.thumbnail}
|
||||
/>
|
||||
<Thumbnail src={originalItem?.thumbnail} />
|
||||
|
||||
<Text className="txt-compact-small text-ui-fg-subtle truncate">
|
||||
{`${originalItem?.variant?.title} · ${originalItem?.variant?.product?.title}`}
|
||||
{`${originalItem?.variant_title} · ${originalItem?.product_title}`}
|
||||
</Text>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { AdminOrderLineItem } from "@medusajs/types"
|
||||
import { useOrderChanges } from "../../../../../hooks/api"
|
||||
import { useOrderChanges, useOrderLineItems } from "../../../../../hooks/api"
|
||||
import { useCancelClaim, useClaims } from "../../../../../hooks/api/claims"
|
||||
import {
|
||||
useCancelExchange,
|
||||
@@ -112,14 +112,36 @@ type Activity = {
|
||||
const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const itemsMap = useMemo(
|
||||
() => new Map(order?.items?.map((i) => [i.id, i])),
|
||||
[order.items]
|
||||
const { order_changes: orderChanges = [] } = useOrderChanges(order.id, {
|
||||
change_type: ["edit", "claim", "exchange", "return"],
|
||||
})
|
||||
|
||||
const missingLineItemIds = getMissingLineItemIds(order, orderChanges)
|
||||
const { order_items: removedLineItems = [] } = useOrderLineItems(
|
||||
order.id,
|
||||
|
||||
{
|
||||
fields: "+quantity",
|
||||
item_id: missingLineItemIds,
|
||||
},
|
||||
{
|
||||
enabled: !!orderChanges.length,
|
||||
}
|
||||
)
|
||||
|
||||
const { order_changes: orderChanges = [] } = useOrderChanges(order.id, {
|
||||
change_type: "edit",
|
||||
})
|
||||
const itemsMap = useMemo(() => {
|
||||
const _itemsMap = new Map(order?.items?.map((i) => [i.id, i]))
|
||||
|
||||
for (const id of missingLineItemIds) {
|
||||
const i = removedLineItems.find((i) => i.item.id === id)
|
||||
|
||||
if (i) {
|
||||
_itemsMap.set(id, { ...i.item, quantity: i.quantity }) // copy quantity from OrderItem to OrderLineItem
|
||||
}
|
||||
}
|
||||
|
||||
return _itemsMap
|
||||
}, [order.items, removedLineItems, missingLineItemIds])
|
||||
|
||||
const { returns = [] } = useReturns({
|
||||
order_id: order.id,
|
||||
@@ -226,9 +248,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||
items.push({
|
||||
title: t("orders.activity.events.fulfillment.delivered"),
|
||||
timestamp: fulfillment.delivered_at,
|
||||
children: (
|
||||
<FulfillmentCreatedBody fulfillment={fulfillment} />
|
||||
),
|
||||
children: <FulfillmentCreatedBody fulfillment={fulfillment} />,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -334,7 +354,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||
})
|
||||
}
|
||||
|
||||
for (const edit of orderChanges) {
|
||||
for (const edit of orderChanges.filter((oc) => oc.change_type === "edit")) {
|
||||
const isConfirmed = edit.status === "confirmed"
|
||||
const isPending = edit.status === "pending"
|
||||
|
||||
@@ -350,10 +370,10 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||
edit.status === "requested"
|
||||
? edit.requested_at
|
||||
: edit.status === "declined"
|
||||
? edit.declined_at
|
||||
: edit.status === "canceled"
|
||||
? edit.canceled_at
|
||||
: edit.created_at,
|
||||
? edit.declined_at
|
||||
: edit.status === "canceled"
|
||||
? edit.canceled_at
|
||||
: edit.created_at,
|
||||
children: isConfirmed ? (
|
||||
<OrderEditBody edit={edit} itemsMap={itemsMap} />
|
||||
) : null,
|
||||
@@ -390,7 +410,16 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||
}
|
||||
|
||||
return [...sortedActivities, createdAt]
|
||||
}, [order, payments, returns, exchanges, orderChanges, notes, isLoading])
|
||||
}, [
|
||||
order,
|
||||
payments,
|
||||
returns,
|
||||
exchanges,
|
||||
orderChanges,
|
||||
notes,
|
||||
isLoading,
|
||||
itemsMap,
|
||||
])
|
||||
}
|
||||
|
||||
type OrderActivityItemProps = PropsWithChildren<{
|
||||
@@ -813,14 +842,13 @@ const OrderEditBody = ({
|
||||
itemsMap,
|
||||
}: {
|
||||
edit: AdminOrderChange
|
||||
isRequested: boolean
|
||||
itemsMap: Record<string, AdminOrderLineItem>
|
||||
itemsMap: Map<string, AdminOrderLineItem>
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [itemsAdded, itemsRemoved] = useMemo(
|
||||
() => countItemsChange(edit.actions, itemsMap),
|
||||
[edit]
|
||||
[edit, itemsMap]
|
||||
)
|
||||
|
||||
return (
|
||||
@@ -840,21 +868,24 @@ const OrderEditBody = ({
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns count of added and removed item quantity
|
||||
*/
|
||||
function countItemsChange(
|
||||
actions: AdminOrderChange["actions"],
|
||||
itemsMap: Record<string, AdminOrderLineItem>
|
||||
itemsMap: Map<string, AdminOrderLineItem>
|
||||
) {
|
||||
let added = 0
|
||||
let removed = 0
|
||||
|
||||
actions.forEach((action) => {
|
||||
if (action.action === "ITEM_ADD") {
|
||||
added += action.details.quantity
|
||||
added += action.details!.quantity as number
|
||||
}
|
||||
if (action.action === "ITEM_UPDATE") {
|
||||
const newQuantity: number = action.details!.quantity
|
||||
const newQuantity = action.details!.quantity as number
|
||||
const originalQuantity: number | undefined = itemsMap.get(
|
||||
action.details!.reference_id
|
||||
action.details!.reference_id as string
|
||||
)?.quantity
|
||||
|
||||
if (typeof originalQuantity === "number") {
|
||||
@@ -872,3 +903,28 @@ function countItemsChange(
|
||||
|
||||
return [added, removed]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IDs of missing line items that were removed from the order.
|
||||
*/
|
||||
function getMissingLineItemIds(order: AdminOrder, changes: AdminOrderChange[]) {
|
||||
if (!changes?.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
const retIds = new Set<string>()
|
||||
const existingItemsMap = new Map(order.items.map((item) => [item.id, true]))
|
||||
|
||||
changes.forEach((change) => {
|
||||
change.actions.forEach((action) => {
|
||||
if (
|
||||
(action.details!.reference_id as string).startsWith("ordli_") &&
|
||||
!existingItemsMap.has(action.details!.reference_id as string)
|
||||
) {
|
||||
retIds.add(action.details!.reference_id as string)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return Array.from(retIds)
|
||||
}
|
||||
|
||||
@@ -148,4 +148,17 @@ export class Order {
|
||||
headers,
|
||||
})
|
||||
}
|
||||
|
||||
async listLineItems(
|
||||
id: string,
|
||||
queryParams?: FindParams & HttpTypes.AdminOrderItemsFilters,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<
|
||||
PaginatedResponse<HttpTypes.AdminOrderLineItemsListResponse>
|
||||
>(`/admin/orders/${id}/line-items`, {
|
||||
query: queryParams,
|
||||
headers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,19 @@ export interface AdminOrderChange
|
||||
actions: AdminOrderChangeAction[]
|
||||
}
|
||||
|
||||
export interface AdminOrderItem {
|
||||
order_id: string
|
||||
item_id: string
|
||||
version: number
|
||||
history: {
|
||||
version: {
|
||||
from: number
|
||||
to: number
|
||||
}
|
||||
}
|
||||
item: AdminOrderLineItem
|
||||
}
|
||||
|
||||
export interface AdminOrderChangeAction
|
||||
extends Omit<BaseOrderChangeAction, "order_change" | "order"> {
|
||||
order_change: AdminOrderChange
|
||||
|
||||
@@ -14,6 +14,13 @@ export interface AdminOrderFilters extends FindParams, BaseOrderFilters {
|
||||
updated_at?: OperatorMap<string>
|
||||
}
|
||||
|
||||
export interface AdminOrderItemsFilters extends FindParams {
|
||||
id?: string[] | string
|
||||
item_id?: string[] | string
|
||||
order_id?: string[] | string
|
||||
version?: number[] | number
|
||||
}
|
||||
|
||||
export interface AdminOrderChangesFilters extends BaseOrderChangesFilters {}
|
||||
|
||||
export interface AdminOrderItemsFilters extends FindParams {
|
||||
|
||||
Reference in New Issue
Block a user