.
This commit is contained in:
parent
01ead56fff
commit
a4f928b716
@ -86,7 +86,6 @@ export function UnsavedChangesProvider({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<UnsavedChangesContext.Provider value={{ requestConfirm }}>
|
<UnsavedChangesContext.Provider value={{ requestConfirm }}>
|
||||||
<h1>hola</h1>
|
|
||||||
{children}
|
{children}
|
||||||
<UnsavedChangesDialog open={open} onConfirm={handleConfirm} />
|
<UnsavedChangesDialog open={open} onConfirm={handleConfirm} />
|
||||||
</UnsavedChangesContext.Provider>
|
</UnsavedChangesContext.Provider>
|
||||||
|
|||||||
@ -49,14 +49,18 @@ export function CustomerEditForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider {...form}>
|
<FormProvider {...form}>
|
||||||
<FormDebug />
|
|
||||||
<form id={formId} onSubmit={form.handleSubmit(onSubmit, onError)}>
|
<form id={formId} onSubmit={form.handleSubmit(onSubmit, onError)}>
|
||||||
<div className='w-full xl:w-2/3'>
|
<div className='xl:flex xl:flex-row-reverse xl:items-start'>
|
||||||
|
<div className='w-full xl:w-6/12'>
|
||||||
|
<FormDebug />
|
||||||
|
</div>
|
||||||
|
<div className='w-full xl:grow'>
|
||||||
<CustomerBasicInfoFields />
|
<CustomerBasicInfoFields />
|
||||||
<CustomerContactFields />
|
<CustomerContactFields />
|
||||||
<CustomerAddressFields />
|
<CustomerAddressFields />
|
||||||
<CustomerAdditionalConfigFields />
|
<CustomerAdditionalConfigFields />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { useDataSource } from "@erp/core/hooks";
|
import { useDataSource } from "@erp/core/hooks";
|
||||||
import { UniqueID } from "@repo/rdx-ddd";
|
import { UniqueID } from "@repo/rdx-ddd";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { CustomerCreateData, CustomerData } from "../schemas";
|
import { CustomerFormData } from "../schemas";
|
||||||
import { CUSTOMERS_LIST_KEY } from "./use-update-customer-mutation";
|
import { CUSTOMERS_LIST_KEY } from "./use-update-customer-mutation";
|
||||||
|
|
||||||
type CreateCustomerPayload = {
|
type CreateCustomerPayload = {
|
||||||
data: CustomerCreateData;
|
data: CustomerFormData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useCreateCustomerMutation() {
|
export function useCreateCustomerMutation() {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const dataSource = useDataSource();
|
const dataSource = useDataSource();
|
||||||
|
|
||||||
return useMutation<CustomerData, Error, CreateCustomerPayload>({
|
return useMutation<CustomerFormData, Error, CreateCustomerPayload>({
|
||||||
mutationKey: ["customer:create"],
|
mutationKey: ["customer:create"],
|
||||||
|
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async (payload) => {
|
||||||
@ -23,7 +23,7 @@ export function useCreateCustomerMutation() {
|
|||||||
...data,
|
...data,
|
||||||
id: customerId.toString(),
|
id: customerId.toString(),
|
||||||
});
|
});
|
||||||
return created as CustomerData;
|
return created as CustomerFormData;
|
||||||
},
|
},
|
||||||
|
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
|||||||
@ -25,6 +25,8 @@ export const CustomerCreate = () => {
|
|||||||
|
|
||||||
// 3) Submit con navegación condicionada por éxito
|
// 3) Submit con navegación condicionada por éxito
|
||||||
const handleSubmit = async (formData: CustomerFormData) => {
|
const handleSubmit = async (formData: CustomerFormData) => {
|
||||||
|
console.log("formData => ", formData);
|
||||||
|
|
||||||
/*const changedData: Record<string, string> = {};
|
/*const changedData: Record<string, string> = {};
|
||||||
|
|
||||||
Object.keys(dirtyFields).forEach((field) => {
|
Object.keys(dirtyFields).forEach((field) => {
|
||||||
@ -51,8 +53,6 @@ export const CustomerCreate = () => {
|
|||||||
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
|
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("render");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppBreadcrumb />
|
<AppBreadcrumb />
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export const CustomerFormSchema = z.object({
|
|||||||
reference: z.string().optional(),
|
reference: z.string().optional(),
|
||||||
|
|
||||||
is_company: z.string().optional(),
|
is_company: z.string().optional(),
|
||||||
name: z.string().optional(),
|
name: z.string().nonempty(),
|
||||||
trade_name: z.string().optional(),
|
trade_name: z.string().optional(),
|
||||||
tin: z.string().optional(),
|
tin: z.string().optional(),
|
||||||
default_taxes: z.array(z.string()).optional(), // completo (sustituye), o null => vaciar
|
default_taxes: z.array(z.string()).optional(), // completo (sustituye), o null => vaciar
|
||||||
@ -28,8 +28,8 @@ export const CustomerFormSchema = z.object({
|
|||||||
|
|
||||||
legal_record: z.string().optional(),
|
legal_record: z.string().optional(),
|
||||||
|
|
||||||
language_code: z.string().optional(),
|
language_code: z.string().nonempty(),
|
||||||
currency_code: z.string().optional(),
|
currency_code: z.string().nonempty(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type CustomerFormData = z.infer<typeof CustomerFormSchema>;
|
export type CustomerFormData = z.infer<typeof CustomerFormSchema>;
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
import { Criteria } from "@repo/rdx-criteria/server";
|
||||||
|
import { UniqueID } from "@repo/rdx-ddd";
|
||||||
|
import { Collection, Result } from "@repo/rdx-utils";
|
||||||
|
import { CustomerInvoiceListDTO } from "../../infrastructure";
|
||||||
|
import { CustomerInvoice } from "../aggregates";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interfaz del repositorio para el agregado `CustomerInvoice`.
|
||||||
|
* El escopado multitenant está representado por `companyId`.
|
||||||
|
*/
|
||||||
|
export interface ICustomerInvoiceRepository {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Persiste una nueva factura o actualiza una existente.
|
||||||
|
* Retorna el objeto actualizado tras la operación.
|
||||||
|
*
|
||||||
|
* @param invoice - El agregado a guardar.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<CustomerInvoice, Error>
|
||||||
|
*/
|
||||||
|
save(invoice: CustomerInvoice, transaction: any): Promise<Result<CustomerInvoice, Error>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comprueba si existe una factura con un `id` dentro de una `company`.
|
||||||
|
*/
|
||||||
|
existsByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
id: UniqueID,
|
||||||
|
transaction?: any
|
||||||
|
): Promise<Result<boolean, Error>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupera una factura por su ID y companyId.
|
||||||
|
* Devuelve un `NotFoundError` si no se encuentra.
|
||||||
|
*/
|
||||||
|
getByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
id: UniqueID,
|
||||||
|
transaction?: any
|
||||||
|
): Promise<Result<CustomerInvoice, Error>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Consulta facturas dentro de una empresa usando un
|
||||||
|
* objeto Criteria (filtros, orden, paginación).
|
||||||
|
* El resultado está encapsulado en un objeto `Collection<T>`.
|
||||||
|
*
|
||||||
|
* @param companyId - ID de la empresa.
|
||||||
|
* @param criteria - Criterios de búsqueda.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<Collection<CustomerInvoiceListDTO>, Error>
|
||||||
|
*
|
||||||
|
* @see Criteria
|
||||||
|
*/
|
||||||
|
findByCriteriaInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
criteria: Criteria,
|
||||||
|
transaction: any
|
||||||
|
): Promise<Result<Collection<CustomerInvoiceListDTO>, Error>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Elimina o marca como eliminada una factura dentro de una empresa.
|
||||||
|
*
|
||||||
|
* @param companyId - ID de la empresa.
|
||||||
|
* @param id - UUID de la factura a eliminar.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<void, Error>
|
||||||
|
*/
|
||||||
|
deleteByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
id: UniqueID,
|
||||||
|
transaction: any
|
||||||
|
): Promise<Result<void, Error>>;
|
||||||
|
}
|
||||||
139
modules/verifactu/src/api/domain/services/verifactu.service.ts
Normal file
139
modules/verifactu/src/api/domain/services/verifactu.service.ts
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import { Criteria } from "@repo/rdx-criteria/server";
|
||||||
|
import { UniqueID } from "@repo/rdx-ddd";
|
||||||
|
import { Collection, Result } from "@repo/rdx-utils";
|
||||||
|
import { Transaction } from "sequelize";
|
||||||
|
import { CustomerInvoiceListDTO } from "../../infrastructure";
|
||||||
|
import { CustomerInvoice, CustomerInvoicePatchProps, CustomerInvoiceProps } from "../aggregates";
|
||||||
|
import { ICustomerInvoiceRepository } from "../repositories";
|
||||||
|
|
||||||
|
export class CustomerInvoiceService {
|
||||||
|
constructor(private readonly repository: ICustomerInvoiceRepository) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construye un nuevo agregado CustomerInvoice a partir de props validadas.
|
||||||
|
*
|
||||||
|
* @param companyId - Identificador de la empresa a la que pertenece el cliente.
|
||||||
|
* @param props - Las propiedades ya validadas para crear la factura.
|
||||||
|
* @param invoiceId - Identificador UUID de la factura (opcional).
|
||||||
|
* @returns Result<CustomerInvoice, Error> - El agregado construido o un error si falla la creación.
|
||||||
|
*/
|
||||||
|
buildInvoiceInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
props: Omit<CustomerInvoiceProps, "companyId">,
|
||||||
|
invoiceId?: UniqueID
|
||||||
|
): Result<CustomerInvoice, Error> {
|
||||||
|
return CustomerInvoice.create({ ...props, companyId }, invoiceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guarda una instancia de CustomerInvoice en persistencia.
|
||||||
|
*
|
||||||
|
* @param invoice - El agregado a guardar.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<CustomerInvoice, Error> - El agregado guardado o un error si falla la operación.
|
||||||
|
*/
|
||||||
|
async saveInvoice(
|
||||||
|
invoice: CustomerInvoice,
|
||||||
|
transaction: any
|
||||||
|
): Promise<Result<CustomerInvoice, Error>> {
|
||||||
|
return this.repository.save(invoice, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Comprueba si existe o no en persistencia una factura con el ID proporcionado
|
||||||
|
*
|
||||||
|
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
|
||||||
|
* @param invoiceId - Identificador UUID de la factura.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<Boolean, Error> - Existe la factura o no.
|
||||||
|
*/
|
||||||
|
|
||||||
|
async existsByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
invoiceId: UniqueID,
|
||||||
|
transaction?: any
|
||||||
|
): Promise<Result<boolean, Error>> {
|
||||||
|
return this.repository.existsByIdInCompany(companyId, invoiceId, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtiene una colección de facturas que cumplen con los filtros definidos en un objeto Criteria.
|
||||||
|
*
|
||||||
|
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
|
||||||
|
* @param criteria - Objeto con condiciones de filtro, paginación y orden.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<Collection<CustomerInvoiceListDTO>, Error> - Colección de facturas o error.
|
||||||
|
*/
|
||||||
|
async findInvoiceByCriteriaInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
criteria: Criteria,
|
||||||
|
transaction?: Transaction
|
||||||
|
): Promise<Result<Collection<CustomerInvoiceListDTO>, Error>> {
|
||||||
|
return this.repository.findByCriteriaInCompany(companyId, criteria, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupera una factura por su identificador único.
|
||||||
|
*
|
||||||
|
* @param invoiceId - Identificador UUID de la factura.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<CustomerInvoice, Error> - Factura encontrada o error.
|
||||||
|
*/
|
||||||
|
async getInvoiceByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
invoiceId: UniqueID,
|
||||||
|
transaction?: Transaction
|
||||||
|
): Promise<Result<CustomerInvoice>> {
|
||||||
|
return await this.repository.getByIdInCompany(companyId, invoiceId, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actualiza parcialmente una factura existente con nuevos datos.
|
||||||
|
* No lo guarda en el repositorio.
|
||||||
|
*
|
||||||
|
* @param companyId - Identificador de la empresa a la que pertenece el cliente.
|
||||||
|
* @param invoiceId - Identificador de la factura a actualizar.
|
||||||
|
* @param changes - Subconjunto de props válidas para aplicar.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<CustomerInvoice, Error> - Factura actualizada o error.
|
||||||
|
*/
|
||||||
|
async updateInvoiceByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
invoiceId: UniqueID,
|
||||||
|
changes: CustomerInvoicePatchProps,
|
||||||
|
transaction?: Transaction
|
||||||
|
): Promise<Result<CustomerInvoice, Error>> {
|
||||||
|
// Verificar si la factura existe
|
||||||
|
const invoiceResult = await this.getInvoiceByIdInCompany(companyId, invoiceId, transaction);
|
||||||
|
|
||||||
|
if (invoiceResult.isFailure) {
|
||||||
|
return Result.fail(invoiceResult.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const invoice = invoiceResult.data;
|
||||||
|
const updatedInvoice = invoice.update(changes);
|
||||||
|
|
||||||
|
if (updatedInvoice.isFailure) {
|
||||||
|
return Result.fail(updatedInvoice.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.ok(updatedInvoice.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina (o marca como eliminada) una factura según su ID.
|
||||||
|
*
|
||||||
|
* @param companyId - Identificador de la empresa a la que pertenece el cliente.
|
||||||
|
* @param invoiceId - Identificador UUID de la factura.
|
||||||
|
* @param transaction - Transacción activa para la operación.
|
||||||
|
* @returns Result<boolean, Error> - Resultado de la operación.
|
||||||
|
*/
|
||||||
|
async deleteInvoiceByIdInCompany(
|
||||||
|
companyId: UniqueID,
|
||||||
|
invoiceId: UniqueID,
|
||||||
|
transaction?: Transaction
|
||||||
|
): Promise<Result<void, Error>> {
|
||||||
|
return this.repository.deleteByIdInCompany(companyId, invoiceId, transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user