feat(adshboard,types,medusa): enable adding notes/return reason to inbound claims (#8488)
* wip: setup UI * wip: rendering modal, adding claim items, create checks * fix: make form work after merge * fix: continuation of claim edit * chore: ability to add and remove items to claim inbound * chore: minor fixes * chore: add toast messages on actions * feat(adshboard,types,medusa): enable adding notes/return reason to inbound items * chore: fix types in a bunch of places * chore: add conditional for actions * Update packages/admin-next/dashboard/src/routes/orders/order-create-claim/components/claim-create-form/claim-create-form.tsx Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> --------- Co-authored-by: fPolic <mainacc.polic@gmail.com> Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
@@ -6,10 +6,10 @@ import {
|
||||
UseQueryOptions,
|
||||
} from "@tanstack/react-query"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const ORDERS_QUERY_KEY = "orders" as const
|
||||
const _orderKeys = queryKeysFactory(ORDERS_QUERY_KEY)
|
||||
@@ -40,7 +40,12 @@ export const useOrder = (
|
||||
export const useOrderPreview = (
|
||||
id: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<any, Error, any, QueryKey>,
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminOrderPreviewResponse,
|
||||
Error,
|
||||
HttpTypes.AdminOrderPreviewResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
>
|
||||
) => {
|
||||
|
||||
@@ -886,7 +886,12 @@
|
||||
"create": "Create Claim",
|
||||
"outbound": "Outbound",
|
||||
"refundAmount": "Estimated difference",
|
||||
"activeChangeError": "There is an active order change on this order. Please finish or discard the previous change."
|
||||
"activeChangeError": "There is an active order change on this order. Please finish or discard the previous change.",
|
||||
"actions": {
|
||||
"cancelClaim": {
|
||||
"successToast": "Claim was successfully canceled."
|
||||
}
|
||||
}
|
||||
},
|
||||
"reservations": {
|
||||
"allocatedLabel": "Allocated",
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { AdminClaim, AdminOrder, InventoryLevelDTO } from "@medusajs/types"
|
||||
import {
|
||||
AdminClaim,
|
||||
AdminOrder,
|
||||
AdminOrderPreview,
|
||||
InventoryLevelDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
@@ -46,7 +51,7 @@ import { currencies } from "../../../../../lib/data/currencies"
|
||||
type ReturnCreateFormProps = {
|
||||
order: AdminOrder
|
||||
claim: AdminClaim
|
||||
preview: AdminOrder
|
||||
preview: AdminOrderPreview
|
||||
}
|
||||
|
||||
let itemsToAdd: string[] = []
|
||||
@@ -134,14 +139,14 @@ export const ClaimCreateForm = ({
|
||||
*/
|
||||
const previewItems = useMemo(
|
||||
() =>
|
||||
preview.items.filter(
|
||||
preview?.items?.filter(
|
||||
(i) => !!i.actions?.find((a) => a.claim_id === claim.id)
|
||||
),
|
||||
[preview.items]
|
||||
)
|
||||
|
||||
const itemsMap = useMemo(
|
||||
() => new Map(order.items.map((i) => [i.id, i])),
|
||||
() => new Map(order?.items?.map((i) => [i.id, i])),
|
||||
[order.items]
|
||||
)
|
||||
|
||||
@@ -161,14 +166,18 @@ export const ClaimCreateForm = ({
|
||||
)
|
||||
|
||||
return Promise.resolve({
|
||||
inbound_items: previewItems.map((i) => ({
|
||||
item_id: i.id,
|
||||
quantity: i.detail.return_requested_quantity,
|
||||
note: i.actions?.find((a) => a.action === "RETURN_ITEM")
|
||||
?.internal_note,
|
||||
reason_id: i.actions?.find((a) => a.action === "RETURN_ITEM")?.details
|
||||
?.reason_id,
|
||||
})),
|
||||
inbound_items: previewItems.map((i) => {
|
||||
const returnAction = i.actions?.find(
|
||||
(a) => a.action === "RETURN_ITEM"
|
||||
)
|
||||
|
||||
return {
|
||||
item_id: i.id,
|
||||
quantity: i.detail.return_requested_quantity,
|
||||
note: returnAction?.internal_note,
|
||||
reason_id: returnAction?.details?.reason_id as string | undefined,
|
||||
}
|
||||
}),
|
||||
inbound_option_id: method ? method.shipping_option_id : "",
|
||||
location_id: "",
|
||||
send_notification: false,
|
||||
@@ -188,7 +197,7 @@ export const ClaimCreateForm = ({
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const existingItemsMap = {}
|
||||
const existingItemsMap: Record<string, boolean> = {}
|
||||
|
||||
previewItems.forEach((i) => {
|
||||
const ind = items.findIndex((field) => field.item_id === i.id)
|
||||
@@ -205,7 +214,7 @@ export const ClaimCreateForm = ({
|
||||
...items[ind],
|
||||
quantity: i.detail.return_requested_quantity,
|
||||
note: returnItemAction?.internal_note,
|
||||
reason_id: returnItemAction?.details?.reason_id,
|
||||
reason_id: returnItemAction?.details?.reason_id as string,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -226,13 +235,13 @@ export const ClaimCreateForm = ({
|
||||
)
|
||||
|
||||
if (method) {
|
||||
form.setValue("option_id", method.shipping_option_id)
|
||||
form.setValue("inbound_option_id", method.shipping_option_id)
|
||||
}
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
const showPlaceholder = !items.length
|
||||
const locationId = form.watch("location_id")
|
||||
const shippingOptionId = form.watch("option_id")
|
||||
const shippingOptionId = form.watch("inbound_option_id")
|
||||
|
||||
const handleSubmit = form.handleSubmit(async (data) => {
|
||||
try {
|
||||
@@ -242,19 +251,25 @@ export const ClaimCreateForm = ({
|
||||
} catch (e) {
|
||||
toast.error(t("general.error"), {
|
||||
description: e.message,
|
||||
dismissLabel: t("actions.close"),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const onItemsSelected = async () => {
|
||||
itemsToAdd.length &&
|
||||
(await addInboundItem({
|
||||
items: itemsToAdd.map((id) => ({
|
||||
id,
|
||||
quantity: 1,
|
||||
})),
|
||||
}))
|
||||
(await addInboundItem(
|
||||
{
|
||||
items: itemsToAdd.map((id) => ({
|
||||
id,
|
||||
quantity: 1,
|
||||
})),
|
||||
},
|
||||
{
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
}
|
||||
))
|
||||
|
||||
for (const itemToRemove of itemsToRemove) {
|
||||
const actionId = previewItems
|
||||
@@ -262,14 +277,18 @@ export const ClaimCreateForm = ({
|
||||
?.actions?.find((a) => a.action === "RETURN_ITEM")?.id
|
||||
|
||||
if (actionId) {
|
||||
await removeInboundItem(actionId)
|
||||
await removeInboundItem(actionId, {
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setIsOpen("items", false)
|
||||
}
|
||||
|
||||
const onLocationChange = async (selectedLocationId: string) => {
|
||||
const onLocationChange = async (selectedLocationId?: string | null) => {
|
||||
await updateClaimRequest({ location_id: selectedLocationId })
|
||||
}
|
||||
|
||||
@@ -281,12 +300,19 @@ export const ClaimCreateForm = ({
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
await addInboundShipping({ shipping_option_id: selectedOptionId })
|
||||
await addInboundShipping(
|
||||
{ shipping_option_id: selectedOptionId },
|
||||
{
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isShippingPriceEdit) {
|
||||
document.getElementById("js-shipping-input").focus()
|
||||
document.getElementById("js-shipping-input")?.focus()
|
||||
}
|
||||
}, [isShippingPriceEdit])
|
||||
|
||||
@@ -298,7 +324,7 @@ export const ClaimCreateForm = ({
|
||||
const allItemsHaveLocation = items
|
||||
.map((_i) => {
|
||||
const item = itemsMap.get(_i.item_id)
|
||||
if (!item?.variant_id) {
|
||||
if (!item?.variant_id || !item?.variant) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -326,11 +352,12 @@ export const ClaimCreateForm = ({
|
||||
;(
|
||||
await Promise.all(
|
||||
items.map(async (_i) => {
|
||||
const item = itemsMap.get(_i.item_id)
|
||||
const item = itemsMap.get(_i.item_id)!
|
||||
|
||||
if (!item.variant_id) {
|
||||
if (!item.variant_id || !item.variant?.product) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return await sdk.admin.product.retrieveVariant(
|
||||
item.variant.product.id,
|
||||
item.variant_id,
|
||||
@@ -339,8 +366,9 @@ export const ClaimCreateForm = ({
|
||||
})
|
||||
)
|
||||
)
|
||||
.filter((it) => it?.variant)
|
||||
.filter((it) => !!it?.variant)
|
||||
.forEach((item) => {
|
||||
|
||||
const { variant } = item
|
||||
const levels = variant.inventory[0]?.location_levels
|
||||
|
||||
@@ -365,23 +393,30 @@ export const ClaimCreateForm = ({
|
||||
*/
|
||||
return () => {
|
||||
if (IS_CANCELING) {
|
||||
cancelClaimRequest()
|
||||
cancelClaimRequest(undefined, {
|
||||
onSuccess: () => {
|
||||
toast.success(t("orders.claims.actions.cancelClaim.successToast"))
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
})
|
||||
|
||||
// TODO: add this on ESC press
|
||||
IS_CANCELING = false
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const returnTotal = preview.return_requested_total
|
||||
|
||||
const shippingTotal = useMemo(() => {
|
||||
const method = preview.shipping_methods.find(
|
||||
(sm) => !!sm.actions?.find((a) => a.action === "SHIPPING_ADD")
|
||||
)
|
||||
|
||||
return method?.total || 0
|
||||
return (method?.total as number) || 0
|
||||
}, [preview.shipping_methods])
|
||||
|
||||
const returnTotal = preview.return_requested_total
|
||||
const refundAmount = returnTotal - shippingTotal
|
||||
|
||||
return (
|
||||
@@ -473,7 +508,11 @@ export const ClaimCreateForm = ({
|
||||
?.actions?.find((a) => a.action === "RETURN_ITEM")?.id
|
||||
|
||||
if (actionId) {
|
||||
removeInboundItem(actionId)
|
||||
removeInboundItem(actionId, {
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
})
|
||||
}
|
||||
}}
|
||||
onUpdate={(payload) => {
|
||||
@@ -482,7 +521,14 @@ export const ClaimCreateForm = ({
|
||||
?.actions?.find((a) => a.action === "RETURN_ITEM")?.id
|
||||
|
||||
if (actionId) {
|
||||
updateInboundItem({ ...payload, actionId })
|
||||
updateInboundItem(
|
||||
{ ...payload, actionId },
|
||||
{
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
}}
|
||||
index={index}
|
||||
@@ -543,16 +589,16 @@ export const ClaimCreateForm = ({
|
||||
{/*TODO: WHAT IF THE RETURN OPTION HAS COMPUTED PRICE*/}
|
||||
<Form.Field
|
||||
control={form.control}
|
||||
name="option_id"
|
||||
name="inbound_option_id"
|
||||
render={({ field: { value, onChange, ...field } }) => {
|
||||
return (
|
||||
<Form.Item>
|
||||
<Form.Control>
|
||||
<Combobox
|
||||
value={value}
|
||||
onChange={(v) => {
|
||||
onChange(v)
|
||||
onShippingOptionChange(v)
|
||||
value={value ?? undefined}
|
||||
onChange={(val) => {
|
||||
onChange(val)
|
||||
val && onShippingOptionChange(val)
|
||||
}}
|
||||
{...field}
|
||||
options={(shipping_options ?? [])
|
||||
@@ -640,13 +686,20 @@ export const ClaimCreateForm = ({
|
||||
})
|
||||
|
||||
if (actionId) {
|
||||
updateInboundShipping({
|
||||
actionId,
|
||||
custom_price:
|
||||
typeof customShippingAmount === "string"
|
||||
? null
|
||||
: customShippingAmount,
|
||||
})
|
||||
updateInboundShipping(
|
||||
{
|
||||
actionId,
|
||||
custom_price:
|
||||
typeof customShippingAmount === "string"
|
||||
? null
|
||||
: customShippingAmount,
|
||||
},
|
||||
{
|
||||
onError: (error) => {
|
||||
toast.error(error.message)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
setIsShippingPriceEdit(false)
|
||||
}}
|
||||
@@ -656,7 +709,7 @@ export const ClaimCreateForm = ({
|
||||
}
|
||||
code={order.currency_code}
|
||||
onValueChange={(value) =>
|
||||
setCustomShippingAmount(value ? parseInt(value) : "")
|
||||
value && setCustomShippingAmount(parseInt(value))
|
||||
}
|
||||
value={customShippingAmount}
|
||||
disabled={showPlaceholder}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import React from "react"
|
||||
import { ChatBubble, DocumentText, XCircle, XMark } from "@medusajs/icons"
|
||||
import { AdminOrderLineItem, HttpTypes } from "@medusajs/types"
|
||||
import { IconButton, Input, Text } from "@medusajs/ui"
|
||||
import { UseFormReturn } from "react-hook-form"
|
||||
import { HttpTypes, AdminOrderLineItem } from "@medusajs/types"
|
||||
import { ChatBubble, DocumentText, XCircle, XMark } from "@medusajs/icons"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { Thumbnail } from "../../../../../components/common/thumbnail"
|
||||
import { MoneyAmountCell } from "../../../../../components/table/table-cells/common/money-amount-cell"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import { Thumbnail } from "../../../../../components/common/thumbnail"
|
||||
import { Combobox } from "../../../../../components/inputs/combobox"
|
||||
import { MoneyAmountCell } from "../../../../../components/table/table-cells/common/money-amount-cell"
|
||||
import { useReturnReasons } from "../../../../../hooks/api/return-reasons"
|
||||
|
||||
type OrderEditItemProps = {
|
||||
@@ -35,11 +33,9 @@ function ClaimInboundItem({
|
||||
index,
|
||||
}: OrderEditItemProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const { return_reasons = [] } = useReturnReasons({ fields: "+label" })
|
||||
|
||||
const formItem = form.watch(`inbound_items.${index}`)
|
||||
|
||||
const showReturnReason = typeof formItem.reason_id === "string"
|
||||
const showNote = typeof formItem.note === "string"
|
||||
|
||||
@@ -48,15 +44,17 @@ function ClaimInboundItem({
|
||||
<div className="flex flex-col items-center gap-x-2 gap-y-2 border-b p-3 text-sm md:flex-row">
|
||||
<div className="flex flex-1 items-center gap-x-3">
|
||||
<Thumbnail src={item.thumbnail} />
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div>
|
||||
<Text className="txt-small" as="span" weight="plus">
|
||||
{item.title}{" "}
|
||||
</Text>
|
||||
{item.variant.sku && <span>({item.variant.sku})</span>}
|
||||
|
||||
{item.variant?.sku && <span>({item.variant.sku})</span>}
|
||||
</div>
|
||||
<Text as="div" className="text-ui-fg-subtle txt-small">
|
||||
{item.variant.product.title}
|
||||
{item.variant?.product?.title}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
@@ -71,19 +69,18 @@ function ClaimInboundItem({
|
||||
<Form.Item>
|
||||
<Form.Control>
|
||||
<Input
|
||||
{...field}
|
||||
className="bg-ui-bg-base txt-small w-[67px] rounded-lg"
|
||||
min={1}
|
||||
max={item.quantity}
|
||||
type="number"
|
||||
{...field}
|
||||
onChange={(e) => {
|
||||
onBlur={(e) => {
|
||||
const val = e.target.value
|
||||
const payload = val === "" ? null : Number(val)
|
||||
|
||||
field.onChange(payload)
|
||||
|
||||
if (payload) {
|
||||
// todo: move on blur
|
||||
onUpdate({ quantity: payload })
|
||||
}
|
||||
}}
|
||||
@@ -178,8 +175,9 @@ function ClaimInboundItem({
|
||||
className="flex-shrink"
|
||||
variant="transparent"
|
||||
onClick={() => {
|
||||
onUpdate({ reason_id: null }) // TODO BE: we should be able to set to unset reason here
|
||||
form.setValue(`inbound_items.${index}.reason_id`, "")
|
||||
form.setValue(`inbound_items.${index}.reason_id`, null)
|
||||
|
||||
onUpdate({ reason_id: null })
|
||||
}}
|
||||
>
|
||||
<XMark className="text-ui-fg-muted" />
|
||||
@@ -202,17 +200,17 @@ function ClaimInboundItem({
|
||||
<div className="flex-grow">
|
||||
<Form.Field
|
||||
control={form.control}
|
||||
name={`items.${index}.note`}
|
||||
render={({ field: { ref, onChange, ...field } }) => {
|
||||
name={`inbound_items.${index}.note`}
|
||||
render={({ field: { ref, ...field } }) => {
|
||||
return (
|
||||
<Form.Item>
|
||||
<Form.Control>
|
||||
<Input
|
||||
onChange={onChange}
|
||||
{...field}
|
||||
onBlur={() =>
|
||||
onBlur={() => {
|
||||
field.onChange(field.value)
|
||||
onUpdate({ internal_note: field.value })
|
||||
}
|
||||
}}
|
||||
className="bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover"
|
||||
/>
|
||||
</Form.Control>
|
||||
@@ -222,15 +220,14 @@ function ClaimInboundItem({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<IconButton
|
||||
type="button"
|
||||
className="flex-shrink"
|
||||
variant="transparent"
|
||||
onClick={() => {
|
||||
form.setValue(`items.${index}.note`, {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
})
|
||||
form.setValue(`inbound_items.${index}.note`, null)
|
||||
|
||||
onUpdate({ internal_note: null })
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -5,18 +5,19 @@ export const ClaimCreateSchema = z.object({
|
||||
z.object({
|
||||
item_id: z.string(),
|
||||
quantity: z.number(),
|
||||
reason_id: z.string().optional().nullable(),
|
||||
note: z.string().optional().nullable(),
|
||||
})
|
||||
),
|
||||
outbound_items: z.array(
|
||||
z.object({
|
||||
item_id: z.string(), // TODO: variant id?
|
||||
quantity: z.number(),
|
||||
reason_id: z.string().nullish(),
|
||||
note: z.string().nullish(),
|
||||
})
|
||||
),
|
||||
// TODO: Bring back when introducing outbound items
|
||||
// outbound_items: z.array(
|
||||
// z.object({
|
||||
// item_id: z.string(), // TODO: variant id?
|
||||
// quantity: z.number(),
|
||||
// })
|
||||
// ),
|
||||
location_id: z.string().optional(),
|
||||
inbound_option_id: z.string(),
|
||||
inbound_option_id: z.string().nullish(),
|
||||
send_notification: z.boolean().optional(),
|
||||
})
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export class Order {
|
||||
}
|
||||
|
||||
async retrievePreview(id: string, headers?: ClientHeaders) {
|
||||
return await this.client.fetch<{ order: HttpTypes.AdminOrder }>(
|
||||
return await this.client.fetch<HttpTypes.AdminOrderPreviewResponse>(
|
||||
`/admin/orders/${id}/preview`,
|
||||
{
|
||||
headers,
|
||||
|
||||
@@ -17,9 +17,9 @@ interface AdminClaimAddItems {
|
||||
|
||||
interface AdminClaimUpdateItem {
|
||||
quantity?: number
|
||||
reason_id?: ClaimReason
|
||||
reason_id?: string | null
|
||||
description?: string
|
||||
internal_note?: string
|
||||
internal_note?: string | null
|
||||
}
|
||||
|
||||
interface AdminClaimAddShippingMethod {
|
||||
@@ -31,7 +31,7 @@ interface AdminClaimAddShippingMethod {
|
||||
}
|
||||
|
||||
interface AdminClaimUpdateShippingMethod {
|
||||
custom_price?: number
|
||||
custom_price?: number | null
|
||||
internal_note?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { GeoZoneType } from "../../../fulfillment"
|
||||
import { AdminShippingOption } from "../../shipping-option"
|
||||
import { AdminStockLocation } from "../../stock-locations"
|
||||
|
||||
export interface AdminGeoZone {
|
||||
id: string
|
||||
@@ -17,6 +18,7 @@ export interface AdminServiceZone {
|
||||
id: string
|
||||
name: string
|
||||
fulfillment_set_id: string
|
||||
fulfillment_set: AdminFulfillmentSet
|
||||
geo_zones: AdminGeoZone[]
|
||||
shipping_options: AdminShippingOption[]
|
||||
created_at: string
|
||||
@@ -28,6 +30,7 @@ export interface AdminFulfillmentSet {
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
location: AdminStockLocation
|
||||
service_zones: AdminServiceZone[]
|
||||
created_at: string
|
||||
updated_at: string
|
||||
|
||||
@@ -2,6 +2,8 @@ import { AdminPaymentCollection } from "../payment/admin"
|
||||
import {
|
||||
BaseOrder,
|
||||
BaseOrderAddress,
|
||||
BaseOrderChange,
|
||||
BaseOrderChangeAction,
|
||||
BaseOrderFilters,
|
||||
BaseOrderLineItem,
|
||||
BaseOrderShippingMethod,
|
||||
@@ -45,3 +47,19 @@ export interface AdminCreateOrderShipment {
|
||||
export interface AdminCancelOrderFulfillment {
|
||||
no_notification?: boolean
|
||||
}
|
||||
|
||||
// Order Preview
|
||||
|
||||
export interface AdminOrderPreview
|
||||
extends Omit<AdminOrder, "items" | "shipping_methods"> {
|
||||
return_requested_total: number
|
||||
order_change: BaseOrderChange
|
||||
items: (BaseOrderLineItem & { actions?: BaseOrderChangeAction[] })[]
|
||||
shipping_methods: (BaseOrderShippingMethod & {
|
||||
actions?: BaseOrderChangeAction[]
|
||||
})[]
|
||||
}
|
||||
|
||||
export interface AdminOrderPreviewResponse {
|
||||
order: AdminOrderPreview
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
import { BigNumberValue } from "../../totals"
|
||||
import { BaseClaim } from "../claim/common"
|
||||
import { BasePaymentCollection } from "../payment/common"
|
||||
import { BaseProduct, BaseProductVariant } from "../product/common"
|
||||
|
||||
@@ -116,7 +117,7 @@ export interface BaseOrderLineItem {
|
||||
title: string
|
||||
subtitle: string | null
|
||||
thumbnail: string | null
|
||||
variant?: BaseProductVariant
|
||||
variant?: BaseProductVariant | null
|
||||
variant_id: string | null
|
||||
product?: BaseProduct
|
||||
product_id: string | null
|
||||
@@ -305,3 +306,224 @@ export interface BaseOrderFilters extends BaseFilterable<BaseOrderFilters> {
|
||||
id?: string[] | string | OperatorMap<string | string[]>
|
||||
status?: string[] | string | OperatorMap<string | string[]>
|
||||
}
|
||||
|
||||
export interface BaseOrderChange {
|
||||
/**
|
||||
* The ID of the order change
|
||||
*/
|
||||
id: string
|
||||
|
||||
/**
|
||||
* The version of the order change
|
||||
*/
|
||||
version: number
|
||||
|
||||
/**
|
||||
* The type of the order change
|
||||
*/
|
||||
change_type?: "return" | "exchange" | "claim" | "edit"
|
||||
|
||||
/**
|
||||
* The ID of the associated order
|
||||
*/
|
||||
order_id: string
|
||||
|
||||
/**
|
||||
* The ID of the associated return order
|
||||
*/
|
||||
return_id: string
|
||||
|
||||
/**
|
||||
* The ID of the associated exchange order
|
||||
*/
|
||||
exchange_id: string
|
||||
|
||||
/**
|
||||
* The ID of the associated claim order
|
||||
*/
|
||||
claim_id: string
|
||||
|
||||
/**
|
||||
* The associated order
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
order: BaseOrder
|
||||
|
||||
/**
|
||||
* The associated return order
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
return_order: any
|
||||
|
||||
/**
|
||||
* The associated exchange order
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
exchange: any
|
||||
|
||||
/**
|
||||
* The associated claim order
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
claim: BaseClaim
|
||||
|
||||
/**
|
||||
* The actions of the order change
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
actions: BaseOrderChangeAction[]
|
||||
|
||||
/**
|
||||
* The status of the order change
|
||||
*/
|
||||
status: string
|
||||
|
||||
/**
|
||||
* The requested by of the order change
|
||||
*/
|
||||
requested_by: string | null
|
||||
|
||||
/**
|
||||
* When the order change was requested
|
||||
*/
|
||||
requested_at: Date | string | null
|
||||
|
||||
/**
|
||||
* The confirmed by of the order change
|
||||
*/
|
||||
confirmed_by: string | null
|
||||
|
||||
/**
|
||||
* When the order change was confirmed
|
||||
*/
|
||||
confirmed_at: Date | string | null
|
||||
|
||||
/**
|
||||
* The declined by of the order change
|
||||
*/
|
||||
declined_by: string | null
|
||||
|
||||
/**
|
||||
* The declined reason of the order change
|
||||
*/
|
||||
declined_reason: string | null
|
||||
|
||||
/**
|
||||
* The metadata of the order change
|
||||
*/
|
||||
metadata: Record<string, unknown> | null
|
||||
|
||||
/**
|
||||
* When the order change was declined
|
||||
*/
|
||||
declined_at: Date | string | null
|
||||
|
||||
/**
|
||||
* The canceled by of the order change
|
||||
*/
|
||||
canceled_by: string | null
|
||||
|
||||
/**
|
||||
* When the order change was canceled
|
||||
*/
|
||||
canceled_at: Date | string | null
|
||||
|
||||
/**
|
||||
* When the order change was created
|
||||
*/
|
||||
created_at: Date | string
|
||||
|
||||
/**
|
||||
* When the order change was updated
|
||||
*/
|
||||
updated_at: Date | string
|
||||
}
|
||||
|
||||
/**
|
||||
* The order change action details.
|
||||
*/
|
||||
export interface BaseOrderChangeAction {
|
||||
/**
|
||||
* The ID of the order change action
|
||||
*/
|
||||
id: string
|
||||
|
||||
/**
|
||||
* The ID of the associated order change
|
||||
*/
|
||||
order_change_id: string | null
|
||||
|
||||
/**
|
||||
* The associated order change
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
order_change: BaseOrderChange | null
|
||||
|
||||
/**
|
||||
* The ID of the associated order
|
||||
*/
|
||||
order_id: string | null
|
||||
|
||||
/**
|
||||
* The ID of the associated return.
|
||||
*/
|
||||
return_id: string | null
|
||||
|
||||
/**
|
||||
* The ID of the associated claim.
|
||||
*/
|
||||
claim_id: string | null
|
||||
|
||||
/**
|
||||
* The ID of the associated exchange.
|
||||
*/
|
||||
exchange_id: string | null
|
||||
|
||||
/**
|
||||
* The associated order
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
order: BaseOrder | null
|
||||
|
||||
/**
|
||||
* The reference of the order change action
|
||||
*/
|
||||
reference: string
|
||||
|
||||
/**
|
||||
* The ID of the reference
|
||||
*/
|
||||
reference_id: string
|
||||
|
||||
/**
|
||||
* The action of the order change action
|
||||
*/
|
||||
action: string
|
||||
|
||||
/**
|
||||
* The details of the order change action
|
||||
*/
|
||||
details: Record<string, unknown> | null
|
||||
|
||||
/**
|
||||
* The internal note of the order change action
|
||||
*/
|
||||
internal_note: string | null
|
||||
|
||||
/**
|
||||
* When the order change action was created
|
||||
*/
|
||||
created_at: Date | string
|
||||
|
||||
/**
|
||||
* When the order change action was updated
|
||||
*/
|
||||
updated_at: Date | string
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ export interface AdminAddReturnItems {
|
||||
|
||||
export interface AdminUpdateReturnItems {
|
||||
quantity?: number
|
||||
internal_note?: string
|
||||
reason_id?: string
|
||||
internal_note?: string | null
|
||||
reason_id?: string | null
|
||||
}
|
||||
|
||||
export interface AdminAddReturnShipping {
|
||||
|
||||
@@ -86,7 +86,7 @@ export interface UpdateClaimItemWorkflowInput {
|
||||
action_id: string
|
||||
data: {
|
||||
quantity?: BigNumberInput
|
||||
reason_id?: ClaimReason
|
||||
reason_id?: string | null
|
||||
internal_note?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ export const AdminPostOrderClaimsReqSchema = z.object({
|
||||
order_id: z.string(),
|
||||
description: z.string().optional(),
|
||||
internal_note: z.string().optional(),
|
||||
reason_id: z.string().nullish(),
|
||||
metadata: z.record(z.unknown()).nullish(),
|
||||
})
|
||||
export type AdminPostOrderClaimsReqSchemaType = z.infer<
|
||||
@@ -173,7 +174,7 @@ export type AdminPostClaimItemsReqSchemaType = z.infer<
|
||||
export const AdminPostClaimsRequestItemsActionReqSchema = z.object({
|
||||
quantity: z.number().optional(),
|
||||
internal_note: z.string().nullish().optional(),
|
||||
reason: z.nativeEnum(ClaimReason).nullish().optional(),
|
||||
reason_id: z.string().nullish(),
|
||||
metadata: z.record(z.unknown()).nullish().optional(),
|
||||
})
|
||||
|
||||
@@ -183,7 +184,7 @@ export type AdminPostClaimsRequestItemsActionReqSchemaType = z.infer<
|
||||
|
||||
export const AdminPostClaimsItemsActionReqSchema = z.object({
|
||||
quantity: z.number().optional(),
|
||||
reason: z.nativeEnum(ClaimReason).nullish().optional(),
|
||||
reason_id: z.string().nullish(),
|
||||
internal_note: z.string().nullish().optional(),
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user