import { zodResolver } from "@hookform/resolvers/zod" import { HttpTypes } from "@medusajs/types" import { Button, CurrencyInput, Label, Select, Textarea, toast, } from "@medusajs/ui" import { useEffect, useMemo, useState } from "react" import { formatValue } from "react-currency-input-field" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import { useSearchParams } from "react-router-dom" import * as zod from "zod" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useRefundPayment, useRefundReasons } from "../../../../../hooks/api" import { currencies } from "../../../../../lib/data/currencies" import { formatCurrency } from "../../../../../lib/format-currency" import { getLocaleAmount } from "../../../../../lib/money-amount-helpers" import { getPaymentsFromOrder } from "../../../../../lib/orders" import { useDocumentDirection } from "../../../../../hooks/use-document-direction" import { formatProvider } from "../../../../../lib/format-provider.ts" type CreateRefundFormProps = { order: HttpTypes.AdminOrder } const CreateRefundSchema = zod.object({ amount: zod.object({ value: zod.string().or(zod.number()), float: zod.number().or(zod.null()), }), note: zod.string().optional(), refund_reason_id: zod.string().optional(), }) export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() const { refund_reasons } = useRefundReasons() const [searchParams] = useSearchParams() const hasPaymentIdInSearchParams = !!searchParams.get("paymentId") const [paymentId, setPaymentId] = useState( searchParams.get("paymentId") || undefined ) const payments = getPaymentsFromOrder(order) const payment = payments.find((p) => p.id === paymentId) const paymentAmount = payment?.amount || 0 const currency = useMemo( () => currencies[order.currency_code.toUpperCase()], [order.currency_code] ) const direction = useDocumentDirection() const form = useForm>({ defaultValues: { amount: { value: paymentAmount.toFixed(currency.decimal_digits), float: paymentAmount, }, }, resolver: zodResolver(CreateRefundSchema), }) useEffect(() => { const pendingDifference = order.summary.pending_difference as number const paymentAmount = (payment?.amount || 0) as number const pendingAmount = pendingDifference < 0 ? Math.min(Math.abs(pendingDifference), paymentAmount) : paymentAmount const normalizedAmount = pendingAmount < 0 ? pendingAmount * -1 : pendingAmount form.setValue("amount", { value: normalizedAmount.toFixed(currency.decimal_digits), float: normalizedAmount, }) }, [payment?.id || ""]) const { mutateAsync, isPending } = useRefundPayment(order.id, payment?.id!) const handleSubmit = form.handleSubmit(async (data) => { await mutateAsync( { amount: data.amount.float!, note: data.note, refund_reason_id: data.refund_reason_id, }, { onSuccess: () => { toast.success( t("orders.payment.refundPaymentSuccess", { amount: formatCurrency( data.amount.float!, payment?.currency_code! ), }) ) handleSuccess() }, onError: (error) => { toast.error(error.message) }, } ) }) return (
{!hasPaymentIdInSearchParams && ( )} {hasPaymentIdInSearchParams && (
{getLocaleAmount( payment!.amount as number, payment!.currency_code )}  -  (#{payment!.id.substring(23)})
)} { return ( {t("fields.amount")} onChange({ value: values?.value ?? "", float: values?.float ?? null, }) } autoFocus /> ) }} /> { return ( {t("fields.refundReason")} ) }} /> { return ( {t("fields.note")}