fix(dashboard, core-flows): improvements to order page on canceled orders (#10888)
what: - Remove pending payment for canceled orders - Hide unfulfilled items for canceled orders - Disable non refundable payments from being refunded - Populate refund created_by - Disable order edit when canceled - Fix bug https://github.com/medusajs/medusa/issues/10852 RESOLVES CMRC-842
This commit is contained in:
@@ -44,8 +44,7 @@ export const CreateRefundForm = ({
|
||||
const paymentId = searchParams.get("paymentId")
|
||||
const payments = getPaymentsFromOrder(order)
|
||||
const payment = payments.find((p) => p.id === paymentId)!
|
||||
const paymentAmount = (payment?.amount || 0) as number
|
||||
|
||||
const paymentAmount = payment.amount || 0
|
||||
const form = useForm<zod.infer<typeof CreateRefundSchema>>({
|
||||
defaultValues: {
|
||||
amount: paymentAmount,
|
||||
@@ -121,19 +120,32 @@ export const CreateRefundForm = ({
|
||||
</Select.Trigger>
|
||||
|
||||
<Select.Content>
|
||||
{payments.map((payment) => (
|
||||
<Select.Item value={payment!.id} key={payment.id}>
|
||||
<span>
|
||||
{getLocaleAmount(
|
||||
payment.amount as number,
|
||||
payment.currency_code
|
||||
)}
|
||||
{" - "}
|
||||
</span>
|
||||
<span>{payment.provider_id}</span>
|
||||
<span> - ({payment.id.replace("pay_", "")})</span>
|
||||
</Select.Item>
|
||||
))}
|
||||
{payments.map((payment) => {
|
||||
const totalRefunded = payment.refunds.reduce(
|
||||
(acc, next) => next.amount + acc,
|
||||
0
|
||||
)
|
||||
|
||||
return (
|
||||
<Select.Item
|
||||
value={payment!.id}
|
||||
key={payment.id}
|
||||
disabled={
|
||||
!!payment.canceled_at || totalRefunded >= payment.amount
|
||||
}
|
||||
>
|
||||
<span>
|
||||
{getLocaleAmount(
|
||||
payment.amount as number,
|
||||
payment.currency_code
|
||||
)}
|
||||
{" - "}
|
||||
</span>
|
||||
<span>{payment.provider_id}</span>
|
||||
<span> - ({payment.id.replace("pay_", "")})</span>
|
||||
</Select.Item>
|
||||
)
|
||||
})}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
|
||||
@@ -154,16 +166,11 @@ export const CreateRefundForm = ({
|
||||
<CurrencyInput
|
||||
{...field}
|
||||
min={0}
|
||||
onChange={(e) => {
|
||||
const val =
|
||||
e.target.value === ""
|
||||
? null
|
||||
: Number(e.target.value)
|
||||
onValueChange={(value) => {
|
||||
const fieldValue = value ? parseInt(value) : ""
|
||||
|
||||
onChange(val)
|
||||
|
||||
if (val && !isNaN(val)) {
|
||||
if (val < 0 || val > paymentAmount) {
|
||||
if (fieldValue && !isNaN(fieldValue)) {
|
||||
if (fieldValue < 0 || fieldValue > paymentAmount) {
|
||||
form.setError(`amount`, {
|
||||
type: "manual",
|
||||
message: t(
|
||||
@@ -175,6 +182,8 @@ export const CreateRefundForm = ({
|
||||
form.clearErrors(`amount`)
|
||||
}
|
||||
}
|
||||
|
||||
onChange(fieldValue)
|
||||
}}
|
||||
code={order.currency_code}
|
||||
symbol={getCurrencySymbol(order.currency_code)}
|
||||
|
||||
@@ -150,6 +150,10 @@ const UnfulfilledItemDisplay = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (order.status === "canceled") {
|
||||
return
|
||||
}
|
||||
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { ArrowDownRightMini, DocumentText, XCircle } from "@medusajs/icons"
|
||||
import {
|
||||
AdminPayment,
|
||||
AdminPaymentCollection,
|
||||
HttpTypes,
|
||||
} from "@medusajs/types"
|
||||
import { AdminOrder, AdminPayment, HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
@@ -58,10 +54,7 @@ export const OrderPaymentSection = ({ order }: OrderPaymentSectionProps) => {
|
||||
currencyCode={order.currency_code}
|
||||
/>
|
||||
|
||||
<Total
|
||||
paymentCollections={order.payment_collections}
|
||||
currencyCode={order.currency_code}
|
||||
/>
|
||||
<Total order={order} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -195,6 +188,11 @@ const Payment = ({
|
||||
const showCapture =
|
||||
payment.captured_at === null && payment.canceled_at === null
|
||||
|
||||
const totalRefunded = payment.refunds.reduce(
|
||||
(acc, next) => next.amount + acc,
|
||||
0
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="divide-y divide-dashed">
|
||||
<div className="text-ui-fg-subtle grid grid-cols-[1fr_1fr_1fr_20px] items-center gap-x-4 px-6 py-4 sm:grid-cols-[1fr_1fr_1fr_1fr_20px]">
|
||||
@@ -237,7 +235,10 @@ const Payment = ({
|
||||
label: t("orders.payment.refund"),
|
||||
icon: <XCircle />,
|
||||
to: `/orders/${order.id}/refund?paymentId=${payment.id}`,
|
||||
disabled: !payment.captured_at,
|
||||
disabled:
|
||||
!payment.captured_at ||
|
||||
!!payment.canceled_at ||
|
||||
totalRefunded >= payment.amount,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -341,15 +342,9 @@ const PaymentBreakdown = ({
|
||||
)
|
||||
}
|
||||
|
||||
const Total = ({
|
||||
paymentCollections,
|
||||
currencyCode,
|
||||
}: {
|
||||
paymentCollections: AdminPaymentCollection[]
|
||||
currencyCode: string
|
||||
}) => {
|
||||
const Total = ({ order }: { order: AdminOrder }) => {
|
||||
const { t } = useTranslation()
|
||||
const totalPending = getTotalPending(paymentCollections)
|
||||
const totalPending = getTotalPending(order.payment_collections)
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -360,20 +355,20 @@ const Total = ({
|
||||
|
||||
<Text size="small" weight="plus" leading="compact">
|
||||
{getStylizedAmount(
|
||||
getTotalCaptured(paymentCollections),
|
||||
currencyCode
|
||||
getTotalCaptured(order.payment_collections),
|
||||
order.currency_code
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{totalPending > 0 && (
|
||||
{order.status !== "canceled" && totalPending > 0 && (
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Text size="small" weight="plus" leading="compact">
|
||||
Total pending
|
||||
</Text>
|
||||
|
||||
<Text size="small" weight="plus" leading="compact">
|
||||
{getStylizedAmount(totalPending, currencyCode)}
|
||||
{getStylizedAmount(totalPending, order.currency_code)}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
AdminOrderPreview,
|
||||
AdminRegion,
|
||||
AdminReturn,
|
||||
AdminPaymentCollection,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
Badge,
|
||||
@@ -36,7 +37,6 @@ import {
|
||||
} from "@medusajs/ui"
|
||||
|
||||
import { AdminReservation } from "@medusajs/types/src/http"
|
||||
import { AdminPaymentCollection } from "../../../../../../../../core/types/dist/http/payment/admin/entities"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { Thumbnail } from "../../../../../components/common/thumbnail"
|
||||
import { useClaims } from "../../../../../hooks/api/claims"
|
||||
@@ -309,6 +309,7 @@ const Header = ({
|
||||
to: `/orders/${order.id}/edits`,
|
||||
icon: <PencilSquare />,
|
||||
disabled:
|
||||
order.status === "canceled" ||
|
||||
(orderPreview?.order_change &&
|
||||
orderPreview?.order_change?.change_type !== "edit") ||
|
||||
(orderPreview?.order_change?.change_type === "edit" &&
|
||||
|
||||
Reference in New Issue
Block a user