109 lines
3.3 KiB
TypeScript
109 lines
3.3 KiB
TypeScript
import { Description, FieldGroup, Fieldset, Legend } from "@repo/rdx-ui/components";
|
|
import { Badge } from "@repo/shadcn-ui/components";
|
|
import { ReceiptIcon } from "lucide-react";
|
|
import { useFormContext, useWatch } from "react-hook-form";
|
|
import { useTranslation } from "../../i18n";
|
|
import { CustomerInvoiceFormData } from "../../schemas";
|
|
|
|
export const InvoiceTaxSummary = () => {
|
|
const { t } = useTranslation();
|
|
const { control } = useFormContext<CustomerInvoiceFormData>();
|
|
|
|
const taxes = useWatch({
|
|
control,
|
|
name: "taxes",
|
|
defaultValue: [],
|
|
});
|
|
|
|
const formatCurrency = (amount: {
|
|
value: string;
|
|
scale: string;
|
|
currency_code: string;
|
|
}) => {
|
|
const { currency_code, value, scale } = amount;
|
|
|
|
return new Intl.NumberFormat("es-ES", {
|
|
style: "currency",
|
|
currency: currency_code,
|
|
minimumFractionDigits: Number(scale),
|
|
maximumFractionDigits: Number(scale),
|
|
compactDisplay: "short",
|
|
currencyDisplay: "symbol",
|
|
}).format(Number(value) / 10 ** Number(scale));
|
|
};
|
|
|
|
// Mock tax data
|
|
const mockTaxes = [
|
|
{
|
|
tax_code: "IVA 21%",
|
|
taxable_amount: {
|
|
value: "10000",
|
|
scale: "2",
|
|
currency_code: "EUR",
|
|
},
|
|
taxes_amount: {
|
|
value: "21000",
|
|
scale: "2",
|
|
currency_code: "EUR",
|
|
},
|
|
},
|
|
{
|
|
tax_code: "IVA 10%",
|
|
taxable_amount: {
|
|
value: "50000",
|
|
scale: "2",
|
|
currency_code: "EUR",
|
|
},
|
|
taxes_amount: {
|
|
value: "5000",
|
|
scale: "2",
|
|
currency_code: "EUR",
|
|
},
|
|
},
|
|
];
|
|
|
|
const displayTaxes = taxes ? taxes : mockTaxes;
|
|
|
|
return (
|
|
<Fieldset>
|
|
<Legend className='flex items-center gap-2 text-foreground'>
|
|
<ReceiptIcon className='h-5 w-5' /> {t("form_groups.tax_resume.title")}
|
|
</Legend>
|
|
|
|
<Description>{t("form_groups.tax_resume.description")}</Description>
|
|
<FieldGroup className='grid grid-cols-1'>
|
|
<div className='space-y-3'>
|
|
{displayTaxes.map((tax, index) => (
|
|
<div key={`${tax.tax_code}-${index}`} className='border rounded-lg p-3'>
|
|
<div className='flex items-center justify-between mb-2'>
|
|
<Badge variant='secondary' className='text-xs'>
|
|
{tax.tax_code}
|
|
</Badge>
|
|
</div>
|
|
<div className='space-y-1 text-sm'>
|
|
<div className='flex justify-between'>
|
|
<span className='text-muted-foreground'>Base Imponible:</span>
|
|
<span className='font-medium'>{formatCurrency(tax.taxable_amount)}</span>
|
|
</div>
|
|
<div className='flex justify-between'>
|
|
<span className='text-muted-foreground'>Importe Impuesto:</span>
|
|
<span className='font-medium text-primary'>
|
|
{formatCurrency(tax.taxes_amount)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
|
|
{displayTaxes.length === 0 && (
|
|
<div className='text-center py-6 text-muted-foreground'>
|
|
<ReceiptIcon className='h-8 w-8 mx-auto mb-2 opacity-50' />
|
|
<p className='text-sm'>No hay impuestos aplicados</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</FieldGroup>
|
|
</Fieldset>
|
|
);
|
|
};
|