Facturas de cliente
This commit is contained in:
parent
ef8a20d296
commit
27a5e30d37
@ -39,7 +39,7 @@ export function AmountInputField<T extends FieldValues>({
|
||||
<FormControl>
|
||||
<AmountInput
|
||||
id={inputId}
|
||||
value={field.value}
|
||||
value={field.value ?? ""}
|
||||
onChange={field.onChange}
|
||||
{...inputProps}
|
||||
/>
|
||||
|
||||
@ -5,8 +5,8 @@ import { InputEmptyMode, InputReadOnlyMode } from './quantity-input';
|
||||
|
||||
|
||||
export type AmountInputProps = {
|
||||
value: number | "" | string; // "" → no mostrar nada; string puede venir con separadores
|
||||
onChange: (next: number | "") => void;
|
||||
value: number | string; // "" → no mostrar nada; string puede venir con separadores
|
||||
onChange: (next: number | string) => void;
|
||||
readOnly?: boolean;
|
||||
readOnlyMode?: InputReadOnlyMode; // default "textlike-input"
|
||||
id?: string;
|
||||
|
||||
@ -28,25 +28,27 @@ export function QuantityInputField<TFormValues extends FieldValues>({
|
||||
<FormField
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
render={({ field }) => {
|
||||
const { value, onChange } = field;
|
||||
console.log(value);
|
||||
return <FormItem>
|
||||
{label ? (
|
||||
<FormLabel htmlFor={inputId}>
|
||||
{label} {required ? <span aria-hidden="true">*</span> : null}
|
||||
{label} {required ? <span aria-hidden='true'>*</span> : null}
|
||||
</FormLabel>
|
||||
) : null}
|
||||
<FormControl>
|
||||
<QuantityInput
|
||||
id={inputId}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
{...inputProps}
|
||||
/>
|
||||
</FormControl>
|
||||
{description ? <FormDescription>{description}</FormDescription> : null}
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -110,9 +110,12 @@ export function useInvoiceAutoRecalc(
|
||||
|
||||
// Suscripción reactiva a cambios del formulario
|
||||
React.useEffect(() => {
|
||||
console.log("recalculo algo?");
|
||||
|
||||
if (!isDirty || isLoading || isSubmitting) return;
|
||||
|
||||
const subscription = watch(async (formData, { name, type }) => {
|
||||
const subscription = watch((formData, { name, type }) => {
|
||||
console.log(name, type);
|
||||
const items = (formData?.items || []) as InvoiceItemFormData[];
|
||||
|
||||
if (items.length === 0) return;
|
||||
@ -126,7 +129,7 @@ export function useInvoiceAutoRecalc(
|
||||
setInvoiceTotals(form, invoiceTotals);
|
||||
|
||||
// 3) valida una vez (opcional)
|
||||
await trigger([
|
||||
trigger([
|
||||
"subtotal_amount",
|
||||
"discount_amount",
|
||||
"taxable_amount",
|
||||
@ -137,19 +140,25 @@ export function useInvoiceAutoRecalc(
|
||||
|
||||
// 2. Cambio puntual de una línea
|
||||
if (name?.startsWith("items.") && type === "change") {
|
||||
console.log("2. items!");
|
||||
|
||||
const index = Number(name.split(".")[1]);
|
||||
const field = name.split(".")[2];
|
||||
|
||||
if (["quantity", "unit_amount", "discount_percentage", "tax_codes"].includes(field)) {
|
||||
console.log("2.1. recalculo items!");
|
||||
const item = items[index] as InvoiceItemFormData;
|
||||
const prevTotals = itemCache.current.get(index);
|
||||
const newTotals = calculateItemTotals(item);
|
||||
|
||||
console.log(prevTotals, newTotals);
|
||||
|
||||
// Si no hay cambios en los totales, no tocamos nada
|
||||
const itemHasChanges =
|
||||
prevTotals && JSON.stringify(prevTotals) !== JSON.stringify(newTotals);
|
||||
prevTotals || JSON.stringify(prevTotals) !== JSON.stringify(newTotals);
|
||||
|
||||
if (!itemHasChanges) {
|
||||
console.log("No hay cambios, me voy!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -173,7 +182,7 @@ export function useInvoiceAutoRecalc(
|
||||
setInvoiceTotals(form, invoiceTotals);
|
||||
|
||||
// 3) valida una vez (opcional)
|
||||
await trigger([
|
||||
trigger([
|
||||
"items",
|
||||
"subtotal_amount",
|
||||
"discount_amount",
|
||||
@ -188,10 +197,15 @@ export function useInvoiceAutoRecalc(
|
||||
return () => subscription.unsubscribe();
|
||||
}, [
|
||||
watch,
|
||||
trigger,
|
||||
setValue,
|
||||
getValues,
|
||||
isDirty,
|
||||
isLoading,
|
||||
isSubmitting,
|
||||
itemCache,
|
||||
setInvoiceItemTotals,
|
||||
setInvoiceTotals,
|
||||
calculateItemTotals,
|
||||
calculateInvoiceTotals,
|
||||
]);
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
import { NumericStringSchema } from "@erp/core";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
export const InvoiceItemFormSchema = z.object({
|
||||
is_non_valued: z.boolean(),
|
||||
|
||||
description: z.string().max(2000).optional().default(""),
|
||||
quantity: NumericStringSchema.optional(),
|
||||
unit_amount: NumericStringSchema.optional(),
|
||||
quantity: z.any(), //NumericStringSchema.optional(),
|
||||
unit_amount: z.any(), //NumericStringSchema.optional(),
|
||||
|
||||
subtotal_amount: z.number(),
|
||||
discount_percentage: NumericStringSchema.optional(),
|
||||
subtotal_amount: z.any(), //z.number(),
|
||||
discount_percentage: z.any(), //NumericStringSchema.optional(),
|
||||
discount_amount: z.number(),
|
||||
taxable_amount: z.number(),
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user