This commit is contained in:
David Arranz 2026-04-05 14:01:52 +02:00
parent 9e1b975ea2
commit 56584d2bfd
19 changed files with 207 additions and 145 deletions

View File

@ -2,7 +2,7 @@ import type { CriteriaDTO } from "@erp/core";
import { useDebounce } from "@repo/rdx-ui/components"; import { useDebounce } from "@repo/rdx-ui/components";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { useCustomerListQuery } from "../../shared"; import { useCustomersListQuery } from "../../shared";
export const useListCustomersController = () => { export const useListCustomersController = () => {
const [pageIndex, setPageIndex] = useState(0); const [pageIndex, setPageIndex] = useState(0);
@ -21,7 +21,7 @@ export const useListCustomersController = () => {
}; };
}, [pageSize, pageIndex, debouncedQ]); }, [pageSize, pageIndex, debouncedQ]);
const query = useCustomerListQuery({ criteria }); const query = useCustomersListQuery({ criteria });
const setSearchValue = (value: string) => { const setSearchValue = (value: string) => {
const nextValue = value.trim().replace(/\s+/g, " "); const nextValue = value.trim().replace(/\s+/g, " ");

View File

@ -1,6 +1,4 @@
import type { CreateCustomerResponseDTO } from "@erp/customers/common"; import type { CreateCustomerResult, GetCustomerByIdResult, UpdateCustomerByIdResult } from "../api";
import type { GetCustomerByIdResult, UpdateCustomerByIdResult } from "../api";
import type { Customer } from "../entities"; import type { Customer } from "../entities";
/** /**
@ -18,7 +16,7 @@ import type { Customer } from "../entities";
export const GetCustomerByIdAdapter = { export const GetCustomerByIdAdapter = {
fromDTO( fromDTO(
dto: GetCustomerByIdResult | CreateCustomerResponseDTO | UpdateCustomerByIdResult, dto: GetCustomerByIdResult | CreateCustomerResult | UpdateCustomerByIdResult,
context?: unknown context?: unknown
): Customer { ): Customer {
const taxesAdapter = (taxes: string) => const taxesAdapter = (taxes: string) =>

View File

@ -24,13 +24,13 @@ export const useCustomerCreateMutation = () => {
return useMutation<Customer, DefaultError, CreateCustomerParams, CreateCustomerContext>({ return useMutation<Customer, DefaultError, CreateCustomerParams, CreateCustomerContext>({
mutationKey: CUSTOMER_CREATE_KEY, mutationKey: CUSTOMER_CREATE_KEY,
mutationFn: async (payload) => { mutationFn: async (params) => {
const result = schema.safeParse(payload); const result = schema.safeParse(params);
if (!result.success) { if (!result.success) {
throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error)); throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error));
} }
const dto: CreateCustomerResult = await createCustomer(dataSource, payload); const dto: CreateCustomerResult = await createCustomer(dataSource, params);
return GetCustomerByIdAdapter.fromDTO(dto); return GetCustomerByIdAdapter.fromDTO(dto);
}, },

View File

@ -8,25 +8,26 @@ import type { Customer } from "../entities";
import { CUSTOMER_QUERY_KEY } from "./keys"; import { CUSTOMER_QUERY_KEY } from "./keys";
type CustomerGetQueryOptions = { type CustomerGetQueryOptions = {
id?: string;
enabled?: boolean; enabled?: boolean;
}; };
export const useCustomerGetQuery = ( export const useCustomerGetQuery = (
customerId?: string,
options?: CustomerGetQueryOptions options?: CustomerGetQueryOptions
): UseQueryResult<Customer, DefaultError> => { ): UseQueryResult<Customer, DefaultError> => {
//const queryClient = useQueryClient();
const dataSource = useDataSource(); const dataSource = useDataSource();
const enabled = options?.enabled ?? Boolean(customerId); const id = options?.id;
const enabled = options?.enabled ?? Boolean(id);
return useQuery<Customer, DefaultError>({ return useQuery<Customer, DefaultError>({
queryKey: CUSTOMER_QUERY_KEY(customerId), queryKey: CUSTOMER_QUERY_KEY(id),
queryFn: async ({ signal }) => { queryFn: async ({ signal }) => {
const dto: GetCustomerByIdResult = await getCustomerById( if (!id) throw new Error("customerId is required");
dataSource,
{ id: customerId! }, const dto: GetCustomerByIdResult = await getCustomerById(dataSource, {
signal id: id!,
); signal,
});
return GetCustomerByIdAdapter.fromDTO(dto); return GetCustomerByIdAdapter.fromDTO(dto);
}, },
enabled, enabled,

View File

@ -28,8 +28,8 @@ export const useCustomerUpdateMutation = () => {
return useMutation<Customer, DefaultError, UpdateCustomerByIdParams, UpdateCustomerContext>({ return useMutation<Customer, DefaultError, UpdateCustomerByIdParams, UpdateCustomerContext>({
mutationKey: CUSTOMER_UPDATE_KEY, mutationKey: CUSTOMER_UPDATE_KEY,
mutationFn: async (payload) => { mutationFn: async (params) => {
const { id: customerId, data } = payload; const { id: customerId, data } = params;
if (!customerId) { if (!customerId) {
throw new Error("customerId is required"); throw new Error("customerId is required");
} }
@ -41,7 +41,7 @@ export const useCustomerUpdateMutation = () => {
const dto: UpdateCustomerByIdResult = await updateCustomerById( const dto: UpdateCustomerByIdResult = await updateCustomerById(
dataSource, dataSource,
payload as UpdateCustomerByIdParams params as UpdateCustomerByIdParams
); );
return GetCustomerByIdAdapter.fromDTO(dto); return GetCustomerByIdAdapter.fromDTO(dto);
}, },

View File

@ -8,13 +8,13 @@ import type { CustomerList } from "../entities";
import { LIST_CUSTOMERS_QUERY_KEY } from "./keys"; import { LIST_CUSTOMERS_QUERY_KEY } from "./keys";
type CustomerListQueryOptions = { type CustomersListQueryOptions = {
enabled?: boolean;
criteria?: Partial<CriteriaDTO>; criteria?: Partial<CriteriaDTO>;
enabled?: boolean;
}; };
export const useCustomerListQuery = ( export const useCustomersListQuery = (
options?: CustomerListQueryOptions options?: CustomersListQueryOptions
): UseQueryResult<CustomerList, DefaultError> => { ): UseQueryResult<CustomerList, DefaultError> => {
const dataSource = useDataSource(); const dataSource = useDataSource();
const enabled = options?.enabled ?? true; const enabled = options?.enabled ?? true;
@ -23,11 +23,10 @@ export const useCustomerListQuery = (
return useQuery<CustomerList, DefaultError>({ return useQuery<CustomerList, DefaultError>({
queryKey: LIST_CUSTOMERS_QUERY_KEY(criteria), queryKey: LIST_CUSTOMERS_QUERY_KEY(criteria),
queryFn: async ({ signal }) => { queryFn: async ({ signal }) => {
const dto: ListCustomersResult = await getListCustomersByCriteria( const dto: ListCustomersResult = await getListCustomersByCriteria(dataSource, {
dataSource, criteria,
{ criteria }, signal,
signal });
);
return ListCustomersAdapter.fromDTO(dto); return ListCustomersAdapter.fromDTO(dto);
}, },
enabled, enabled,

View File

@ -4,4 +4,4 @@ import {
} from "./get-supplier-by-id.response.dto"; } from "./get-supplier-by-id.response.dto";
export const CreateSupplierResponseSchema = GetSupplierByIdResponseSchema; export const CreateSupplierResponseSchema = GetSupplierByIdResponseSchema;
export type SupplierCreationResponseDTO = GetSupplierByIdResponseDTO; export type CreateSupplierResponseDTO = GetSupplierByIdResponseDTO;

View File

@ -1,8 +1,8 @@
import type { GetSupplierByIdResponseDTO } from "../../../common"; import type { CreateSupplierResult, GetSupplierByIdResult, UpdateSupplierByIdResult } from "../api";
import type { Supplier } from "../entities"; import type { Supplier } from "../entities";
export const GetSupplierByIdAdapter = { export const GetSupplierByIdAdapter = {
fromDTO(dto: GetSupplierByIdResponseDTO): Supplier { fromDTO(dto: GetSupplierByIdResult | CreateSupplierResult | UpdateSupplierByIdResult): Supplier {
return { return {
id: dto.id, id: dto.id,
companyId: dto.company_id, companyId: dto.company_id,

View File

@ -1,24 +1,32 @@
import type { IDataSource } from "@erp/core/client"; import type { IDataSource } from "@erp/core/client";
import type { CreateSupplierRequestDTO, SupplierCreationResponseDTO } from "../../../common"; import type { CreateSupplierRequestDTO, CreateSupplierResponseDTO } from "../../../common";
export type SupplierCreateInput = CreateSupplierRequestDTO; /**
export type SupplierCreateOutput = SupplierCreationResponseDTO; * Crea un nuevo cliente en el sistema utilizando la fuente de datos proporcionada.
*
* @param dataSource - La fuente de datos para interactuar con la API.
* @param params - Los parámetros necesarios para crear el cliente.
* @returns Una promesa que resuelve con los detalles del cliente creado.
* @throws Error si el ID del cliente no es proporcionado o si la creación falla.
*/
export interface CreateSupplierParams {
id: string;
data: CreateSupplierRequestDTO;
}
export type CreateSupplierResult = CreateSupplierResponseDTO;
export function createSupplier(dataSource: IDataSource, params: CreateSupplierParams) {
const { id, data } = params;
export async function createSupplier(
dataSource: IDataSource,
id: string,
data: SupplierCreateInput
) {
if (!id) throw new Error("supplierId is required"); if (!id) throw new Error("supplierId is required");
const response = await dataSource.createOne<SupplierCreateInput, SupplierCreateOutput>( if (id !== data.id) throw new Error("supplierId in params must match id in data");
"suppliers",
{
...data,
id,
}
);
return response; return dataSource.createOne<CreateSupplierRequestDTO, CreateSupplierResponseDTO>(
"suppliers",
data
);
} }

View File

@ -1,13 +1,30 @@
import type { IDataSource } from "@erp/core/client"; import type { IDataSource } from "@erp/core/client";
import type { DeleteSupplierByIdRequestDTO } from "../../../common"; /**
* Elimina un proveedor existente en el sistema utilizando la fuente de datos proporcionada.
*
* @param dataSource - La fuente de datos para interactuar con la API.
* @param params - Los parámetros necesarios para eliminar el proveedor.
* @returns Una promesa que se resuelve cuando el proveedor ha sido eliminado exitosamente.
* @throws Error si el ID del proveedor no es proporcionado o si la eliminación falla.
*/
export type SupplierDeleteInput = DeleteSupplierByIdRequestDTO; export interface DeleteSupplierByIdParams {
id: string;
signal?: AbortSignal;
}
export async function deleteSupplierById(dataSource: IDataSource, id: string, signal: AbortSignal) { export type DeleteSupplierByIdResult = void;
const response = await dataSource.deleteOne<SupplierDeleteInput>("suppliers", id, {
export function deleteSupplierById(
dataSource: IDataSource,
params: DeleteSupplierByIdParams
): Promise<DeleteSupplierByIdResult> {
const { id, signal } = params;
if (!id) throw new Error("supplierId is required");
return dataSource.deleteOne<DeleteSupplierByIdResult>("suppliers", id, {
signal, signal,
}); });
return response;
} }

View File

@ -2,12 +2,27 @@ import type { IDataSource } from "@erp/core/client";
import type { GetSupplierByIdResponseDTO } from "../../../common"; import type { GetSupplierByIdResponseDTO } from "../../../common";
export type SupplierGetOutput = GetSupplierByIdResponseDTO; /**
* Recupera los detalles de un proveedor específico utilizando su ID a través de la fuente de datos proporcionada.
*
* @param dataSource - La fuente de datos para interactuar con la API.
* @param params - Los parámetros necesarios para obtener el proveedor, incluyendo su ID.
* @returns Una promesa que resuelve con los detalles del proveedor solicitado.
* @throws Error si el ID del proveedor no es proporcionado o si la recuperación falla.
*/
export async function getSupplierById(dataSource: IDataSource, id: string, signal: AbortSignal) { export interface GetSupplierByIdParams {
const response = dataSource.getOne<SupplierGetOutput>("suppliers", id, { id: string;
signal, signal?: AbortSignal;
}); }
return response; export type GetSupplierByIdResult = GetSupplierByIdResponseDTO;
export function getSupplierById(
dataSource: IDataSource,
params: GetSupplierByIdParams
): Promise<GetSupplierByIdResult> {
const { id, signal } = params;
if (!id) throw new Error("supplierId is required");
return dataSource.getOne<GetSupplierByIdResponseDTO>("suppliers", id, { signal });
} }

View File

@ -3,17 +3,30 @@ import type { IDataSource } from "@erp/core/client";
import type { ListSuppliersResponseDTO } from "../../../common"; import type { ListSuppliersResponseDTO } from "../../../common";
export type SupplierListOutput = ListSuppliersResponseDTO; /**
* Recupera una lista de proveedores del sistema utilizando la
* fuente de datos proporcionada y los criterios de búsqueda especificados.
*
* @param dataSource - La fuente de datos para interactuar con la API.
* @param params - Los parámetros necesarios para listar los proveedores, incluyendo los criterios de búsqueda.
* @returns Una promesa que resuelve con una lista de proveedores que cumplen con los criterios especificados.
* @throws Error si la recuperación de la lista de proveedores falla.
*/
export async function getListSuppliers( export type ListSuppliersByCriteriaParams = {
criteria?: CriteriaDTO;
signal?: AbortSignal;
};
export type ListSuppliersResult = ListSuppliersResponseDTO;
export function getListSuppliersByCriteria(
dataSource: IDataSource, dataSource: IDataSource,
criteria: CriteriaDTO, params: ListSuppliersByCriteriaParams
signal: AbortSignal ): Promise<ListSuppliersResult> {
) { const { criteria, signal } = params || { criteria: undefined, signal: undefined };
const response = dataSource.getList<SupplierListOutput>("suppliers", { return dataSource.getList<ListSuppliersResponseDTO>("suppliers", {
signal, signal,
...criteria, ...criteria,
}); });
return response;
} }

View File

@ -2,21 +2,32 @@ import type { IDataSource } from "@erp/core/client";
import type { UpdateSupplierByIdRequestDTO, UpdateSupplierByIdResponseDTO } from "../../../common"; import type { UpdateSupplierByIdRequestDTO, UpdateSupplierByIdResponseDTO } from "../../../common";
export type SupplierUpdateInput = UpdateSupplierByIdRequestDTO; /**
export type SupplierUpdateOutput = UpdateSupplierByIdResponseDTO; * Actualiza un proveedor existente en el sistema utilizando la fuente de datos proporcionada.
*
* @param dataSource - La fuente de datos para interactuar con la API.
* @param params - Los parámetros necesarios para actualizar el proveedor.
* @returns Una promesa que resuelve con los detalles del proveedor actualizado.
* @throws Error si el ID del proveedor no es proporcionado o si la actualización falla.
*/
export async function updateSupplierById( export type UpdateSupplierByIdParams = {
id: string;
data: UpdateSupplierByIdRequestDTO;
};
export type UpdateSupplierByIdResult = UpdateSupplierByIdResponseDTO;
export function updateSupplierById(
dataSource: IDataSource, dataSource: IDataSource,
id: string, params: UpdateSupplierByIdParams
data: SupplierUpdateInput ): Promise<UpdateSupplierByIdResult> {
) { const { id, data } = params;
if (!id) throw new Error("supplierId is required");
const response = dataSource.updateOne<SupplierUpdateInput, SupplierUpdateOutput>( if (!id) throw new Error("supplierId is required");
return dataSource.updateOne<UpdateSupplierByIdRequestDTO, UpdateSupplierByIdResponseDTO>(
"suppliers", "suppliers",
id, id,
data data
); );
return response;
} }

View File

@ -1,8 +1,8 @@
export * from "./keys"; export * from "./keys";
export * from "./supplier-cache-strategy"; export * from "./supplier-cache-strategy";
export * from "./to-validation-errors"; export * from "./to-validation-errors";
export * from "./use-list-suppliers-query";
export * from "./use-supplier-create-mutation"; export * from "./use-supplier-create-mutation";
export * from "./use-supplier-delete-mutation"; export * from "./use-supplier-delete-mutation";
export * from "./use-supplier-get-query"; export * from "./use-supplier-get-query";
export * from "./use-supplier-update-mutation"; export * from "./use-supplier-update-mutation";
export * from "./use-suppliers-list-query";

View File

@ -1,10 +1,10 @@
import { useDataSource } from "@erp/core/hooks"; import { useDataSource } from "@erp/core/hooks";
import { UniqueID, ValidationErrorCollection } from "@repo/rdx-ddd"; import { ValidationErrorCollection } from "@repo/rdx-ddd";
import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-query"; import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-query";
import { CreateSupplierRequestSchema } from "../../../common"; import { CreateSupplierRequestSchema } from "../../../common";
import { GetSupplierByIdAdapter } from "../adapters"; import { GetSupplierByIdAdapter } from "../adapters";
import { type SupplierCreateInput, createSupplier } from "../api"; import { type CreateSupplierParams, type CreateSupplierResult, createSupplier } from "../api";
import type { Supplier } from "../entities"; import type { Supplier } from "../entities";
import { SUPPLIER_CREATE_KEY } from "./keys"; import { SUPPLIER_CREATE_KEY } from "./keys";
@ -16,27 +16,21 @@ import { toValidationErrors } from "./to-validation-errors";
type CreateSupplierContext = {}; type CreateSupplierContext = {};
type CreateSupplierPayload = {
data: SupplierCreateInput;
};
export const useSupplierCreateMutation = () => { export const useSupplierCreateMutation = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const dataSource = useDataSource(); const dataSource = useDataSource();
const schema = CreateSupplierRequestSchema; const schema = CreateSupplierRequestSchema;
return useMutation<Supplier, DefaultError, CreateSupplierPayload, CreateSupplierContext>({ return useMutation<Supplier, DefaultError, CreateSupplierParams, CreateSupplierContext>({
mutationKey: SUPPLIER_CREATE_KEY, mutationKey: SUPPLIER_CREATE_KEY,
mutationFn: async ({ data }) => { mutationFn: async (params) => {
const id = UniqueID.generateNewID().toString(); const result = schema.safeParse(params);
const result = schema.safeParse(data);
if (!result.success) { if (!result.success) {
throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error)); throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error));
} }
const dto = await createSupplier(dataSource, id, data); const dto: CreateSupplierResult = await createSupplier(dataSource, params);
return GetSupplierByIdAdapter.fromDTO(dto); return GetSupplierByIdAdapter.fromDTO(dto);
}, },

View File

@ -1,7 +1,7 @@
import { useDataSource } from "@erp/core/hooks"; import { useDataSource } from "@erp/core/hooks";
import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-query"; import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-query";
import { deleteSupplierById } from "../api"; import { type DeleteSupplierByIdParams, deleteSupplierById } from "../api";
import { SUPPLIER_DELETE_KEY } from "./keys"; import { SUPPLIER_DELETE_KEY } from "./keys";
import { import {
@ -12,42 +12,39 @@ import {
rollbackDeleteSupplierOptimisticUpdate, rollbackDeleteSupplierOptimisticUpdate,
} from "./supplier-cache-strategy"; } from "./supplier-cache-strategy";
export interface DeleteSupplierPayload {
id: string;
}
interface DeleteSupplierContext extends DeleteSupplierCacheContext {} interface DeleteSupplierContext extends DeleteSupplierCacheContext {}
export const useSupplierDeleteMutation = () => { export const useSupplierDeleteMutation = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const dataSource = useDataSource(); const dataSource = useDataSource();
return useMutation<{ id: string }, DefaultError, DeleteSupplierPayload, DeleteSupplierContext>({ return useMutation<{ id: string }, DefaultError, DeleteSupplierByIdParams, DeleteSupplierContext>(
mutationKey: SUPPLIER_DELETE_KEY, {
mutationKey: SUPPLIER_DELETE_KEY,
mutationFn: async ({ id, signal }) => {
if (!id) {
throw new Error("customerId is required");
}
mutationFn: async ({ id }) => { await deleteSupplierById(dataSource, { id, signal });
if (!id) { return { id };
throw new Error("supplierId is required"); },
}
await deleteSupplierById(dataSource, id, new AbortController().signal); onMutate: async ({ id }) => {
return { id }; return prepareDeleteSupplierOptimisticUpdate(queryClient, id);
}, },
onMutate: async ({ id }) => { onError: (_error, _variables, context) => {
return prepareDeleteSupplierOptimisticUpdate(queryClient, id); rollbackDeleteSupplierOptimisticUpdate(queryClient, context);
}, },
onError: (_error, _variables, context) => { onSuccess: ({ id }) => {
rollbackDeleteSupplierOptimisticUpdate(queryClient, context); finalizeDeletedSupplierCaches(queryClient, id);
}, },
onSuccess: ({ id }) => { onSettled: async () => {
finalizeDeletedSupplierCaches(queryClient, id); await invalidateSupplierListQueries(queryClient);
}, },
}
onSettled: async () => { );
await invalidateSupplierListQueries(queryClient);
},
});
}; };

View File

@ -1,4 +1,3 @@
import { useDataSource } from "@erp/core/hooks";
import { type DefaultError, type UseQueryResult, useQuery } from "@tanstack/react-query"; import { type DefaultError, type UseQueryResult, useQuery } from "@tanstack/react-query";
import { GetSupplierByIdAdapter } from "../adapters"; import { GetSupplierByIdAdapter } from "../adapters";
@ -8,20 +7,25 @@ import type { Supplier } from "../entities";
import { SUPPLIER_QUERY_KEY } from "./keys"; import { SUPPLIER_QUERY_KEY } from "./keys";
type SupplierGetQueryOptions = { type SupplierGetQueryOptions = {
id?: string;
enabled?: boolean; enabled?: boolean;
}; };
export const useSupplierGetQuery = ( export const useSupplierGetQuery = (
supplierId?: string,
options?: SupplierGetQueryOptions options?: SupplierGetQueryOptions
): UseQueryResult<Supplier, DefaultError> => { ): UseQueryResult<Supplier, DefaultError> => {
const dataSource = useDataSource(); const id = options?.id;
const enabled = options?.enabled ?? Boolean(supplierId); const enabled = options?.enabled ?? Boolean(id);
return useQuery<Supplier, DefaultError>({ return useQuery<Supplier, DefaultError>({
queryKey: SUPPLIER_QUERY_KEY(supplierId), queryKey: SUPPLIER_QUERY_KEY(id),
queryFn: async ({ signal }) => { queryFn: async ({ signal }) => {
const dto = await getSupplierById(dataSource, String(supplierId), signal); if (!id) throw new Error("supplierId is required");
const dto: GetSupplierByIdResult = await getSupplierById(dataSource, {
id: id!,
signal,
});
return GetSupplierByIdAdapter.fromDTO(dto); return GetSupplierByIdAdapter.fromDTO(dto);
}, },
enabled, enabled,

View File

@ -4,7 +4,11 @@ import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-
import { UpdateSupplierByIdRequestSchema } from "../../../common"; import { UpdateSupplierByIdRequestSchema } from "../../../common";
import { GetSupplierByIdAdapter } from "../adapters"; import { GetSupplierByIdAdapter } from "../adapters";
import { type SupplierUpdateInput, updateSupplierById } from "../api"; import {
type UpdateSupplierByIdParams,
type UpdateSupplierByIdResult,
updateSupplierById,
} from "../api";
import type { Supplier } from "../entities"; import type { Supplier } from "../entities";
import { SUPPLIER_UPDATE_KEY } from "./keys"; import { SUPPLIER_UPDATE_KEY } from "./keys";
@ -16,21 +20,17 @@ import { toValidationErrors } from "./to-validation-errors";
type UpdateSupplierContext = {}; type UpdateSupplierContext = {};
type UpdateSupplierPayload = {
id: string;
data: SupplierUpdateInput;
};
export const useSupplierUpdateMutation = () => { export const useSupplierUpdateMutation = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const dataSource = useDataSource(); const dataSource = useDataSource();
const schema = UpdateSupplierByIdRequestSchema; const schema = UpdateSupplierByIdRequestSchema;
return useMutation<Supplier, DefaultError, UpdateSupplierPayload, UpdateSupplierContext>({ return useMutation<Supplier, DefaultError, UpdateSupplierByIdParams, UpdateSupplierContext>({
mutationKey: SUPPLIER_UPDATE_KEY, mutationKey: SUPPLIER_UPDATE_KEY,
mutationFn: async ({ id, data }) => { mutationFn: async (params) => {
if (!id) { const { id: supplierId, data } = params;
if (!supplierId) {
throw new Error("supplierId is required"); throw new Error("supplierId is required");
} }
@ -39,7 +39,10 @@ export const useSupplierUpdateMutation = () => {
throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error)); throw new ValidationErrorCollection("Validation failed", toValidationErrors(result.error));
} }
const dto = await updateSupplierById(dataSource, id, data); const dto: UpdateSupplierByIdResult = await updateSupplierById(
dataSource,
params as UpdateSupplierByIdParams
);
return GetSupplierByIdAdapter.fromDTO(dto); return GetSupplierByIdAdapter.fromDTO(dto);
}, },

View File

@ -3,30 +3,32 @@ import { useDataSource } from "@erp/core/hooks";
import { type DefaultError, type UseQueryResult, useQuery } from "@tanstack/react-query"; import { type DefaultError, type UseQueryResult, useQuery } from "@tanstack/react-query";
import { ListSuppliersAdapter } from "../adapters"; import { ListSuppliersAdapter } from "../adapters";
import { getListSuppliers } from "../api";
import type { SupplierList } from "../entities"; import type { SupplierList } from "../entities";
import { LIST_SUPPLIERS_QUERY_KEY } from "./keys"; import { LIST_SUPPLIERS_QUERY_KEY } from "./keys";
type ListSuppliersQueryOptions = { type SuppliersListQueryOptions = {
enabled?: boolean;
criteria?: Partial<CriteriaDTO>; criteria?: Partial<CriteriaDTO>;
enabled?: boolean;
}; };
export const useListSuppliersQuery = ( export const useSuppliersListQuery = (
options?: ListSuppliersQueryOptions options?: SuppliersListQueryOptions
): UseQueryResult<SupplierList, DefaultError> => { ): UseQueryResult<SupplierList, DefaultError> => {
const dataSource = useDataSource(); const dataSource = useDataSource();
const enabled = options?.enabled ?? true; const enabled = options?.enabled ?? true;
const criteria = options?.criteria ?? {}; const criteria = options?.criteria ?? {};
return useQuery<SupplierList, DefaultError>({ return useQuery<SupplierList, DefaultError>({
queryKey: LIST_SUPPLIERS_QUERY_KEY(criteria as CriteriaDTO), queryKey: LIST_SUPPLIERS_QUERY_KEY(criteria),
queryFn: async ({ signal }) => { queryFn: async ({ signal }) => {
const dto = await getListSuppliers(dataSource, criteria as CriteriaDTO, signal); const dto: ListSuppliersResult = await getListSuppliersByCriteria(dataSource, {
criteria,
signal,
});
return ListSuppliersAdapter.fromDTO(dto); return ListSuppliersAdapter.fromDTO(dto);
}, },
enabled, enabled,
placeholderData: (previousData) => previousData, placeholderData: (previousData) => previousData, // Mantiene la página anterior durante refetch por cambio de criteria
}); });
}; };