v1.0.3 - 2 decimales en importes
This commit is contained in:
parent
6e236bba91
commit
ee26a8bfa4
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@uecko-presupuestador/client",
|
"name": "@uecko-presupuestador/client",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"author": "Rodax Software <dev@rodax-software.com>",
|
"author": "Rodax Software <dev@rodax-software.com>",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -10,7 +10,6 @@ export const CatalogList = () => {
|
|||||||
<h2 className='text-2xl font-bold tracking-tight'>
|
<h2 className='text-2xl font-bold tracking-tight'>
|
||||||
<Trans i18nKey='catalog.list.title' />
|
<Trans i18nKey='catalog.list.title' />
|
||||||
</h2>
|
</h2>
|
||||||
<p className='text-muted-foreground'>descripción</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import { useToast } from "@/ui/use-toast";
|
|||||||
import { IListQuotes_Response_DTO, UTCDateValue } from "@shared/contexts";
|
import { IListQuotes_Response_DTO, UTCDateValue } from "@shared/contexts";
|
||||||
import { ColumnDef, Row } from "@tanstack/react-table";
|
import { ColumnDef, Row } from "@tanstack/react-table";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { FilePenLineIcon, MoreVerticalIcon } from "lucide-react";
|
import { FilePenLineIcon, MoreVerticalIcon, SendIcon } from "lucide-react";
|
||||||
import { useCallback, useEffect, useId, useMemo, useState } from "react";
|
import { useCallback, useEffect, useId, useMemo, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useQuotes } from "../hooks";
|
import { useQuotes } from "../hooks";
|
||||||
@ -74,7 +74,6 @@ export const QuotesDataTable = ({
|
|||||||
|
|
||||||
const handleEditQuote = useCallback(
|
const handleEditQuote = useCallback(
|
||||||
(quote: IListQuotes_Response_DTO) => {
|
(quote: IListQuotes_Response_DTO) => {
|
||||||
toast({ title: "Guardo => " + quote.id });
|
|
||||||
navigate(`/quotes/edit/${quote.id}`, { relative: "path" });
|
navigate(`/quotes/edit/${quote.id}`, { relative: "path" });
|
||||||
},
|
},
|
||||||
[navigate, toast]
|
[navigate, toast]
|
||||||
@ -92,19 +91,25 @@ export const QuotesDataTable = ({
|
|||||||
}: {
|
}: {
|
||||||
row: { original: IListQuotes_Response_DTO };
|
row: { original: IListQuotes_Response_DTO };
|
||||||
renderValue: () => any;
|
renderValue: () => any;
|
||||||
}) => (
|
}) => {
|
||||||
<Button
|
const allowToSent = original?.status === "accepted" && !original?.date_sent;
|
||||||
size='sm'
|
const isSent = Boolean(original?.status === "accepted" && original?.date_sent);
|
||||||
variant='link'
|
|
||||||
className='h-8 gap-1 px-0 text-left text-ellipsis'
|
return (
|
||||||
onClick={(e) => {
|
<Button
|
||||||
e.preventDefault();
|
size='sm'
|
||||||
handleEditQuote(original);
|
variant='link'
|
||||||
}}
|
disabled={allowToSent || isSent}
|
||||||
>
|
className='h-8 gap-1 px-0 text-left text-ellipsis'
|
||||||
<div className=''>{renderValue()}</div>
|
onClick={(e) => {
|
||||||
</Button>
|
e.preventDefault();
|
||||||
),
|
handleEditQuote(original);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className=''>{renderValue()}</div>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -116,16 +121,35 @@ export const QuotesDataTable = ({
|
|||||||
<ColorBadge label={t(`quotes.status.${original.status}`)} />
|
<ColorBadge label={t(`quotes.status.${original.status}`)} />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "date_sent" as const,
|
||||||
|
accessor: "date_sent",
|
||||||
|
header: () => (
|
||||||
|
<div className='text-left text-ellipsis'>{t("quotes.list.columns.date_sent")}</div>
|
||||||
|
),
|
||||||
|
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => {
|
||||||
|
const quoteDate = UTCDateValue.create(original.date_sent);
|
||||||
|
return (
|
||||||
|
<div className='text-left text-ellipsis'>
|
||||||
|
{quoteDate.isSuccess ? (
|
||||||
|
<ColorBadge label={quoteDate.object.toLocaleDateString("es-ES")} />
|
||||||
|
) : (
|
||||||
|
<>-</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "date" as const,
|
id: "date" as const,
|
||||||
accessor: "date",
|
accessor: "date",
|
||||||
header: () => (
|
header: () => (
|
||||||
<div className='text-right text-ellipsis'>{t("quotes.list.columns.date")}</div>
|
<div className='text-left text-ellipsis'>{t("quotes.list.columns.date")}</div>
|
||||||
),
|
),
|
||||||
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => {
|
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => {
|
||||||
const quoteDate = UTCDateValue.create(original.date);
|
const quoteDate = UTCDateValue.create(original.date);
|
||||||
return (
|
return (
|
||||||
<div className='text-right text-ellipsis'>
|
<div className='text-left text-ellipsis'>
|
||||||
{quoteDate.isSuccess ? quoteDate.object.toLocaleDateString("es-ES") : "-"}
|
{quoteDate.isSuccess ? quoteDate.object.toLocaleDateString("es-ES") : "-"}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -162,22 +186,7 @@ export const QuotesDataTable = ({
|
|||||||
),
|
),
|
||||||
size: 600,
|
size: 600,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "date_sent" as const,
|
|
||||||
accessor: "date_sent",
|
|
||||||
header: () => (
|
|
||||||
<div className='text-right text-ellipsis'>{t("quotes.list.columns.date_sent")}</div>
|
|
||||||
),
|
|
||||||
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => {
|
|
||||||
const quoteDate = UTCDateValue.create(original.date_sent);
|
|
||||||
return (
|
|
||||||
<div className='text-right text-ellipsis'>
|
|
||||||
{quoteDate.isSuccess}
|
|
||||||
{quoteDate.isSuccess ? quoteDate.object.toLocaleDateString("es-ES") : "-"}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
/*{
|
/*{
|
||||||
id: "total_price" as const,
|
id: "total_price" as const,
|
||||||
accessor: "total_price",
|
accessor: "total_price",
|
||||||
@ -195,68 +204,77 @@ export const QuotesDataTable = ({
|
|||||||
{
|
{
|
||||||
id: "row-actions",
|
id: "row-actions",
|
||||||
header: () => null,
|
header: () => null,
|
||||||
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => (
|
cell: ({ row: { original } }: { row: { original: IListQuotes_Response_DTO } }) => {
|
||||||
<ButtonGroup>
|
const allowToSent = original?.status === "accepted" && !original?.date_sent;
|
||||||
<Tooltip>
|
const isSent = original?.status === "accepted" && original?.date_sent;
|
||||||
<TooltipTrigger asChild>
|
|
||||||
{original.status === "accepted" && !original.date_sent ? (
|
|
||||||
<Button
|
|
||||||
size='sm'
|
|
||||||
variant='default'
|
|
||||||
className='h-8 gap-1'
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
//handleSentToUecko(original);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FilePenLineIcon className='h-3.5 w-3.5' />
|
|
||||||
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
|
||||||
{t("quotes.list.columns.actions.sent_to")}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
size='sm'
|
|
||||||
variant='outline'
|
|
||||||
className='h-8 gap-1'
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
handleEditQuote(original);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FilePenLineIcon className='h-3.5 w-3.5' />
|
|
||||||
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
|
||||||
{t("quotes.list.columns.actions.edit")}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>{t("quotes.list.columns.actions.sent_to_uecko")}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<DropdownMenu>
|
return (
|
||||||
<DropdownMenuTrigger asChild>
|
<ButtonGroup>
|
||||||
<Button size='icon' variant='outline' className='w-8 h-8'>
|
<Tooltip>
|
||||||
<MoreVerticalIcon className='h-3.5 w-3.5' />
|
<TooltipTrigger asChild>
|
||||||
<span className='sr-only'>{t("common.more")}</span>
|
<>
|
||||||
</Button>
|
{allowToSent && !isSent && (
|
||||||
</DropdownMenuTrigger>
|
<Button
|
||||||
<DropdownMenuContent align='end'>
|
size='sm'
|
||||||
<DropdownMenuItem
|
variant='default'
|
||||||
onClick={() => {
|
className='h-8 gap-1'
|
||||||
download(original.id, getQuotePDFFilename(original));
|
onClick={(e) => {
|
||||||
}}
|
e.preventDefault();
|
||||||
>
|
//handleSentToUecko(original);
|
||||||
Download
|
}}
|
||||||
</DropdownMenuItem>
|
>
|
||||||
<DropdownMenuSeparator />
|
<SendIcon className='h-3.5 w-3.5' />
|
||||||
<DropdownMenuItem>{t("common.archive")}</DropdownMenuItem>
|
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
||||||
</DropdownMenuContent>
|
{t("quotes.list.columns.actions.sent_to")}
|
||||||
</DropdownMenu>
|
</span>
|
||||||
</ButtonGroup>
|
</Button>
|
||||||
),
|
)}
|
||||||
|
|
||||||
|
{!allowToSent && !isSent && (
|
||||||
|
<Button
|
||||||
|
size='sm'
|
||||||
|
variant='outline'
|
||||||
|
className='h-8 gap-1'
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleEditQuote(original);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FilePenLineIcon className='h-3.5 w-3.5' />
|
||||||
|
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
||||||
|
{t("quotes.list.columns.actions.edit")}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>{t("quotes.list.columns.actions.sent_to_uecko")}</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button size='icon' variant='outline' className='w-8 h-8'>
|
||||||
|
<MoreVerticalIcon className='h-3.5 w-3.5' />
|
||||||
|
<span className='sr-only'>{t("common.more")}</span>
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align='end'>
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => {
|
||||||
|
download(original.id, getQuotePDFFilename(original));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Download
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem>{t("common.archive")}</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</ButtonGroup>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ export const QuoteDetailsCardEditor = ({
|
|||||||
<FormCurrencyField
|
<FormCurrencyField
|
||||||
currency={currency}
|
currency={currency}
|
||||||
language={language}
|
language={language}
|
||||||
scale={4}
|
scale={2}
|
||||||
className='text-right'
|
className='text-right'
|
||||||
{...register(`items.${index}.unit_price`)}
|
{...register(`items.${index}.unit_price`)}
|
||||||
/>
|
/>
|
||||||
@ -129,7 +129,7 @@ export const QuoteDetailsCardEditor = ({
|
|||||||
<FormCurrencyField
|
<FormCurrencyField
|
||||||
currency={currency}
|
currency={currency}
|
||||||
language={language}
|
language={language}
|
||||||
scale={4}
|
scale={2}
|
||||||
readOnly
|
readOnly
|
||||||
className='text-right'
|
className='text-right'
|
||||||
{...register(`items.${index}.subtotal_price`)}
|
{...register(`items.${index}.subtotal_price`)}
|
||||||
@ -165,7 +165,7 @@ export const QuoteDetailsCardEditor = ({
|
|||||||
variant='ghost'
|
variant='ghost'
|
||||||
currency={currency}
|
currency={currency}
|
||||||
language={language}
|
language={language}
|
||||||
scale={4}
|
scale={2}
|
||||||
readOnly
|
readOnly
|
||||||
className='font-semibold text-right'
|
className='font-semibold text-right'
|
||||||
{...register(`items.${index}.total_price`)}
|
{...register(`items.${index}.total_price`)}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
} from "@/ui";
|
} from "@/ui";
|
||||||
import { IGetQuote_Response_DTO } from "@shared/contexts";
|
import { IGetQuote_Response_DTO } from "@shared/contexts";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
|
import { SendIcon } from "lucide-react";
|
||||||
|
|
||||||
export const QuoteSentToEditor = ({
|
export const QuoteSentToEditor = ({
|
||||||
quote,
|
quote,
|
||||||
@ -28,6 +29,7 @@ export const QuoteSentToEditor = ({
|
|||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<Button size='sm' variant='default' className='h-8 gap-1'>
|
<Button size='sm' variant='default' className='h-8 gap-1'>
|
||||||
|
<SendIcon className='h-3.5 w-3.5' />
|
||||||
{t("quotes.quote_sent_to_editor.trigger_button")}
|
{t("quotes.quote_sent_to_editor.trigger_button")}
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
|
|||||||
@ -99,12 +99,12 @@ export const QuoteEdit = () => {
|
|||||||
},
|
},
|
||||||
unit_price: {
|
unit_price: {
|
||||||
amount: null,
|
amount: null,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
currency_code: data?.currency_code ?? quoteCurrency.code,
|
currency_code: data?.currency_code ?? quoteCurrency.code,
|
||||||
},
|
},
|
||||||
subtotal_price: {
|
subtotal_price: {
|
||||||
amount: null,
|
amount: null,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
currency_code: data?.currency_code ?? quoteCurrency.code,
|
currency_code: data?.currency_code ?? quoteCurrency.code,
|
||||||
},
|
},
|
||||||
discount: {
|
discount: {
|
||||||
@ -113,7 +113,7 @@ export const QuoteEdit = () => {
|
|||||||
},
|
},
|
||||||
total_price: {
|
total_price: {
|
||||||
amount: null,
|
amount: null,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
currency_code: data?.currency_code ?? quoteCurrency.code,
|
currency_code: data?.currency_code ?? quoteCurrency.code,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -266,7 +266,7 @@ export const QuoteEdit = () => {
|
|||||||
<h1 className='flex-1 text-xl font-semibold tracking-tight shrink-0 whitespace-nowrap sm:grow-0'>
|
<h1 className='flex-1 text-xl font-semibold tracking-tight shrink-0 whitespace-nowrap sm:grow-0'>
|
||||||
{t("quotes.edit.title")} {data.reference}
|
{t("quotes.edit.title")} {data.reference}
|
||||||
</h1>
|
</h1>
|
||||||
<ColorBadge label={data.status} className='ml-auto sm:ml-0' />
|
<ColorBadge label={t(`quotes.status.${data.status}`)} className='ml-auto sm:ml-0' />
|
||||||
|
|
||||||
<div className='items-center hidden gap-2 md:ml-auto md:flex'>
|
<div className='items-center hidden gap-2 md:ml-auto md:flex'>
|
||||||
<CancelButton
|
<CancelButton
|
||||||
|
|||||||
@ -40,7 +40,13 @@ function stringToColorPair(str: string) {
|
|||||||
return [textColor, bgColor];
|
return [textColor, bgColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ColorBadge = ({ label, className }: { label: string; className?: string }) => {
|
export type ColorBadgeProps = {
|
||||||
|
label: string;
|
||||||
|
className?: string;
|
||||||
|
bgcolor?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ColorBadge = ({ label, className }: ColorBadgeProps) => {
|
||||||
const [color, backgroundColor] = stringToColorPair(label);
|
const [color, backgroundColor] = stringToColorPair(label);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export const LoadingOverlay = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"fixed top-0 bottom-0 left-0 right-0 z-50 w-full h-screen overflow-hidden flex justify-center bg-secondary-foreground/85"
|
"fixed top-0 bottom-0 left-0 right-0 z-50 w-full h-screen overflow-hidden flex justify-center"
|
||||||
}
|
}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -8,9 +8,9 @@ type ProctectRouteProps = {
|
|||||||
|
|
||||||
export const ProtectedRoute = ({ children }: ProctectRouteProps) => {
|
export const ProtectedRoute = ({ children }: ProctectRouteProps) => {
|
||||||
const { isSuccess, data: { authenticated, redirectTo } = {} } = useIsLoggedIn();
|
const { isSuccess, data: { authenticated, redirectTo } = {} } = useIsLoggedIn();
|
||||||
//const { data: profile, ...profileStatus } = useGetProfile();
|
/*const { data: profile, ...profileStatus } = useGetProfile();
|
||||||
|
|
||||||
/*const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
const [langCode, setLangCode] = useState(i18n.language);
|
const [langCode, setLangCode] = useState(i18n.language);
|
||||||
|
|
||||||
if (i18n.language !== langCode) {
|
if (i18n.language !== langCode) {
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export const calculateQuoteTotals = (quote: any, force: boolean = false) => {
|
|||||||
export const calculateQuoteItemsTotals = (items: any[]) => {
|
export const calculateQuoteItemsTotals = (items: any[]) => {
|
||||||
let totalPrice = MoneyValue.create({
|
let totalPrice = MoneyValue.create({
|
||||||
amount: 0,
|
amount: 0,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
}).object;
|
}).object;
|
||||||
|
|
||||||
items &&
|
items &&
|
||||||
@ -89,11 +89,11 @@ export const calculateQuoteItemTotals = (item: any) => {
|
|||||||
}).object,
|
}).object,
|
||||||
unitPrice: MoneyValue.create({
|
unitPrice: MoneyValue.create({
|
||||||
amount: unit_price_dto.amount,
|
amount: unit_price_dto.amount,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
}).object,
|
}).object,
|
||||||
subtotalPrice: MoneyValue.create({
|
subtotalPrice: MoneyValue.create({
|
||||||
amount: null,
|
amount: null,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
}).object,
|
}).object,
|
||||||
discount: Percentage.create({
|
discount: Percentage.create({
|
||||||
amount: discount_dto.amount,
|
amount: discount_dto.amount,
|
||||||
@ -101,7 +101,7 @@ export const calculateQuoteItemTotals = (item: any) => {
|
|||||||
}).object,
|
}).object,
|
||||||
totalPrice: MoneyValue.create({
|
totalPrice: MoneyValue.create({
|
||||||
amount: null,
|
amount: null,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
}).object,
|
}).object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,8 +50,8 @@ export const useCustomLocalization = (props: UseLocalizationProps) => {
|
|||||||
|
|
||||||
const result = new Intl.NumberFormat("es", {
|
const result = new Intl.NumberFormat("es", {
|
||||||
/*minimumSignificantDigits: scale,
|
/*minimumSignificantDigits: scale,
|
||||||
maximumSignificantDigits: scale,
|
maximumSignificantDigits: scale,*/
|
||||||
minimumFractionDigits: scale,*/
|
minimumFractionDigits: scale,
|
||||||
useGrouping: true,
|
useGrouping: true,
|
||||||
}).format(amount === null ? 0 : adjustPrecision({ amount, scale }));
|
}).format(amount === null ? 0 : adjustPrecision({ amount, scale }));
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "uecko-presupuestador",
|
"name": "uecko-presupuestador",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"author": "Rodax Software <dev@rodax-software.com>",
|
"author": "Rodax Software <dev@rodax-software.com>",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@uecko-presupuestador/server",
|
"name": "@uecko-presupuestador/server",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.3",
|
||||||
"author": "Rodax Software <dev@rodax-software.com>",
|
"author": "Rodax Software <dev@rodax-software.com>",
|
||||||
"main": "./src/index.ts",
|
"main": "./src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -20,10 +20,10 @@ class ArticleMapper
|
|||||||
const id_article = this.mapsValue(source, "id_article", ArticleIdentifier.create);
|
const id_article = this.mapsValue(source, "id_article", ArticleIdentifier.create);
|
||||||
const reference = this.mapsValue(source, "reference", Slug.create);
|
const reference = this.mapsValue(source, "reference", Slug.create);
|
||||||
const points = this.mapsValue(source, "points", (value: any) =>
|
const points = this.mapsValue(source, "points", (value: any) =>
|
||||||
Quantity.create({ amount: value, scale: 4 })
|
Quantity.create({ amount: value, scale: 2 })
|
||||||
);
|
);
|
||||||
const retail_price = this.mapsValue(source, "retail_price", (value: any) =>
|
const retail_price = this.mapsValue(source, "retail_price", (value: any) =>
|
||||||
UnitPrice.create({ amount: value, scale: 4 })
|
UnitPrice.create({ amount: value, scale: 2 })
|
||||||
);
|
);
|
||||||
|
|
||||||
const language = this.mapsValue(source, "lang_code", Language.createFromCode);
|
const language = this.mapsValue(source, "lang_code", Language.createFromCode);
|
||||||
|
|||||||
@ -92,9 +92,8 @@ export class Quote extends AggregateRoot<IQuoteProps> implements IQuote {
|
|||||||
.toArray()
|
.toArray()
|
||||||
.reduce<MoneyValue>(
|
.reduce<MoneyValue>(
|
||||||
(accumulator, currentItem) => accumulator.add(currentItem.totalPrice),
|
(accumulator, currentItem) => accumulator.add(currentItem.totalPrice),
|
||||||
MoneyValue.create({ amount: 0, scale: 4, currencyCode: this.currency.code }).object
|
MoneyValue.create({ amount: 0, scale: 2, currencyCode: this.currency.code }).object
|
||||||
)
|
);
|
||||||
.convertScale(2);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -54,7 +54,7 @@ export class QuoteItem extends Entity<IQuoteItemProps> implements IQuoteItem {
|
|||||||
|
|
||||||
get subtotalPrice(): MoneyValue {
|
get subtotalPrice(): MoneyValue {
|
||||||
return this.quantity.isNull() || this.unitPrice.isNull()
|
return this.quantity.isNull() || this.unitPrice.isNull()
|
||||||
? MoneyValue.create({ amount: null, scale: 4 }).object
|
? MoneyValue.create({ amount: null, scale: 2 }).object
|
||||||
: this.unitPrice.multiply(this.quantity.toNumber());
|
: this.unitPrice.multiply(this.quantity.toNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ export class QuoteItem extends Entity<IQuoteItemProps> implements IQuoteItem {
|
|||||||
|
|
||||||
get totalPrice(): MoneyValue {
|
get totalPrice(): MoneyValue {
|
||||||
return this.subtotalPrice.isNull()
|
return this.subtotalPrice.isNull()
|
||||||
? MoneyValue.create({ amount: null, scale: 4 }).object
|
? MoneyValue.create({ amount: null, scale: 2 }).object
|
||||||
: this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
: this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,9 +55,9 @@ const quoteItemPresenter = (
|
|||||||
id_article: item.idArticle.toString(),
|
id_article: item.idArticle.toString(),
|
||||||
description: item.description.toString(),
|
description: item.description.toString(),
|
||||||
quantity: item.quantity.convertScale(2).toObject(),
|
quantity: item.quantity.convertScale(2).toObject(),
|
||||||
unit_price: item.unitPrice.convertScale(4).toObject(),
|
unit_price: item.unitPrice.convertScale(2).toObject(),
|
||||||
subtotal_price: item.subtotalPrice.convertScale(4).toObject(),
|
subtotal_price: item.subtotalPrice.convertScale(2).toObject(),
|
||||||
discount: item.discount.convertScale(2).toObject(),
|
discount: item.discount.convertScale(2).toObject(),
|
||||||
total_price: item.totalPrice.convertScale(4).toObject(),
|
total_price: item.totalPrice.convertScale(2).toObject(),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@ -57,9 +57,9 @@ const quoteItemPresenter = (
|
|||||||
id_article: item.idArticle.toString(),
|
id_article: item.idArticle.toString(),
|
||||||
description: item.description.toString(),
|
description: item.description.toString(),
|
||||||
quantity: item.quantity.convertScale(2).toObject(),
|
quantity: item.quantity.convertScale(2).toObject(),
|
||||||
unit_price: item.unitPrice.convertScale(4).toObject(),
|
unit_price: item.unitPrice.convertScale(2).toObject(),
|
||||||
subtotal_price: item.subtotalPrice.convertScale(4).toObject(),
|
subtotal_price: item.subtotalPrice.convertScale(2).toObject(),
|
||||||
discount: item.discount.convertScale(2).toObject(),
|
discount: item.discount.convertScale(2).toObject(),
|
||||||
total_price: item.totalPrice.convertScale(4).toObject(),
|
total_price: item.totalPrice.convertScale(2).toObject(),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@ -55,9 +55,9 @@ const quoteItemPresenter = (
|
|||||||
id_article: item.idArticle.toString(),
|
id_article: item.idArticle.toString(),
|
||||||
description: item.description.toString(),
|
description: item.description.toString(),
|
||||||
quantity: item.quantity.convertScale(2).toObject(),
|
quantity: item.quantity.convertScale(2).toObject(),
|
||||||
unit_price: item.unitPrice.convertScale(4).toObject(),
|
unit_price: item.unitPrice.convertScale(2).toObject(),
|
||||||
subtotal_price: item.subtotalPrice.convertScale(4).toObject(),
|
subtotal_price: item.subtotalPrice.convertScale(2).toObject(),
|
||||||
discount: item.discount.convertScale(2).toObject(),
|
discount: item.discount.convertScale(2).toObject(),
|
||||||
total_price: item.totalPrice.convertScale(4).toObject(),
|
total_price: item.totalPrice.convertScale(2).toObject(),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class QuoteItemMapper
|
|||||||
MoneyValue.create({
|
MoneyValue.create({
|
||||||
amount: unit_price,
|
amount: unit_price,
|
||||||
currencyCode: sourceParent.currency_code,
|
currencyCode: sourceParent.currency_code,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class QuoteItemMapper
|
|||||||
MoneyValue.create({
|
MoneyValue.create({
|
||||||
amount: subtotal_price,
|
amount: subtotal_price,
|
||||||
currencyCode: sourceParent.currency_code,
|
currencyCode: sourceParent.currency_code,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
*/
|
*/
|
||||||
@ -62,7 +62,7 @@ class QuoteItemMapper
|
|||||||
MoneyValue.create({
|
MoneyValue.create({
|
||||||
amount: total_price,
|
amount: total_price,
|
||||||
currencyCode: sourceParent.currency_code,
|
currencyCode: sourceParent.currency_code,
|
||||||
scale: 4,
|
scale: 2,
|
||||||
})
|
})
|
||||||
),*/
|
),*/
|
||||||
};
|
};
|
||||||
@ -89,10 +89,10 @@ class QuoteItemMapper
|
|||||||
id_article: source.idArticle.toPrimitive(),
|
id_article: source.idArticle.toPrimitive(),
|
||||||
description: source.description.toPrimitive(),
|
description: source.description.toPrimitive(),
|
||||||
quantity: source.quantity.convertScale(2).toPrimitive(),
|
quantity: source.quantity.convertScale(2).toPrimitive(),
|
||||||
unit_price: source.unitPrice.convertScale(4).toPrimitive(),
|
unit_price: source.unitPrice.convertScale(2).toPrimitive(),
|
||||||
subtotal_price: source.subtotalPrice.convertScale(4).toPrimitive(),
|
subtotal_price: source.subtotalPrice.convertScale(2).toPrimitive(),
|
||||||
discount: source.discount.convertScale(2).toPrimitive(),
|
discount: source.discount.convertScale(2).toPrimitive(),
|
||||||
total_price: source.totalPrice.convertScale(4).toPrimitive(),
|
total_price: source.totalPrice.convertScale(2).toPrimitive(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,11 @@ export interface IUnitPriceProps {
|
|||||||
scale: number;
|
scale: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_UNIT_PRICE_SCALE = 2;
|
||||||
|
|
||||||
export class UnitPrice extends MoneyValue {
|
export class UnitPrice extends MoneyValue {
|
||||||
public static create(props: IUnitPriceProps) {
|
public static create(props: IUnitPriceProps) {
|
||||||
const { amount, currencyCode, scale = 4 } = props;
|
const { amount, currencyCode, scale = DEFAULT_UNIT_PRICE_SCALE } = props;
|
||||||
const _unitPriceOrError = MoneyValue.create({
|
const _unitPriceOrError = MoneyValue.create({
|
||||||
amount,
|
amount,
|
||||||
currencyCode,
|
currencyCode,
|
||||||
@ -20,7 +22,7 @@ export class UnitPrice extends MoneyValue {
|
|||||||
return _unitPriceOrError;
|
return _unitPriceOrError;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _unitPrice = _unitPriceOrError.object.convertScale(4);
|
const _unitPrice = _unitPriceOrError.object.convertScale(DEFAULT_UNIT_PRICE_SCALE);
|
||||||
|
|
||||||
return Result.ok<UnitPrice>(_unitPrice);
|
return Result.ok<UnitPrice>(_unitPrice);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user