diff --git a/client/src/app/quotes/components/QuotePricesResume.tsx b/client/src/app/quotes/components/QuotePricesResume.tsx index 9dc36a5..bcf28ae 100644 --- a/client/src/app/quotes/components/QuotePricesResume.tsx +++ b/client/src/app/quotes/components/QuotePricesResume.tsx @@ -1,27 +1,37 @@ import { FormPercentageField } from "@/components"; import { useLocalization } from "@/lib/hooks"; import { Card, CardContent, CardDescription, CardTitle, Separator } from "@/ui"; +import { CurrencyData } from "@shared/contexts"; import { t } from "i18next"; +import { useMemo } from "react"; import { useFormContext } from "react-hook-form"; export const QuotePricesResume = () => { const { watch, register, formState } = useFormContext(); const { formatNumber } = useLocalization(); + const currency_code = watch("currency_code"); const subtotal_price = formatNumber(watch("subtotal_price")); const discount_price = formatNumber(watch("discount_price")); const tax_price = formatNumber(watch("tax_price")); const total_price = formatNumber(watch("total_price")); + const currency_symbol = useMemo(() => { + const currencyOrError = CurrencyData.createFromCode(currency_code); + return currencyOrError.isSuccess ? currencyOrError.object.symbol : ""; + }, [currency_code]); + return (
- Importe neto + + {t("quotes.form_fields.subtotal_price.label")} + {subtotal_price} - + {currency_symbol}
@@ -41,10 +51,12 @@ export const QuotePricesResume = () => { />
- Imp. descuento + + {t("quotes.form_fields.discount_price.label")} + {discount_price} - + {currency_symbol}
@@ -65,20 +77,24 @@ export const QuotePricesResume = () => { />
- Importe IVA + + {t("quotes.form_fields.tax_price.label")} + {tax_price} - + {currency_symbol}
{" "}
- Importe total + + {t("quotes.form_fields.total_price.label")} + {total_price} - + {currency_symbol}
diff --git a/client/src/app/quotes/components/QuotesDataTable.tsx b/client/src/app/quotes/components/QuotesDataTable.tsx index cbb665e..f87bec1 100644 --- a/client/src/app/quotes/components/QuotesDataTable.tsx +++ b/client/src/app/quotes/components/QuotesDataTable.tsx @@ -15,7 +15,6 @@ import { useQuotes } from "../hooks"; export const QuotesDataTable = ({ status = "all" }: { status?: string }) => { const navigate = useNavigate(); const { pagination, globalFilter, isFiltered } = useDataTableContext(); - const { useList } = useQuotes(); const { data, isPending, isError, error } = useList({ @@ -48,7 +47,12 @@ export const QuotesDataTable = ({ status = "all" }: { status?: string }) => {
{original.customer_information.split("\n").map((item, index) => { return ( - + {item}
@@ -78,7 +82,7 @@ export const QuotesDataTable = ({ status = "all" }: { status?: string }) => { id: "total_price" as const, accessor: "total_price", header: () =>
{t("quotes.list.columns.total_price")}
, - cell: ({ table, row: { index, original }, column, getValue }) => { + cell: ({ row: { original } }) => { const price = MoneyValue.create(original.total_price); return (
{price.isSuccess ? price.object.toFormat() : "-"}
diff --git a/client/src/app/settings/edit.tsx b/client/src/app/settings/edit.tsx index 8b987ed..644ee08 100644 --- a/client/src/app/settings/edit.tsx +++ b/client/src/app/settings/edit.tsx @@ -1,4 +1,4 @@ -import { ErrorOverlay, FormTextAreaField, LoadingOverlay } from "@/components"; +import { ErrorOverlay, FormPercentageField, FormTextAreaField, LoadingOverlay } from "@/components"; import { Alert, AlertDescription, @@ -12,6 +12,7 @@ import { CardTitle, Form, } from "@/ui"; +import { joiResolver } from "@hookform/resolvers/joi"; import { t } from "i18next"; import { AlertCircleIcon } from "lucide-react"; @@ -22,13 +23,14 @@ import { Trans } from "react-i18next"; import { useUnsavedChangesNotifier } from "@/lib/hooks"; import { cn } from "@/lib/utils"; import { IUpdateProfile_Request_DTO } from "@shared/contexts"; +import Joi from "joi"; import { toast } from "react-toastify"; import { useSettings } from "./hooks"; type SettingsDataForm = IUpdateProfile_Request_DTO; export const SettingsEditor = () => { - const [activeSection, setActiveSection] = useState("profile"); + const [activeSection, setActiveSection] = useState("quotes"); const { useOne, useUpdate } = useSettings(); const { data, status, error: queryError } = useOne(); @@ -40,6 +42,10 @@ export const SettingsEditor = () => { default_notes: "", default_legal_terms: "", default_quote_validity: "", + default_tax: { + amount: undefined, + scale: 2, + }, }), [] ); @@ -50,18 +56,19 @@ export const SettingsEditor = () => { mode: "onBlur", values: data?.dealer, defaultValues, - //defaultValues: _defaultValues, - /*resolver: joiResolver( + resolver: joiResolver( Joi.object({ - email: Joi.string() - .email({ tlds: { allow: false } }) - .required(), - password: Joi.string().min(4).alphanum().required(), - }), - { - messages: SpanishJoiMessages, - } - ),*/ + contact_information: Joi.string().optional().allow(null).allow("").default(""), + default_payment_method: Joi.string().optional().allow(null).allow("").default(""), + default_notes: Joi.string().optional().allow(null).allow("").default(""), + default_legal_terms: Joi.string().optional().allow(null).allow("").default(""), + default_quote_validity: Joi.string().optional().allow(null).allow("").default(""), + default_tax: Joi.object({ + amount: Joi.number().allow(null), + scale: Joi.number(), + }).required(), + }) + ), }); const { formState, reset, getValues, handleSubmit } = form; @@ -159,10 +166,8 @@ export const SettingsEditor = () => { //autoSize rows={8} placeholder={t("settings.form_fields.contact_information.placeholder")} - {...form.register("contact_information", { - required: true, - })} - errors={form.formState.errors} + name='contact_information' + required /> @@ -173,6 +178,31 @@ export const SettingsEditor = () => {
+ + + + + + + + + + + + + + + + + @@ -186,9 +216,8 @@ export const SettingsEditor = () => { @@ -211,10 +240,8 @@ export const SettingsEditor = () => { @@ -237,10 +264,8 @@ export const SettingsEditor = () => { @@ -265,10 +290,8 @@ export const SettingsEditor = () => { //autoSize rows={25} placeholder={t("settings.form_fields.default_legal_terms.placeholder")} - {...form.register("default_legal_terms", { - required: true, - })} - errors={form.formState.errors} + name='default_legal_terms' + required /> diff --git a/client/src/components/DataTable/DataTable.tsx b/client/src/components/DataTable/DataTable.tsx index 7877d7e..2d7aeb1 100644 --- a/client/src/components/DataTable/DataTable.tsx +++ b/client/src/components/DataTable/DataTable.tsx @@ -106,7 +106,7 @@ export function DataTable({ {row.getVisibleCells().map((cell) => ( diff --git a/client/src/components/DataTable/DataTableColumnHeader.tsx b/client/src/components/DataTable/DataTableColumnHeader.tsx index d887f74..15fa1c7 100644 --- a/client/src/components/DataTable/DataTableColumnHeader.tsx +++ b/client/src/components/DataTable/DataTableColumnHeader.tsx @@ -26,12 +26,7 @@ export function DataTableColumnHeader({ if (!header.column.getCanSort()) { return ( <> -
+
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 750b13e..cd7aea2 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -194,21 +194,41 @@ "placeholder": "", "desc": "Quote's validity time" }, - "discount": { - "label": "Discount", - "placeholder": "%", - "desc": "Percentage discount" - }, - "tax": { - "label": "Tax", - "placeholder": "%", - "desc": "Percentage Tax" - }, "subtotal_price": { "label": "Subtotal", "placeholder": "", "desc": "Quote subtotal" }, + "discount": { + "label": "Discount (%)", + "placeholder": "", + "desc": "Percentage discount" + }, + "discount_price": { + "label": "Discount price", + "placeholder": "", + "desc": "Percentage discount price" + }, + "before_tax_price": { + "label": "Before tax price", + "placeholder": "", + "desc": "Before tax price" + }, + "tax": { + "label": "Tax (%)", + "placeholder": "", + "desc": "Percentage Tax" + }, + "tax_price": { + "label": "Tax price", + "placeholder": "", + "desc": "Percentage tax price" + }, + "total_price": { + "label": "Total price", + "placeholder": "", + "desc": "Quote total price" + }, "items": { "quantity": { "label": "Quantity", @@ -256,14 +276,19 @@ "form_fields": { "image": { "label": "Logotype", - "placeholder": "placeholder", + "placeholder": "", "desc": "Información de contacto" }, "contact_information": { "label": "Your contact information", - "placeholder": "placeholder", + "placeholder": "", "desc": "Your contact information as a dealer that will appear on the quotes given to your customers." }, + "default_tax": { + "label": "Default tax (%)", + "placeholder": "", + "desc": "Default tax rate for your quotes" + }, "default_legal_terms": { "label": "Legal terms", "placeholder": "", @@ -271,7 +296,7 @@ }, "default_payment_method": { "label": "Payment method", - "placeholder": "placeholder", + "placeholder": "", "desc": "Default payment method to be used for new quotes" }, "default_notes": { diff --git a/client/src/locales/es.json b/client/src/locales/es.json index a0180cf..367b2e2 100644 --- a/client/src/locales/es.json +++ b/client/src/locales/es.json @@ -194,21 +194,41 @@ "placeholder": "", "desc": "desc" }, - "discount": { - "label": "Descuento", - "placeholder": "%", - "desc": "Porcentaje de descuento" - }, - "tax": { - "label": "IVA", - "placeholder": "%", - "desc": "Porcentaje de IVA" - }, "subtotal_price": { "label": "Importe neto", "placeholder": "", "desc": "" }, + "discount": { + "label": "Descuento (%)", + "placeholder": "", + "desc": "Porcentaje de descuento" + }, + "discount_price": { + "label": "Imp. descuento", + "placeholder": "", + "desc": "Importe del descuento" + }, + "before_tax_price": { + "label": "Base imponible", + "placeholder": "", + "desc": "" + }, + "tax": { + "label": "IVA (%)", + "placeholder": "", + "desc": "Porcentaje de IVA" + }, + "tax_price": { + "label": "Imp. descuento", + "placeholder": "", + "desc": "Importe del descuento" + }, + "total_price": { + "label": "Total price", + "placeholder": "", + "desc": "Quote total price" + }, "items": { "quantity": { "label": "Cantidad", @@ -244,37 +264,39 @@ } }, "settings": { - "title": "Ajustes", - "profile": { - "title": "Ajustes de perfil", - "items": { - "image": { - "label": "Información de contacto", - "placeholder": "placeholder", - "desc": "Información de contacto" - }, - "contact_information": { - "label": "Información de contacto", - "placeholder": "placeholder", - "desc": "Información de contacto" - } + "edit": { + "title": "Ajustes", + "subtitle": "", + "tabs": { + "profile": "Ajustes de perfil", + "quotes": "Ajustes legales", + "legal": "Ajustes para cotizaciones" } }, - "legal": { - "title": "Ajustes legales", - "items": { - "default_legal_terms": { - "label": "Cláusulas legales", - "placeholder": "", - "desc": "desc" - } - } - }, - "quotes": { - "title": "Ajustes para cotizaciones", + "form_fields": { + "image": { + "label": "Información de contacto", + "placeholder": "", + "desc": "Información de contacto" + }, + "contact_information": { + "label": "Información de contacto", + "placeholder": "", + "desc": "Información de contacto" + }, + "default_tax": { + "label": "IVA por defecto (%)", + "placeholder": "", + "desc": "Porcentaje de IVA por defecto para tus cotizaciones" + }, + "default_legal_terms": { + "label": "Cláusulas legales", + "placeholder": "", + "desc": "desc" + }, "default_payment_method": { "label": "Forma de pago", - "placeholder": "placeholder", + "placeholder": "", "desc": "desc" }, "default_notes": { diff --git a/server/src/contexts/profile/application/UpdateProfile.useCase.ts b/server/src/contexts/profile/application/UpdateProfile.useCase.ts index 08e63a9..f3961a0 100644 --- a/server/src/contexts/profile/application/UpdateProfile.useCase.ts +++ b/server/src/contexts/profile/application/UpdateProfile.useCase.ts @@ -7,7 +7,13 @@ import { import { IRepositoryManager } from "@/contexts/common/domain"; import { IInfrastructureError } from "@/contexts/common/infrastructure"; import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize"; -import { IUpdateProfile_Request_DTO, Result, TextValueObject, UniqueID } from "@shared/contexts"; +import { + IUpdateProfile_Request_DTO, + Percentage, + Result, + TextValueObject, + UniqueID, +} from "@shared/contexts"; import { IProfileRepository, Profile } from "../domain"; export interface IUpdateProfileUseCaseRequest extends IUseCaseRequest { @@ -33,8 +39,6 @@ export class UpdateProfileUseCase async execute(request: IUpdateProfileUseCaseRequest): Promise { const { userId, profileDTO } = request; - console.log(request); - // Comprobar que existe el profile const exitsOrError = await this._getProfileDealer(userId); if (exitsOrError.isFailure) { @@ -55,6 +59,13 @@ export class UpdateProfileUseCase profile.defaultNotes = TextValueObject.create(profileDTO.default_notes).object; profile.defaultQuoteValidity = TextValueObject.create(profileDTO.default_quote_validity).object; + const taxOrError = Percentage.create(profileDTO.default_tax); + if (taxOrError.isFailure) { + return Result.fail(taxOrError.error); + } + + profile.defaultTax = taxOrError.object; + // Guardar los cambios return this._saveProfile(profile); } diff --git a/server/src/contexts/profile/domain/entities/Profile.ts b/server/src/contexts/profile/domain/entities/Profile.ts index 9123964..48b4e11 100644 --- a/server/src/contexts/profile/domain/entities/Profile.ts +++ b/server/src/contexts/profile/domain/entities/Profile.ts @@ -6,6 +6,7 @@ import { Language, Name, Note, + Percentage, Result, UniqueID, } from "@shared/contexts"; @@ -21,6 +22,7 @@ export interface IProfileProps { defaultNotes: Note; defaultLegalTerms: Note; defaultQuoteValidity: Note; + defaultTax: Percentage; } export interface IProfile { @@ -34,7 +36,9 @@ export interface IProfile { defaultPaymentMethod: Note; defaultNotes: Note; defaultLegalTerms: Note; + defaultQuoteValidity: Note; + defaultTax: Percentage; } export class Profile extends AggregateRoot implements IProfile { @@ -98,4 +102,12 @@ export class Profile extends AggregateRoot implements IProfile { set defaultQuoteValidity(newDefaultQuoteValidity: Note) { this.props.defaultQuoteValidity = newDefaultQuoteValidity; } + + get defaultTax(): Percentage { + return this.props.defaultTax; + } + + set defaultTax(newDefaultTax: Percentage) { + this.props.defaultTax = newDefaultTax; + } } diff --git a/server/src/contexts/profile/infrastructure/express/controllers/getProfile/presenter/GetProfile.presenter.ts b/server/src/contexts/profile/infrastructure/express/controllers/getProfile/presenter/GetProfile.presenter.ts index a10c743..5e73674 100644 --- a/server/src/contexts/profile/infrastructure/express/controllers/getProfile/presenter/GetProfile.presenter.ts +++ b/server/src/contexts/profile/infrastructure/express/controllers/getProfile/presenter/GetProfile.presenter.ts @@ -27,6 +27,7 @@ export const GetProfilePresenter: IGetProfilePresenter = { default_notes: profile.defaultNotes.toString(), default_legal_terms: profile.defaultLegalTerms.toString(), default_quote_validity: profile.defaultQuoteValidity.toString(), + default_tax: profile.defaultTax.convertScale(2).toObject(), }, }; }, diff --git a/server/src/contexts/profile/infrastructure/express/controllers/updateProfile/presenter/UpdateUser.presenter.ts b/server/src/contexts/profile/infrastructure/express/controllers/updateProfile/presenter/UpdateUser.presenter.ts index f07fef3..de747da 100644 --- a/server/src/contexts/profile/infrastructure/express/controllers/updateProfile/presenter/UpdateUser.presenter.ts +++ b/server/src/contexts/profile/infrastructure/express/controllers/updateProfile/presenter/UpdateUser.presenter.ts @@ -15,6 +15,7 @@ export const UpdateProfilePresenter: IUpdateProfilePresenter = { default_notes: profile.defaultNotes.toString(), default_legal_terms: profile.defaultLegalTerms.toString(), default_quote_validity: profile.defaultQuoteValidity.toString(), + default_tax: profile.defaultTax.convertScale(2).toObject(), }; }, }; diff --git a/server/src/contexts/profile/infrastructure/mappers/profile.mapper.ts b/server/src/contexts/profile/infrastructure/mappers/profile.mapper.ts index 0b2aac5..2acf961 100644 --- a/server/src/contexts/profile/infrastructure/mappers/profile.mapper.ts +++ b/server/src/contexts/profile/infrastructure/mappers/profile.mapper.ts @@ -5,7 +5,14 @@ import { } from "@/contexts/common/infrastructure"; import { DealerStatus } from "@/contexts/sales/domain"; import { Dealer_Model, DealerCreationAttributes } from "@/contexts/sales/infrastructure/sequelize"; -import { CurrencyData, Language, Name, TextValueObject, UniqueID } from "@shared/contexts"; +import { + CurrencyData, + Language, + Name, + Percentage, + TextValueObject, + UniqueID, +} from "@shared/contexts"; import { IProfileProps, Profile } from "../../domain"; import { IProfileContext } from "../Profile.context"; @@ -44,6 +51,13 @@ class ProfileMapper TextValueObject.create ); + const defaultTax = this.mapsValue(source, "default_tax", (tax) => + Percentage.create({ + amount: tax, + scale: 2, + }) + ); + const props: IProfileProps = { name, status, @@ -55,6 +69,7 @@ class ProfileMapper defaultNotes, defaultLegalTerms, defaultQuoteValidity, + defaultTax, }; const id = this.mapsValue(source, "id", UniqueID.create); @@ -76,6 +91,7 @@ class ProfileMapper default_notes: source.defaultNotes.toPrimitive(), default_legal_terms: source.defaultLegalTerms.toPrimitive(), default_quote_validity: source.defaultQuoteValidity.toPrimitive(), + default_tax: source.defaultTax.convertScale(2).toPrimitive(), }; } } diff --git a/server/src/contexts/sales/application/Quote/ListQuotes.useCase.ts b/server/src/contexts/sales/application/Quote/ListQuotes.useCase.ts index 8b8b8c1..b72ff05 100644 --- a/server/src/contexts/sales/application/Quote/ListQuotes.useCase.ts +++ b/server/src/contexts/sales/application/Quote/ListQuotes.useCase.ts @@ -41,6 +41,8 @@ export class ListQuotesUseCase implements IUseCase implements IQuot return this.mapper.mapToDomain(rawQuote); } - public async findAll(queryCriteria?: IQueryCriteria): Promise> { + public async findAll(queryCriteria?: IQueryCriteria): Promise> { + const QuoteItem_Model: ModelDefined = this._adapter.getModel("QuoteItem_Model"); + const { rows, count } = await this._findAll("Quote_Model", queryCriteria, { include: [], // esto es para quitar las asociaciones al hacer la consulta + /*include: [ + { + model: QuoteItem_Model, + as: "items", + }, + ],*/ order: [ ["date", "DESC"], ["customer_information", "ASC"], diff --git a/server/src/contexts/sales/infrastructure/mappers/dealer.mapper.ts b/server/src/contexts/sales/infrastructure/mappers/dealer.mapper.ts index cfaf407..8ef3870 100644 --- a/server/src/contexts/sales/infrastructure/mappers/dealer.mapper.ts +++ b/server/src/contexts/sales/infrastructure/mappers/dealer.mapper.ts @@ -32,6 +32,7 @@ class DealerMapper ["default_notes", source.default_notes], ["default_legal_terms", source.default_legal_terms], ["default_quote_validity", source.default_quote_validity], + ["default_tax", source.default_tax], ]); const props: IDealerProps = { @@ -69,6 +70,7 @@ class DealerMapper default_notes: source.additionalInfo.get("default_notes")?.toString() ?? "", default_legal_terms: source.additionalInfo.get("default_legal_terms")?.toString() ?? "", default_quote_validity: source.additionalInfo.get("default_quote_validity")?.toString() ?? "", + default_tax: source.additionalInfo.get("default_tax")?.toString() ?? "", }; } } diff --git a/server/src/contexts/sales/infrastructure/sequelize/dealer.model.ts b/server/src/contexts/sales/infrastructure/sequelize/dealer.model.ts index ae185e9..6fc61a8 100644 --- a/server/src/contexts/sales/infrastructure/sequelize/dealer.model.ts +++ b/server/src/contexts/sales/infrastructure/sequelize/dealer.model.ts @@ -53,6 +53,7 @@ export class Dealer_Model extends Model< declare default_notes: CreationOptional; declare default_legal_terms: CreationOptional; declare default_quote_validity: CreationOptional; + declare default_tax: CreationOptional; declare status: CreationOptional; declare lang_code: CreationOptional; declare currency_code: CreationOptional; @@ -85,6 +86,12 @@ export default (sequelize: Sequelize) => { default_legal_terms: DataTypes.TEXT, default_quote_validity: DataTypes.TEXT, + default_tax: { + type: new DataTypes.SMALLINT(), + allowNull: true, + defaultValue: 2100, + }, + lang_code: { type: DataTypes.STRING(2), allowNull: false, diff --git a/shared/lib/contexts/common/domain/entities/QueryCriteria/Pagination/defaults.ts b/shared/lib/contexts/common/domain/entities/QueryCriteria/Pagination/defaults.ts index 9c0efc8..05835c7 100644 --- a/shared/lib/contexts/common/domain/entities/QueryCriteria/Pagination/defaults.ts +++ b/shared/lib/contexts/common/domain/entities/QueryCriteria/Pagination/defaults.ts @@ -1,5 +1,5 @@ export const INITIAL_PAGE_INDEX = 0; -export const INITIAL_PAGE_SIZE = 5; +export const INITIAL_PAGE_SIZE = 10; export const MIN_PAGE_INDEX = 0; export const MIN_PAGE_SIZE = 1; diff --git a/shared/lib/contexts/profile/application/dto/GetProfile.dto/IGetProfile_Response.dto.ts b/shared/lib/contexts/profile/application/dto/GetProfile.dto/IGetProfile_Response.dto.ts index ce93fc6..79806be 100644 --- a/shared/lib/contexts/profile/application/dto/GetProfile.dto/IGetProfile_Response.dto.ts +++ b/shared/lib/contexts/profile/application/dto/GetProfile.dto/IGetProfile_Response.dto.ts @@ -1,3 +1,5 @@ +import { IPercentage_DTO } from "../../../../common"; + export interface IGetProfileResponse_DTO { id: string; name: string; @@ -12,6 +14,7 @@ export interface IGetProfileResponse_DTO { default_notes: string; default_legal_terms: string; default_quote_validity: string; + default_tax: IPercentage_DTO; status: string; lang_code: string; currency_code: string; diff --git a/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Request.dto.ts b/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Request.dto.ts index 4d96d97..3510706 100644 --- a/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Request.dto.ts +++ b/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Request.dto.ts @@ -1,5 +1,5 @@ import Joi from "joi"; -import { Result, RuleValidator } from "../../../../common"; +import { IPercentage_DTO, Result, RuleValidator } from "../../../../common"; export interface IUpdateProfile_Request_DTO { contact_information: string; @@ -7,6 +7,7 @@ export interface IUpdateProfile_Request_DTO { default_notes: string; default_legal_terms: string; default_quote_validity: string; + default_tax: IPercentage_DTO; } export function ensureUpdateProfile_Request_DTOIsValid(userDTO: IUpdateProfile_Request_DTO) { @@ -16,6 +17,10 @@ export function ensureUpdateProfile_Request_DTOIsValid(userDTO: IUpdateProfile_R default_notes: Joi.string().optional().allow(null).allow("").default(""), default_legal_terms: Joi.string().optional().allow(null).allow("").default(""), default_quote_validity: Joi.string().optional().allow(null).allow("").default(""), + default_tax: Joi.object({ + amount: Joi.number().allow(null), + scale: Joi.number(), + }).optional(), }).unknown(true); const result = RuleValidator.validate(schema, userDTO); diff --git a/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Response.dto.ts b/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Response.dto.ts index edbc426..b568c88 100644 --- a/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Response.dto.ts +++ b/shared/lib/contexts/profile/application/dto/UpdateProfile.dto/IUpdateProfile_Response.dto.ts @@ -1,3 +1,5 @@ +import { IPercentage_DTO } from "../../../../common"; + export interface IUpdateProfileResponse_DTO { dealer_id: string; contact_information: string; @@ -5,4 +7,5 @@ export interface IUpdateProfileResponse_DTO { default_notes: string; default_legal_terms: string; default_quote_validity: string; + default_tax: IPercentage_DTO; }