diff --git a/client/src/app/quotes/components/QuotesDataTable.tsx b/client/src/app/quotes/components/QuotesDataTable.tsx index 74ca224..01bbd4a 100644 --- a/client/src/app/quotes/components/QuotesDataTable.tsx +++ b/client/src/app/quotes/components/QuotesDataTable.tsx @@ -46,7 +46,7 @@ export const QuotesDataTable = () => {
{original.customer_information.split("\n").map((item, index) => { return ( - + {item}
@@ -93,7 +93,7 @@ export const QuotesDataTable = () => { variant='secondary' onClick={(e) => { e.preventDefault(); - navigate(`/quotes/edit/${row.original.id}`, { relative: "path", replace: true }); + navigate(`/quotes/edit/${row.original.id}`, { relative: "path" }); }} > diff --git a/client/src/app/quotes/create.tsx b/client/src/app/quotes/create.tsx index 76bf542..aafa161 100644 --- a/client/src/app/quotes/create.tsx +++ b/client/src/app/quotes/create.tsx @@ -6,11 +6,9 @@ import { } from "@/components"; import { t } from "i18next"; -import { ChevronLeft } from "lucide-react"; - import { SubmitButton } from "@/components"; import { useWarnAboutChange } from "@/lib/hooks"; -import { Button, Form } from "@/ui"; +import { Form } from "@/ui"; import { ICreateQuote_Request_DTO } from "@shared/contexts"; import { useEffect } from "react"; import { FieldErrors, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form"; @@ -52,7 +50,7 @@ export const QuoteCreate = () => { setWarnWhen(false); mutate(formData, { onSuccess: (data) => { - navigate(`/quotes/edit/${data.id}`, { relative: "path", replace: true }); + navigate(`/quotes/edit/${data.id}`, { relative: "path" }); }, }); } finally { @@ -71,15 +69,7 @@ export const QuoteCreate = () => {
- +

{t("quotes.create.title")}

diff --git a/client/src/app/quotes/edit.tsx b/client/src/app/quotes/edit.tsx index 7dd583a..9e131fd 100644 --- a/client/src/app/quotes/edit.tsx +++ b/client/src/app/quotes/edit.tsx @@ -1,12 +1,19 @@ -import { ErrorOverlay, FormCurrencyField, LoadingOverlay, SubmitButton } from "@/components"; +import { + BackHistoryButton, + CancelButton, + ErrorOverlay, + FormCurrencyField, + LoadingOverlay, + SubmitButton, +} from "@/components"; import { calculateItemTotals } from "@/lib/calc"; import { useUrlId } from "@/lib/hooks/useUrlId"; import { Badge, Button, Form, Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui"; import { CurrencyData, IUpdateQuote_Request_DTO, MoneyValue } from "@shared/contexts"; import { t } from "i18next"; -import { ChevronLeftIcon } from "lucide-react"; import { useEffect, useState } from "react"; import { SubmitHandler, useForm } from "react-hook-form"; +import { useNavigate } from "react-router-dom"; import { QuoteDetailsCardEditor, QuoteGeneralCardEditor } from "./components/editors"; import { useQuotes } from "./hooks"; @@ -14,6 +21,7 @@ interface QuoteDataForm extends IUpdateQuote_Request_DTO {} // eslint-disable-next-line @typescript-eslint/no-unused-vars export const QuoteEdit = () => { + const navigate = useNavigate(); const quoteId = useUrlId(); const [quoteCurrency, setQuoteCurrency] = useState( CurrencyData.createDefaultCode().object @@ -46,6 +54,20 @@ export const QuoteEdit = () => { payment_method: "", notes: "", validity: "", + subtotal_price: { + amount: undefined, + precision: 2, + currency_code: data?.currency_code, + }, + discount: { + amount: undefined, + precision: 0, + }, + total_price: { + amount: undefined, + precision: 2, + currency_code: data?.currency_code, + }, items: [], }, }); @@ -140,10 +162,7 @@ export const QuoteEdit = () => {
- +

{t("quotes.edit.title")}

@@ -151,9 +170,9 @@ export const QuoteEdit = () => { {data.status}
- + {t("common.save")} diff --git a/client/src/app/quotes/hooks/useQuotes.tsx b/client/src/app/quotes/hooks/useQuotes.tsx index 98e2b67..38086f1 100644 --- a/client/src/app/quotes/hooks/useQuotes.tsx +++ b/client/src/app/quotes/hooks/useQuotes.tsx @@ -58,11 +58,14 @@ export const useQuotes = () => { useSave({ mutationKey: keys().data().resource("quotes").action("one").id(id).params().get(), mutationFn: (data) => { + const { date: quoteDate } = data; + return dataSource.updateOne({ resource: "quotes", id, data: { ...data, + date: new Date(quoteDate).toISOString().slice(0, 10), }, }); }, diff --git a/client/src/components/CustomButtons/BackHistoryButton.tsx b/client/src/components/CustomButtons/BackHistoryButton.tsx index 4af3e98..a69d10f 100644 --- a/client/src/components/CustomButtons/BackHistoryButton.tsx +++ b/client/src/components/CustomButtons/BackHistoryButton.tsx @@ -1,45 +1,15 @@ -import { Button, ButtonProps } from "@/ui"; -import { ChevronLeft } from "lucide-react"; -import { To, useNavigate } from "react-router-dom"; -import { CustomButton } from "../Buttons/CustomButton"; +import { Button } from "@/ui"; +import { t } from "i18next"; +import { ChevronLeftIcon } from "lucide-react"; +import { useNavigate } from "react-router-dom"; -export interface BackHistoryButtonProps extends ButtonProps { - label?: string; - url?: To; -} - -export const BackHistoryButton = ({ - label = "Volver atrĂ¡s", - size, - url = undefined, - ...props -}: BackHistoryButtonProps): JSX.Element => { +export const BackHistoryButton = () => { const navigate = useNavigate(); return ( - { - url ? navigate(url) : navigate(-1); - }} - {...props} - /> - ); - - return ( - ); }; diff --git a/client/src/components/DataTable/DataTablePagination.tsx b/client/src/components/DataTable/DataTablePagination.tsx index d22a880..adda93d 100644 --- a/client/src/components/DataTable/DataTablePagination.tsx +++ b/client/src/components/DataTable/DataTablePagination.tsx @@ -33,11 +33,16 @@ export function DataTablePagination({ return (
- {t("common.rows_selected", { - count: table.getFilteredSelectedRowModel().rows.length, - total: table.getFilteredRowModel().rows.length, - })} + {table.getSelectedRowModel().rows.length > 0 && ( + <> + {t("common.rows_selected", { + count: table.getFilteredSelectedRowModel().rows.length, + total: table.getFilteredRowModel().rows.length, + })} + + )}
+

{t("common.rows_per_page")}

diff --git a/client/src/components/Forms/FormDatePickerField.tsx b/client/src/components/Forms/FormDatePickerField.tsx index 9637dac..28afc14 100644 --- a/client/src/components/Forms/FormDatePickerField.tsx +++ b/client/src/components/Forms/FormDatePickerField.tsx @@ -94,7 +94,7 @@ export const FormDatePickerField = React.forwardRef< field.onChange(e); setIsPopoverOpen(false); }} - disabled={(date) => date < new Date("2024-06-01")} + disabled={(date) => date < new Date("1980-01-01")} weekStartsOn={1} fixedWeeks={true} fromYear={2024} diff --git a/server/src/contexts/sales/infrastructure/Quote.repository.ts b/server/src/contexts/sales/infrastructure/Quote.repository.ts index b446750..b87cc8f 100644 --- a/server/src/contexts/sales/infrastructure/Quote.repository.ts +++ b/server/src/contexts/sales/infrastructure/Quote.repository.ts @@ -75,6 +75,11 @@ export class QuoteRepository extends SequelizeRepository implements IQuot public async findAll(queryCriteria?: IQueryCriteria): Promise> { const { rows, count } = await this._findAll("Quote_Model", queryCriteria, { include: [], // esto es para quitar las asociaciones al hacer la consulta + order: [ + ["date", "DESC"], + ["customer_information", "ASC"], + ["status", "ASC"], + ], }); return this.mapper.mapArrayAndCountToDomain(rows, count); diff --git a/shared/lib/contexts/sales/application/dto/Quote/UpdateQuote.dto/IUpdateQuote_Request.dto.ts b/shared/lib/contexts/sales/application/dto/Quote/UpdateQuote.dto/IUpdateQuote_Request.dto.ts index c8c7f7b..99a036a 100644 --- a/shared/lib/contexts/sales/application/dto/Quote/UpdateQuote.dto/IUpdateQuote_Request.dto.ts +++ b/shared/lib/contexts/sales/application/dto/Quote/UpdateQuote.dto/IUpdateQuote_Request.dto.ts @@ -49,20 +49,26 @@ export function ensureUpdateQuote_Request_DTOIsValid(quoteDTO: IUpdateQuote_Requ notes: Joi.string().optional().allow(null).allow("").default(""), validity: Joi.string().optional().allow(null).allow("").default(""), - subtotal: Joi.object({ + subtotal_price: Joi.object({ amount: Joi.number(), precision: Joi.number(), currency_code: Joi.string(), - }), + }).unknown(), discount: Joi.object({ amount: Joi.number(), precision: Joi.number(), }).unknown(), + total_price: Joi.object({ + amount: Joi.number(), + precision: Joi.number(), + currency_code: Joi.string(), + }).unknown(), + items: Joi.array().items( Joi.object({ - article_id: Joi.string(), + article_id: Joi.string().optional().allow(null).allow("").default(""), quantity: Joi.object({ amount: Joi.number(), precision: Joi.number(),