.
This commit is contained in:
parent
8ad1c63acc
commit
533b22dd98
@ -10,7 +10,7 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
import { Layout, LayoutContent, LayoutHeader } from "@/components";
|
||||
import { useGetIdentity } from "@/lib/hooks";
|
||||
import { useGetProfile } from "@/lib/hooks";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
@ -49,7 +49,7 @@ import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const DashboardPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const { data: userIdentity, status } = useGetIdentity();
|
||||
const { data: userIdentity, status } = useGetProfile();
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
|
||||
@ -202,14 +202,8 @@ export const QuoteEdit = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormCurrencyField
|
||||
currency={quoteCurrency}
|
||||
precision={4}
|
||||
className='text-right'
|
||||
label={"subtotal_price"}
|
||||
disabled={form.formState.disabled}
|
||||
{...form.register("subtotal_price")}
|
||||
/>
|
||||
<QuoteGeneralCardEditor />
|
||||
<QuoteDetailsCardEditor currency={quoteCurrency} />
|
||||
|
||||
<Tabs defaultValue='items' className='space-y-4'>
|
||||
<TabsList>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCustomDialog, useGetIdentity } from "@/lib/hooks";
|
||||
import { useCustomDialog, useGetProfile } from "@/lib/hooks";
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
@ -32,7 +32,7 @@ export const UserButton = () => {
|
||||
navigate("/logout");
|
||||
},
|
||||
});
|
||||
const { data, status } = useGetIdentity();
|
||||
const { data, status } = useGetProfile();
|
||||
|
||||
const openUserMenu = (event: SyntheticEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
@ -24,7 +24,7 @@ export const createAxiosAuthActions = (
|
||||
return {
|
||||
success: true,
|
||||
data,
|
||||
redirectTo: "/",
|
||||
redirectTo: "/home",
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
@ -61,10 +61,18 @@ export const createAxiosAuthActions = (
|
||||
);
|
||||
},
|
||||
|
||||
getIdentity: async () => {
|
||||
getProfile: async () => {
|
||||
/**
|
||||
* id: string;
|
||||
* name: string;
|
||||
* email: string;
|
||||
* lang_code: string;
|
||||
* roles: string[];
|
||||
*/
|
||||
|
||||
try {
|
||||
const result = await httpClient.request<IIdentity_Response_DTO>({
|
||||
url: `${apiUrl}/auth/identity`,
|
||||
url: `${apiUrl}/profile`,
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IIdentity_Response_DTO } from "@shared/contexts";
|
||||
import { IGetProfileResponse_DTO } from "@shared/contexts";
|
||||
|
||||
export type SuccessNotificationResponse = {
|
||||
message: string;
|
||||
@ -7,7 +7,7 @@ export type SuccessNotificationResponse = {
|
||||
|
||||
export type PermissionResponse = unknown;
|
||||
|
||||
export type IdentityResponse = IIdentity_Response_DTO | null;
|
||||
export type ProfileResponse = IGetProfileResponse_DTO | null;
|
||||
|
||||
export type AuthActionCheckResponse = {
|
||||
authenticated: boolean;
|
||||
@ -39,5 +39,5 @@ export interface IAuthActions {
|
||||
forgotPassword?: (params: unknown) => Promise<AuthActionResponse>;
|
||||
updatePassword?: (params: unknown) => Promise<AuthActionResponse>;
|
||||
getPermissions?: (params?: Record<string, unknown>) => Promise<PermissionResponse>;
|
||||
getIdentity?: (params?: unknown) => Promise<IdentityResponse>;
|
||||
getProfile?: (params?: unknown) => Promise<ProfileResponse>;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
export * from "./AuthActions";
|
||||
export * from "./AuthContext";
|
||||
export * from "./useAuth";
|
||||
export * from "./useGetIdentity";
|
||||
export * from "./useGetProfile";
|
||||
export * from "./useIsLoggedIn";
|
||||
export * from "./useLogin";
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
import { IdentityResponse, useAuth } from "@/lib/hooks";
|
||||
import { UseQueryOptions, useQuery } from "@tanstack/react-query";
|
||||
import { useQueryKey } from "../useQueryKey";
|
||||
|
||||
export const useGetIdentity = (queryOptions?: UseQueryOptions<IdentityResponse>) => {
|
||||
const keys = useQueryKey();
|
||||
const { getIdentity } = useAuth();
|
||||
|
||||
const result = useQuery<IdentityResponse>({
|
||||
queryKey: keys().auth().action("identity").get(),
|
||||
queryFn: getIdentity,
|
||||
...queryOptions,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
16
client/src/lib/hooks/useAuth/useGetProfile.ts
Normal file
16
client/src/lib/hooks/useAuth/useGetProfile.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ProfileResponse, useAuth } from "@/lib/hooks";
|
||||
import { UseQueryOptions, useQuery } from "@tanstack/react-query";
|
||||
import { useQueryKey } from "../useQueryKey";
|
||||
|
||||
export const useGetProfile = (queryOptions?: UseQueryOptions<ProfileResponse>) => {
|
||||
const keys = useQueryKey();
|
||||
const { getProfile } = useAuth();
|
||||
|
||||
const result = useQuery<ProfileResponse>({
|
||||
queryKey: keys().auth().action("profile").get(),
|
||||
queryFn: getProfile,
|
||||
...queryOptions,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
@ -17,7 +17,7 @@ export const useLogin = (params?: UseMutationOptions<AuthActionResponse, Error,
|
||||
onSuccess: (data, variables, context) => {
|
||||
const { success, redirectTo } = data;
|
||||
if (success && redirectTo) {
|
||||
navigate(redirectTo || "/", { replace: true });
|
||||
navigate(redirectTo || "/home", { replace: false });
|
||||
}
|
||||
if (onSuccess) {
|
||||
onSuccess(data, variables, context);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useGetIdentity } from "../useAuth";
|
||||
import { useGetProfile } from "../useAuth";
|
||||
|
||||
export const usePreferredLanguage = () => {
|
||||
const { data } = useGetIdentity();
|
||||
const { data } = useGetProfile();
|
||||
|
||||
if (!data || !data.language) {
|
||||
return navigator.languages && navigator.languages.length
|
||||
|
||||
@ -16,7 +16,7 @@ type DataMutationActions =
|
||||
type AuthActionType =
|
||||
| "login"
|
||||
| "logout"
|
||||
| "identity"
|
||||
| "profile"
|
||||
| "register"
|
||||
| "forgotPassword"
|
||||
| "check"
|
||||
|
||||
@ -4,36 +4,243 @@
|
||||
"cancel": "Cancel",
|
||||
"no": "No",
|
||||
"yes": "Yes",
|
||||
"Accept": "Accept"
|
||||
"save": "Save",
|
||||
"accept": "OK",
|
||||
"hide": "Ocultar",
|
||||
"back": "Back",
|
||||
"upload": "Upload",
|
||||
"continue": "Continue",
|
||||
"sort_asc": "Asc",
|
||||
"sort_asc_description": "En order ascendente. Click para ordenar descendentemente.",
|
||||
"sort_desc": "Desc",
|
||||
"sort_desc_description": "En orden descendente. Click para ordenar ascendentemente.",
|
||||
"sort_none_description": "Sin orden. Click para ordenar ascendentemente.",
|
||||
"rows_selected": "{{count}} de {{total}} fila(s) seleccionadas.",
|
||||
"rows_per_page": "Filas por página",
|
||||
"num_page_of_total": "Página {{count}} de {{total}}",
|
||||
"go_to_first_page": "Ir a la primera página",
|
||||
"go_to_prev_page": "Ir a la página anterior",
|
||||
"go_to_next_page": "Ir a la página siguiente",
|
||||
"go_to_last_page": "Ir a la última página",
|
||||
"filter_placeholder": "Escribe aquí para filtrar...",
|
||||
"reset_filter": "Quitar el filtro",
|
||||
"error": "Error",
|
||||
"actions": "Acciones",
|
||||
"open_menu": "Abrir el menú",
|
||||
"duplicate_rows": "Duplicar",
|
||||
"duplicate_rows_tooltip": "Duplica las fila(s) seleccionadas(s)",
|
||||
"pick_date": "Elige una fecha",
|
||||
"required_field": "Este campo es obligatorio",
|
||||
"unsaved_changes_prompt": "Los últimos cambios no se han guardado. Si continúas, se perderán",
|
||||
"edit": "Editar"
|
||||
},
|
||||
"main_menu": {
|
||||
"home": "Home",
|
||||
"settings": "Settings",
|
||||
"dealers": "Dealers",
|
||||
"catalog": "Catalog",
|
||||
"quotes": "Quotes",
|
||||
"search_placeholder": "Search product, quotes, etc...",
|
||||
"home": "Inicio",
|
||||
"settings": "Ajustes",
|
||||
"dealers": "Distribuidores",
|
||||
"catalog": "Catálogo",
|
||||
"quotes": "Cotizaciones",
|
||||
"search_placeholder": "Buscar productos, cotizaciones, etc...",
|
||||
"user": {
|
||||
"user_menu": "User menu",
|
||||
"my_account": "My account",
|
||||
"profile": "Profile",
|
||||
"settings": "Settings",
|
||||
"support": "Support",
|
||||
"logout": "Logout"
|
||||
"user_menu": "Menú del usuario",
|
||||
"my_account": "Mi cuenta",
|
||||
"profile": "Perfil",
|
||||
"settings": "Ajustes",
|
||||
"support": "Soporte",
|
||||
"logout": "Salir"
|
||||
},
|
||||
"logout": {}
|
||||
},
|
||||
"login_page": {
|
||||
"title": "Uecko Quotes",
|
||||
"description": "Enter your email address and password to login",
|
||||
"title": "Presupuestador para distribuidores",
|
||||
"description": "Introduzca su dirección de correo electrónico y contraseña para acceder",
|
||||
"email_label": "Email",
|
||||
"email_placeholder": "user@sample.com",
|
||||
"password_label": "Password",
|
||||
"forgotten_password": "Forgot your password?",
|
||||
"become_dealer": "Do you want to become a Uecko dealer?",
|
||||
"contact_us": "Contact us",
|
||||
"login": "Login",
|
||||
"error": "Error"
|
||||
"email_placeholder": "micorreo@ejemplo.com",
|
||||
"password_label": "Contraseña",
|
||||
"forgotten_password": "¿Has olvidado tu contraseña?",
|
||||
"become_dealer": "¿Quieres ser distribuidor de Uecko?",
|
||||
"contact_us": "Contacta con nosotros",
|
||||
"login": "Entrar"
|
||||
},
|
||||
"dashboard": {
|
||||
"welcome": "Bienvenido"
|
||||
},
|
||||
"catalog": {
|
||||
"list": {
|
||||
"title": "Catálogo de artículos",
|
||||
"columns": {
|
||||
"description": "Descripción",
|
||||
"points": "Puntos",
|
||||
"retail_price": "PVP"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quotes": {
|
||||
"list": {
|
||||
"title": "Quotes",
|
||||
"subtitle": "",
|
||||
"tabs": {
|
||||
"all": "All",
|
||||
"draft": "Draft",
|
||||
"archived": "Archive"
|
||||
},
|
||||
"columns": {
|
||||
"date": "Date",
|
||||
"reference": "Reference",
|
||||
"status": "Status",
|
||||
"customer_information": "Customer",
|
||||
"total_price": "Imp. total"
|
||||
}
|
||||
},
|
||||
"create": {
|
||||
"title": "New quote",
|
||||
"buttons": {
|
||||
"save_quote": "Guardar cotización",
|
||||
"discard": "Descartar"
|
||||
},
|
||||
"tabs": {
|
||||
"general": "Datos generales",
|
||||
"items": "Contenido",
|
||||
"documents": "Documentos",
|
||||
"history": "Historial"
|
||||
},
|
||||
"form_groups": {
|
||||
"general": {
|
||||
"title": "Datos generales",
|
||||
"desc": "Datos generales y cliente al que va la cotización"
|
||||
},
|
||||
"status": {
|
||||
"title": "Estado",
|
||||
"desc": "Estado de la cotización"
|
||||
},
|
||||
"items": {
|
||||
"title": "Contenido de la cotización",
|
||||
"desc": "Líneas de detalle de la cotización. Ayúdese del catálogo para rellenar más fácilmente el contenido."
|
||||
},
|
||||
"documents": {
|
||||
"title": "Documentos",
|
||||
"desc": "Añada adjuntar con su cotización documentos como fotos, planos, croquis, etc."
|
||||
},
|
||||
"history": {
|
||||
"title": "",
|
||||
"desc": ""
|
||||
}
|
||||
},
|
||||
"edit": {
|
||||
"title": "Cotización"
|
||||
}
|
||||
},
|
||||
"edit": {
|
||||
"title": "Cotización"
|
||||
},
|
||||
"status": {
|
||||
"draft": "Borrador"
|
||||
},
|
||||
"form_fields": {
|
||||
"date": {
|
||||
"label": "Fecha",
|
||||
"desc": "Fecha de esta cotización",
|
||||
"placeholder": ""
|
||||
},
|
||||
"reference": {
|
||||
"label": "Referencia",
|
||||
"desc": "Referencia para esta cotización",
|
||||
"placeholder": ""
|
||||
},
|
||||
"lang_code": {
|
||||
"label": "Idioma",
|
||||
"desc": "Idioma de la cotización",
|
||||
"placeholder": ""
|
||||
},
|
||||
"currency_code": {
|
||||
"label": "Moneda",
|
||||
"desc": "Moneda de la cotización",
|
||||
"placeholder": ""
|
||||
},
|
||||
"customer_information": {
|
||||
"label": "Datos del cliente",
|
||||
"desc": "Escriba el nombre del cliente en la primera línea, la direccion en la segunda y el código postal y ciudad en la tercera.",
|
||||
"placeholder": "Nombre y apellidos\nCalle y número\nCódigo postal y ciudad..."
|
||||
},
|
||||
"payment_method": {
|
||||
"label": "Forma de pago",
|
||||
"placeholder": "placeholder",
|
||||
"desc": "desc"
|
||||
},
|
||||
"notes": {
|
||||
"label": "Notas",
|
||||
"placeholder": "",
|
||||
"desc": "desc"
|
||||
},
|
||||
"validity": {
|
||||
"label": "Validez de la cotización",
|
||||
"placeholder": "",
|
||||
"desc": "desc"
|
||||
},
|
||||
"items": {
|
||||
"quantity": {
|
||||
"label": "Cantidad",
|
||||
"placeholder": "",
|
||||
"desc": ""
|
||||
},
|
||||
"description": {
|
||||
"label": "Descripción",
|
||||
"placeholder": "",
|
||||
"desc": ""
|
||||
},
|
||||
"unit_price": {
|
||||
"label": "Imp. unitario",
|
||||
"placeholder": "",
|
||||
"desc": "Importe unitario del artículo"
|
||||
},
|
||||
"subtotal_price": {
|
||||
"label": "Subtotal",
|
||||
"placeholder": "",
|
||||
"desc": ""
|
||||
},
|
||||
"discount": {
|
||||
"label": "Dto (%)",
|
||||
"placeholder": "",
|
||||
"desc": "Porcentaje de descuento"
|
||||
},
|
||||
"total_price": {
|
||||
"label": "Imp. total",
|
||||
"placeholder": "",
|
||||
"desc": "Importe total con el descuento ya aplicado"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ajustes",
|
||||
"quotes": {
|
||||
"title": "Cotizaciones",
|
||||
"contact_information": {
|
||||
"label": "Información de contacto",
|
||||
"placeholder": "placeholder",
|
||||
"desc": "Información de contacto"
|
||||
},
|
||||
"default_payment_method": {
|
||||
"label": "Forma de pago",
|
||||
"placeholder": "placeholder",
|
||||
"desc": "desc"
|
||||
},
|
||||
"default_notes": {
|
||||
"label": "Notas",
|
||||
"placeholder": "",
|
||||
"desc": "desc"
|
||||
},
|
||||
"default_legal_terms": {
|
||||
"label": "Cláusulas legales",
|
||||
"placeholder": "",
|
||||
"desc": "desc"
|
||||
},
|
||||
"default_quote_validity": {
|
||||
"label": "Validez por defecto",
|
||||
"placeholder": "",
|
||||
"desc": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ export interface IAuthUser {
|
||||
isUser: boolean;
|
||||
isAdmin: boolean;
|
||||
getRoles: () => AuthUserRole[];
|
||||
getRolesArray: () => string[];
|
||||
|
||||
verifyPassword: (candidatePassword: string) => boolean;
|
||||
}
|
||||
@ -77,6 +78,10 @@ export class AuthUser extends AggregateRoot<IAuthUserProps> implements IAuthUser
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
public getRolesArray(): string[] {
|
||||
return this.getRoles()?.map((rol) => rol.toString());
|
||||
}
|
||||
|
||||
public verifyPassword(candidatePassword: string): boolean {
|
||||
return this.props.password.verifyPassword(candidatePassword);
|
||||
}
|
||||
|
||||
@ -15,8 +15,8 @@ export const identityPresenter: IIdentityPresenter = {
|
||||
id: user.id.toString(),
|
||||
name: user.name.toString(),
|
||||
email: user.email.toString(),
|
||||
language: user.language.toString(),
|
||||
roles: user.getRoles()?.map((rol) => rol.toString()),
|
||||
lang_code: user.language.toString(),
|
||||
roles: user.getRolesArray(),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,20 +1,40 @@
|
||||
import { AggregateRoot, IDomainError, Result, UniqueID } from "@shared/contexts";
|
||||
import { DealerStatus } from "@/contexts/sales/domain";
|
||||
import {
|
||||
AggregateRoot,
|
||||
CurrencyData,
|
||||
IDomainError,
|
||||
Language,
|
||||
Name,
|
||||
Note,
|
||||
Result,
|
||||
UniqueID,
|
||||
} from "@shared/contexts";
|
||||
|
||||
export interface IProfileProps {
|
||||
contactInformation: string;
|
||||
defaultPaymentMethod: string;
|
||||
defaultNotes: string;
|
||||
defaultLegalTerms: string;
|
||||
defaultQuoteValidity: string;
|
||||
name: Name;
|
||||
language: Language;
|
||||
status: DealerStatus;
|
||||
currency: CurrencyData;
|
||||
|
||||
contactInformation: Note;
|
||||
defaultPaymentMethod: Note;
|
||||
defaultNotes: Note;
|
||||
defaultLegalTerms: Note;
|
||||
defaultQuoteValidity: Note;
|
||||
}
|
||||
|
||||
export interface IProfile {
|
||||
id: UniqueID;
|
||||
contactInformation: string;
|
||||
defaultPaymentMethod: string;
|
||||
defaultNotes: string;
|
||||
defaultLegalTerms: string;
|
||||
defaultQuoteValidity: string;
|
||||
name: Name;
|
||||
language: Language;
|
||||
status: DealerStatus;
|
||||
currency: CurrencyData;
|
||||
|
||||
contactInformation: Note;
|
||||
defaultPaymentMethod: Note;
|
||||
defaultNotes: Note;
|
||||
defaultLegalTerms: Note;
|
||||
defaultQuoteValidity: Note;
|
||||
}
|
||||
|
||||
export class Profile extends AggregateRoot<IProfileProps> implements IProfile {
|
||||
@ -23,23 +43,39 @@ export class Profile extends AggregateRoot<IProfileProps> implements IProfile {
|
||||
return Result.ok<Profile>(profile);
|
||||
}
|
||||
|
||||
get contactInformation(): string {
|
||||
get name(): Name {
|
||||
return this.props.name;
|
||||
}
|
||||
|
||||
get language(): Language {
|
||||
return this.props.language;
|
||||
}
|
||||
|
||||
get status(): DealerStatus {
|
||||
return this.props.status;
|
||||
}
|
||||
|
||||
get currency(): CurrencyData {
|
||||
return this.props.currency;
|
||||
}
|
||||
|
||||
get contactInformation(): Note {
|
||||
return this.props.contactInformation;
|
||||
}
|
||||
|
||||
get defaultPaymentMethod(): string {
|
||||
get defaultPaymentMethod(): Note {
|
||||
return this.props.defaultPaymentMethod;
|
||||
}
|
||||
|
||||
get defaultNotes(): string {
|
||||
get defaultNotes(): Note {
|
||||
return this.props.defaultNotes;
|
||||
}
|
||||
|
||||
get defaultLegalTerms(): string {
|
||||
get defaultLegalTerms(): Note {
|
||||
return this.props.defaultLegalTerms;
|
||||
}
|
||||
|
||||
get defaultQuoteValidity(): string {
|
||||
get defaultQuoteValidity(): Note {
|
||||
return this.props.defaultQuoteValidity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ export class ProfileRepository extends SequelizeRepository<Profile> implements I
|
||||
}
|
||||
|
||||
public async getByUserId(userId: UniqueID): Promise<Profile | null> {
|
||||
const rawDealer: any = await this._getBy("Profile_Model", "user_id", userId.toPrimitive());
|
||||
const rawDealer: any = await this._getBy("Dealer_Model", "user_id", userId.toPrimitive());
|
||||
|
||||
if (!rawDealer === true) {
|
||||
return null;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { IUseCaseError, UseCaseError } from "@/contexts/common/application/useCases";
|
||||
import { ExpressController } from "@/contexts/common/infrastructure/express";
|
||||
import { User } from "@/contexts/users/domain/entities/User";
|
||||
import { IGetProfileResponse_DTO } from "@shared/contexts";
|
||||
|
||||
import { AuthUser } from "@/contexts/auth/domain";
|
||||
import { IServerError } from "@/contexts/common/domain/errors";
|
||||
import { IInfrastructureError, InfrastructureError } from "@/contexts/common/infrastructure";
|
||||
import { GetProfileUseCase } from "@/contexts/profile/application/GetProfile.useCase";
|
||||
@ -30,7 +30,7 @@ export class GetProfileController extends ExpressController {
|
||||
}
|
||||
|
||||
async executeImpl(): Promise<any> {
|
||||
const user = <User | undefined>this.req.user;
|
||||
const user = <AuthUser>this.req.user;
|
||||
|
||||
if (!user) {
|
||||
const errorMessage = "Unexpected missing user data";
|
||||
@ -42,17 +42,17 @@ export class GetProfileController extends ExpressController {
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.useCase.execute({
|
||||
const profileOrError = await this.useCase.execute({
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (result.isFailure) {
|
||||
return this._handleExecuteError(result.error);
|
||||
if (profileOrError.isFailure) {
|
||||
return this._handleExecuteError(profileOrError.error);
|
||||
}
|
||||
|
||||
const profile = result.object;
|
||||
const profile = profileOrError.object;
|
||||
|
||||
return this.ok<IGetProfileResponse_DTO>(this.presenter.map(profile, this.context));
|
||||
return this.ok<IGetProfileResponse_DTO>(this.presenter.map(profile, user, this.context));
|
||||
} catch (e: unknown) {
|
||||
return this.fail(e as IServerError);
|
||||
}
|
||||
|
||||
@ -1,20 +1,32 @@
|
||||
import { AuthUser } from "@/contexts/auth/domain";
|
||||
import { Profile } from "@/contexts/profile/domain";
|
||||
import { IProfileContext } from "@/contexts/profile/infrastructure/Profile.context";
|
||||
import { IGetProfileResponse_DTO } from "@shared/contexts";
|
||||
|
||||
export interface IGetProfilePresenter {
|
||||
map: (profile: Profile, context: IProfileContext) => IGetProfileResponse_DTO;
|
||||
map: (profile: Profile, user: AuthUser, context: IProfileContext) => IGetProfileResponse_DTO;
|
||||
}
|
||||
|
||||
export const GetProfilePresenter: IGetProfilePresenter = {
|
||||
map: (profile: Profile, context: IProfileContext): IGetProfileResponse_DTO => {
|
||||
map: (profile: Profile, user: AuthUser, context: IProfileContext): IGetProfileResponse_DTO => {
|
||||
return {
|
||||
dealer_id: profile.id.toString(),
|
||||
contact_information: profile.contactInformation,
|
||||
default_payment_method: profile.defaultPaymentMethod,
|
||||
default_notes: profile.defaultNotes,
|
||||
default_legal_terms: profile.defaultLegalTerms,
|
||||
default_quote_validity: profile.defaultQuoteValidity,
|
||||
name: user.name.toString(),
|
||||
email: user.email.toString(),
|
||||
lang_code: user.language.code,
|
||||
roles: user.getRolesArray(),
|
||||
dealer: {
|
||||
id: profile.id.toString(),
|
||||
name: profile.name.toString(),
|
||||
status: profile.status.toString(),
|
||||
lang_code: profile.language.toString(),
|
||||
currency_code: profile.currency.toString(),
|
||||
|
||||
contact_information: profile.contactInformation.toString(),
|
||||
default_payment_method: profile.defaultPaymentMethod.toString(),
|
||||
default_notes: profile.defaultNotes.toString(),
|
||||
default_legal_terms: profile.defaultLegalTerms.toString(),
|
||||
default_quote_validity: profile.defaultQuoteValidity.toString(),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@ -3,7 +3,9 @@ import {
|
||||
MapperParamsType,
|
||||
SequelizeMapper,
|
||||
} from "@/contexts/common/infrastructure";
|
||||
import { UniqueID } from "@shared/contexts";
|
||||
import { DealerStatus } from "@/contexts/sales/domain";
|
||||
import { Dealer_Model } from "@/contexts/sales/infrastructure/sequelize";
|
||||
import { CurrencyData, Language, Name, Note, UniqueID } from "@shared/contexts";
|
||||
import { IProfileProps, Profile } from "../../domain";
|
||||
import { IProfileContext } from "../Profile.context";
|
||||
import { ProfileCreationAttributes, Profile_Model } from "../sequelize";
|
||||
@ -19,13 +21,29 @@ class ProfileMapper
|
||||
super(props);
|
||||
}
|
||||
|
||||
protected toDomainMappingImpl(source: Profile_Model, params: any): Profile {
|
||||
protected toDomainMappingImpl(source: Dealer_Model, params: any): Profile {
|
||||
const name = this.mapsValue(source, "name", Name.create);
|
||||
const status = this.mapsValue(source, "status", DealerStatus.create);
|
||||
const language = this.mapsValue(source, "lang_code", Language.createFromCode);
|
||||
const currency = this.mapsValue(source, "currency_code", CurrencyData.createFromCode);
|
||||
|
||||
const contactInformation = this.mapsValue(source, "contact_information", Note.create);
|
||||
const defaultPaymentMethod = this.mapsValue(source, "default_payment_method", Note.create);
|
||||
const defaultNotes = this.mapsValue(source, "default_notes", Note.create);
|
||||
const defaultLegalTerms = this.mapsValue(source, "default_legal_terms", Note.create);
|
||||
const defaultQuoteValidity = this.mapsValue(source, "default_quote_validity", Note.create);
|
||||
|
||||
const props: IProfileProps = {
|
||||
contactInformation: source.contact_information,
|
||||
defaultPaymentMethod: source.default_payment_method,
|
||||
defaultNotes: source.default_notes,
|
||||
defaultLegalTerms: source.default_legal_terms,
|
||||
defaultQuoteValidity: source.default_quote_validity,
|
||||
name,
|
||||
status,
|
||||
language,
|
||||
currency,
|
||||
|
||||
contactInformation,
|
||||
defaultPaymentMethod,
|
||||
defaultNotes,
|
||||
defaultLegalTerms,
|
||||
defaultQuoteValidity,
|
||||
};
|
||||
|
||||
const id = this.mapsValue(source, "id", UniqueID.create);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
AggregateRoot,
|
||||
CurrencyData,
|
||||
IDomainError,
|
||||
KeyValueMap,
|
||||
Language,
|
||||
@ -12,10 +13,11 @@ import { DealerStatus } from "./DealerStatus";
|
||||
export interface IDealerProps {
|
||||
user_id: UniqueID;
|
||||
name: Name;
|
||||
logo: string;
|
||||
//logo: string;
|
||||
language: Language;
|
||||
additionalInfo: KeyValueMap;
|
||||
status: DealerStatus;
|
||||
currency: CurrencyData;
|
||||
}
|
||||
|
||||
export interface IDealer {
|
||||
@ -26,6 +28,7 @@ export interface IDealer {
|
||||
|
||||
additionalInfo: KeyValueMap;
|
||||
status: DealerStatus;
|
||||
currency: CurrencyData;
|
||||
}
|
||||
|
||||
export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
||||
@ -53,4 +56,8 @@ export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
||||
get additionalInfo(): KeyValueMap {
|
||||
return this.props.additionalInfo;
|
||||
}
|
||||
|
||||
get currency(): CurrencyData {
|
||||
return this.props.currency;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import {
|
||||
MapperParamsType,
|
||||
SequelizeMapper,
|
||||
} from "@/contexts/common/infrastructure";
|
||||
import { KeyValueMap, Language, Name, UniqueID } from "@shared/contexts";
|
||||
import { CurrencyData, KeyValueMap, Language, Name, UniqueID } from "@shared/contexts";
|
||||
import { Dealer, DealerStatus, IDealerProps } from "../../domain/entities";
|
||||
import { ISalesContext } from "../Sales.context";
|
||||
import { DealerCreationAttributes, Dealer_Model } from "../sequelize";
|
||||
@ -24,6 +24,7 @@ class DealerMapper
|
||||
const user_id = this.mapsValue(source, "user_id", UniqueID.create);
|
||||
const status = this.mapsValue(source, "status", DealerStatus.create);
|
||||
const language = this.mapsValue(source, "lang_code", Language.createFromCode);
|
||||
const currency = this.mapsValue(source, "currency_code", CurrencyData.createFromCode);
|
||||
|
||||
const additionalInfoOrError = KeyValueMap.create([
|
||||
["contact_information", source.contact_information],
|
||||
@ -35,10 +36,11 @@ class DealerMapper
|
||||
|
||||
const props: IDealerProps = {
|
||||
user_id,
|
||||
logo: "",
|
||||
//logo: "",
|
||||
name,
|
||||
status,
|
||||
language,
|
||||
currency,
|
||||
additionalInfo: additionalInfoOrError.object,
|
||||
};
|
||||
|
||||
@ -57,7 +59,8 @@ class DealerMapper
|
||||
id: source.id.toPrimitive(),
|
||||
user_id: source.user_id.toPrimitive(),
|
||||
//contact_id: undefined,
|
||||
logo: "",
|
||||
currency_code: source.currency.toPrimitive(),
|
||||
//logo: "",
|
||||
name: source.name.toPrimitive(),
|
||||
status: source.status.toPrimitive(),
|
||||
lang_code: source.language.toPrimitive(),
|
||||
|
||||
@ -55,6 +55,7 @@ export class Dealer_Model extends Model<
|
||||
declare default_quote_validity: CreationOptional<string>;
|
||||
declare status: CreationOptional<string>;
|
||||
declare lang_code: CreationOptional<string>;
|
||||
declare currency_code: CreationOptional<string>;
|
||||
|
||||
declare user: NonAttribute<User_Model>;
|
||||
declare quotes: NonAttribute<Quote_Model>;
|
||||
@ -90,6 +91,12 @@ export default (sequelize: Sequelize) => {
|
||||
defaultValue: "es",
|
||||
},
|
||||
|
||||
currency_code: {
|
||||
type: new DataTypes.STRING(3),
|
||||
allowNull: false,
|
||||
defaultValue: "EUR",
|
||||
},
|
||||
|
||||
status: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { checkUser, createLoginController } from "@/contexts/auth";
|
||||
import { createIdentityController } from "@/contexts/auth/infrastructure/express/controllers/identity";
|
||||
import Express from "express";
|
||||
import passport from "passport";
|
||||
|
||||
@ -27,12 +26,15 @@ export const authRouter = (appRouter: Express.Router) => {
|
||||
|
||||
authRoutes.post("/register");
|
||||
|
||||
/*
|
||||
-> Sustituido por /profile
|
||||
|
||||
authRoutes.get(
|
||||
"/identity",
|
||||
checkUser,
|
||||
(req: Express.Request, res: Express.Response, next: Express.NextFunction) =>
|
||||
createIdentityController(res.locals["context"]).execute(req, res, next)
|
||||
);
|
||||
);*/
|
||||
|
||||
appRouter.use("/auth", authRoutes);
|
||||
};
|
||||
|
||||
@ -2,6 +2,6 @@ export interface IIdentity_Response_DTO {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
language: string;
|
||||
lang_code: string;
|
||||
roles: string[];
|
||||
}
|
||||
|
||||
@ -1,8 +1,18 @@
|
||||
export interface IGetProfileResponse_DTO {
|
||||
dealer_id: string;
|
||||
contact_information: string;
|
||||
default_payment_method: string;
|
||||
default_notes: string;
|
||||
default_legal_terms: string;
|
||||
default_quote_validity: string;
|
||||
name: string;
|
||||
email: string;
|
||||
lang_code: string;
|
||||
roles: string[];
|
||||
dealer: {
|
||||
id: string;
|
||||
name: string;
|
||||
contact_information: string;
|
||||
default_payment_method: string;
|
||||
default_notes: string;
|
||||
default_legal_terms: string;
|
||||
default_quote_validity: string;
|
||||
status: string;
|
||||
lang_code: string;
|
||||
currency_code: string;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user