feat: Add Draft Order plugin (#13291)
* feat: Add draft order plugin * version draft order plugin * update readme * chore: Update scripts * Create purple-dolls-cheer.md * port over latest changes * chore: Make package public
This commit is contained in:
1767
packages/plugins/draft-order/src/admin/lib/data/countries.ts
Normal file
1767
packages/plugins/draft-order/src/admin/lib/data/countries.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
export const getLocaleAmount = (amount: number, currencyCode: string) => {
|
||||
const formatter = new Intl.NumberFormat([], {
|
||||
style: "currency",
|
||||
currencyDisplay: "narrowSymbol",
|
||||
currency: currencyCode,
|
||||
})
|
||||
|
||||
return formatter.format(amount)
|
||||
}
|
||||
|
||||
export const getNativeSymbol = (currencyCode: string) => {
|
||||
const formatted = new Intl.NumberFormat([], {
|
||||
style: "currency",
|
||||
currency: currencyCode,
|
||||
currencyDisplay: "narrowSymbol",
|
||||
}).format(0)
|
||||
|
||||
return formatted.replace(/\d/g, "").replace(/[.,]/g, "").trim()
|
||||
}
|
||||
|
||||
export const getDecimalDigits = (currencyCode: string) => {
|
||||
const formatter = new Intl.NumberFormat(undefined, {
|
||||
style: "currency",
|
||||
currency: currencyCode,
|
||||
})
|
||||
|
||||
return formatter.resolvedOptions().maximumFractionDigits
|
||||
}
|
||||
|
||||
export const getStylizedAmount = (amount: number, currencyCode: string) => {
|
||||
const symbol = getNativeSymbol(currencyCode)
|
||||
const decimalDigits = getDecimalDigits(currencyCode)
|
||||
|
||||
const total = amount.toLocaleString(undefined, {
|
||||
minimumFractionDigits: decimalDigits,
|
||||
maximumFractionDigits: decimalDigits,
|
||||
})
|
||||
|
||||
return `${symbol} ${total} ${currencyCode.toUpperCase()}`
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const orderDetailQuery = (id: string) => ({
|
||||
queryKey: ordersQueryKeys.detail(id),
|
||||
queryFn: async () =>
|
||||
sdk.admin.order.retrieve(id, {
|
||||
fields: DEFAULT_FIELDS,
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
import Medusa from "@medusajs/js-sdk"
|
||||
|
||||
export const sdk = new Medusa({
|
||||
baseUrl: "/",
|
||||
auth: {
|
||||
type: "session",
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const addressSchema = z.object({
|
||||
country_code: z.string().min(1),
|
||||
first_name: z.string().min(1),
|
||||
last_name: z.string().min(1),
|
||||
address_1: z.string().min(1),
|
||||
address_2: z.string().optional(),
|
||||
company: z.string().optional(),
|
||||
city: z.string().min(1),
|
||||
province: z.string().optional(),
|
||||
postal_code: z.string().min(1),
|
||||
phone: z.string().optional(),
|
||||
})
|
||||
@@ -0,0 +1,88 @@
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { getCountryByIso2 } from "../data/countries"
|
||||
|
||||
export function isSameAddress(
|
||||
a?: HttpTypes.AdminOrderAddress | null,
|
||||
b?: HttpTypes.AdminOrderAddress | null
|
||||
) {
|
||||
if (!a || !b) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
a.first_name === b.first_name &&
|
||||
a.last_name === b.last_name &&
|
||||
a.address_1 === b.address_1 &&
|
||||
a.address_2 === b.address_2 &&
|
||||
a.city === b.city &&
|
||||
a.postal_code === b.postal_code &&
|
||||
a.province === b.province &&
|
||||
a.country_code === b.country_code &&
|
||||
a.phone === b.phone &&
|
||||
a.company === b.company
|
||||
)
|
||||
}
|
||||
|
||||
export function getFormattedAddress(
|
||||
address?: HttpTypes.AdminOrderAddress | HttpTypes.AdminCustomerAddress | null
|
||||
) {
|
||||
if (!address) {
|
||||
return []
|
||||
}
|
||||
|
||||
const {
|
||||
first_name,
|
||||
last_name,
|
||||
company,
|
||||
address_1,
|
||||
address_2,
|
||||
city,
|
||||
postal_code,
|
||||
province,
|
||||
country_code,
|
||||
} = address
|
||||
|
||||
const country = "country" in address ? address.country : null
|
||||
|
||||
const name = [first_name, last_name].filter(Boolean).join(" ")
|
||||
|
||||
const formattedAddress: string[] = []
|
||||
|
||||
if (name) {
|
||||
formattedAddress.push(name)
|
||||
}
|
||||
|
||||
if (company) {
|
||||
formattedAddress.push(company)
|
||||
}
|
||||
|
||||
if (address_1) {
|
||||
formattedAddress.push(address_1)
|
||||
}
|
||||
|
||||
if (address_2) {
|
||||
formattedAddress.push(address_2)
|
||||
}
|
||||
|
||||
const cityProvincePostal = [city, province, postal_code]
|
||||
.filter(Boolean)
|
||||
.join(" ")
|
||||
|
||||
if (cityProvincePostal) {
|
||||
formattedAddress.push(cityProvincePostal)
|
||||
}
|
||||
|
||||
if (country) {
|
||||
formattedAddress.push(country.display_name!)
|
||||
} else if (country_code) {
|
||||
const country = getCountryByIso2(country_code)
|
||||
|
||||
if (country) {
|
||||
formattedAddress.push(country.display_name)
|
||||
} else {
|
||||
formattedAddress.push(country_code.toUpperCase())
|
||||
}
|
||||
}
|
||||
|
||||
return formattedAddress
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { format, formatDistance, sub } from "date-fns"
|
||||
import { enUS } from "date-fns/locale"
|
||||
|
||||
const LOCALE = enUS
|
||||
|
||||
export function getRelativeDate(date: string | Date): string {
|
||||
const now = new Date()
|
||||
|
||||
return formatDistance(sub(new Date(date), { minutes: 0 }), now, {
|
||||
addSuffix: true,
|
||||
locale: LOCALE,
|
||||
})
|
||||
}
|
||||
|
||||
export const getFullDate = ({
|
||||
date,
|
||||
includeTime = false,
|
||||
}: {
|
||||
date: string | Date
|
||||
includeTime?: boolean
|
||||
}) => {
|
||||
const ensuredDate = new Date(date)
|
||||
|
||||
if (isNaN(ensuredDate.getTime())) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const timeFormat = includeTime ? "p" : ""
|
||||
|
||||
return format(ensuredDate, `PP ${timeFormat}`, {
|
||||
locale: LOCALE,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function convertNumber(value?: string | number) {
|
||||
return typeof value === "string" ? Number(value.replace(",", ".")) : value
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export function getUniqueShippingProfiles(
|
||||
items: HttpTypes.AdminOrderLineItem[]
|
||||
): HttpTypes.AdminShippingProfile[] {
|
||||
const profiles = new Map<string, HttpTypes.AdminShippingProfile>()
|
||||
items.forEach((item) => {
|
||||
const profile = item.variant?.product?.shipping_profile
|
||||
if (profile) {
|
||||
profiles.set(profile.id, profile)
|
||||
}
|
||||
})
|
||||
return Array.from(profiles.values())
|
||||
}
|
||||
|
||||
export function getItemsWithShippingProfile(
|
||||
shipping_profile_id: string,
|
||||
items: HttpTypes.AdminOrderLineItem[]
|
||||
) {
|
||||
return items.filter(
|
||||
(item) =>
|
||||
item.variant?.product?.shipping_profile?.id === shipping_profile_id
|
||||
)
|
||||
}
|
||||
|
||||
export function getOrderCustomer(obj: HttpTypes.AdminOrder) {
|
||||
const { first_name: sFirstName, last_name: sLastName } =
|
||||
obj.shipping_address || {}
|
||||
const { first_name: bFirstName, last_name: bLastName } =
|
||||
obj.billing_address || {}
|
||||
const { first_name: cFirstName, last_name: cLastName } = obj.customer || {}
|
||||
|
||||
const customerName = [cFirstName, cLastName].filter(Boolean).join(" ")
|
||||
const shippingName = [sFirstName, sLastName].filter(Boolean).join(" ")
|
||||
const billingName = [bFirstName, bLastName].filter(Boolean).join(" ")
|
||||
|
||||
const name = customerName || shippingName || billingName
|
||||
|
||||
return name
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function pluralize(count: number, plural: string, singular: string) {
|
||||
return count === 1 ? singular : plural
|
||||
}
|
||||
Reference in New Issue
Block a user