.
This commit is contained in:
parent
c1b61a0b60
commit
986322e3e3
@ -1,15 +1,16 @@
|
|||||||
import { DollarSign } from "lucide-react";
|
import { FormPercentageField } from "@/components";
|
||||||
|
|
||||||
import { useLocalization } from "@/lib/hooks";
|
import { useLocalization } from "@/lib/hooks";
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Separator } from "@/ui";
|
import { Card, CardContent, CardDescription, CardTitle, Separator } from "@/ui";
|
||||||
|
import { t } from "i18next";
|
||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
|
|
||||||
export const QuotePricesResume = () => {
|
export const QuotePricesResume = () => {
|
||||||
const { watch } = useFormContext();
|
const { watch, register, formState } = useFormContext();
|
||||||
const { formatNumber, formatCurrency, formatPercentage } = useLocalization();
|
const { formatNumber, formatPercentage } = useLocalization();
|
||||||
|
|
||||||
const subtotal_price = formatNumber(watch("subtotal_price"));
|
const subtotal_price = formatNumber(watch("subtotal_price"));
|
||||||
const discount = formatPercentage(watch("discount"));
|
const discount_price = formatPercentage(watch("discount_price"));
|
||||||
|
const tax_price = formatPercentage(watch("tax_price"));
|
||||||
const total_price = formatNumber(watch("total_price"));
|
const total_price = formatNumber(watch("total_price"));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -25,35 +26,48 @@ export const QuotePricesResume = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Separator orientation='vertical' className='w-px h-16 mx-2' />
|
<Separator orientation='vertical' className='w-px h-16 mx-2' />
|
||||||
<div className='grid flex-1 h-16 grid-cols-2 gap-2 auto-rows-max'>
|
<div className='grid flex-1 h-16 grid-cols-2 gap-6 auto-rows-max'>
|
||||||
<div className='grid gap-1 font-medium text-muted-foreground'>
|
<div className='grid gap-1 font-medium text-muted-foreground'>
|
||||||
<CardDescription className='text-sm'>Descuento</CardDescription>
|
<CardDescription className='text-sm'>
|
||||||
<CardTitle className='flex items-baseline gap-1 text-xl tabular-nums'>
|
{t("quotes.form_fields.discount.label")}
|
||||||
{discount}
|
</CardDescription>
|
||||||
<span className='text-base tracking-normal'>%</span>
|
<FormPercentageField
|
||||||
</CardTitle>
|
scale={2}
|
||||||
|
disabled={formState.disabled}
|
||||||
|
placeholder={t("quotes.form_fields.discount.placeholder")}
|
||||||
|
{...register("discount", {
|
||||||
|
required: false,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid gap-1 font-semibold text-muted-foreground'>
|
<div className='grid gap-1 font-semibold text-muted-foreground'>
|
||||||
<CardDescription className='text-sm'>Imp. descuento</CardDescription>
|
<CardDescription className='text-sm'>Imp. descuento</CardDescription>
|
||||||
<CardTitle className='flex items-baseline text-2xl tabular-nums'>
|
<CardTitle className='flex items-baseline text-2xl tabular-nums'>
|
||||||
{subtotal_price}
|
{discount_price}
|
||||||
<span className='ml-1 text-lg tracking-normal'>€</span>
|
<span className='ml-1 text-lg tracking-normal'>€</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Separator orientation='vertical' className='w-px h-16 mx-2' />
|
<Separator orientation='vertical' className='w-px h-16 mx-2' />
|
||||||
<div className='grid flex-1 h-16 grid-cols-2 gap-2 auto-rows-max'>
|
<div className='grid flex-1 h-16 grid-cols-2 gap-6 auto-rows-max'>
|
||||||
<div className='grid gap-1 font-medium text-muted-foreground'>
|
<div className='grid gap-1 font-medium text-muted-foreground'>
|
||||||
<CardDescription className='text-sm'>IVA</CardDescription>
|
<CardDescription className='text-sm'>
|
||||||
<CardTitle className='flex items-baseline gap-1 text-xl tabular-nums'>
|
{t("quotes.form_fields.tax.label")}
|
||||||
{discount}
|
</CardDescription>
|
||||||
<span className='text-base tracking-normal'>%</span>
|
|
||||||
</CardTitle>
|
<FormPercentageField
|
||||||
|
scale={2}
|
||||||
|
disabled={formState.disabled}
|
||||||
|
placeholder={t("quotes.form_fields.tax.placeholder")}
|
||||||
|
{...register("tax", {
|
||||||
|
required: false,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid gap-1 font-semibold text-muted-foreground'>
|
<div className='grid gap-1 font-semibold text-muted-foreground'>
|
||||||
<CardDescription className='text-sm'>Importe IVA</CardDescription>
|
<CardDescription className='text-sm'>Importe IVA</CardDescription>
|
||||||
<CardTitle className='flex items-baseline gap-1 text-2xl tabular-nums'>
|
<CardTitle className='flex items-baseline gap-1 text-2xl tabular-nums'>
|
||||||
{subtotal_price}
|
{tax_price}
|
||||||
<span className='text-base font-medium tracking-normal'>€</span>
|
<span className='text-base font-medium tracking-normal'>€</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
@ -71,99 +85,4 @@ export const QuotePricesResume = () => {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<Card className='w-full'>
|
|
||||||
<CardContent className='flex flex-row items-center w-full gap-2 p-4 border-t'>
|
|
||||||
<div className='flex flex-row items-center gap-4 space-y-0 pb-2 [&>div]:flex-1 border border-blue-600'>
|
|
||||||
<div>
|
|
||||||
<CardDescription>Descuento</CardDescription>
|
|
||||||
<CardTitle className='flex items-baseline gap-1 text-4xl tabular-nums'>
|
|
||||||
62
|
|
||||||
<span className='text-sm font-normal tracking-normal text-muted-foreground'>%</span>
|
|
||||||
</CardTitle>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<CardDescription>Importe dto.</CardDescription>
|
|
||||||
<CardTitle className='flex items-baseline gap-1 text-4xl tabular-nums'>
|
|
||||||
3.346
|
|
||||||
<span className='text-sm font-normal tracking-normal text-muted-foreground'>€</span>
|
|
||||||
</CardTitle>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='flex flex-row gap-3 items-center space-y-0 [&>div]:flex-1 border border-blue-600'>
|
|
||||||
<div className='grid flex-1 gap-3 bg-red-500 auto-rows-min'></div>
|
|
||||||
<div className='grid flex-1 gap-3 bg-red-500 auto-rows-min'>
|
|
||||||
<CardDescription className='font-medium text-right'>Importe neto</CardDescription>
|
|
||||||
<div className='flex items-baseline justify-end gap-1 text-2xl font-semibold leading-none tabular-nums text-muted-foreground'>
|
|
||||||
{subtotal_price.amount}
|
|
||||||
<span className='text-sm font-normal tracking-normal text-muted-foreground'>
|
|
||||||
{subtotal_price.currency_code}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Separator orientation='vertical' className='w-px h-10 mx-2' />
|
|
||||||
|
|
||||||
<div className='flex flex-row gap-3 items-center space-y-0 [&>div]:flex-1 border border-blue-600'>
|
|
||||||
<div className='grid flex-1 gap-3 bg-red-500 auto-rows-min'>
|
|
||||||
<div className='text-sm font-medium text-left text-muted-foreground'>Descuento</div>
|
|
||||||
<div className='flex items-baseline justify-between gap-1 text-2xl font-semibold leading-none tabular-nums text-muted-foreground'>
|
|
||||||
<div>
|
|
||||||
73
|
|
||||||
<span className='text-sm font-normal text-muted-foreground'>%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='grid flex-1 gap-3 bg-green-500 auto-rows-min'>
|
|
||||||
<div className='text-sm font-medium text-muted-foreground'>Descuento</div>
|
|
||||||
<div>
|
|
||||||
73
|
|
||||||
<span className='text-sm font-normal text-muted-foreground'>€</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Separator orientation='vertical' className='w-px h-10 mx-2' />
|
|
||||||
<div className='grid flex-1 gap-3 border border-blue-600 auto-rows-min'>
|
|
||||||
<div className='text-sm font-medium text-right text-muted-foreground'>Base imponible</div>
|
|
||||||
<div className='flex items-baseline justify-end gap-1 text-2xl font-semibold leading-none tabular-nums text-muted-foreground'>
|
|
||||||
14
|
|
||||||
<span className='text-sm font-normal text-muted-foreground'>€</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator orientation='vertical' className='w-px h-10 mx-2' />
|
|
||||||
<div className='grid flex-1 gap-3 auto-rows-min'>
|
|
||||||
<div className='text-sm font-medium text-muted-foreground'>IVA</div>
|
|
||||||
<div className='flex items-baseline justify-end gap-1 text-2xl font-semibold leading-none tabular-nums text-muted-foreground'>
|
|
||||||
14
|
|
||||||
<span className='text-sm font-normal text-muted-foreground'>€</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator orientation='vertical' className='w-px h-10 mx-2' />
|
|
||||||
<div className='grid flex-1 gap-3 auto-rows-min'>
|
|
||||||
<div className='text-sm font-medium text-muted-foreground'>Importe total</div>
|
|
||||||
<div className='flex items-baseline justify-end gap-1 text-2xl font-bold leading-none tabular-nums'>
|
|
||||||
14
|
|
||||||
<span className='text-sm font-normal text-muted-foreground'>€</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<CardHeader className='flex flex-row items-center justify-between pb-2 space-y-0'>
|
|
||||||
<CardTitle className='text-sm font-medium'>Total Revenue</CardTitle>
|
|
||||||
<DollarSign className='w-4 h-4 text-muted-foreground' />
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div className='text-2xl font-bold'>$45,231.89</div>
|
|
||||||
<p className='text-sm font-medium text-muted-foreground'>+20.1% from last month</p>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { MoneyValue, Percentage, Quantity } from "@shared/contexts";
|
import { MoneyValue, Percentage, Quantity } from "@shared/contexts";
|
||||||
|
|
||||||
export const calculateQuoteTotals = (quote: any) => {
|
export const calculateQuoteTotals = (quote: any) => {
|
||||||
const { discount: discount_dto /* tax: tax_dto */ } = quote;
|
const { discount: discount_dto, tax: tax_dto } = quote || {};
|
||||||
|
|
||||||
const discountOrError = Percentage.create(discount_dto);
|
const discountOrError = Percentage.create(discount_dto);
|
||||||
if (discountOrError.isFailure) {
|
if (discountOrError.isFailure) {
|
||||||
@ -9,15 +9,11 @@ export const calculateQuoteTotals = (quote: any) => {
|
|||||||
}
|
}
|
||||||
const discount = discountOrError.object;
|
const discount = discountOrError.object;
|
||||||
|
|
||||||
/*const taxOrError = Percentage.create(tax_dto);
|
const taxOrError = Percentage.create(tax_dto);
|
||||||
if (taxOrError.isFailure) {
|
if (taxOrError.isFailure) {
|
||||||
throw taxOrError.error;
|
throw taxOrError.error;
|
||||||
}
|
}
|
||||||
const tax = taxOrError.object;*/
|
const tax = taxOrError.object;
|
||||||
const tax = Percentage.create({
|
|
||||||
amount: 2100,
|
|
||||||
scale: 2,
|
|
||||||
}).object;
|
|
||||||
|
|
||||||
const subtotalPrice = calculateQuoteItemsTotals(quote.items).convertScale(2);
|
const subtotalPrice = calculateQuoteItemsTotals(quote.items).convertScale(2);
|
||||||
|
|
||||||
@ -56,9 +52,12 @@ export const calculateQuoteItemsTotals = (items: any[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const calculateQuoteItemTotals = (item: any) => {
|
export const calculateQuoteItemTotals = (item: any) => {
|
||||||
const { quantity: quantity_dto, unit_price: unit_price_dto, discount: discount_dto } = item;
|
const { quantity: quantity_dto, unit_price: unit_price_dto, discount: discount_dto } = item || {};
|
||||||
|
|
||||||
if (quantity_dto.amount === null || unit_price_dto.amount === null) {
|
if (
|
||||||
|
(quantity_dto && quantity_dto.amount === null) ||
|
||||||
|
(unit_price_dto && unit_price_dto.amount === null)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
quantity: Quantity.create({
|
quantity: Quantity.create({
|
||||||
amount: quantity_dto.amount,
|
amount: quantity_dto.amount,
|
||||||
|
|||||||
@ -177,6 +177,16 @@
|
|||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"desc": "desc"
|
"desc": "desc"
|
||||||
},
|
},
|
||||||
|
"discount": {
|
||||||
|
"label": "Descuento",
|
||||||
|
"placeholder": "",
|
||||||
|
"desc": ""
|
||||||
|
},
|
||||||
|
"tax": {
|
||||||
|
"label": "IVA",
|
||||||
|
"placeholder": "",
|
||||||
|
"desc": ""
|
||||||
|
},
|
||||||
"items": {
|
"items": {
|
||||||
"quantity": {
|
"quantity": {
|
||||||
"label": "Cantidad",
|
"label": "Cantidad",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user