From 8455ae43db53724cfb246648e7f7deaf94f18b10 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 22 Apr 2025 10:11:50 +0200 Subject: [PATCH] . --- apps/server/src/app.ts | 8 +- .../domain/value-objects/money-value.ts | 6 +- .../middlewares/global-error-handler.ts | 7 +- .../express/validate-request-dto.ts | 47 +++---- .../invoices/domain/aggregates/invoice.ts | 2 +- .../entities/invoice-items/invoice-item.ts | 23 +++- .../value-objects/invoice-item-description.ts | 4 + .../mappers/invoice-item.mapper.ts | 119 ++++++++++++------ .../intrastructure/mappers/invoice.mapper.ts | 41 +++--- .../intrastructure/sequelize/index.ts | 1 + ...e-item.mo.del.ts => invoice-item.model.ts} | 57 +++++---- .../intrastructure/sequelize/invoice.model.ts | 18 +-- .../presentation/dto/invoices.schemas.ts | 36 +++--- apps/server/src/index.ts | 2 +- apps/server/src/routes/v1.routes.ts | 9 +- .../create-factura/create-factura.use-case.ts | 63 ---------- .../delete-factura/delete-factura.use-case.ts | 63 ---------- .../emit-factura/emit-factura.use-case.ts | 63 ---------- .../reject-factura/reject-factura.use-case.ts | 73 ----------- .../search-factura-by-id.use-case.ts | 68 ---------- .../search-factura-by-reference.use-case.ts | 60 --------- .../billing/domain/events/factura-rejected.ts | 60 --------- .../billing/domain/events/factura-sent.ts | 69 ---------- src-1/contexts/billing/domain/events/index.ts | 60 --------- .../factura-repository.interface.ts | 60 --------- .../billing/domain/repositories/index.ts | 67 ---------- .../contexts/billing/domain/services/index.ts | 63 ---------- .../domain/value-objects/factura-reference.ts | 68 ---------- .../domain/value-objects/factura-status.ts | 65 ---------- .../billing/domain/value-objects/index.ts | 63 ---------- .../billing/infrastructure/express/index.ts | 66 ---------- .../billing/infrastructure/mappers/index.ts | 73 ----------- .../billing/infrastructure/sequelize/index.ts | 63 ---------- .../create-factura.controller.ts | 60 --------- .../delete-factura.controller.ts | 60 --------- .../emit-factura/emit-factura.controller.ts | 60 --------- .../reject-factura.controller.ts | 66 ---------- .../search-factura-by-id.controller.ts | 73 ----------- .../search-factura-by-reference.controller.ts | 66 ---------- .../presentation/dto/factura-request.ts | 65 ---------- .../presentation/dto/factura-response.ts | 73 ----------- .../presentation/dto/factura-schemas.ts | 60 --------- 42 files changed, 228 insertions(+), 1902 deletions(-) rename apps/server/src/contexts/invoices/intrastructure/sequelize/{invoice-item.mo.del.ts => invoice-item.model.ts} (80%) delete mode 100644 src-1/contexts/billing/application/create-factura/create-factura.use-case.ts delete mode 100644 src-1/contexts/billing/application/delete-factura/delete-factura.use-case.ts delete mode 100644 src-1/contexts/billing/application/emit-factura/emit-factura.use-case.ts delete mode 100644 src-1/contexts/billing/application/reject-factura/reject-factura.use-case.ts delete mode 100644 src-1/contexts/billing/application/search-factura-by-id/search-factura-by-id.use-case.ts delete mode 100644 src-1/contexts/billing/application/search-factura-by-reference/search-factura-by-reference.use-case.ts delete mode 100644 src-1/contexts/billing/domain/events/factura-rejected.ts delete mode 100644 src-1/contexts/billing/domain/events/factura-sent.ts delete mode 100644 src-1/contexts/billing/domain/events/index.ts delete mode 100644 src-1/contexts/billing/domain/repositories/factura-repository.interface.ts delete mode 100644 src-1/contexts/billing/domain/repositories/index.ts delete mode 100644 src-1/contexts/billing/domain/services/index.ts delete mode 100644 src-1/contexts/billing/domain/value-objects/factura-reference.ts delete mode 100644 src-1/contexts/billing/domain/value-objects/factura-status.ts delete mode 100644 src-1/contexts/billing/domain/value-objects/index.ts delete mode 100644 src-1/contexts/billing/infrastructure/express/index.ts delete mode 100644 src-1/contexts/billing/infrastructure/mappers/index.ts delete mode 100644 src-1/contexts/billing/infrastructure/sequelize/index.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/create-factura/create-factura.controller.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/delete-factura/delete-factura.controller.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/emit-factura/emit-factura.controller.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/reject-factura/reject-factura.controller.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/search-factura-by-id/search-factura-by-id.controller.ts delete mode 100644 src-1/contexts/billing/presentation/controllers/search-factura-by-reference/search-factura-by-reference.controller.ts delete mode 100644 src-1/contexts/billing/presentation/dto/factura-request.ts delete mode 100644 src-1/contexts/billing/presentation/dto/factura-response.ts delete mode 100644 src-1/contexts/billing/presentation/dto/factura-schemas.ts diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index 7766c2f6..0c8a5340 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -46,11 +46,13 @@ export function createApp(): Application { next(); }); - // Gestión global de errores - app.use(globalErrorHandler); - // Registrar rutas de la API app.use("/api/v1", v1Routes()); + // Gestión global de errores. + // Siempre al final de la cadena de middlewares + // y después de las rutas. + app.use(globalErrorHandler); + return app; } diff --git a/apps/server/src/common/domain/value-objects/money-value.ts b/apps/server/src/common/domain/value-objects/money-value.ts index ec1dea5b..d151ba37 100644 --- a/apps/server/src/common/domain/value-objects/money-value.ts +++ b/apps/server/src/common/domain/value-objects/money-value.ts @@ -84,7 +84,7 @@ export class MoneyValue extends ValueObject implements IMoneyV /** Serializa el VO a una cadena del tipo "EUR:123400:2" */ toPersistence(): string { - return `${this.currency()}:${this.value.getAmount()}:${this.getScale()}`; + return `${this.currency}:${this.dinero.getAmount()}:${this.scale}`; } /** Reconstruye el VO desde la cadena persistida */ @@ -92,8 +92,8 @@ export class MoneyValue extends ValueObject implements IMoneyV const [currencyCode, amountStr, scaleStr] = value.split(":"); const amount = parseInt(amountStr, 10); const scale = parseInt(scaleStr, 10); - const currency = getCurrencyByCode(currencyCode); - return new MoneyValue(amount, scale, currency); + const currency = currencyCode; + return new MoneyValue({ amount, scale, currency_code: currency }); } toPrimitive() { diff --git a/apps/server/src/common/presentation/express/middlewares/global-error-handler.ts b/apps/server/src/common/presentation/express/middlewares/global-error-handler.ts index 0cf7b636..958fe1e3 100644 --- a/apps/server/src/common/presentation/express/middlewares/global-error-handler.ts +++ b/apps/server/src/common/presentation/express/middlewares/global-error-handler.ts @@ -2,7 +2,12 @@ import { logger } from "@common/infrastructure/logger"; import { NextFunction, Request, Response } from "express"; import { ApiError } from "../api-error"; -export const globalErrorHandler = (error: any, req: Request, res: Response, next: NextFunction) => { +export const globalErrorHandler = async ( + error: Error, + req: Request, + res: Response, + next: NextFunction +) => { // Si ya se envió una respuesta, delegamos al siguiente error handler if (res.headersSent) { return next(error); diff --git a/apps/server/src/common/presentation/express/validate-request-dto.ts b/apps/server/src/common/presentation/express/validate-request-dto.ts index 5db5ea0b..7ff5f042 100644 --- a/apps/server/src/common/presentation/express/validate-request-dto.ts +++ b/apps/server/src/common/presentation/express/validate-request-dto.ts @@ -7,27 +7,32 @@ export const validateAndParseBody = (schema: ZodSchema, options?: { sanitize?: boolean }) => (req: Request, res: Response, next: NextFunction) => { const result = schema.safeParse(req.body); - if (!result.success) { - // Construye errores detallados - const validationErrors = result.error.errors.map((err) => ({ - field: err.path.join("."), - message: err.message, - })); + try { + if (!result.success) { + // Construye errores detallados + const validationErrors = result.error.errors.map((err) => ({ + field: err.path.join("."), + message: err.message, + })); - throw new ApiError({ - status: httpStatus.BAD_REQUEST, //400 - title: "Validation Error", - detail: "Algunos campos no cumplen con los criterios de validación.", - type: "https://example.com/probs/validation-error", - instance: req.originalUrl, - errors: validationErrors, - }); + throw new ApiError({ + status: httpStatus.BAD_REQUEST, //400 + title: "Validation Error", + detail: "Algunos campos no cumplen con los criterios de validación.", + type: "https://example.com/probs/validation-error", + instance: req.originalUrl, + errors: validationErrors, + }); + } + + // Si pasa la validación, opcionalmente reescribe req.body + if (options?.sanitize ?? true) { + req.body = result.data; + } + + next(); + } catch (error: unknown) { + // Si ocurre un error, delega al manejador de errores global + next(error as ApiError); } - - // Si pasa la validación, opcionalmente reescribe req.body - if (options?.sanitize ?? true) { - req.body = result.data; - } - - next(); }; diff --git a/apps/server/src/contexts/invoices/domain/aggregates/invoice.ts b/apps/server/src/contexts/invoices/domain/aggregates/invoice.ts index 6061bc56..f866f998 100644 --- a/apps/server/src/contexts/invoices/domain/aggregates/invoice.ts +++ b/apps/server/src/contexts/invoices/domain/aggregates/invoice.ts @@ -28,7 +28,7 @@ export interface IInvoiceProps { //paymentTerms: string; customer?: InvoiceCustomer; - items?: Collection; + items?: InvoiceItems; } export interface IInvoice { diff --git a/apps/server/src/contexts/invoices/domain/entities/invoice-items/invoice-item.ts b/apps/server/src/contexts/invoices/domain/entities/invoice-items/invoice-item.ts index bbb29d67..742a6d91 100644 --- a/apps/server/src/contexts/invoices/domain/entities/invoice-items/invoice-item.ts +++ b/apps/server/src/contexts/invoices/domain/entities/invoice-items/invoice-item.ts @@ -1,4 +1,4 @@ -import { MoneyValue, Percentage, Quantity, ValueObject } from "@common/domain"; +import { DomainEntity, MoneyValue, Percentage, Quantity, UniqueID } from "@common/domain"; import { Result } from "@common/helpers"; import { InvoiceItemDescription } from "../../value-objects"; @@ -6,12 +6,13 @@ export interface IInvoiceItemProps { description: InvoiceItemDescription; quantity: Quantity; // Cantidad de unidades unitPrice: MoneyValue; // Precio unitario en la moneda de la factura - subtotalPrice?: MoneyValue; // Precio unitario * Cantidad + //subtotalPrice?: MoneyValue; // Precio unitario * Cantidad discount: Percentage; // % descuento - totalPrice?: MoneyValue; + //totalPrice?: MoneyValue; } export interface IInvoiceItem { + id: UniqueID; description: InvoiceItemDescription; quantity: Quantity; unitPrice: MoneyValue; @@ -20,12 +21,22 @@ export interface IInvoiceItem { totalPrice: MoneyValue; } -export class InvoiceItem extends ValueObject implements IInvoiceItem { +export class InvoiceItem extends DomainEntity implements IInvoiceItem { private _subtotalPrice!: MoneyValue; private _totalPrice!: MoneyValue; - public static create(props: IInvoiceItemProps): Result { - return Result.ok(new InvoiceItem(props)); + public static create(props: IInvoiceItemProps, id?: UniqueID): Result { + const item = new InvoiceItem(props, id); + + // Reglas de negocio / validaciones + // ... + // ... + + // 🔹 Disparar evento de dominio "InvoiceItemCreatedEvent" + //const { invoice } = props; + //user.addDomainEvent(new InvoiceAuthenticatedEvent(id, invoice.toString())); + + return Result.ok(item); } get description(): InvoiceItemDescription { diff --git a/apps/server/src/contexts/invoices/domain/value-objects/invoice-item-description.ts b/apps/server/src/contexts/invoices/domain/value-objects/invoice-item-description.ts index e58759be..591471ec 100644 --- a/apps/server/src/contexts/invoices/domain/value-objects/invoice-item-description.ts +++ b/apps/server/src/contexts/invoices/domain/value-objects/invoice-item-description.ts @@ -43,4 +43,8 @@ export class InvoiceItemDescription extends ValueObject {} + extends ISequelizeMapper {} -export const createInvoiceItemMapper = (context: IInvoicingContext): IInvoiceItemMapper => - new InvoiceItemMapper({ context }); - -class InvoiceItemMapper - extends SequelizeMapper +export class InvoiceItemMapper + extends SequelizeMapper implements IInvoiceItemMapper { - protected toDomainMappingImpl( - source: InvoiceItem_Model, - params: { sourceParent: InvoiceModel } - ): InvoiceItem { - const { sourceParent } = params; - const id = this.mapsValue(source, "item_id", UniqueID.create); + public mapToDomain( + source: InvoiceItemModel, + params?: MapperParamsType + ): Result { + const { sourceParent } = params as { sourceParent: InvoiceModel }; - const props: IInvoiceSimpleItemProps = { - description: this.mapsValue(source, "description", Description.create), - quantity: this.mapsValue(source, "quantity", Quantity.create), - unitPrice: this.mapsValue(source, "unit_price", (unit_price) => - UnitPrice.create({ - amount: unit_price, - currencyCode: sourceParent.invoice_currency, - precision: 4, - }) - ), - }; + const idOrError = UniqueID.create(source.item_id); - const invoiceItemOrError = InvoiceSimpleItem.create(props, id); + const descriptionOrError = InvoiceItemDescription.create(source.description); - if (invoiceItemOrError.isFailure) { - throw invoiceItemOrError.error; + const quantityOrError = Quantity.create({ + amount: source.quantity_amount, + scale: source.quantity_scale, + }); + + const unitPriceOrError = MoneyValue.create({ + amount: source.unit_price_amount, + scale: source.unit_price_scale, + currency_code: sourceParent.invoice_currency, + }); + + const discountOrError = Percentage.create({ + amount: source.discount_amount, + scale: source.discount_scale, + }); + + const result = Result.combine([ + idOrError, + descriptionOrError, + quantityOrError, + unitPriceOrError, + discountOrError, + ]); + + if (result.isFailure) { + return Result.fail(result.error); } - return invoiceItemOrError.object; + return InvoiceItem.create( + { + description: descriptionOrError.data, + quantity: quantityOrError.data, + unitPrice: unitPriceOrError.data, + discount: discountOrError.data, + }, + idOrError.data + //sourceParent + ); } - protected toPersistenceMappingImpl( + public mapToPersistence( source: InvoiceItem, - params: { index: number; sourceParent: Invoice } - ): TCreationInvoiceItem_Model { - const { index, sourceParent } = params; + params?: MapperParamsType + ): InferCreationAttributes { + const { index, sourceParent } = params as { + index: number; + sourceParent: Invoice; + }; const lineData = { parent_id: undefined, @@ -57,10 +83,21 @@ class InvoiceItemMapper item_id: source.id.toPrimitive(), description: source.description.toPrimitive(), - quantity: source.quantity.toPrimitive(), - unit_price: source.unitPrice.toPrimitive(), - subtotal: source.calculateSubtotal().toPrimitive(), - total: source.calculateTotal().toPrimitive(), + + quantity_amount: source.quantity.toPrimitive().amount, + quantity_scale: source.quantity.toPrimitive().scale, + + unit_price_amount: source.unitPrice.toPrimitive().amount, + unit_price_scale: source.unitPrice.toPrimitive().scale, + + subtotal_amount: source.subtotalPrice.toPrimitive().amount, + subtotal_scale: source.subtotalPrice.toPrimitive().scale, + + discount_amount: source.discount.toPrimitive().amount, + discount_scale: source.discount.toPrimitive().scale, + + total_amount: source.totalPrice.toPrimitive().amount, + total_scale: source.totalPrice.toPrimitive().scale, }; return lineData; } diff --git a/apps/server/src/contexts/invoices/intrastructure/mappers/invoice.mapper.ts b/apps/server/src/contexts/invoices/intrastructure/mappers/invoice.mapper.ts index 897322d0..80d67226 100644 --- a/apps/server/src/contexts/invoices/intrastructure/mappers/invoice.mapper.ts +++ b/apps/server/src/contexts/invoices/intrastructure/mappers/invoice.mapper.ts @@ -7,6 +7,7 @@ import { } from "@common/infrastructure/sequelize/sequelize-mapper"; import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "@contexts/invoices/domain/"; import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize"; +import { InvoiceItemMapper } from "./invoice-item.mapper"; // Importar el mapper de items export interface IInvoiceMapper extends ISequelizeMapper {} @@ -15,6 +16,13 @@ export class InvoiceMapper extends SequelizeMapper implements IInvoiceMapper { + private invoiceItemMapper: InvoiceItemMapper; + + constructor() { + super(); + this.invoiceItemMapper = new InvoiceItemMapper(); // Instanciar el mapper de items + } + public mapToDomain(source: InvoiceModel, params?: MapperParamsType): Result { const idOrError = UniqueID.create(source.id); const statusOrError = InvoiceStatus.create(source.invoice_status); @@ -23,18 +31,6 @@ export class InvoiceMapper const issueDateOrError = UtcDate.create(source.issue_date); const operationDateOrError = UtcDate.create(source.operation_date); - /*const subtotalOrError = MoneyValue.create({ - amount: source.subtotal, - scale: 2, - currency_code: source.invoice_currency, - }); - - const totalOrError = MoneyValue.create({ - amount: source.total, - scale: 2, - currency_code: source.invoice_currency, - });*/ - const result = Result.combine([ idOrError, statusOrError, @@ -42,14 +38,22 @@ export class InvoiceMapper invoiceNumberOrError, issueDateOrError, operationDateOrError, - //subtotalOrError, - //totalOrError, ]); if (result.isFailure) { return Result.fail(result.error); } + // Mapear los items de la factura + const itemsOrErrors = this.invoiceItemMapper.mapArrayToDomain(source.items, { + sourceParent: source, + ...params, + }); + + if (itemsOrErrors.isFailure) { + return Result.fail(itemsOrErrors.error); + } + const invoiceCurrency = source.invoice_currency || "EUR"; return Invoice.create( @@ -60,10 +64,7 @@ export class InvoiceMapper issueDate: issueDateOrError.data, operationDate: operationDateOrError.data, invoiceCurrency, - - //currency: source.invoice_currency, - //subtotal: subtotalOrError.data, - //total: totalOrError.data, + items: itemsOrErrors.data, }, idOrError.data ); @@ -73,6 +74,8 @@ export class InvoiceMapper const subtotal = source.calculateSubtotal(); const total = source.calculateTotal(); + const items = this.invoiceItemMapper.mapCollectionToPersistence(source.items, params); + return { id: source.id.toString(), invoice_status: source.status.toPrimitive(), @@ -88,6 +91,8 @@ export class InvoiceMapper total_amount: total.amount, total_scale: total.scale, + + items, }; } } diff --git a/apps/server/src/contexts/invoices/intrastructure/sequelize/index.ts b/apps/server/src/contexts/invoices/intrastructure/sequelize/index.ts index 7fefbbdb..d063103a 100644 --- a/apps/server/src/contexts/invoices/intrastructure/sequelize/index.ts +++ b/apps/server/src/contexts/invoices/intrastructure/sequelize/index.ts @@ -1,6 +1,7 @@ import { IInvoiceRepository } from "@contexts/invoices/domain"; import { invoiceRepository } from "./invoice.repository"; +export * from "./invoice-item.model"; export * from "./invoice.model"; export * from "./invoice.repository"; diff --git a/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.mo.del.ts b/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.model.ts similarity index 80% rename from apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.mo.del.ts rename to apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.model.ts index cc3b2b00..198dc274 100644 --- a/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.mo.del.ts +++ b/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice-item.model.ts @@ -4,47 +4,32 @@ import { InferAttributes, InferCreationAttributes, Model, - NonAttribute, Sequelize, } from "sequelize"; -import { InvoiceModel } from "./invoice.model"; -export type TCreationInvoiceItem_Model = InferCreationAttributes< - InvoiceItem_Model, - { - /*omit: "invoice"*/ - } ->; +export type InvoiceItemCreationAttributes = InferCreationAttributes & {}; -export class InvoiceItem_Model extends Model< - InferAttributes< - InvoiceItem_Model, - { - /*omit: "invoice"*/ - } - >, - InferCreationAttributes< - InvoiceItem_Model, - { - /*omit: "invoice"*/ - } - > +export class InvoiceItemModel extends Model< + InferAttributes, + InvoiceItemCreationAttributes > { static associate(connection: Sequelize) { - const { Invoice_Model, InvoiceItem_Model } = connection.models; + /*const { Invoice_Model, InvoiceItem_Model } = connection.models; InvoiceItem_Model.belongsTo(Invoice_Model, { as: "invoice", foreignKey: "invoice_id", onDelete: "CASCADE", - }); + });*/ } - declare invoice_id: string; declare item_id: string; + declare invoice_id: string; + declare parent_id: CreationOptional; declare position: number; declare item_type: string; + declare description: CreationOptional; declare quantity_amount: CreationOptional; @@ -56,14 +41,17 @@ export class InvoiceItem_Model extends Model< declare subtotal_amount: CreationOptional; declare subtotal_scale: CreationOptional; + declare discount_amount: CreationOptional; + declare discount_scale: CreationOptional; + declare total_amount: CreationOptional; declare total_scale: CreationOptional; - declare invoice?: NonAttribute; + //declare invoice?: NonAttribute; } export default (sequelize: Sequelize) => { - InvoiceItem_Model.init( + InvoiceItemModel.init( { item_id: { type: new DataTypes.UUID(), @@ -138,6 +126,17 @@ export default (sequelize: Sequelize) => { defaultValue: null, }, + discount_amount: { + type: new DataTypes.SMALLINT(), + allowNull: true, + defaultValue: null, + }, + discount_scale: { + type: new DataTypes.SMALLINT(), + allowNull: true, + defaultValue: null, + }, + /*tax_amount: { type: new DataTypes.BIGINT(), allowNull: true, @@ -156,8 +155,12 @@ export default (sequelize: Sequelize) => { { sequelize, tableName: "invoice_items", + + defaultScope: {}, + + scopes: {}, } ); - return InvoiceItem_Model; + return InvoiceItemModel; }; diff --git a/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice.model.ts b/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice.model.ts index 0b1e13a8..a439bf22 100644 --- a/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice.model.ts +++ b/apps/server/src/contexts/invoices/intrastructure/sequelize/invoice.model.ts @@ -4,25 +4,24 @@ import { InferAttributes, InferCreationAttributes, Model, + NonAttribute, Sequelize, } from "sequelize"; +import { InvoiceItemCreationAttributes, InvoiceItemModel } from "./invoice-item.model"; -export type InvoiceCreationAttributes = InferCreationAttributes & {}; +export type InvoiceCreationAttributes = InferCreationAttributes & { + items?: InvoiceItemCreationAttributes[]; +}; export class InvoiceModel extends Model, InvoiceCreationAttributes> { static associate(connection: Sequelize) { - /*const { Invoice_Model, InvoiceItem_Model, InvoiceParticipant_Model } = connection.models; + const { InvoiceModel, InvoiceItemModel } = connection.models; - Invoice_Model.hasMany(InvoiceItem_Model, { + InvoiceModel.hasMany(InvoiceItemModel, { as: "items", foreignKey: "invoice_id", onDelete: "CASCADE", }); - Invoice_Model.hasMany(InvoiceParticipant_Model, { - as: "customer", - foreignKey: "invoice_id", - onDelete: "CASCADE", - });*/ } declare id: string; @@ -43,7 +42,8 @@ export class InvoiceModel extends Model, InvoiceCr declare total_amount: CreationOptional; declare total_scale: CreationOptional; - //declare items: NonAttribute; + // Relationships + declare items: NonAttribute; //declare customer: NonAttribute; } diff --git a/apps/server/src/contexts/invoices/presentation/dto/invoices.schemas.ts b/apps/server/src/contexts/invoices/presentation/dto/invoices.schemas.ts index c93b6c25..e07ec582 100644 --- a/apps/server/src/contexts/invoices/presentation/dto/invoices.schemas.ts +++ b/apps/server/src/contexts/invoices/presentation/dto/invoices.schemas.ts @@ -12,24 +12,30 @@ export const ICreateInvoiceRequestSchema = z.object({ const dateStr = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format"); return dateStr.safeParse(date).success; }), - customerId: z.string().uuid(), + //customerId: z.string().uuid(), lang_code: z.string().min(1), currency_code: z.string().min(1), - items: z.array( - z.object({ - //id: z.string().uuid(), - description: z.string().min(1), - unit_price: z.object({ - amount: z.number().positive(), - scale: z.number().positive(), - }), - quantity: z.object({ - amount: z.number().positive(), - scale: z.number().positive(), - }), - }) - ), + items: z + .array( + z.object({ + //id: z.string().uuid(), + description: z.string().optional(), + unit_price: z + .object({ + amount: z.number().positive(), + scale: z.number().positive(), + }) + .optional(), + quantity: z + .object({ + amount: z.number().positive(), + scale: z.number().positive(), + }) + .optional(), + }) + ) + .optional(), }); export const IUpdateInvoiceRequestSchema = z.object({}); diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index 0909f316..f1f7e1d3 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -50,7 +50,7 @@ const serverError = (error: NodeJS.ErrnoException) => { } // Dependiendo de la criticidad, podrías forzar el proceso a salir - // process.exit(1); + process.exit(1); }; // Almacena en "connections" cada nueva conexión (descomentar si se quiere seguimiento) diff --git a/apps/server/src/routes/v1.routes.ts b/apps/server/src/routes/v1.routes.ts index e0c4aeef..2fbec422 100644 --- a/apps/server/src/routes/v1.routes.ts +++ b/apps/server/src/routes/v1.routes.ts @@ -1,8 +1,5 @@ import { Router } from "express"; -import { accountsRouter } from "./accounts.routes"; -import { authRouter } from "./auth.routes"; import { invoicesRouter } from "./invoices.routes"; -import { usersRouter } from "./users.routes"; export const v1Routes = () => { const routes = Router({ mergeParams: true }); @@ -11,9 +8,9 @@ export const v1Routes = () => { res.send("Hello world!"); }); - authRouter(routes); - usersRouter(routes); - accountsRouter(routes); + //authRouter(routes); + //usersRouter(routes); + //accountsRouter(routes); // Sales invoicesRouter(routes); diff --git a/src-1/contexts/billing/application/create-factura/create-factura.use-case.ts b/src-1/contexts/billing/application/create-factura/create-factura.use-case.ts deleted file mode 100644 index 8ea1d54f..00000000 --- a/src-1/contexts/billing/application/create-factura/create-factura.use-case.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // 🔹 Disparar evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id, this.props.referencia)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/application/delete-factura/delete-factura.use-case.ts b/src-1/contexts/billing/application/delete-factura/delete-factura.use-case.ts deleted file mode 100644 index b2a91a28..00000000 --- a/src-1/contexts/billing/application/delete-factura/delete-factura.use-case.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - modify(props: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, props); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/application/emit-factura/emit-factura.use-case.ts b/src-1/contexts/billing/application/emit-factura/emit-factura.use-case.ts deleted file mode 100644 index f546c1ad..00000000 --- a/src-1/contexts/billing/application/emit-factura/emit-factura.use-case.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/application/reject-factura/reject-factura.use-case.ts b/src-1/contexts/billing/application/reject-factura/reject-factura.use-case.ts deleted file mode 100644 index 5f4c1aea..00000000 --- a/src-1/contexts/billing/application/reject-factura/reject-factura.use-case.ts +++ /dev/null @@ -1,73 +0,0 @@ -// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - factura.addDomainEvent(new FacturaDraft(factura.id)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.createEmitted()) { - return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } - - get lineasDetalle(): any[] { - return this.props.lineasDetalle; - } - - get clienteOProveedor(): string { - return this.props.clienteOProveedor; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/application/search-factura-by-id/search-factura-by-id.use-case.ts b/src-1/contexts/billing/application/search-factura-by-id/search-factura-by-id.use-case.ts deleted file mode 100644 index 91170a8f..00000000 --- a/src-1/contexts/billing/application/search-factura-by-id/search-factura-by-id.use-case.ts +++ /dev/null @@ -1,68 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(props.id)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/application/search-factura-by-reference/search-factura-by-reference.use-case.ts b/src-1/contexts/billing/application/search-factura-by-reference/search-factura-by-reference.use-case.ts deleted file mode 100644 index a0f77422..00000000 --- a/src-1/contexts/billing/application/search-factura-by-reference/search-factura-by-reference.use-case.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - - // Lógica para eliminar la factura - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id, this.props.referencia)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia)); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/events/factura-rejected.ts b/src-1/contexts/billing/domain/events/factura-rejected.ts deleted file mode 100644 index c35df344..00000000 --- a/src-1/contexts/billing/domain/events/factura-rejected.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - - // Lógica para eliminar la factura - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/events/factura-sent.ts b/src-1/contexts/billing/domain/events/factura-sent.ts deleted file mode 100644 index 76313e42..00000000 --- a/src-1/contexts/billing/domain/events/factura-sent.ts +++ /dev/null @@ -1,69 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.createEmitted()) { - return Result.fail(new Error("La factura solo se puede enviar en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.createEmitted()) { - return Result.fail(new Error("La factura solo se puede rechazar en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } - - get lineasDetalle(): any[] { - return this.props.lineasDetalle; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/events/index.ts b/src-1/contexts/billing/domain/events/index.ts deleted file mode 100644 index c35df344..00000000 --- a/src-1/contexts/billing/domain/events/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - - // Lógica para eliminar la factura - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/repositories/factura-repository.interface.ts b/src-1/contexts/billing/domain/repositories/factura-repository.interface.ts deleted file mode 100644 index a0f77422..00000000 --- a/src-1/contexts/billing/domain/repositories/factura-repository.interface.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - - // Lógica para eliminar la factura - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id, this.props.referencia)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia)); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/repositories/index.ts b/src-1/contexts/billing/domain/repositories/index.ts deleted file mode 100644 index 577b5d4c..00000000 --- a/src-1/contexts/billing/domain/repositories/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id, props.referencia)); - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, newProps); - return Result.ok(undefined); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id, this.props.referencia)); - return Result.ok(undefined); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id, this.props.referencia)); - return Result.ok(undefined); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id, this.props.referencia)); - return Result.ok(undefined); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/services/index.ts b/src-1/contexts/billing/domain/services/index.ts deleted file mode 100644 index 8b316ef6..00000000 --- a/src-1/contexts/billing/domain/services/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/value-objects/factura-reference.ts b/src-1/contexts/billing/domain/value-objects/factura-reference.ts deleted file mode 100644 index d6702796..00000000 --- a/src-1/contexts/billing/domain/value-objects/factura-reference.ts +++ /dev/null @@ -1,68 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id, this.props.referencia)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia)); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/value-objects/factura-status.ts b/src-1/contexts/billing/domain/value-objects/factura-status.ts deleted file mode 100644 index cf35769f..00000000 --- a/src-1/contexts/billing/domain/value-objects/factura-status.ts +++ /dev/null @@ -1,65 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Se puede definir una entidad específica para las líneas de detalle - clienteOProveedor: any; // Se puede definir una entidad específica para el cliente o proveedor - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'.")); - } - this.props.estado = FacturaStatus.emitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.emitted) { - return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.sent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'.")); - } - this.props.estado = FacturaStatus.rejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/domain/value-objects/index.ts b/src-1/contexts/billing/domain/value-objects/index.ts deleted file mode 100644 index 65904df5..00000000 --- a/src-1/contexts/billing/domain/value-objects/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - update(props: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, props); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/infrastructure/express/index.ts b/src-1/contexts/billing/infrastructure/express/index.ts deleted file mode 100644 index 036fa33f..00000000 --- a/src-1/contexts/billing/infrastructure/express/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - update(props: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, props); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/infrastructure/mappers/index.ts b/src-1/contexts/billing/infrastructure/mappers/index.ts deleted file mode 100644 index f6f9541d..00000000 --- a/src-1/contexts/billing/infrastructure/mappers/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'.")); - } - this.props.estado = FacturaStatus.emitted; - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.emitted) { - return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.sent; - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'.")); - } - this.props.estado = FacturaStatus.rejected; - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } - - get lineasDetalle(): any[] { - return this.props.lineasDetalle; - } - - get clienteOProveedor(): string { - return this.props.clienteOProveedor; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/infrastructure/sequelize/index.ts b/src-1/contexts/billing/infrastructure/sequelize/index.ts deleted file mode 100644 index 1925dbe6..00000000 --- a/src-1/contexts/billing/infrastructure/sequelize/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, newProps); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/create-factura/create-factura.controller.ts b/src-1/contexts/billing/presentation/controllers/create-factura/create-factura.controller.ts deleted file mode 100644 index 15f78f5b..00000000 --- a/src-1/contexts/billing/presentation/controllers/create-factura/create-factura.controller.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/delete-factura/delete-factura.controller.ts b/src-1/contexts/billing/presentation/controllers/delete-factura/delete-factura.controller.ts deleted file mode 100644 index b416e44a..00000000 --- a/src-1/contexts/billing/presentation/controllers/delete-factura/delete-factura.controller.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: any; // Aquí puedes definir un tipo más específico si es necesario - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/emit-factura/emit-factura.controller.ts b/src-1/contexts/billing/presentation/controllers/emit-factura/emit-factura.controller.ts deleted file mode 100644 index 5993a03b..00000000 --- a/src-1/contexts/billing/presentation/controllers/emit-factura/emit-factura.controller.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(factura.id)); - return Result.ok(factura); - } - - update(props: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, props); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.createEmitted()) { - return Result.fail(new Error("La factura solo se puede enviar si ha sido emitida.")); - } - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede rechazar en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/reject-factura/reject-factura.controller.ts b/src-1/contexts/billing/presentation/controllers/reject-factura/reject-factura.controller.ts deleted file mode 100644 index 036fa33f..00000000 --- a/src-1/contexts/billing/presentation/controllers/reject-factura/reject-factura.controller.ts +++ /dev/null @@ -1,66 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - update(props: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, props); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/search-factura-by-id/search-factura-by-id.controller.ts b/src-1/contexts/billing/presentation/controllers/search-factura-by-id/search-factura-by-id.controller.ts deleted file mode 100644 index 28654ca7..00000000 --- a/src-1/contexts/billing/presentation/controllers/search-factura-by-id/search-factura-by-id.controller.ts +++ /dev/null @@ -1,73 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(factura.id)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'.")); - } - this.props.estado = FacturaStatus.emitted; - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.emitted) { - return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.sent; - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.draft) { - return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'.")); - } - this.props.estado = FacturaStatus.rejected; - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } - - get lineasDetalle(): any[] { - return this.props.lineasDetalle; - } - - get clienteOProveedor(): string { - return this.props.clienteOProveedor; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/controllers/search-factura-by-reference/search-factura-by-reference.controller.ts b/src-1/contexts/billing/presentation/controllers/search-factura-by-reference/search-factura-by-reference.controller.ts deleted file mode 100644 index f86409fb..00000000 --- a/src-1/contexts/billing/presentation/controllers/search-factura-by-reference/search-factura-by-reference.controller.ts +++ /dev/null @@ -1,66 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - Object.assign(this.props, newProps); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/dto/factura-request.ts b/src-1/contexts/billing/presentation/dto/factura-request.ts deleted file mode 100644 index 099513df..00000000 --- a/src-1/contexts/billing/presentation/dto/factura-request.ts +++ /dev/null @@ -1,65 +0,0 @@ -// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - - // Emitir evento de dominio "FacturaDraft" - factura.addDomainEvent(new FacturaDraft(factura.id)); - - return Result.ok(factura); - } - - modify(newProps: Partial): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - - Object.assign(this.props, newProps); - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/dto/factura-response.ts b/src-1/contexts/billing/presentation/dto/factura-response.ts deleted file mode 100644 index 2de0b040..00000000 --- a/src-1/contexts/billing/presentation/dto/factura-response.ts +++ /dev/null @@ -1,73 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle - clienteOProveedor: string; // Puede ser un ID o un objeto más complejo - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props); - factura.addDomainEvent(new FacturaDraft(props.id)); - return Result.ok(factura); - } - - emit(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.props.id)); - return Result.ok(); - } - - send(): Result { - if (this.props.estado !== FacturaStatus.createEmitted()) { - return Result.fail(new Error("La factura solo se puede enviar en estado 'emitted'.")); - } - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.props.id)); - return Result.ok(); - } - - reject(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede rechazar en estado 'draft'.")); - } - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.props.id)); - return Result.ok(); - } - - get referencia(): FacturaReference { - return this.props.referencia; - } - - get estado(): FacturaStatus { - return this.props.estado; - } - - get fecha(): UTCDate { - return this.props.fecha; - } - - get lineasDetalle(): any[] { - return this.props.lineasDetalle; - } - - get clienteOProveedor(): string { - return this.props.clienteOProveedor; - } -} \ No newline at end of file diff --git a/src-1/contexts/billing/presentation/dto/factura-schemas.ts b/src-1/contexts/billing/presentation/dto/factura-schemas.ts deleted file mode 100644 index 840b79c4..00000000 --- a/src-1/contexts/billing/presentation/dto/factura-schemas.ts +++ /dev/null @@ -1,60 +0,0 @@ -// filepath: src/contexts/billing/domain/aggregates/factura.ts -import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; -import { Result } from "@common/helpers"; -import { FacturaDraft } from "../events/factura-draft"; -import { FacturaEmitted } from "../events/factura-emitted"; -import { FacturaSent } from "../events/factura-sent"; -import { FacturaRejected } from "../events/factura-rejected"; -import { FacturaReference } from "../value-objects/factura-reference"; -import { FacturaStatus } from "../value-objects/factura-status"; - -export interface IFacturaProps { - id: UniqueID; - referencia: FacturaReference; - lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario - clienteOProveedor: any; // Aquí puedes definir un tipo más específico si es necesario - estado: FacturaStatus; - fecha: UTCDate; -} - -export class Factura extends AggregateRoot { - static create(props: IFacturaProps): Result { - const factura = new Factura(props, props.id); - factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); - return Result.ok(factura); - } - - modify(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'.")); - } - // Lógica para modificar la factura - return Result.ok(); - } - - delete(): Result { - if (this.props.estado !== FacturaStatus.createDraft()) { - return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'.")); - } - // Lógica para eliminar la factura - return Result.ok(); - } - - emit(): Result { - this.props.estado = FacturaStatus.createEmitted(); - this.addDomainEvent(new FacturaEmitted(this.id)); - return Result.ok(); - } - - send(): Result { - this.props.estado = FacturaStatus.createSent(); - this.addDomainEvent(new FacturaSent(this.id)); - return Result.ok(); - } - - reject(): Result { - this.props.estado = FacturaStatus.createRejected(); - this.addDomainEvent(new FacturaRejected(this.id)); - return Result.ok(); - } -} \ No newline at end of file