feat(dashboard): transfer order admin (#10189)

**What**
- request order transfer from order details page
- timeline events

---

CLOSES CMRC-706
CLOSES CMRC-707
This commit is contained in:
Frane Polić
2024-11-22 09:29:12 +01:00
committed by GitHub
parent 58f24a373d
commit 44265a928d
16 changed files with 765 additions and 75 deletions

View File

@@ -251,13 +251,13 @@ export const useMarkOrderFulfillmentAsDelivered = (
export const useCancelOrder = (
orderId: string,
options?: UseMutationOptions<any, FetchError, any>
options?: UseMutationOptions<HttpTypes.AdminOrderResponse, FetchError, void>
) => {
return useMutation({
mutationFn: (id) => sdk.admin.order.cancel(id),
mutationFn: () => sdk.admin.order.cancel(orderId),
onSuccess: (data: any, variables: any, context: any) => {
queryClient.invalidateQueries({
queryKey: ordersQueryKeys.details(),
queryKey: ordersQueryKeys.detail(orderId),
})
queryClient.invalidateQueries({
@@ -269,3 +269,25 @@ export const useCancelOrder = (
...options,
})
}
export const useRequestTransferOrder = (
orderId: string,
options?: UseMutationOptions<
HttpTypes.AdminOrderResponse,
FetchError,
HttpTypes.AdminRequestOrderTransfer
>
) => {
return useMutation({
mutationFn: (payload: HttpTypes.AdminRequestOrderTransfer) =>
sdk.admin.order.requestTransfer(orderId, payload),
onSuccess: (data: any, variables: any, context: any) => {
queryClient.invalidateQueries({
queryKey: ordersQueryKeys.preview(orderId),
})
options?.onSuccess?.(data, variables, context)
},
...options,
})
}

View File

@@ -3820,6 +3820,38 @@
],
"additionalProperties": false
},
"transfer": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"requestSuccess": {
"type": "string"
},
"currentOwner": {
"type": "string"
},
"newOwner": {
"type": "string"
},
"currentOwnerDescription": {
"type": "string"
},
"newOwnerDescription": {
"type": "string"
}
},
"required": [
"title",
"requestSuccess",
"currentOwner",
"newOwner",
"currentOwnerDescription",
"newOwnerDescription"
],
"additionalProperties": false
},
"payment": {
"type": "object",
"properties": {
@@ -5058,6 +5090,12 @@
],
"additionalProperties": false
},
"from": {
"type": "string"
},
"to": {
"type": "string"
},
"events": {
"type": "object",
"properties": {
@@ -5268,6 +5306,22 @@
"confirmed"
],
"additionalProperties": false
},
"transfer": {
"type": "object",
"properties": {
"requested": {
"type": "string"
},
"confirmed": {
"type": "string"
}
},
"required": [
"requested",
"confirmed"
],
"additionalProperties": false
}
},
"required": [
@@ -5280,7 +5334,8 @@
"note",
"claim",
"exchange",
"edit"
"edit",
"transfer"
],
"additionalProperties": false
}
@@ -5290,6 +5345,8 @@
"showMoreActivities_one",
"showMoreActivities_other",
"comment",
"from",
"to",
"events"
],
"additionalProperties": false
@@ -5324,6 +5381,7 @@
"onDateFromSalesChannel",
"list",
"summary",
"transfer",
"payment",
"edits",
"returns",

View File

@@ -922,6 +922,14 @@
"discountSubtotal": "Discount Subtotal",
"taxTotal": "Tax Total"
},
"transfer": {
"title": "Transfer ownership",
"requestSuccess": "Order transfer request sent to: {{email}}.",
"currentOwner": "Current owner",
"newOwner": "New owner",
"currentOwnerDescription": "The customer currently related to this order.",
"newOwnerDescription": "The customer to transfer this order to."
},
"payment": {
"title": "Payments",
"isReadyToBeCaptured": "Payment <0/> is ready to be captured.",
@@ -1225,6 +1233,8 @@
"addButtonText": "Add comment",
"deleteButtonText": "Delete comment"
},
"from": "From",
"to": "To",
"events": {
"common": {
"toReturn": "To return",
@@ -1277,6 +1287,10 @@
"edit": {
"requested": "Order edit #{{editId}} requested",
"confirmed": "Order edit #{{editId}} confirmed"
},
"transfer": {
"requested": "Order transfer #{{transferId}} requested",
"confirmed": "Order transfer #{{transferId}} confirmed"
}
}
},

View File

@@ -317,6 +317,11 @@ export const RouteMap: RouteObject[] = [
lazy: () =>
import("../../routes/orders/order-create-refund"),
},
{
path: "transfer",
lazy: () =>
import("../../routes/orders/order-request-transfer"),
},
],
},
],

View File

@@ -102,7 +102,7 @@ const CustomerOrderActions = ({ order }: { order: HttpTypes.AdminOrder }) => {
actions: [
{
label: t("transferOwnership.label"),
to: `${order.id}/transfer-ownership`,
to: `${order.id}/transfer`,
icon: <ArrowPath />,
},
],

View File

@@ -16,7 +16,11 @@ import {
import { useTranslation } from "react-i18next"
import { AdminOrderLineItem } from "@medusajs/types"
import { useOrderChanges, useOrderLineItems } from "../../../../../hooks/api"
import {
useCustomer,
useOrderChanges,
useOrderLineItems,
} from "../../../../../hooks/api"
import { useCancelClaim, useClaims } from "../../../../../hooks/api/claims"
import {
useCancelExchange,
@@ -113,10 +117,12 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
const { t } = useTranslation()
const { order_changes: orderChanges = [] } = useOrderChanges(order.id, {
change_type: ["edit", "claim", "exchange", "return"],
change_type: ["edit", "claim", "exchange", "return", "transfer"],
})
const missingLineItemIds = getMissingLineItemIds(order, orderChanges)
const rmaChanges = orderChanges.filter((oc) => oc.change_type !== "transfer")
const missingLineItemIds = getMissingLineItemIds(order, rmaChanges)
const { order_items: removedLineItems = [] } = useOrderLineItems(
order.id,
@@ -125,7 +131,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
item_id: missingLineItemIds,
},
{
enabled: !!orderChanges.length,
enabled: !!rmaChanges.length,
}
)
@@ -370,16 +376,39 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
edit.status === "requested"
? edit.requested_at
: edit.status === "confirmed"
? edit.confirmed_at
: edit.status === "declined"
? edit.declined_at
: edit.status === "canceled"
? edit.canceled_at
: edit.created_at,
? edit.confirmed_at
: edit.status === "declined"
? edit.declined_at
: edit.status === "canceled"
? edit.canceled_at
: edit.created_at,
children: isConfirmed ? <OrderEditBody edit={edit} /> : null,
})
}
for (const transfer of orderChanges.filter(
(oc) => oc.change_type === "transfer"
)) {
if (transfer.requested_at) {
items.push({
title: t(`orders.activity.events.transfer.requested`, {
transferId: transfer.id.slice(-7),
}),
timestamp: transfer.requested_at,
children: <TransferOrderRequestBody transfer={transfer} />,
})
}
if (transfer.confirmed_at) {
items.push({
title: t(`orders.activity.events.transfer.confirmed`, {
transferId: transfer.id.slice(-7),
}),
timestamp: transfer.confirmed_at,
})
}
}
// for (const note of notes || []) {
// items.push({
// title: t("orders.activity.events.note.comment"),
@@ -862,6 +891,36 @@ const OrderEditBody = ({ edit }: { edit: AdminOrderChange }) => {
)
}
const TransferOrderRequestBody = ({
transfer,
}: {
transfer: AdminOrderChange
}) => {
const { t } = useTranslation()
const action = transfer.actions[0]
const { customer } = useCustomer(action.reference_id)
/**
* TODO: change original_email to customer info when action details is changed
*/
return (
<div>
<Text size="small" className="text-ui-fg-subtle">
{t("orders.activity.from")}: {action.details?.original_email}
</Text>
<Text size="small" className="text-ui-fg-subtle">
{t("orders.activity.to")}:{" "}
{customer?.first_name
? `${customer?.first_name} ${customer?.last_name}`
: customer?.email}
</Text>
</div>
)
}
/**
* Returns count of added and removed item quantity
*/

View File

@@ -33,7 +33,7 @@ const Header = () => {
actions: [
{
label: t("transferOwnership.label"),
to: `transfer-ownership`,
to: `transfer`,
icon: <ArrowPath />,
},
],

View File

@@ -41,7 +41,7 @@ export const OrderGeneralSection = ({ order }: OrderGeneralSectionProps) => {
return
}
await cancelOrder(order.id)
await cancelOrder()
}
return (

View File

@@ -0,0 +1,150 @@
import * as zod from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { HttpTypes } from "@medusajs/types"
import { Button, Input, toast } from "@medusajs/ui"
import { useForm } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { Form } from "../../../../../components/common/form"
import { RouteDrawer, useRouteModal } from "../../../../../components/modals"
import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
import { useComboboxData } from "../../../../../hooks/use-combobox-data"
import { Combobox } from "../../../../../components/inputs/combobox"
import { useRequestTransferOrder } from "../../../../../hooks/api"
import { sdk } from "../../../../../lib/client"
import { TransferHeader } from "./transfer-header"
type CreateOrderTransferFormProps = {
order: HttpTypes.AdminOrder
}
const CreateOrderTransferSchema = zod.object({
customer_id: zod.string().min(1),
current_customer_details: zod.string().min(1),
})
export function CreateOrderTransferForm({
order,
}: CreateOrderTransferFormProps) {
const { t } = useTranslation()
const { handleSuccess } = useRouteModal()
const form = useForm<zod.infer<typeof CreateOrderTransferSchema>>({
defaultValues: {
customer_id: "",
current_customer_details: order.customer?.first_name
? `${order.customer?.first_name} ${order.customer?.last_name} (${order.customer?.email}) `
: order.customer?.email,
},
resolver: zodResolver(CreateOrderTransferSchema),
})
const customers = useComboboxData({
queryKey: ["customers"],
queryFn: (params) =>
sdk.admin.customer.list({ ...params, has_account: true }),
getOptions: (data) =>
data.customers.map((item) => ({
label: `${item.first_name || ""} ${item.last_name || ""} (${item.email})`,
value: item.id,
})),
})
const { mutateAsync, isPending } = useRequestTransferOrder(order.id)
const handleSubmit = form.handleSubmit(async (data) => {
try {
await mutateAsync({
customer_id: data.customer_id,
})
toast.success(t("orders.transfer.requestSuccess", { email: order.email }))
handleSuccess()
} catch (error) {
toast.error((error as Error).message)
}
})
return (
<RouteDrawer.Form form={form}>
<KeyboundForm
onSubmit={handleSubmit}
className="flex size-full flex-col overflow-hidden"
>
<RouteDrawer.Body className="flex-1 overflow-auto">
<div className="flex flex-col gap-y-8">
<TransferHeader />
<Form.Field
control={form.control}
name="current_customer_details"
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("orders.transfer.currentOwner")}</Form.Label>
<span className="txt-small text-ui-fg-muted">
{t("orders.transfer.currentOwnerDescription")}
</span>
<Form.Control>
<Input type="email" {...field} disabled />
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
<Form.Field
control={form.control}
name="customer_id"
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("orders.transfer.newOwner")}</Form.Label>
<span className="txt-small text-ui-fg-muted">
{t("orders.transfer.newOwnerDescription")}
</span>
<Form.Control>
<Combobox
{...field}
options={customers.options}
searchValue={customers.searchValue}
onSearchValueChange={customers.onSearchValueChange}
fetchNextPage={customers.fetchNextPage}
className="bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover"
placeholder={t("actions.select")}
/>
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
</div>
</RouteDrawer.Body>
<RouteDrawer.Footer>
<div className="flex items-center justify-end gap-x-2">
<RouteDrawer.Close asChild>
<Button variant="secondary" size="small">
{t("actions.cancel")}
</Button>
</RouteDrawer.Close>
<Button
isLoading={isPending}
type="submit"
variant="primary"
size="small"
disabled={!!Object.keys(form.formState.errors || {}).length}
>
{t("actions.save")}
</Button>
</div>
</RouteDrawer.Footer>
</KeyboundForm>
</RouteDrawer.Form>
)
}

View File

@@ -0,0 +1 @@
export * from "./create-order-transfer-form"

View File

@@ -0,0 +1,303 @@
export function TransferHeader() {
return (
<svg
width="200"
height="128"
viewBox="0 0 200 128"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.00428286"
y="-0.742904"
width="33.5"
height="65.5"
rx="6.75"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 149.756 60.938)"
fill="#E4E4E7"
stroke="#52525B"
strokeWidth="1.5"
/>
<rect
x="0.00428286"
y="-0.742904"
width="33.5"
height="65.5"
rx="6.75"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 149.756 57.9383)"
fill="white"
stroke="#52525B"
strokeWidth="1.5"
/>
<g clipPath="url(#clip0_20787_38934)">
<path
d="M140.579 79.6421L139.126 80.4592"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.88"
d="M142.305 82.046L140.257 82.0342"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.75"
d="M140.552 84.4297L139.108 83.5959"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.63"
d="M136.347 85.3975L136.354 84.23"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.5"
d="M132.154 84.3813L133.606 83.5642"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.38"
d="M130.428 81.9775L132.476 81.9893"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.25"
d="M132.181 79.5938L133.625 80.4275"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
opacity="0.13"
d="M136.386 78.626L136.379 79.7935"
stroke="#52525B"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<rect
width="12"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 156.447 64.7927)"
fill="#E4E4E7"
/>
<rect
x="0.00428286"
y="-0.742904"
width="33.5"
height="65.5"
rx="6.75"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 77.0232 18.9148)"
fill="#E4E4E7"
stroke="#52525B"
strokeWidth="1.5"
/>
<rect
x="0.00428286"
y="-0.742904"
width="33.5"
height="65.5"
rx="6.75"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 77.0232 15.9148)"
fill="white"
stroke="#52525B"
strokeWidth="1.5"
/>
<rect
width="12"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 83.7141 22.7693)"
fill="#E4E4E7"
/>
<rect
width="17"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 57.5554 39.458)"
fill="#E4E4E7"
/>
<rect
width="12"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 53.1975 41.9094)"
fill="#E4E4E7"
/>
<g clipPath="url(#clip1_20787_38934)">
<path
d="M52.3603 36.4564C50.9277 35.6287 48.59 35.6152 47.148 36.4264C45.7059 37.2375 45.6983 38.5703 47.1308 39.398C48.5634 40.2257 50.9011 40.2392 52.3432 39.428C53.7852 38.6169 53.7929 37.2841 52.3603 36.4564ZM48.4382 38.6626C47.7221 38.2488 47.726 37.5822 48.4468 37.1768C49.1676 36.7713 50.3369 36.7781 51.0529 37.1918C51.769 37.6055 51.7652 38.2722 51.0444 38.6776C50.3236 39.083 49.1543 39.0763 48.4382 38.6626Z"
fill="#A1A1AA"
/>
</g>
<rect
width="17"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 69.7573 32.5945)"
fill="#E4E4E7"
/>
<rect
width="12"
height="3"
rx="1.5"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 65.3994 35.0459)"
fill="#E4E4E7"
/>
<g clipPath="url(#clip2_20787_38934)">
<path
d="M64.5622 29.5929C63.1296 28.7652 60.7919 28.7517 59.3499 29.5628C57.9079 30.374 57.9002 31.7067 59.3327 32.5344C60.7653 33.3622 63.103 33.3756 64.5451 32.5645C65.9871 31.7534 65.9948 30.4206 64.5622 29.5929ZM63.8581 31.3974L60.8148 31.6267C60.6827 31.6368 60.5495 31.6135 60.4486 31.5632C60.4399 31.5587 60.4321 31.5547 60.4244 31.5502C60.3386 31.5006 60.2899 31.4337 60.2903 31.3639L60.2933 30.6203C60.2937 30.4754 60.5012 30.3587 60.7557 30.3602C61.0102 30.3616 61.2163 30.4802 61.2155 30.6258L61.2138 31.0671L63.7317 30.8771C63.9833 30.858 64.2168 30.9586 64.2512 31.1032C64.286 31.247 64.1101 31.379 63.8581 31.3978L63.8581 31.3974Z"
fill="#A1A1AA"
/>
</g>
<g clipPath="url(#clip3_20787_38934)">
<path
d="M93.106 54.3022L100.49 54.3448L100.514 50.135"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<g clipPath="url(#clip4_20787_38934)">
<path
d="M103.496 60.3056L110.881 60.3482L110.905 56.1384"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<g clipPath="url(#clip5_20787_38934)">
<path
d="M113.887 66.3088L121.271 66.3514L121.295 62.1416"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<g clipPath="url(#clip6_20787_38934)">
<path
d="M86.1135 61.6911L78.7294 61.6486L78.7051 65.8583"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<g clipPath="url(#clip7_20787_38934)">
<path
d="M96.5039 67.6945L89.1198 67.652L89.0955 71.8618"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<g clipPath="url(#clip8_20787_38934)">
<path
d="M106.894 73.6977L99.5102 73.6551L99.4859 77.8649"
stroke="#A1A1AA"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 136.401 76.0686)"
/>
</clipPath>
<clipPath id="clip1_20787_38934">
<rect
width="6"
height="6"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 49.7627 34.9556)"
/>
</clipPath>
<clipPath id="clip2_20787_38934">
<rect
width="6"
height="6"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 61.9646 28.092)"
/>
</clipPath>
<clipPath id="clip3_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 98.3596 47.1509)"
/>
</clipPath>
<clipPath id="clip4_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 108.75 53.1543)"
/>
</clipPath>
<clipPath id="clip5_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 119.14 59.1575)"
/>
</clipPath>
<clipPath id="clip6_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 80.9282 56.9561)"
/>
</clipPath>
<clipPath id="clip7_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 91.3186 62.9595)"
/>
</clipPath>
<clipPath id="clip8_20787_38934">
<rect
width="12"
height="12"
fill="white"
transform="matrix(0.865865 0.500278 -0.871576 0.490261 101.709 68.9626)"
/>
</clipPath>
</defs>
</svg>
)
}

View File

@@ -0,0 +1 @@
export { OrderRequestTransfer as Component } from "./order-request-transfer"

View File

@@ -0,0 +1,26 @@
import { Heading } from "@medusajs/ui"
import { useTranslation } from "react-i18next"
import { useParams } from "react-router-dom"
import { RouteDrawer } from "../../../components/modals"
import { useOrder } from "../../../hooks/api"
import { DEFAULT_FIELDS } from "../order-detail/constants"
import { CreateOrderTransferForm } from "./components/create-order-transfer-form"
export const OrderRequestTransfer = () => {
const { t } = useTranslation()
const params = useParams()
const { order } = useOrder(params.id!, {
fields: DEFAULT_FIELDS,
})
return (
<RouteDrawer>
<RouteDrawer.Header>
<Heading>{t("orders.transfer.title")}</Heading>
</RouteDrawer.Header>
<CreateOrderTransferForm order={order} />
</RouteDrawer>
)
}

View File

@@ -22,27 +22,27 @@ export class Order {
}
/**
* This method retrieves an order by its ID. It sends a request to the
* This method retrieves an order by its ID. It sends a request to the
* [Get Order](https://docs.medusajs.com/api/admin#orders_getordersid)
* API route.
*
*
* @param id - The order's ID.
* @param query - Configure the fields to retrieve in the order.
* @param headers - Headers to pass in the request
* @returns The order's details.
*
*
* @example
* To retrieve an order by its ID:
*
*
* ```ts
* sdk.admin.order.retrieve("order_123")
* .then(({ order }) => {
* console.log(order)
* })
* ```
*
*
* To specify the fields and relations to retrieve:
*
*
* ```ts
* sdk.admin.order.retrieve("order_123", {
* fields: "id,*items"
@@ -51,7 +51,7 @@ export class Order {
* console.log(order)
* })
* ```
*
*
* Learn more about the `fields` property in the [API reference](https://docs.medusajs.com/api/store#select-fields-and-relations).
*/
async retrieve(id: string, query?: SelectParams, headers?: ClientHeaders) {
@@ -65,14 +65,14 @@ export class Order {
}
/**
* This method retrieves the preview of an order based on its last associated change. It sends a request to the
* This method retrieves the preview of an order based on its last associated change. It sends a request to the
* [Get Order Preview](https://docs.medusajs.com/api/admin#orders_getordersidpreview) API route.
*
*
* @param id - The order's ID.
* @param query - Query parameters.
* @param headers - Headers to pass in the request
* @returns The order preview's details.
*
*
* @example
* sdk.admin.order.retrievePreview("order_123")
* .then(({ order }) => {
@@ -94,27 +94,27 @@ export class Order {
}
/**
* This method retrieves a paginated list of orders. It sends a request to the
* This method retrieves a paginated list of orders. It sends a request to the
* [List Orders](https://docs.medusajs.com/api/admin#orders_getorders) API route.
*
*
* @param queryParams - Filters and pagination configurations.
* @param headers - Headers to pass in the request.
* @returns The paginated list of orders.
*
*
* @example
* To retrieve the list of orders:
*
*
* ```ts
* sdk.admin.order.list()
* .then(({ orders, count, limit, offset }) => {
* console.log(orders)
* })
* ```
*
*
* To configure the pagination, pass the `limit` and `offset` query parameters.
*
*
* For example, to retrieve only 10 items and skip 10 items:
*
*
* ```ts
* sdk.admin.order.list({
* limit: 10,
@@ -124,10 +124,10 @@ export class Order {
* console.log(orders)
* })
* ```
*
*
* Using the `fields` query parameter, you can specify the fields and relations to retrieve
* in each order:
*
*
* ```ts
* sdk.admin.order.list({
* fields: "id,*items"
@@ -136,30 +136,31 @@ export class Order {
* console.log(orders)
* })
* ```
*
*
* Learn more about the `fields` property in the [API reference](https://docs.medusajs.com/api/store#select-fields-and-relations).
*/
async list(
queryParams?: HttpTypes.AdminOrderFilters,
headers?: ClientHeaders
) {
return await this.client.fetch<
HttpTypes.AdminOrderListResponse
>(`/admin/orders`, {
query: queryParams,
headers,
})
return await this.client.fetch<HttpTypes.AdminOrderListResponse>(
`/admin/orders`,
{
query: queryParams,
headers,
}
)
}
/**
* This method cancels an order. It sends a request to the
* [Cancel Order](https://docs.medusajs.com/api/admin#orders_postordersidcancel)
* API route.
*
*
* @param id - The order's ID.
* @param headers - Headers to pass in the request.
* @returns The order's details.
*
*
* @example
* sdk.admin.order.cancel("order_123")
* .then(({ order }) => {
@@ -176,17 +177,51 @@ export class Order {
)
}
/**
* This method requests an order transfer. It sends a request to the
* [Request Order Transfer](https://docs.medusajs.com/api/admin#orders_postordersidrequesttransfer)
* API route.
*
* @param id - The order's ID.
* @param headers - Headers to pass in the request.
* @param body - The transfer's details - the id of the next owner.
* @returns The order's details.
*
* @example
* sdk.admin.order.requestTransfer("order_123", {
* customer_id: "cus_123",
* internal_note: "Internal note",
* })
* .then(({ order }) => {
* console.log(order)
* })
*/
async requestTransfer(
id: string,
body: HttpTypes.AdminRequestOrderTransfer,
headers?: ClientHeaders
) {
return await this.client.fetch<HttpTypes.AdminOrderResponse>(
`/admin/orders/${id}/transfer`,
{
method: "POST",
headers,
body,
}
)
}
/**
* This method creates a fulfillment for an order. It sends a request to the
* [Create Fulfillment](https://docs.medusajs.com/api/admin#orders_postordersidfulfillments)
* API route.
*
*
* @param id - The order's ID.
* @param body - The fulfillment's details.
* @param query - Configure the fields to retrieve in the order.
* @param headers - Headers to pass in the request
* @returns The order's details.
*
*
* @example
* sdk.admin.order.createFulfillment("order_123", {
* items: [
@@ -221,13 +256,13 @@ export class Order {
* This method cancels an order's fulfillment. It sends a request to the
* [Cancel Fulfillment](https://docs.medusajs.com/api/admin#orders_postordersidfulfillmentsfulfillment_idcancel)
* API route.
*
*
* @param id - The order's ID.
* @param fulfillmentId - The ID of the fulfillment to cancel.
* @param body - The cancelation's details.
* @param headers - Headers to pass in the request
* @returns The order's details.
*
*
* @example
* sdk.admin.order.cancelFulfillment(
* "order_123",
@@ -260,14 +295,14 @@ export class Order {
* This method creates a shipment for an order's fulfillment. It sends a request to the
* [Create Shipment](https://docs.medusajs.com/api/admin#orders_postordersidfulfillmentsfulfillment_idshipments)
* API route.
*
*
* @param id - The order's ID.
* @param fulfillmentId - The ID of the fulfillment.
* @param body - The shipment's details.
* @param query - Configure the fields to retrieve in the order.
* @param headers - Headers to pass in the request
* @returns The order's details.
*
*
* @example
* sdk.admin.order.createShipment(
* "order_123",
@@ -307,14 +342,14 @@ export class Order {
* This method marks an order's fulfillment as delivered. It sends a request to the
* [Mark Delivered ](https://docs.medusajs.com/api/admin#orders_postordersidfulfillmentsfulfillment_idmarkasdelivered)
* API route.
*
*
* @param id - The order's ID.
* @param fulfillmentId - The fulfillment's ID.
* @param body - The delivery details.
* @param query - Configure the fields to retrieve in the order.
* @param headers - Headers to pass in the request
* @returns The order's details.
*
*
* @example
* sdk.admin.order.markAsDelivered(
* "order_123",
@@ -345,15 +380,15 @@ export class Order {
/**
* This method retrieves a list of changes made on an order, including returns, exchanges, etc...
*
*
* This method sends a request to the [List Changes](https://docs.medusajs.com/api/admin#orders_getordersidchanges)
* API route.
*
*
* @param id - The order's ID.
* @param queryParams - Configure the fields to retrieve in each order change.
* @param headers - Headers to pass in the request
* @returns The list of order changes.
*
*
* @example
* sdk.admin.order.listChanges("order_123")
* .then(({ order_changes }) => {
@@ -377,12 +412,12 @@ export class Order {
* This method retrieves the order's line items. It sends a request to the
* [List Line Items](https://docs.medusajs.com/api/admin#orders_getordersidlineitems)
* API routes.
*
*
* @param id - The order's ID.
* @param queryParams - Configure the fields to retrieve in each line item.
* @param headers - Headers to pass in the request
* @returns The list of line items.
*
*
* @example
* sdk.admin.order.listLineItems("order_123")
* .then(({ order_items }) => {
@@ -394,11 +429,12 @@ export class Order {
queryParams?: FindParams & HttpTypes.AdminOrderItemsFilters,
headers?: ClientHeaders
) {
return await this.client.fetch<
HttpTypes.AdminOrderLineItemsListResponse
>(`/admin/orders/${id}/line-items`, {
query: queryParams,
headers,
})
return await this.client.fetch<HttpTypes.AdminOrderLineItemsListResponse>(
`/admin/orders/${id}/line-items`,
{
query: queryParams,
headers,
}
)
}
}

View File

@@ -5,8 +5,8 @@ export interface AdminCreateOrderFulfillment {
items: {
/**
* The order item's ID.
*/
id: string;
*/
id: string
/**
* The quantity to fulfill.
*/
@@ -34,8 +34,8 @@ export interface AdminCreateOrderShipment {
items: {
/**
* The item's ID.
*/
id: string;
*/
id: string
/**
* The quantity to ship.
*/
@@ -76,3 +76,9 @@ export interface AdminCancelOrderFulfillment {
}
export interface AdminMarkOrderFulfillmentAsDelivered {}
export interface AdminRequestOrderTransfer {
customer_id: string
internal_note?: string
description?: string
}

View File

@@ -224,7 +224,7 @@ export interface BaseOrderAddress {
city?: string
/**
* The address's country code.
*
*
* @example us
*/
country_code?: string
@@ -281,7 +281,7 @@ export interface BaseOrderShippingMethod {
shipping_option_id: string | null
/**
* Data relevant for the fulfillment provider handling the shipping.
*
*
* Learn more in [this guide](https://docs.medusajs.com/resources/commerce-modules/fulfillment/shipping-option#data-property).
*/
data: Record<string, unknown> | null
@@ -631,7 +631,7 @@ export interface BaseOrderTransaction {
amount: number
/**
* The transaction's currency code.
*
*
* @example
* usd
*/
@@ -689,7 +689,7 @@ export interface BaseOrderFulfillment {
requires_shipping: boolean
/**
* Data necessary for the provider handling the fulfillment.
*
*
* Learn more in [this guide](https://docs.medusajs.com/resources/commerce-modules/fulfillment/shipping-option#data-property).
*/
data: Record<string, unknown> | null
@@ -764,7 +764,7 @@ export interface BaseOrder {
email: string | null
/**
* The order's currency code.
*
*
* @example
* usd
*/
@@ -925,7 +925,10 @@ export interface BaseOrderFilters
/**
* Filter by status(es).
*/
status?: OrderStatus[] | OrderStatus | OperatorMap<OrderStatus | OrderStatus[]>
status?:
| OrderStatus[]
| OrderStatus
| OperatorMap<OrderStatus | OrderStatus[]>
}
export interface BaseOrderChangesFilters
@@ -958,7 +961,13 @@ export interface BaseOrderChange {
/**
* The type of the order change
*/
change_type?: "return" | "exchange" | "claim" | "edit" | "return_request"
change_type?:
| "return"
| "exchange"
| "claim"
| "edit"
| "return_request"
| "transfer"
/**
* The ID of the associated order