-
-
-
-
+
diff --git a/modules/customers/src/web/hooks/use-create-customer-mutation.ts b/modules/customers/src/web/hooks/use-create-customer-mutation.ts
index 0d2e85af..5dd2364a 100644
--- a/modules/customers/src/web/hooks/use-create-customer-mutation.ts
+++ b/modules/customers/src/web/hooks/use-create-customer-mutation.ts
@@ -1,18 +1,18 @@
import { useDataSource } from "@erp/core/hooks";
import { UniqueID } from "@repo/rdx-ddd";
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";
type CreateCustomerPayload = {
- data: CustomerCreateData;
+ data: CustomerFormData;
};
export function useCreateCustomerMutation() {
const queryClient = useQueryClient();
const dataSource = useDataSource();
- return useMutation
({
+ return useMutation({
mutationKey: ["customer:create"],
mutationFn: async (payload) => {
@@ -23,7 +23,7 @@ export function useCreateCustomerMutation() {
...data,
id: customerId.toString(),
});
- return created as CustomerData;
+ return created as CustomerFormData;
},
onSuccess: () => {
diff --git a/modules/customers/src/web/pages/create/customer-create.tsx b/modules/customers/src/web/pages/create/customer-create.tsx
index 64df4ca1..1cdfdb84 100644
--- a/modules/customers/src/web/pages/create/customer-create.tsx
+++ b/modules/customers/src/web/pages/create/customer-create.tsx
@@ -25,6 +25,8 @@ export const CustomerCreate = () => {
// 3) Submit con navegación condicionada por éxito
const handleSubmit = async (formData: CustomerFormData) => {
+ console.log("formData => ", formData);
+
/*const changedData: Record = {};
Object.keys(dirtyFields).forEach((field) => {
@@ -51,8 +53,6 @@ export const CustomerCreate = () => {
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
};
- console.log("render");
-
return (
<>
diff --git a/modules/customers/src/web/schemas/customer.form.schema.ts b/modules/customers/src/web/schemas/customer.form.schema.ts
index 4d14346c..233e27dc 100644
--- a/modules/customers/src/web/schemas/customer.form.schema.ts
+++ b/modules/customers/src/web/schemas/customer.form.schema.ts
@@ -4,7 +4,7 @@ export const CustomerFormSchema = z.object({
reference: z.string().optional(),
is_company: z.string().optional(),
- name: z.string().optional(),
+ name: z.string().nonempty(),
trade_name: z.string().optional(),
tin: z.string().optional(),
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(),
- language_code: z.string().optional(),
- currency_code: z.string().optional(),
+ language_code: z.string().nonempty(),
+ currency_code: z.string().nonempty(),
});
export type CustomerFormData = z.infer;
diff --git a/modules/verifactu/src/api/domain/repositories/verifactu-repository.interface.ts b/modules/verifactu/src/api/domain/repositories/verifactu-repository.interface.ts
new file mode 100644
index 00000000..a266bfbb
--- /dev/null
+++ b/modules/verifactu/src/api/domain/repositories/verifactu-repository.interface.ts
@@ -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
+ */
+ save(invoice: CustomerInvoice, transaction: any): Promise>;
+
+ /**
+ * Comprueba si existe una factura con un `id` dentro de una `company`.
+ */
+ existsByIdInCompany(
+ companyId: UniqueID,
+ id: UniqueID,
+ transaction?: any
+ ): Promise>;
+
+ /**
+ * Recupera una factura por su ID y companyId.
+ * Devuelve un `NotFoundError` si no se encuentra.
+ */
+ getByIdInCompany(
+ companyId: UniqueID,
+ id: UniqueID,
+ transaction?: any
+ ): Promise>;
+
+ /**
+ *
+ * Consulta facturas dentro de una empresa usando un
+ * objeto Criteria (filtros, orden, paginación).
+ * El resultado está encapsulado en un objeto `Collection`.
+ *
+ * @param companyId - ID de la empresa.
+ * @param criteria - Criterios de búsqueda.
+ * @param transaction - Transacción activa para la operación.
+ * @returns Result, Error>
+ *
+ * @see Criteria
+ */
+ findByCriteriaInCompany(
+ companyId: UniqueID,
+ criteria: Criteria,
+ transaction: any
+ ): Promise, 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
+ */
+ deleteByIdInCompany(
+ companyId: UniqueID,
+ id: UniqueID,
+ transaction: any
+ ): Promise>;
+}
diff --git a/modules/verifactu/src/api/domain/services/verifactu.service.ts b/modules/verifactu/src/api/domain/services/verifactu.service.ts
new file mode 100644
index 00000000..a0fa7535
--- /dev/null
+++ b/modules/verifactu/src/api/domain/services/verifactu.service.ts
@@ -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 - El agregado construido o un error si falla la creación.
+ */
+ buildInvoiceInCompany(
+ companyId: UniqueID,
+ props: Omit,
+ invoiceId?: UniqueID
+ ): Result {
+ 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 - El agregado guardado o un error si falla la operación.
+ */
+ async saveInvoice(
+ invoice: CustomerInvoice,
+ transaction: any
+ ): Promise> {
+ 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 - Existe la factura o no.
+ */
+
+ async existsByIdInCompany(
+ companyId: UniqueID,
+ invoiceId: UniqueID,
+ transaction?: any
+ ): Promise> {
+ 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, Error> - Colección de facturas o error.
+ */
+ async findInvoiceByCriteriaInCompany(
+ companyId: UniqueID,
+ criteria: Criteria,
+ transaction?: Transaction
+ ): Promise, 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 - Factura encontrada o error.
+ */
+ async getInvoiceByIdInCompany(
+ companyId: UniqueID,
+ invoiceId: UniqueID,
+ transaction?: Transaction
+ ): Promise> {
+ 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 - Factura actualizada o error.
+ */
+ async updateInvoiceByIdInCompany(
+ companyId: UniqueID,
+ invoiceId: UniqueID,
+ changes: CustomerInvoicePatchProps,
+ transaction?: Transaction
+ ): Promise> {
+ // 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 - Resultado de la operación.
+ */
+ async deleteInvoiceByIdInCompany(
+ companyId: UniqueID,
+ invoiceId: UniqueID,
+ transaction?: Transaction
+ ): Promise> {
+ return this.repository.deleteByIdInCompany(companyId, invoiceId, transaction);
+ }
+}