import { zodResolver } from "@hookform/resolvers/zod" import { HttpTypes } from "@medusajs/types" import { Button } from "@medusajs/ui" import { useMemo } from "react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import * as zod from "zod" import { RouteFocusModal, useRouteModal } from "../../../components/modals" import { KeyboundForm } from "../../../components/utilities/keybound-form" import { useUpdateProductVariantsBatch } from "../../../hooks/api/products" import { useRegions } from "../../../hooks/api/regions" import { castNumber } from "../../../lib/cast-number" import { VariantPricingForm } from "../common/variant-pricing-form" import { ExtendedVariantPrice } from "../../product-variants/product-variant-detail/constants" export const UpdateVariantPricesSchema = zod.object({ variants: zod.array( zod.object({ prices: zod .record(zod.string(), zod.string().or(zod.number()).optional()) .optional(), }) ), }) export type UpdateVariantPricesSchemaType = zod.infer< typeof UpdateVariantPricesSchema > export const PricingEdit = ({ product, variantId, }: { product: HttpTypes.AdminProduct variantId?: string }) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() const { mutateAsync, isPending } = useUpdateProductVariantsBatch(product.id) const { regions } = useRegions({ limit: 9999 }) const regionsCurrencyMap = useMemo(() => { if (!regions?.length) { return {} } return regions.reduce( (acc: Record, reg) => { acc[reg.id] = reg.currency_code return acc }, {} as Record ) }, [regions]) const variants = variantId ? product.variants?.filter((v) => v.id === variantId) : product.variants const form = useForm({ defaultValues: { variants: variants?.map((variant: any) => ({ title: variant.title, prices: variant.prices.reduce((acc: any, price: any) => { if (price.rules?.region_id) { acc[price.rules.region_id] = price.amount } else { acc[price.currency_code] = price.amount } return acc }, {}), })) as any, }, resolver: zodResolver(UpdateVariantPricesSchema, {}), }) const handleSubmit = form.handleSubmit(async (values) => { const reqData = values.variants.filter(Boolean).map((variant, ind) => ({ id: variants![ind].id, prices: Object.entries(variant.prices || {}) .filter( ([_, value]) => value !== "" && typeof value !== "undefined" // deleted cells ) .map(([currencyCodeOrRegionId, value]: any) => { const regionId = currencyCodeOrRegionId.startsWith("reg_") ? currencyCodeOrRegionId : undefined const currencyCode = currencyCodeOrRegionId.startsWith("reg_") ? regionsCurrencyMap[regionId] : currencyCodeOrRegionId let existingId: string | undefined = undefined if (regionId) { existingId = variants?.[ind]?.prices?.find( (p) => (p as ExtendedVariantPrice).rules?.["region_id"] === regionId )?.id } else { existingId = variants?.[ind]?.prices?.find( (p) => p.currency_code === currencyCode && Object.keys((p as ExtendedVariantPrice).rules ?? {}).length === 0 )?.id } const amount = castNumber(value) return { id: existingId, currency_code: currencyCode, amount, ...(regionId ? { rules: { region_id: regionId } } : {}), } }), })) await mutateAsync(reqData, { onSuccess: () => { handleSuccess("..") }, }) }) return (
) }