// RefundDestination — a dónde regresa el dinero: efectivo, tarjeta, monedero, // saldo a favor o NC CFDI (benchmark §7, POS-3/DEV-*). import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { Button, Input } from '@asteby/metacore-ui' import { useFormatter, roundMoney } from './format' import { DEFAULT_REFUND_DESTINATIONS, singleDestination, validateRefund, type RefundAllocation, type RefundDestinationKind, type RefundDestinationOption, type RefundValidation, } from './refund' export interface RefundDestinationProps { /** Monto total a reembolsar. */ total: number value: RefundAllocation[] onChange: (allocations: RefundAllocation[]) => void /** Destinos ofrecidos (default: los cinco). Filtra/limita según el documento. */ options?: RefundDestinationOption[] /** Emite la validación tras cada cambio (para bloquear «Confirmar»). */ onValidate?: (v: RefundValidation) => void /** Errores del servidor `"<índice>."`. */ serverErrors?: Record /** Permite repartir entre varios destinos. Default false (un solo destino). */ allowSplit?: boolean currency?: string disabled?: boolean } export function RefundDestination({ total, value, onChange, options = DEFAULT_REFUND_DESTINATIONS, onValidate, serverErrors, allowSplit = false, currency, disabled, }: RefundDestinationProps) { const { t } = useTranslation() const fmt = useFormatter({ currency }) const validation = useMemo(() => validateRefund(total, value, options), [total, value, options]) const errors = { ...validation.errors, ...serverErrors } const chosen = (k: RefundDestinationKind) => value.some((a) => a.kind === k) const emit = (next: RefundAllocation[]) => { onChange(next) onValidate?.(validateRefund(total, next, options)) } const toggle = (o: RefundDestinationOption) => { if (!allowSplit) return emit(singleDestination(o.kind, total)) if (chosen(o.kind)) return emit(value.filter((a) => a.kind !== o.kind)) emit([...value, { kind: o.kind, amount: Math.max(0, roundMoney(total - validation.allocated)) }]) } return (

{t('refund.amount', { defaultValue: 'Monto a reembolsar' })}: {fmt.money(total)}

{options.map((o) => { const off = o.available === false const on = chosen(o.kind) return ( ) })}
{value.map((a, i) => (
{options.find((o) => o.kind === a.kind)?.label ?? a.kind}
emit(value.map((x, j) => (j === i ? { ...x, amount: Number(e.target.value.replace(',', '.')) || 0 } : x)))} /> {errors[`${i}.amount`] &&

{errors[`${i}.amount`]}

}
{(a.kind === 'card' || a.kind === 'transfer' || a.kind === 'credit_note') && ( emit(value.map((x, j) => (j === i ? { ...x, reference: e.target.value } : x)))} /> )} {errors[`${i}.kind`] &&

{errors[`${i}.kind`]}

}
))} {validation.form && value.length > 0 &&

{validation.form}

}
) }