Uecko_ERP/modules/customer-invoices/src/web/components/editor/invoice-totals.tsx

121 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-09-29 18:22:59 +00:00
import { Description, FieldGroup, Fieldset, Legend } from "@repo/rdx-ui/components";
import { Input, Label, Separator } from "@repo/shadcn-ui/components";
import { CalculatorIcon } from "lucide-react";
2025-10-12 10:43:06 +00:00
import { ComponentProps } from 'react';
import { Controller, useFormContext } from "react-hook-form";
2025-09-29 18:22:59 +00:00
import { useTranslation } from "../../i18n";
2025-10-12 10:43:06 +00:00
import { InvoiceFormData } from "../../schemas";
2025-09-29 18:22:59 +00:00
2025-10-12 10:43:06 +00:00
export const InvoiceTotals = (props: ComponentProps<"fieldset">) => {
2025-09-29 18:22:59 +00:00
const { t } = useTranslation();
2025-10-12 10:43:06 +00:00
const { control, getValues } = useFormContext<InvoiceFormData>();
2025-09-29 18:22:59 +00:00
//const invoiceFormData = useWatch({ control });
2025-10-12 10:43:06 +00:00
/*const [invoice, setInvoice] = useState({
2025-09-29 18:22:59 +00:00
items: [],
subtotal_amount: 0,
discount_percentage: 0,
discount_amount: 0,
taxable_amount: 0,
taxes_amount: 0,
total_amount: 0,
});
const updateDiscount = (value: number) => {
2025-10-12 10:43:06 +00:00
const subtotal = getValues('items.reduce(
2025-09-29 18:22:59 +00:00
(sum: number, item: any) => sum + item.subtotal_amount,
0
);
const discountAmount = (subtotal * value) / 100;
const taxableAmount = subtotal - discountAmount;
const taxesAmount = taxableAmount * 0.21; // Mock calculation
const totalAmount = taxableAmount + taxesAmount;
setInvoice({
...invoice,
subtotal_amount: subtotal,
discount_percentage: value,
discount_amount: discountAmount,
taxable_amount: taxableAmount,
taxes_amount: taxesAmount,
total_amount: totalAmount,
});
2025-10-12 10:43:06 +00:00
};*/
2025-09-29 18:22:59 +00:00
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat("es-ES", {
style: "currency",
currency: "EUR",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(amount);
};
return (
2025-10-12 10:43:06 +00:00
<Fieldset {...props}>
2025-09-29 18:22:59 +00:00
<Legend className='flex items-center gap-2 text-foreground'>
2025-10-12 10:43:06 +00:00
<CalculatorIcon className='size-5' /> {t("form_groups.totals.title")}
2025-09-29 18:22:59 +00:00
</Legend>
<Description>{t("form_groups.totals.description")}</Description>
<FieldGroup className='grid grid-cols-1'>
<div className='space-y-3'>
<div className='flex justify-between items-center'>
<Label className='text-sm text-muted-foreground'>Subtotal</Label>
2025-10-12 10:43:06 +00:00
<span className='font-medium tabular-nums'>{formatCurrency(getValues('subtotal_amount'))}</span>
2025-09-29 18:22:59 +00:00
</div>
<div className='flex justify-between items-center gap-4'>
2025-10-12 10:43:06 +00:00
<Label className='text-sm text-muted-foreground'>Descuento (%)</Label>
2025-09-29 18:22:59 +00:00
<div className='flex items-center gap-2'>
2025-10-12 10:43:06 +00:00
<Controller
control={control}
name={"discount_percentage"}
render={({
field, fieldState
}) => (<Input
readOnly={false}
value={field.value}
onChange={field.onChange}
disabled={fieldState.isValidating}
onBlur={field.onBlur}
className='w-20 text-right'
/>)}
2025-09-29 18:22:59 +00:00
/>
</div>
</div>
<div className='flex justify-between items-center'>
2025-10-12 10:43:06 +00:00
<Label className='text-sm text-muted-foreground'>Importe del descuento</Label>
<span className='font-medium text-destructive tabular-nums'>
-{formatCurrency(getValues("discount_amount"))}
2025-09-29 18:22:59 +00:00
</span>
</div>
<Separator />
<div className='flex justify-between items-center'>
2025-10-12 10:43:06 +00:00
<Label className='text-sm text-muted-foreground'>Base imponible</Label>
<span className='font-medium tabular-nums'>{formatCurrency(getValues('taxable_amount'))}</span>
2025-09-29 18:22:59 +00:00
</div>
<div className='flex justify-between items-center'>
2025-10-12 10:43:06 +00:00
<Label className='text-sm text-muted-foreground'>Total de impuestos</Label>
<span className='font-medium tabular-nums'>{formatCurrency(getValues('taxes_amount'))}</span>
2025-09-29 18:22:59 +00:00
</div>
<Separator />
<div className='flex justify-between items-center'>
2025-10-12 10:43:06 +00:00
<Label className='text-lg font-semibold'>Total de la factura</Label>
<span className='text-xl font-bold text-primary tabular-nums'>
{formatCurrency(getValues('total_amount'))}
2025-09-29 18:22:59 +00:00
</span>
</div>
</div>
</FieldGroup>
</Fieldset>
);
};