diff --git a/apps/server/archive/contexts/customer-billing/application/get-customer-invoice.use-case.ts b/apps/server/archive/contexts/customer-billing/application/get-customer-invoice.use-case.ts deleted file mode 100644 index 95005ef5..00000000 --- a/apps/server/archive/contexts/customer-billing/application/get-customer-invoice.use-case.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ICustomerInvoiceService } from "@/contexts/customer-billing/domain"; -import { CustomerInvoice } from "@/contexts/customer-billing/domain/aggregates"; -import { UniqueID } from "@/core/common/domain"; -import { ITransactionManager } from "@/core/common/infrastructure/database"; -import { Result } from "@repo/rdx-utils"; - -export class GetCustomerInvoiceUseCase { - constructor( - private readonly invoiceService: ICustomerInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute(invoiceId: UniqueID): Promise> { - return this.transactionManager.complete((transaction) => { - return this.invoiceService.findCustomerInvoiceById(invoiceId, transaction); - }); - } -} diff --git a/apps/server/archive/contexts/customer-billing/application/index.ts b/apps/server/archive/contexts/customer-billing/application/index.ts deleted file mode 100644 index c57663bd..00000000 --- a/apps/server/archive/contexts/customer-billing/application/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./get-customer-invoice.use-case"; -export * from "./list-customer-invoices-use-case"; diff --git a/apps/server/archive/contexts/customer-billing/application/list-customer-invoices-use-case.ts b/apps/server/archive/contexts/customer-billing/application/list-customer-invoices-use-case.ts deleted file mode 100644 index 0a40f8cb..00000000 --- a/apps/server/archive/contexts/customer-billing/application/list-customer-invoices-use-case.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ITransactionManager } from "@/core/common/infrastructure/database"; -import { Collection, Result } from "@repo/rdx-utils"; -import { CustomerInvoice, ICustomerInvoiceService } from "../domain"; - -export class ListCustomerInvoicesUseCase { - constructor( - private readonly invoiceService: ICustomerInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute(): Promise, Error>> { - return this.transactionManager.complete((transaction) => { - return this.invoiceService.findCustomerInvoices(transaction); - }); - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/aggregates/customer-invoice.ts b/apps/server/archive/contexts/customer-billing/domain/aggregates/customer-invoice.ts deleted file mode 100644 index c2d00081..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/aggregates/customer-invoice.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { AggregateRoot, UniqueID, UtcDate } from "@/core/common/domain"; -import { Maybe, Result } from "@repo/rdx-utils"; -import { Customer, CustomerInvoiceItem } from "../entities"; -import { InvoiceStatus } from "../value-objetcs"; - -export interface ICustomerInvoiceProps { - status: InvoiceStatus; - issueDate: UtcDate; - invoiceNumber: string; - invoiceType: string; - invoiceCustomerReference: Maybe; - - customer: Customer; - items: CustomerInvoiceItem[]; -} - -export interface ICustomerInvoice { - id: UniqueID; - status: InvoiceStatus; - issueDate: UtcDate; - invoiceNumber: string; - invoiceType: string; - invoiceCustomerReference: Maybe; - - customer: Customer; - items: CustomerInvoiceItem[]; - - //send(); - //accept(); -} - -export class CustomerInvoice - extends AggregateRoot - implements ICustomerInvoice -{ - id: UniqueID; - static create(props: ICustomerInvoiceProps, id?: UniqueID): Result { - const invoice = new CustomerInvoice(props, id); - - // Reglas de negocio / validaciones - // ... - // ... - - // 🔹 Disparar evento de dominio "CustomerAuthenticatedEvent" - //const { customer } = props; - //user.addDomainEvent(new CustomerAuthenticatedEvent(id, customer.toString())); - - return Result.ok(invoice); - } - - get status(): InvoiceStatus { - return this.props.status; - } - - get issueDate(): UtcDate { - return this.props.issueDate; - } - - get invoiceNumber(): string { - return this.props.invoiceNumber; - } - - get invoiceType(): string { - return this.props.invoiceType; - } - - get invoiceCustomerReference(): Maybe { - return this.props.invoiceCustomerReference; - } - - get customer(): Customer { - return this.props.customer; - } - - get items(): CustomerInvoiceItem[] { - return this.props.items; - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/aggregates/index.ts b/apps/server/archive/contexts/customer-billing/domain/aggregates/index.ts deleted file mode 100644 index 8fdd6983..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/aggregates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoice"; diff --git a/apps/server/archive/contexts/customer-billing/domain/entities/customer-invoice-item.ts b/apps/server/archive/contexts/customer-billing/domain/entities/customer-invoice-item.ts deleted file mode 100644 index 65c47f27..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/entities/customer-invoice-item.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { DomainEntity, MoneyValue, Percentage, UniqueID } from "@/core/common/domain"; -import { Quantity } from "@/core/common/domain/value-objects/quantity"; -import { Maybe, Result } from "@repo/rdx-utils"; - -export interface ICustomerInvoiceItemProps { - description: Maybe; // Descripción del artículo o servicio - quantity: Maybe; // Cantidad de unidades - unitPrice: Maybe; // Precio unitario en la moneda de la factura - // subtotalPrice: MoneyValue; // Precio unitario * Cantidad - discount: Maybe; // % descuento - // totalPrice: MoneyValue; -} - -export interface ICustomerInvoiceItem { - description: Maybe; - quantity: Maybe; - unitPrice: Maybe; - subtotalPrice: Maybe; - discount: Maybe; - totalPrice: Maybe; - - isEmptyLine(): boolean; -} - -export class CustomerInvoiceItem - extends DomainEntity - implements ICustomerInvoiceItem -{ - private readonly _subtotalPrice!: Maybe; - private readonly _totalPrice!: Maybe; - - static validate(props: ICustomerInvoiceItemProps) { - return Result.ok(props); - } - - static create( - props: ICustomerInvoiceItemProps, - id?: UniqueID - ): Result { - const validation = CustomerInvoiceItem.validate(props); - if (!validation.isSuccess) { - Result.fail(new Error("Invalid invoice line data")); - } - - return Result.ok(new CustomerInvoiceItem(props, id)); - } - - private constructor(props: ICustomerInvoiceItemProps, id?: UniqueID) { - super(props, id); - this._subtotalPrice = this.calculateSubtotal(); - this._totalPrice = this.calculateTotal(); - } - - isEmptyLine(): boolean { - return this.quantity.isNone() && this.unitPrice.isNone() && this.discount.isNone(); - } - - calculateSubtotal(): Maybe { - if (this.quantity.isNone() || this.unitPrice.isNone()) { - return Maybe.none(); - } - - const _quantity = this.quantity.getOrUndefined()!; - const _unitPrice = this.unitPrice.getOrUndefined()!; - const _subtotal = _unitPrice.multiply(_quantity); - - return Maybe.some(_subtotal); - } - - calculateTotal(): Maybe { - const subtotal = this.calculateSubtotal(); - - if (subtotal.isNone()) { - return Maybe.none(); - } - - const _subtotal = subtotal.getOrUndefined()!; - const _discount = this.discount.getOrUndefined()!; - const _total = _subtotal.subtract(_subtotal.percentage(_discount)); - - return Maybe.some(_total); - } - - get description(): Maybe { - return this.props.description; - } - - get quantity(): Maybe { - return this.props.quantity; - } - - get unitPrice(): Maybe { - return this.props.unitPrice; - } - - get subtotalPrice(): Maybe { - return this._subtotalPrice; - } - - get discount(): Maybe { - return this.props.discount; - } - - get totalPrice(): Maybe { - return this._totalPrice; - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/entities/customer.ts b/apps/server/archive/contexts/customer-billing/domain/entities/customer.ts deleted file mode 100644 index 75215024..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/entities/customer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { AggregateRoot, PostalAddress, TINNumber, UniqueID } from "@/core/common/domain"; -import { Result } from "@repo/rdx-utils"; - -export interface ICustomerProps { - name: string; - tin: TINNumber; - address: PostalAddress; -} - -export interface ICustomer { - id: UniqueID; - - name: string; - tin: TINNumber; - address: PostalAddress; -} - -export class Customer extends AggregateRoot implements ICustomer { - id: UniqueID; - static create(props: ICustomerProps, id?: UniqueID): Result { - const customer = new Customer(props, id); - - // Reglas de negocio / validaciones - // ... - // ... - - // 🔹 Disparar evento de dominio "CustomerAuthenticatedEvent" - //const { customer } = props; - //user.addDomainEvent(new CustomerAuthenticatedEvent(id, customer.toString())); - - return Result.ok(customer); - } - - get name() { - return this.props.name; - } - - get tin(): TINNumber { - return this.props.tin; - } - - get address(): PostalAddress { - return this.props.address; - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/entities/index.ts b/apps/server/archive/contexts/customer-billing/domain/entities/index.ts deleted file mode 100644 index daed5a19..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/entities/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./customer"; -export * from "./customer-invoice-item"; -export * from "./tax"; -export * from "./tax-collection"; diff --git a/apps/server/archive/contexts/customer-billing/domain/entities/tax-collection.ts b/apps/server/archive/contexts/customer-billing/domain/entities/tax-collection.ts deleted file mode 100644 index 72288a0e..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/entities/tax-collection.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Slug } from "@/core/common/domain"; -import { Collection } from "@repo/rdx-utils"; -import { Tax } from "./tax"; - -export class TaxCollection extends Collection { - constructor(items: Tax[] = []) { - super(items); - } - - /** - - Agrega un impuesto a la colección garantizando que el slug sea único. */ - add(tax: Tax): void { - if (this.exists(tax.slug)) { - throw new Error(`(El impuesto con slug "${tax.slug.toString()}" ya existe.`); - } - this.add(tax); - } - - /** - - Verifica si un slug ya existe en la colección. */ - exists(slug: Slug): boolean { - return this.some((tax) => tax.slug.equals(slug)); - } - - /** - - Encuentra un impuesto por su slug. */ - findBySlug(slug: Slug): Tax | undefined { - return this.find((tax) => tax.slug.equals(slug)); - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/entities/tax.ts b/apps/server/archive/contexts/customer-billing/domain/entities/tax.ts deleted file mode 100644 index fb5a2c94..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/entities/tax.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { DomainEntity, Percentage, Slug, UniqueID } from "@/core/common/domain"; -import { Result } from "@repo/rdx-utils"; - -interface ITaxProps { - slug: Slug; - name: string; - taxValue: Percentage; -} - -interface ITax { - slug: Slug; - name: string; - taxValue: Percentage; -} - -export class Tax extends DomainEntity implements ITax { - static create(props: ITaxProps, id?: UniqueID): Result { - return Result.ok(new Tax(props, id)); - } - - get slug(): Slug { - return this.props.slug; - } - - get name(): string { - return this.props.name; - } - - get taxValue(): Percentage { - return this.props.taxValue; - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/index.ts b/apps/server/archive/contexts/customer-billing/domain/index.ts deleted file mode 100644 index eddad70d..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./aggregates"; -export * from "./entities"; -export * from "./repositories"; -export * from "./services"; diff --git a/apps/server/archive/contexts/customer-billing/domain/repositories/customer-invoice-repository.interface.ts b/apps/server/archive/contexts/customer-billing/domain/repositories/customer-invoice-repository.interface.ts deleted file mode 100644 index 79826964..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/repositories/customer-invoice-repository.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { UniqueID } from "@/core/common/domain"; -import { Collection, Result } from "@repo/rdx-utils"; -import { CustomerInvoice } from "../aggregates"; - -export interface ICustomerInvoiceRepository { - findAll(transaction?: any): Promise, Error>>; - findById(id: UniqueID, transaction?: any): Promise>; -} diff --git a/apps/server/archive/contexts/customer-billing/domain/repositories/index.ts b/apps/server/archive/contexts/customer-billing/domain/repositories/index.ts deleted file mode 100644 index d149dde6..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/repositories/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoice-repository.interface"; diff --git a/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice-service.interface.ts b/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice-service.interface.ts deleted file mode 100644 index a9c5685f..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice-service.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { UniqueID } from "@/core/common/domain"; -import { Collection, Result } from "@repo/rdx-utils"; -import { CustomerInvoice } from "../aggregates"; - -export interface ICustomerInvoiceService { - findCustomerInvoices(transaction?: any): Promise, Error>>; - findCustomerInvoiceById(invoiceId: UniqueID, transaction?: any): Promise>; -} diff --git a/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice.service.ts b/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice.service.ts deleted file mode 100644 index f7fb1236..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/services/customer-invoice.service.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UniqueID } from "@/core/common/domain"; -import { Collection, Result } from "@repo/rdx-utils"; -import { CustomerInvoice } from "../aggregates"; -import { ICustomerInvoiceRepository } from "../repositories"; -import { ICustomerInvoiceService } from "./customer-invoice-service.interface"; - -export class CustomerInvoiceService implements ICustomerInvoiceService { - constructor(private readonly invoiceRepository: ICustomerInvoiceRepository) {} - - async findCustomerInvoices( - transaction?: any - ): Promise, Error>> { - const invoicesOrError = await this.invoiceRepository.findAll(transaction); - if (invoicesOrError.isFailure) { - return Result.fail(invoicesOrError.error); - } - - return Result.ok(invoicesOrError.data); - } - - async findCustomerInvoiceById( - invoiceId: UniqueID, - transaction?: any - ): Promise> { - return await this.invoiceRepository.findById(invoiceId, transaction); - } -} diff --git a/apps/server/archive/contexts/customer-billing/domain/services/index.ts b/apps/server/archive/contexts/customer-billing/domain/services/index.ts deleted file mode 100644 index 9927fb2f..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/services/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./customer-invoice-service.interface"; -export * from "./customer-invoice.service"; diff --git a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/index.ts b/apps/server/archive/contexts/customer-billing/domain/value-objetcs/index.ts deleted file mode 100644 index 992c7ed2..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./invoice-status"; diff --git a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.spec.ts b/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.spec.ts deleted file mode 100644 index 11470190..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { InvoiceStatus } from "./invoice-status"; - -// Pruebas para InvoiceStatus -describe("InvoiceStatus", () => { - test("Debe crear estados válidos", () => { - const result1 = InvoiceStatus.create("borrador"); - const result2 = InvoiceStatus.create("enviada"); - const result3 = InvoiceStatus.create("cerrada"); - - expect(result1.isSuccess).toBe(true); - expect(result1.data.getValue()).toBe("borrador"); - expect(result1.data.toString()).toBe("borrador"); - - expect(result2.isSuccess).toBe(true); - expect(result2.data.getValue()).toBe("enviada"); - expect(result2.data.toString()).toBe("enviada"); - - expect(result3.isSuccess).toBe(true); - expect(result3.data.getValue()).toBe("cerrada"); - expect(result3.data.toString()).toBe("cerrada"); - }); - - test("Debe lanzar error al crear un estado inválido", () => { - const result = InvoiceStatus.create("inexistente"); - expect(result.isFailure).toBe(true); - }); - - test("Debe permitir transiciones válidas #1", () => { - const result = InvoiceStatus.create("borrador"); - expect(result.isSuccess).toBe(true); - expect(result.data.canTransitionTo("enviada")).toBe(true); - }); - - test("Debe permitir transiciones válidas #2", () => { - const result = InvoiceStatus.create("borrador"); - expect(result.isSuccess).toBe(true); - - const new_state = result.data.transitionTo("enviada"); - expect(new_state.isSuccess).toBe(true); - expect(new_state.data.toString()).toBe("enviada"); - }); - - test("Debe impedir transiciones inválidas", () => { - const result = InvoiceStatus.create("cerrada"); - expect(result.isSuccess).toBe(true); - expect(result.data.canTransitionTo("enviada")).toBe(false); - }); - - test("Debe lanzar error al intentar transición inválida", () => { - const result = InvoiceStatus.create("borrador"); - expect(result.isSuccess).toBe(true); - const new_state = result.data.transitionTo("cerrada"); - expect(new_state.isSuccess).toBe(false); - expect(new_state.error.message).toContain("Transición no permitida de borrador a cerrada"); - }); -}); diff --git a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.ts b/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.ts deleted file mode 100644 index 73ecfcbf..00000000 --- a/apps/server/archive/contexts/customer-billing/domain/value-objetcs/invoice-status.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { ValueObject } from "@repo/rdx-ddd"; -import { Result } from "@repo/rdx-utils"; - -interface IInvoiceStatusProps { - value: string; -} - -export class InvoiceStatus extends ValueObject { - private static readonly ALLOWED_STATUSES = [ - "borrador", - "enviada", - "aceptada", - "registrada", - "rechazada", - "cerrada", - "error", - ]; - - private static readonly TRANSITIONS: Record = { - borrador: ["enviada"], - enviada: ["aceptada", "registrada", "rechazada", "error"], - aceptada: ["registrada"], - registrada: ["cerrada"], - rechazada: ["cerrada"], - error: ["borrador"], - cerrada: [], - }; - - static create(value: string): Result { - if (!this.ALLOWED_STATUSES.includes(value)) { - return Result.fail(new Error(`Estado de factura no válido: ${value}`)); - } - return Result.ok(new InvoiceStatus({ value })); - } - - getValue(): string { - return this.props.value; - } - - canTransitionTo(nextStatus: string): boolean { - return InvoiceStatus.TRANSITIONS[this.props.value].includes(nextStatus); - } - - transitionTo(nextStatus: string): Result { - if (!this.canTransitionTo(nextStatus)) { - return Result.fail( - new Error(`Transición no permitida de ${this.props.value} a ${nextStatus}`) - ); - } - return InvoiceStatus.create(nextStatus); - } - - toString(): string { - return this.getValue(); - } -} diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/index.ts b/apps/server/archive/contexts/customer-billing/infraestructure/index.ts deleted file mode 100644 index 7ccefa3a..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./mappers"; -export * from "./sequelize"; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/mappers/customer-invoice.mapper.ts b/apps/server/archive/contexts/customer-billing/infraestructure/mappers/customer-invoice.mapper.ts deleted file mode 100644 index 595fbcd9..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/mappers/customer-invoice.mapper.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Customer, CustomerInvoice } from "@/contexts/customer-billing/domain"; -import { InvoiceStatus } from "@/contexts/customer-billing/domain/value-objetcs"; -import { PostalAddress, TINNumber, UniqueID, UtcDate } from "@/core/common/domain"; -import { - type ISequelizeMapper, - type MapperParamsType, - SequelizeMapper, -} from "@/core/common/infrastructure/sequelize/sequelize-mapper"; -import { Maybe, Result } from "@repo/rdx-utils"; -import { - CustomerInvoiceCreationAttributes, - CustomerInvoiceModel, -} from "../sequelize/customer-invoice.model"; - -export interface ICustomerInvoiceMapper - extends ISequelizeMapper< - CustomerInvoiceModel, - CustomerInvoiceCreationAttributes, - CustomerInvoice - > {} - -export class CustomerInvoiceMapper - extends SequelizeMapper - implements ICustomerInvoiceMapper -{ - public mapToDomain( - source: CustomerInvoiceModel, - params?: MapperParamsType - ): Result { - const idOrError = UniqueID.create(source.id); - const statusOrError = InvoiceStatus.create(source.status); - const issueDateOrError = UtcDate.create(source.issue_date); - - const result = Result.combine([idOrError, statusOrError, issueDateOrError]); - - if (result.isFailure) { - return Result.fail(result.error); - } - - // Customer - const customerIdOrError = UniqueID.create(source.customer_id); - const tinOrError = TINNumber.create(source.customer_tin); - const postalAddressOrError = PostalAddress.create({ - street: source.customer_street, - street2: source.customer_street2, - city: source.customer_city, - state: source.customer_state, - postalCode: source.customer_postal_code, - country: source.customer_country, - }); - - const check2 = Result.combine([idOrError, tinOrError, postalAddressOrError]); - - if (check2.isFailure) { - return Result.fail(check2.error); - } - - const customerOrError = Customer.create( - { - name: source.customer_name, - tin: tinOrError.data, - address: postalAddressOrError.data, - }, - customerIdOrError.data - ); - - return CustomerInvoice.create( - { - status: statusOrError.data, - issueDate: issueDateOrError.data, - invoiceNumber: source.invoice_number, - invoiceType: source.invoice_type, - invoiceCustomerReference: Maybe.fromNullable(source.invoice_customer_reference), - customer: customerOrError.data, - items: [], - }, - idOrError.data - ); - } - - public mapToPersistence( - source: CustomerInvoice, - params?: MapperParamsType - ): Result { - return Result.ok({ - id: source.id.toString(), - status: source.status.toString(), - - issue_date: source.issueDate.toDateString(), - invoice_number: source.invoiceNumber, - invoice_type: source.invoiceType, - invoice_customer_reference: source.invoiceCustomerReference.getOrUndefined(), - - lang_code: "es", - currency_code: "EUR", - - customer_id: source.customer.id.toString(), - customer_name: source.customer.name, - customer_tin: source.customer.tin.toString(), - customer_street: source.customer.address.street, - customer_street2: source.customer.address.street2.getOrUndefined(), - customer_city: source.customer.address.city, - customer_postal_code: source.customer.address.postalCode, - customer_state: source.customer.address.state, - customer_country: source.customer.address.country, - }); - } -} - -const customerInvoiceMapper: CustomerInvoiceMapper = new CustomerInvoiceMapper(); -export { customerInvoiceMapper }; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/mappers/index.ts b/apps/server/archive/contexts/customer-billing/infraestructure/mappers/index.ts deleted file mode 100644 index 5d78e8fc..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/mappers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoice.mapper"; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice-item.model.ts b/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice-item.model.ts deleted file mode 100644 index 8f52b00f..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice-item.model.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { CustomerInvoiceModel } from "./customer-invoice.model"; - -export type CustomerInvoiceItemCreationAttributes = InferCreationAttributes< - CustomerInvoiceItemModel, - { omit: "invoice" } ->; - -export class CustomerInvoiceItemModel extends Model< - InferAttributes, - InferCreationAttributes -> { - static associate(connection: Sequelize) { - const { CustomerInvoiceModel, CustomerInvoiceItemModel } = connection.models; - - CustomerInvoiceItemModel.belongsTo(CustomerInvoiceModel, { - as: "invoice", - foreignKey: "id", - onDelete: "CASCADE", - }); - } - - declare customer_invoice_id: string; - declare item_id: string; - declare id_article: CreationOptional; - declare position: number; - declare description: CreationOptional; - declare quantity: CreationOptional; - declare unit_price: CreationOptional; - declare subtotal_price: CreationOptional; - declare discount: CreationOptional; - declare total_price: CreationOptional; - - declare invoice: NonAttribute; -} - -export default (sequelize: Sequelize) => { - CustomerInvoiceItemModel.init( - { - item_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - customer_invoice_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - id_article: { - type: DataTypes.BIGINT().UNSIGNED, - allowNull: true, - defaultValue: null, - }, - position: { - type: new DataTypes.MEDIUMINT(), - autoIncrement: false, - allowNull: false, - }, - description: { - type: new DataTypes.TEXT(), - allowNull: true, - defaultValue: null, - }, - quantity: { - type: DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - unit_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - subtotal_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - discount: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - total_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - }, - { - sequelize, - tableName: "customer_invoice_items", - timestamps: false, - - indexes: [], - } - ); - - return CustomerInvoiceItemModel; -}; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.model.ts b/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.model.ts deleted file mode 100644 index 39aa7ecf..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.model.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { CustomerInvoiceItemModel } from "./customer-invoice-item.model"; - -export type CustomerInvoiceCreationAttributes = InferCreationAttributes< - CustomerInvoiceModel, - { omit: "items" } -> & { - // creo que no es necesario - //items: CustomerInvoiceItemCreationAttributes[]; - //customer_id: string; -}; - -export class CustomerInvoiceModel extends Model< - InferAttributes, - InferCreationAttributes -> { - // To avoid table creation - /*static async sync(): Promise { - return Promise.resolve(); - }*/ - - static associate(connection: Sequelize) { - const { CustomerInvoiceModel, CustomerInvoiceItemModel, CustomerModel } = connection.models; - - CustomerInvoiceModel.hasMany(CustomerInvoiceItemModel, { - as: "items", - foreignKey: "customer_invoice_id", - onDelete: "CASCADE", - }); - } - - declare id: string; - declare status: string; - - declare issue_date: string; - declare invoice_number: string; - declare invoice_type: string; - declare invoice_customer_reference?: CreationOptional; - - declare lang_code: string; - declare currency_code: string; - - declare customer_id: string; - declare customer_tin: string; - declare customer_name: string; - - declare customer_street: string; - declare customer_street2?: CreationOptional; - declare customer_city: string; - declare customer_state: string; - declare customer_postal_code: string; - declare customer_country: string; - - declare subtotal_price?: CreationOptional; - - declare discount?: CreationOptional; - declare discount_price?: CreationOptional; - - declare before_tax_price?: CreationOptional; - - declare tax?: CreationOptional; - declare tax_price?: CreationOptional; - - declare total_price?: CreationOptional; - - declare notes?: CreationOptional; - - declare items: NonAttribute; - - declare integrity_hash?: CreationOptional; - declare previous_invoice_id?: CreationOptional; - declare signed_at?: CreationOptional; -} - -export default (sequelize: Sequelize) => { - CustomerInvoiceModel.init( - { - id: { - type: DataTypes.UUID, - primaryKey: true, - }, - - status: { - type: new DataTypes.STRING(), - allowNull: false, - }, - - issue_date: { - type: new DataTypes.DATEONLY(), - allowNull: false, - }, - - invoice_number: { - type: DataTypes.STRING(), - allowNull: false, - }, - - invoice_customer_reference: { - type: new DataTypes.STRING(), - }, - - invoice_type: { - type: new DataTypes.STRING(), - allowNull: false, - }, - - lang_code: { - type: DataTypes.STRING(2), - allowNull: false, - defaultValue: "es", - }, - - currency_code: { - type: new DataTypes.STRING(3), - allowNull: false, - defaultValue: "EUR", - }, - - customer_id: { - type: new DataTypes.UUID(), - allowNull: false, - }, - - customer_name: { - type: DataTypes.STRING, - allowNull: false, - }, - - customer_tin: { - type: DataTypes.STRING, - allowNull: false, - }, - - customer_street: { - type: DataTypes.STRING, - allowNull: false, - }, - - customer_street2: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - }, - - customer_city: { - type: DataTypes.STRING, - allowNull: false, - }, - customer_state: { - type: DataTypes.STRING, - allowNull: false, - }, - customer_postal_code: { - type: DataTypes.STRING, - allowNull: false, - }, - customer_country: { - type: DataTypes.STRING, - allowNull: false, - }, - - subtotal_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - - discount: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - - discount_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - - before_tax_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - - tax: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - - tax_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - - total_price: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - - notes: { - type: DataTypes.TEXT, - allowNull: true, - defaultValue: null, - }, - - integrity_hash: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: "Hash criptográfico para asegurar integridad", - }, - previous_invoice_id: { - type: DataTypes.UUID, - allowNull: true, - defaultValue: null, - comment: "Referencia a la factura anterior (si aplica)", - }, - signed_at: { - type: DataTypes.DATE, - allowNull: true, - defaultValue: null, - comment: "Fecha en que la factura fue firmada digitalmente", - }, - }, - { - sequelize, - tableName: "customer_invoices", - - paranoid: true, // softs deletes - timestamps: true, - - createdAt: "created_at", - updatedAt: "updated_at", - deletedAt: "deleted_at", - - indexes: [ - { name: "status_idx", fields: ["status"] }, - { name: "invoice_number_idx", fields: ["invoice_number"] }, - { name: "deleted_at_idx", fields: ["deleted_at"] }, - { name: "signed_at_idx", fields: ["signed_at"] }, - ], - - whereMergeStrategy: "and", // <- cómo tratar el merge de un scope - - defaultScope: {}, - - scopes: {}, - } - ); - return CustomerInvoiceModel; -}; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.repository.ts b/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.repository.ts deleted file mode 100644 index c517a9db..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer-invoice.repository.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { CustomerInvoice, ICustomerInvoiceRepository } from "@/contexts/customer-billing/domain"; -import { UniqueID } from "@/core/common/domain"; -import { SequelizeRepository } from "@/core/common/infrastructure"; -import { Collection, Result } from "@repo/rdx-utils"; -import { Transaction } from "sequelize"; -import { - type ICustomerInvoiceMapper, - customerInvoiceMapper, -} from "../mappers/customer-invoice.mapper"; -import { CustomerInvoiceModel } from "./customer-invoice.model"; - -class CustomerInvoiceRepository - extends SequelizeRepository - implements ICustomerInvoiceRepository -{ - private readonly _mapper!: ICustomerInvoiceMapper; - - /** - * 🔹 Función personalizada para mapear errores de unicidad en autenticación - */ - private _customErrorMapper(error: Error): string | null { - if (error.name === "SequelizeUniqueConstraintError") { - return "Customer invoice with this email already exists"; - } - - return null; - } - - constructor(mapper: ICustomerInvoiceMapper) { - super(); - this._mapper = mapper; - } - - async findAll(transaction?: Transaction): Promise, Error>> { - try { - const rawCustomerInvoices: any = await this._findAll(CustomerInvoiceModel, {}, transaction); - - if (!rawCustomerInvoices === true) { - return Result.fail(new Error("Customer with email not exists")); - } - - return this._mapper.mapArrayToDomain(rawCustomerInvoices); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async findById(id: UniqueID, transaction?: Transaction): Promise> { - try { - const rawInvoice: any = await this._getById(CustomerInvoiceModel, id, {}, transaction); - - if (!rawInvoice === true) { - return Result.fail(new Error(`Customer with id ${id.toString()} not exists`)); - } - - return this._mapper.mapToDomain(rawInvoice); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } -} - -const customerInvoiceRepository = new CustomerInvoiceRepository(customerInvoiceMapper); -export { customerInvoiceRepository }; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer.model.ts b/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer.model.ts deleted file mode 100644 index b092ac60..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/customer.model.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - Sequelize, -} from "sequelize"; - -export type CustomerCreationAttributes = InferCreationAttributes & {}; - -export class CustomerModel extends Model< - InferAttributes, - InferCreationAttributes -> { - // To avoid table creation - /*static async sync(): Promise { - return Promise.resolve(); - }*/ - - declare id: string; - declare reference: CreationOptional; - - declare is_companyr: boolean; - declare name: string; - declare trade_name: CreationOptional; - declare tin: string; - - declare street: string; - declare city: string; - declare state: string; - declare postal_code: string; - declare country: string; - - declare email: string; - declare phone: string; - declare fax: CreationOptional; - declare website: CreationOptional; - - declare legal_record: string; - - declare default_tax: number; - declare status: string; - declare lang_code: string; - declare currency_code: string; -} - -export default (sequelize: Sequelize) => { - CustomerModel.init( - { - id: { - type: DataTypes.UUID, - primaryKey: true, - }, - reference: { - type: DataTypes.STRING, - allowNull: false, - }, - is_companyr: { - type: DataTypes.BOOLEAN, - allowNull: false, - }, - name: { - type: DataTypes.STRING, - allowNull: false, - }, - trade_name: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - }, - tin: { - type: DataTypes.STRING, - allowNull: false, - }, - - street: { - type: DataTypes.STRING, - allowNull: false, - }, - city: { - type: DataTypes.STRING, - allowNull: false, - }, - state: { - type: DataTypes.STRING, - allowNull: false, - }, - postal_code: { - type: DataTypes.STRING, - allowNull: false, - }, - country: { - type: DataTypes.STRING, - allowNull: false, - }, - - email: { - type: DataTypes.STRING, - allowNull: false, - validate: { - isEmail: true, - }, - }, - phone: { - type: DataTypes.STRING, - allowNull: false, - }, - fax: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - }, - website: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - validate: { - isUrl: true, - }, - }, - legal_record: { - type: DataTypes.TEXT, - allowNull: false, - }, - - default_tax: { - type: new DataTypes.SMALLINT(), - allowNull: false, - defaultValue: 2100, - }, - - lang_code: { - type: DataTypes.STRING(2), - allowNull: false, - defaultValue: "es", - }, - - currency_code: { - type: new DataTypes.STRING(3), - allowNull: false, - defaultValue: "EUR", - }, - - status: { - type: DataTypes.STRING, - allowNull: false, - defaultValue: "active", - }, - }, - { - sequelize, - tableName: "customers", - - paranoid: true, // softs deletes - timestamps: true, - - createdAt: "created_at", - updatedAt: "updated_at", - deletedAt: "deleted_at", - - indexes: [ - { name: "email_idx", fields: ["email"], unique: true }, - { name: "reference_idx", fields: ["reference"], unique: true }, - ], - - whereMergeStrategy: "and", // <- cómo tratar el merge de un scope - - defaultScope: {}, - - scopes: {}, - } - ); - return CustomerModel; -}; diff --git a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/index.ts b/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/index.ts deleted file mode 100644 index 11abc175..00000000 --- a/apps/server/archive/contexts/customer-billing/infraestructure/sequelize/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ICustomerInvoiceRepository } from "@/contexts/customer-billing/domain/"; -import { customerInvoiceRepository } from "./customer-invoice.repository"; - -export * from "./customer-invoice.model"; -export * from "./customer.model"; - -export * from "./customer-invoice.repository"; - -/*export const createCustomerRepository = (): ICustomerRepository => { - return customerRepository; -};*/ - -export const createCustomerInvoiceRepository = (): ICustomerInvoiceRepository => { - return customerInvoiceRepository; -}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.controller.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.controller.ts deleted file mode 100644 index 9180d269..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.controller.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { GetCustomerInvoiceUseCase } from "@/contexts/customer-billing/application"; -import { UniqueID } from "@/core/common/domain"; -import { ExpressController } from "@/core/common/presentation"; -import { IGetCustomerInvoicePresenter } from "./get-customer-invoice.presenter"; - -export class GetCustomerInvoiceController extends ExpressController { - public constructor( - private readonly getCustomerInvoice: GetCustomerInvoiceUseCase, - private readonly presenter: IGetCustomerInvoicePresenter - ) { - super(); - } - - protected async executeImpl() { - const { invoiceId } = this.req.params; - - // Validar ID - const invoiceIdOrError = UniqueID.create(invoiceId); - if (invoiceIdOrError.isFailure) return this.invalidInputError("Invoice ID not valid"); - - const invoiceOrError = await this.getCustomerInvoice.execute(invoiceIdOrError.data); - - if (invoiceOrError.isFailure) { - return this.handleError(invoiceOrError.error); - } - - return this.ok(this.presenter.toDTO(invoiceOrError.data)); - } - - private handleError(error: Error) { - const message = error.message; - - if ( - message.includes("Database connection lost") || - message.includes("Database request timed out") - ) { - return this.unavailableError( - "Database service is currently unavailable. Please try again later." - ); - } - - return this.conflictError(message); - } -} diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.presenter.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.presenter.ts deleted file mode 100644 index e87f06e2..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/get-customer-invoice.presenter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CustomerInvoice } from "@/contexts/customer-billing/domain"; -import { IGetCustomerInvoiceResponseDTO } from "@/contexts/customer-billing/presentation/dto"; - -export interface IGetCustomerInvoicePresenter { - toDTO: (invoice: CustomerInvoice) => IGetCustomerInvoiceResponseDTO; -} - -export const getCustomerInvoicesPresenter: IGetCustomerInvoicePresenter = { - toDTO: (invoice: CustomerInvoice): IGetCustomerInvoiceResponseDTO => { - return {} as IGetCustomerInvoiceResponseDTO; - }, -}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/index.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/index.ts deleted file mode 100644 index 8df4ce18..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/get/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GetCustomerInvoiceUseCase } from "@/contexts/customer-billing/application/"; -import { CustomerInvoiceService } from "@/contexts/customer-billing/domain"; -import { customerInvoiceRepository } from "@/contexts/customer-billing/infraestructure"; -import { SequelizeTransactionManager } from "@/core/common/infrastructure"; -import { GetCustomerInvoiceController } from "./get-customer-invoice.controller"; -import { getCustomerInvoicesPresenter } from "./get-customer-invoice.presenter"; - -export const getCustomerInvoiceController = () => { - const transactionManager = new SequelizeTransactionManager(); - const customerInvoiceService = new CustomerInvoiceService(customerInvoiceRepository); - - const useCase = new GetCustomerInvoiceUseCase(customerInvoiceService, transactionManager); - const presenter = getCustomerInvoicesPresenter; - - return new GetCustomerInvoiceController(useCase, presenter); -}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/index.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/index.ts deleted file mode 100644 index e04b56ea..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./get"; -export * from "./list"; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/index.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/index.ts deleted file mode 100644 index 71a5ef2a..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CustomerInvoiceService } from "@/contexts/customer-billing/domain"; -import { customerInvoiceRepository } from "@/contexts/customer-billing/infraestructure"; -import { SequelizeTransactionManager } from "@/core/common/infrastructure"; -import { ListCustomerInvoicesUseCase } from "../../../../application"; -import { ListCustomerInvoicesController } from "./list-customer-invoices.controller"; -import { listCustomerInvoicesPresenter } from "./list-customer-invoices.presenter"; - -export const listCustomerInvoicesController = () => { - const transactionManager = new SequelizeTransactionManager(); - const customerInvoiceService = new CustomerInvoiceService(customerInvoiceRepository); - - const useCase = new ListCustomerInvoicesUseCase(customerInvoiceService, transactionManager); - const presenter = listCustomerInvoicesPresenter; - - return new ListCustomerInvoicesController(useCase, presenter); -}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.controller.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.controller.ts deleted file mode 100644 index fcb7d852..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.controller.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ListCustomerInvoicesUseCase } from "@/contexts/customer-billing/application"; -import { ExpressController } from "@/core/common/presentation"; -import { IListCustomerInvoicesPresenter } from "./list-customer-invoices.presenter"; - -export class ListCustomerInvoicesController extends ExpressController { - public constructor( - private readonly listCustomerInvoices: ListCustomerInvoicesUseCase, - private readonly presenter: IListCustomerInvoicesPresenter - ) { - super(); - } - - protected async executeImpl() { - const customersOrError = await this.listCustomerInvoices.execute(); - - if (customersOrError.isFailure) { - return this.handleError(customersOrError.error); - } - - return this.ok(this.presenter.toDTO(customersOrError.data)); - } - - private handleError(error: Error) { - const message = error.message; - - if ( - message.includes("Database connection lost") || - message.includes("Database request timed out") - ) { - return this.unavailableError( - "Database service is currently unavailable. Please try again later." - ); - } - - return this.conflictError(message); - } -} diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.presenter.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.presenter.ts deleted file mode 100644 index 144974f4..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/customer-invoices/list/list-customer-invoices.presenter.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Collection, ensureString } from "@repo/rdx-utils"; - -import { CustomerInvoice } from "@/contexts/customer-billing/domain"; -import { IListCustomerInvoicesResponseDTO } from "../../../dto"; - -export interface IListCustomerInvoicesPresenter { - toDTO: (customers: Collection) => IListCustomerInvoicesResponseDTO[]; -} - -export const listCustomerInvoicesPresenter: IListCustomerInvoicesPresenter = { - toDTO: (invoice: Collection): IListCustomerInvoicesResponseDTO[] => - invoice.map((customer) => ({ - id: ensureString(customer.id.toString()), - /*reference: ensureString(customer.), - - is_companyr: ensureBoolean(customer.isFreelancer), - name: ensureString(customer.name), - trade_name: ensureString(customer.tradeName.getValue()), - tin: ensureString(customer.tin.toString()), - - street: ensureString(customer.address.street), - city: ensureString(customer.address.city), - state: ensureString(customer.address.state), - postal_code: ensureString(customer.address.postalCode), - country: ensureString(customer.address.country), - - email: ensureString(customer.email.toString()), - phone: ensureString(customer.phone.toString()), - fax: ensureString(customer.fax.getValue()?.toString()), - website: ensureString(customer.website.getValue()), - - legal_record: ensureString(customer.legalRecord), - - default_tax: ensureNumber(customer.defaultTax), - status: ensureString(customer.isActive ? "active" : "inactive"), - lang_code: ensureString(customer.langCode), - currency_code: ensureString(customer.currencyCode),*/ - })), -}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/controllers/index.ts b/apps/server/archive/contexts/customer-billing/presentation/controllers/index.ts deleted file mode 100644 index 80965b66..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/controllers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoices"; diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.request.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.request.dto.ts deleted file mode 100644 index 632527e2..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.request.dto.ts +++ /dev/null @@ -1 +0,0 @@ -export type IListCustomerInvoicesRequestDTO = {} diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.response.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.response.dto.ts deleted file mode 100644 index c4d3f9af..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.response.dto.ts +++ /dev/null @@ -1,29 +0,0 @@ -export interface IListCustomerInvoicesResponseDTO { - id: string; - /*reference: string; - - is_companyr: boolean; - name: string; - trade_name: string; - tin: string; - - street: string; - city: string; - state: string; - postal_code: string; - country: string; - - email: string; - phone: string; - fax: string; - website: string; - - legal_record: string; - - default_tax: number; - status: string; - lang_code: string; - currency_code: string;*/ -} - -export type IGetCustomerInvoiceResponseDTO = {}; diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.validation.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.validation.dto.ts deleted file mode 100644 index 5de35fd1..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/customer-invoices.validation.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import * as z from "zod/v4"; - -export const ListCustomerInvoicesSchema = z.object({}); -export const GetCustomerInvoiceSchema = z.object({}); diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/index.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/index.ts deleted file mode 100644 index 08586dd7..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customer-invoices/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./customer-invoices.request.dto"; -export * from "./customer-invoices.response.dto"; -export * from "./customer-invoices.validation.dto"; diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.request.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customers.request.dto.ts deleted file mode 100644 index 89fe10bc..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.request.dto.ts +++ /dev/null @@ -1 +0,0 @@ -export type IListCustomersRequestDTO = {} diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.response.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customers.response.dto.ts deleted file mode 100644 index 7f78ab6b..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.response.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -export interface IListCustomersResponseDTO { - id: string; - reference: string; - - is_companyr: boolean; - name: string; - trade_name: string; - tin: string; - - street: string; - city: string; - state: string; - postal_code: string; - country: string; - - email: string; - phone: string; - fax: string; - website: string; - - legal_record: string; - - default_tax: number; - status: string; - lang_code: string; - currency_code: string; -} diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.validation.dto.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/customers.validation.dto.ts deleted file mode 100644 index 43dfc2b5..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/customers.validation.dto.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as z from "zod/v4"; - -export const ListCustomersSchema = z.object({}); diff --git a/apps/server/archive/contexts/customer-billing/presentation/dto/index.ts b/apps/server/archive/contexts/customer-billing/presentation/dto/index.ts deleted file mode 100644 index 9ae48163..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/dto/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./customer-invoices"; -export * from "./customers.request.dto"; -export * from "./customers.response.dto"; -export * from "./customers.validation.dto"; diff --git a/apps/server/archive/contexts/customer-billing/presentation/index.ts b/apps/server/archive/contexts/customer-billing/presentation/index.ts deleted file mode 100644 index a123289d..00000000 --- a/apps/server/archive/contexts/customer-billing/presentation/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./controllers"; -export * from "./dto"; diff --git a/modules.bak/invoices/package.json b/modules.bak/invoices/package.json deleted file mode 100644 index ce14f616..00000000 --- a/modules.bak/invoices/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@modules/invoices", - "version": "0.0.0", - "private": true, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": ["dist/**"], - "scripts": { - "build": "tsc", - "dev": "tsc --watch", - "lint": "eslint src/", - "lint:fix": "eslint src/ --fix", - "typecheck": "tsc --noEmit", - "test": "jest" - }, - "jest": { - "preset": "@repo/jest-presets/node" - }, - "devDependencies": { - "@rdx/utils": "workspace:*", - "@repo/jest-presets": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/dinero.js": "^1.9.4", - "jest": "^29.7.0", - "typescript": "^5.8.3" - }, - "dependencies": {} -} diff --git a/modules.bak/invoices/src/client/index.ts b/modules.bak/invoices/src/client/index.ts deleted file mode 100644 index 2d1ec238..00000000 --- a/modules.bak/invoices/src/client/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default () => {}; diff --git a/modules.bak/invoices/src/index.ts b/modules.bak/invoices/src/index.ts deleted file mode 100644 index 5ec76921..00000000 --- a/modules.bak/invoices/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./client"; diff --git a/modules.bak/invoices/src/server/application/create-invoice.use-case.ts b/modules.bak/invoices/src/server/application/create-invoice.use-case.ts deleted file mode 100644 index 2912a099..00000000 --- a/modules.bak/invoices/src/server/application/create-invoice.use-case.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { UniqueID, UtcDate } from "core/common/domain"; - -import { - IInvoiceProps, - IInvoiceService, - Invoice, - InvoiceNumber, - InvoiceSerie, - InvoiceStatus, -} from "@contexts/invoices/domain"; -import { Result } from "core/common/helpers"; -import { ITransactionManager } from "core/common/infrastructure/database"; -import { logger } from "core/common/infrastructure/logger"; -import { ICreateInvoiceRequestDTO } from "../presentation/dto"; - -export class CreateInvoiceUseCase { - constructor( - private readonly invoiceService: IInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute( - invoiceID: UniqueID, - dto: ICreateInvoiceRequestDTO - ): Promise> { - return this.transactionManager.complete(async (transaction) => { - try { - const validOrErrors = this.validateInvoiceData(dto); - if (validOrErrors.isFailure) { - return Result.fail(validOrErrors.error); - } - - const data = validOrErrors.data; - - // Update invoice with dto - return await this.invoiceService.createInvoice(invoiceID, data, transaction); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); - } - }); - } - - private validateInvoiceData(dto: ICreateInvoiceRequestDTO): Result { - const errors: Error[] = []; - - const invoiceNumerOrError = InvoiceNumber.create(dto.invoice_number); - const invoiceSeriesOrError = InvoiceSerie.create(dto.invoice_series); - const issueDateOrError = UtcDate.create(dto.issue_date); - const operationDateOrError = UtcDate.create(dto.operation_date); - - const result = Result.combine([ - invoiceNumerOrError, - invoiceSeriesOrError, - issueDateOrError, - operationDateOrError, - ]); - - if (result.isFailure) { - return Result.fail(result.error); - } - - const validatedData: IInvoiceProps = { - status: InvoiceStatus.createDraft(), - invoiceNumber: invoiceNumerOrError.data, - invoiceSeries: invoiceSeriesOrError.data, - issueDate: issueDateOrError.data, - operationDate: operationDateOrError.data, - invoiceCurrency: dto.currency_code, - }; - - /*if (errors.length > 0) { - const message = errors.map((err) => err.message).toString(); - return Result.fail(new Error(message)); - }*/ - return Result.ok(validatedData); - - /*let invoice_status = InvoiceStatus.create(dto.status).object; - if (invoice_status.isEmpty()) { - invoice_status = InvoiceStatus.createDraft(); - } - - let invoice_series = InvoiceSeries.create(dto.invoice_series).object; - if (invoice_series.isEmpty()) { - invoice_series = InvoiceSeries.create(dto.invoice_series).object; - } - - let issue_date = InvoiceDate.create(dto.issue_date).object; - if (issue_date.isEmpty()) { - issue_date = InvoiceDate.createCurrentDate().object; - } - - let operation_date = InvoiceDate.create(dto.operation_date).object; - if (operation_date.isEmpty()) { - operation_date = InvoiceDate.createCurrentDate().object; - } - - let invoiceCurrency = Currency.createFromCode(dto.currency).object; - - if (invoiceCurrency.isEmpty()) { - invoiceCurrency = Currency.createDefaultCode().object; - } - - let invoiceLanguage = Language.createFromCode(dto.language_code).object; - - if (invoiceLanguage.isEmpty()) { - invoiceLanguage = Language.createDefaultCode().object; - } - - const items = new Collection( - dto.items?.map( - (item) => - InvoiceSimpleItem.create({ - description: Description.create(item.description).object, - quantity: Quantity.create(item.quantity).object, - unitPrice: UnitPrice.create({ - amount: item.unit_price.amount, - currencyCode: item.unit_price.currency, - precision: item.unit_price.precision, - }).object, - }).object - ) - ); - - if (!invoice_status.isDraft()) { - throw Error("Error al crear una factura que no es borrador"); - } - - return DraftInvoice.create( - { - invoiceSeries: invoice_series, - issueDate: issue_date, - operationDate: operation_date, - invoiceCurrency, - language: invoiceLanguage, - invoiceNumber: InvoiceNumber.create(undefined).object, - //notes: Note.create(invoiceDTO.notes).object, - - //senderId: UniqueID.create(null).object, - recipient, - - items, - }, - invoiceId - );*/ - } -} diff --git a/modules.bak/invoices/src/server/application/delete-invoice.use-case.ts b/modules.bak/invoices/src/server/application/delete-invoice.use-case.ts deleted file mode 100644 index 40988859..00000000 --- a/modules.bak/invoices/src/server/application/delete-invoice.use-case.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { ITransactionManager } from "core/common/infrastructure/database"; -import { logger } from "core/common/infrastructure/logger"; -import { IInvoiceService, Invoice } from "../domain"; - -export class DeleteInvoiceUseCase { - constructor( - private readonly invoiceService: IInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute(invoiceID: UniqueID): Promise> { - return this.transactionManager.complete(async (transaction) => { - try { - return await this.invoiceService.deleteInvoiceById(invoiceID, transaction); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); - } - }); - } -} diff --git a/modules.bak/invoices/src/server/application/get-invoice.use-case.ts b/modules.bak/invoices/src/server/application/get-invoice.use-case.ts deleted file mode 100644 index a396d4e2..00000000 --- a/modules.bak/invoices/src/server/application/get-invoice.use-case.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { ITransactionManager } from "core/common/infrastructure/database"; -import { logger } from "core/common/infrastructure/logger"; -import { IInvoiceService, Invoice } from "../domain"; - -export class GetInvoiceUseCase { - constructor( - private readonly invoiceService: IInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute(invoiceID: UniqueID): Promise> { - return this.transactionManager.complete(async (transaction) => { - try { - return await this.invoiceService.findInvoiceById(invoiceID, transaction); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); - } - }); - } -} diff --git a/modules.bak/invoices/src/server/application/index.ts b/modules.bak/invoices/src/server/application/index.ts deleted file mode 100644 index 83e308e7..00000000 --- a/modules.bak/invoices/src/server/application/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./create-invoice.use-case"; -export * from "./delete-invoice.use-case"; -export * from "./get-invoice.use-case"; -export * from "./list-invoices.use-case"; -export * from "./update-invoice.use-case"; diff --git a/modules.bak/invoices/src/server/application/list-invoices.use-case.ts b/modules.bak/invoices/src/server/application/list-invoices.use-case.ts deleted file mode 100644 index 66a16dfa..00000000 --- a/modules.bak/invoices/src/server/application/list-invoices.use-case.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Collection, Result } from "core/common/helpers"; -import { ITransactionManager } from "core/common/infrastructure/database"; -import { logger } from "core/common/infrastructure/logger"; -import { IInvoiceService, Invoice } from "../domain"; - -export class ListInvoicesUseCase { - constructor( - private readonly invoiceService: IInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute(): Promise, Error>> { - return this.transactionManager.complete(async (transaction) => { - try { - return await this.invoiceService.findInvoices(transaction); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); - } - }); - } -} diff --git a/modules.bak/invoices/src/server/application/services/index.ts b/modules.bak/invoices/src/server/application/services/index.ts deleted file mode 100644 index b79a7a12..00000000 --- a/modules.bak/invoices/src/server/application/services/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./participantAddressFinder"; -export * from "./participantFinder"; diff --git a/modules.bak/invoices/src/server/application/services/participantAddressFinder.ts b/modules.bak/invoices/src/server/application/services/participantAddressFinder.ts deleted file mode 100644 index 7a85cfaf..00000000 --- a/modules.bak/invoices/src/server/application/services/participantAddressFinder.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - ApplicationServiceError, - IApplicationServiceError, -} from "@/contexts/common/application/services/ApplicationServiceError"; -import { IAdapter, RepositoryBuilder } from "@/contexts/common/domain"; -import { Result, UniqueID } from "@shared/contexts"; -import { NullOr } from "@shared/utilities"; -import { - IInvoiceParticipantAddress, - IInvoiceParticipantAddressRepository, -} from "../../domain"; - -export const participantAddressFinder = async ( - addressId: UniqueID, - adapter: IAdapter, - repository: RepositoryBuilder, -) => { - if (addressId.isNull()) { - return Result.fail( - ApplicationServiceError.create( - ApplicationServiceError.INVALID_REQUEST_PARAM, - `Participant address ID required`, - ), - ); - } - - const transaction = adapter.startTransaction(); - let address: NullOr = null; - - try { - await transaction.complete(async (t) => { - address = await repository({ transaction: t }).getById(addressId); - }); - - if (address === null) { - return Result.fail( - ApplicationServiceError.create( - ApplicationServiceError.NOT_FOUND_ERROR, - "", - { - id: addressId.toString(), - entity: "participant address", - }, - ), - ); - } - - return Result.ok(address); - } catch (error: unknown) { - const _error = error as Error; - - if (repository().isRepositoryError(_error)) { - return Result.fail( - ApplicationServiceError.create( - ApplicationServiceError.REPOSITORY_ERROR, - _error.message, - _error, - ), - ); - } - - return Result.fail( - ApplicationServiceError.create( - ApplicationServiceError.UNEXCEPTED_ERROR, - _error.message, - _error, - ), - ); - } -}; diff --git a/modules.bak/invoices/src/server/application/services/participantFinder.ts b/modules.bak/invoices/src/server/application/services/participantFinder.ts deleted file mode 100644 index b73ad1c2..00000000 --- a/modules.bak/invoices/src/server/application/services/participantFinder.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IAdapter, RepositoryBuilder } from "@/contexts/common/domain"; -import { UniqueID } from "@shared/contexts"; -import { IInvoiceParticipantRepository } from "../../domain"; -import { InvoiceCustomer } from "../../domain/entities/invoice-customer/invoice-customer"; - -export const participantFinder = async ( - participantId: UniqueID, - adapter: IAdapter, - repository: RepositoryBuilder -): Promise => { - if (!participantId || (participantId && participantId.isNull())) { - return Promise.resolve(undefined); - } - - const participant = await adapter - .startTransaction() - .complete((t) => repository({ transaction: t }).getById(participantId)); - - return Promise.resolve(participant ? participant : undefined); -}; diff --git a/modules.bak/invoices/src/server/application/update-invoice.use-case.ts b/modules.bak/invoices/src/server/application/update-invoice.use-case.ts deleted file mode 100644 index 87ac3306..00000000 --- a/modules.bak/invoices/src/server/application/update-invoice.use-case.ts +++ /dev/null @@ -1,398 +0,0 @@ -import { UniqueID } from "core/common/domain"; - -import { Result } from "core/common/helpers"; -import { ITransactionManager } from "core/common/infrastructure/database"; -import { logger } from "core/common/infrastructure/logger"; -import { IUpdateInvoiceRequestDTO } from "../presentation/dto"; - -export class CreateInvoiceUseCase { - constructor( - private readonly invoiceService: IInvoiceService, - private readonly transactionManager: ITransactionManager - ) {} - - public execute( - invoiceID: UniqueID, - dto: Partial - ): Promise> { - return this.transactionManager.complete(async (transaction) => { - try { - const validOrErrors = this.validateInvoiceData(dto); - if (validOrErrors.isFailure) { - return Result.fail(validOrErrors.error); - } - - const data = validOrErrors.data; - - // Update invoice with dto - return await this.invoiceService.updateInvoiceById(invoiceID, data, transaction); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); - } - }); - } - - private validateInvoiceData( - dto: Partial - ): Result, Error> { - const errors: Error[] = []; - const validatedData: Partial = {}; - - // Create invoice - let invoice_status = InvoiceStatus.create(invoiceDTO.status).object; - if (invoice_status.isEmpty()) { - invoice_status = InvoiceStatus.createDraft(); - } - - let invoice_series = InvoiceSeries.create(invoiceDTO.invoice_series).object; - if (invoice_series.isEmpty()) { - invoice_series = InvoiceSeries.create(invoiceDTO.invoice_series).object; - } - - let issue_date = InvoiceDate.create(invoiceDTO.issue_date).object; - if (issue_date.isEmpty()) { - issue_date = InvoiceDate.createCurrentDate().object; - } - - let operation_date = InvoiceDate.create(invoiceDTO.operation_date).object; - if (operation_date.isEmpty()) { - operation_date = InvoiceDate.createCurrentDate().object; - } - - let invoiceCurrency = Currency.createFromCode(invoiceDTO.currency).object; - - if (invoiceCurrency.isEmpty()) { - invoiceCurrency = Currency.createDefaultCode().object; - } - - let invoiceLanguage = Language.createFromCode(invoiceDTO.language_code).object; - - if (invoiceLanguage.isEmpty()) { - invoiceLanguage = Language.createDefaultCode().object; - } - - const items = new Collection( - invoiceDTO.items?.map( - (item) => - InvoiceSimpleItem.create({ - description: Description.create(item.description).object, - quantity: Quantity.create(item.quantity).object, - unitPrice: UnitPrice.create({ - amount: item.unit_price.amount, - currencyCode: item.unit_price.currency, - precision: item.unit_price.precision, - }).object, - }).object - ) - ); - - if (!invoice_status.isDraft()) { - throw Error("Error al crear una factura que no es borrador"); - } - - return DraftInvoice.create( - { - invoiceSeries: invoice_series, - issueDate: issue_date, - operationDate: operation_date, - invoiceCurrency, - language: invoiceLanguage, - invoiceNumber: InvoiceNumber.create(undefined).object, - //notes: Note.create(invoiceDTO.notes).object, - - //senderId: UniqueID.create(null).object, - recipient, - - items, - }, - invoiceId - ); - } -} - -export type UpdateInvoiceResponseOrError = - | Result // Misc errors (value objects) - | Result; // Success! - -export class UpdateInvoiceUseCase2 - implements - IUseCase<{ id: UniqueID; data: IUpdateInvoice_DTO }, Promise> -{ - private _context: IInvoicingContext; - private _adapter: ISequelizeAdapter; - private _repositoryManager: IRepositoryManager; - - constructor(context: IInvoicingContext) { - this._context = context; - this._adapter = context.adapter; - this._repositoryManager = context.repositoryManager; - } - - private getRepository(name: string) { - return this._repositoryManager.getRepository(name); - } - - private handleValidationFailure( - validationError: Error, - message?: string - ): Result { - return Result.fail( - UseCaseError.create( - UseCaseError.INVALID_INPUT_DATA, - message ? message : validationError.message, - validationError - ) - ); - } - - async execute(request: { - id: UniqueID; - data: IUpdateInvoice_DTO; - }): Promise { - const { id, data: invoiceDTO } = request; - - // Validaciones - const invoiceDTOOrError = ensureUpdateInvoice_DTOIsValid(invoiceDTO); - if (invoiceDTOOrError.isFailure) { - return this.handleValidationFailure(invoiceDTOOrError.error); - } - - const transaction = this._adapter.startTransaction(); - - const invoiceRepoBuilder = this.getRepository("Invoice"); - - let invoice: Invoice | null = null; - - try { - await transaction.complete(async (t) => { - invoice = await invoiceRepoBuilder({ transaction: t }).getById(id); - }); - - if (invoice === null) { - return Result.fail( - UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, `Invoice not found`, { - id: request.id.toString(), - entity: "invoice", - }) - ); - } - - return Result.ok(invoice); - } catch (error: unknown) { - const _error = error as Error; - if (invoiceRepoBuilder().isRepositoryError(_error)) { - return this.handleRepositoryError(error as BaseError, invoiceRepoBuilder()); - } else { - return this.handleUnexceptedError(error); - } - } - - // Recipient validations - /*const recipientIdOrError = ensureParticipantIdIsValid( - invoiceDTO?.recipient?.id, - ); - if (recipientIdOrError.isFailure) { - return this.handleValidationFailure( - recipientIdOrError.error, - "Recipient ID not valid", - ); - } - const recipientId = recipientIdOrError.object; - - const recipientBillingIdOrError = ensureParticipantAddressIdIsValid( - invoiceDTO?.recipient?.billing_address_id, - ); - if (recipientBillingIdOrError.isFailure) { - return this.handleValidationFailure( - recipientBillingIdOrError.error, - "Recipient billing address ID not valid", - ); - } - const recipientBillingId = recipientBillingIdOrError.object; - - const recipientShippingIdOrError = ensureParticipantAddressIdIsValid( - invoiceDTO?.recipient?.shipping_address_id, - ); - if (recipientShippingIdOrError.isFailure) { - return this.handleValidationFailure( - recipientShippingIdOrError.error, - "Recipient shipping address ID not valid", - ); - } - const recipientShippingId = recipientShippingIdOrError.object; - - const recipientContact = await this.findContact( - recipientId, - recipientBillingId, - recipientShippingId, - ); - - if (!recipientContact) { - return this.handleValidationFailure( - new Error(`Recipient with ID ${recipientId.toString()} does not exist`), - ); - } - - // Crear invoice - const invoiceOrError = await this.tryUpdateInvoiceInstance( - invoiceDTO, - invoiceIdOrError.object, - //senderId, - //senderBillingId, - //senderShippingId, - recipientContact, - ); - - if (invoiceOrError.isFailure) { - const { error: domainError } = invoiceOrError; - let errorCode = ""; - let message = ""; - - switch (domainError.code) { - case Invoice.ERROR_CUSTOMER_WITHOUT_NAME: - errorCode = UseCaseError.INVALID_INPUT_DATA; - message = - "El cliente debe ser una compañía o tener nombre y apellidos."; - break; - - default: - errorCode = UseCaseError.UNEXCEPTED_ERROR; - message = ""; - break; - } - - return Result.fail( - UseCaseError.create(errorCode, message, domainError), - ); - } - - return this.saveInvoice(invoiceOrError.object); - */ - } - - private async tryUpdateInvoiceInstance(invoiceDTO, invoiceId, recipient) { - // Create invoice - let invoice_status = InvoiceStatus.create(invoiceDTO.status).object; - if (invoice_status.isEmpty()) { - invoice_status = InvoiceStatus.createDraft(); - } - - let invoice_series = InvoiceSeries.create(invoiceDTO.invoice_series).object; - if (invoice_series.isEmpty()) { - invoice_series = InvoiceSeries.create(invoiceDTO.invoice_series).object; - } - - let issue_date = InvoiceDate.create(invoiceDTO.issue_date).object; - if (issue_date.isEmpty()) { - issue_date = InvoiceDate.createCurrentDate().object; - } - - let operation_date = InvoiceDate.create(invoiceDTO.operation_date).object; - if (operation_date.isEmpty()) { - operation_date = InvoiceDate.createCurrentDate().object; - } - - let invoiceCurrency = Currency.createFromCode(invoiceDTO.currency).object; - - if (invoiceCurrency.isEmpty()) { - invoiceCurrency = Currency.createDefaultCode().object; - } - - let invoiceLanguage = Language.createFromCode(invoiceDTO.language_code).object; - - if (invoiceLanguage.isEmpty()) { - invoiceLanguage = Language.createDefaultCode().object; - } - - const items = new Collection( - invoiceDTO.items?.map( - (item) => - InvoiceSimpleItem.create({ - description: Description.create(item.description).object, - quantity: Quantity.create(item.quantity).object, - unitPrice: UnitPrice.create({ - amount: item.unit_price.amount, - currencyCode: item.unit_price.currency, - precision: item.unit_price.precision, - }).object, - }).object - ) - ); - - if (!invoice_status.isDraft()) { - throw Error("Error al crear una factura que no es borrador"); - } - - return DraftInvoice.create( - { - invoiceSeries: invoice_series, - issueDate: issue_date, - operationDate: operation_date, - invoiceCurrency, - language: invoiceLanguage, - invoiceNumber: InvoiceNumber.create(undefined).object, - //notes: Note.create(invoiceDTO.notes).object, - - //senderId: UniqueID.create(null).object, - recipient, - - items, - }, - invoiceId - ); - } - - private async findContact( - contactId: UniqueID, - billingAddressId: UniqueID, - shippingAddressId: UniqueID - ) { - const contactRepoBuilder = this.getRepository("Contact"); - - const contact = await contactRepoBuilder().getById2( - contactId, - billingAddressId, - shippingAddressId - ); - - return contact; - } - - private async saveInvoice(invoice: DraftInvoice) { - const transaction = this._adapter.startTransaction(); - const invoiceRepoBuilder = this.getRepository("Invoice"); - - try { - await transaction.complete(async (t) => { - const invoiceRepo = invoiceRepoBuilder({ transaction: t }); - await invoiceRepo.save(invoice); - }); - - return Result.ok(invoice); - } catch (error: unknown) { - const _error = error as Error; - if (invoiceRepoBuilder().isRepositoryError(_error)) { - return this.handleRepositoryError(error as BaseError, invoiceRepoBuilder()); - } else { - return this.handleUnexceptedError(error); - } - } - } - - private handleUnexceptedError(error): Result { - return Result.fail( - UseCaseError.create(UseCaseError.UNEXCEPTED_ERROR, error.message, error) - ); - } - - private handleRepositoryError( - error: BaseError, - repository: IInvoiceRepository - ): Result { - const { message, details } = repository.handleRepositoryError(error); - return Result.fail( - UseCaseError.create(UseCaseError.REPOSITORY_ERROR, message, details) - ); - } -} diff --git a/modules.bak/invoices/src/server/domain/aggregates/index.ts b/modules.bak/invoices/src/server/domain/aggregates/index.ts deleted file mode 100644 index c759eb69..00000000 --- a/modules.bak/invoices/src/server/domain/aggregates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./invoice"; diff --git a/modules.bak/invoices/src/server/domain/aggregates/invoice.ts b/modules.bak/invoices/src/server/domain/aggregates/invoice.ts deleted file mode 100644 index e5be6b14..00000000 --- a/modules.bak/invoices/src/server/domain/aggregates/invoice.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { AggregateRoot, MoneyValue, UniqueID, UtcDate } from "core/common/domain"; -import { Collection, Result } from "core/common/helpers"; -import { InvoiceCustomer, InvoiceItem, InvoiceItems } from "../entities"; -import { InvoiceNumber, InvoiceSerie, InvoiceStatus } from "../value-objects"; - -export interface IInvoiceProps { - invoiceNumber: InvoiceNumber; - invoiceSeries: InvoiceSerie; - - status: InvoiceStatus; - - issueDate: UtcDate; - operationDate: UtcDate; - - //dueDate: UtcDate; // ? --> depende de la forma de pago - - //tax: Tax; // ? --> detalles? - invoiceCurrency: string; - - //language: Language; - - //purchareOrderNumber: string; - //notes: Note; - - //senderId: UniqueID; - - //paymentInstructions: Note; - //paymentTerms: string; - - customer?: InvoiceCustomer; - items?: InvoiceItems; -} - -export interface IInvoice { - id: UniqueID; - invoiceNumber: InvoiceNumber; - invoiceSeries: InvoiceSerie; - - status: InvoiceStatus; - - issueDate: UtcDate; - operationDate: UtcDate; - - //senderId: UniqueID; - - customer?: InvoiceCustomer; - - //dueDate - - //tax: Tax; - //language: Language; - invoiceCurrency: string; - - //purchareOrderNumber: string; - //notes: Note; - - //paymentInstructions: Note; - //paymentTerms: string; - - items: InvoiceItems; - - calculateSubtotal: () => MoneyValue; - calculateTaxTotal: () => MoneyValue; - calculateTotal: () => MoneyValue; -} - -export class Invoice extends AggregateRoot implements IInvoice { - private _items!: Collection; - //protected _status: InvoiceStatus; - - protected constructor(props: IInvoiceProps, id?: UniqueID) { - super(props, id); - - this._items = props.items || InvoiceItems.create(); - } - - static create(props: IInvoiceProps, id?: UniqueID): Result { - const invoice = new Invoice(props, id); - - // Reglas de negocio / validaciones - // ... - // ... - - // 🔹 Disparar evento de dominio "InvoiceAuthenticatedEvent" - //const { invoice } = props; - //user.addDomainEvent(new InvoiceAuthenticatedEvent(id, invoice.toString())); - - return Result.ok(invoice); - } - - get invoiceNumber() { - return this.props.invoiceNumber; - } - - get invoiceSeries() { - return this.props.invoiceSeries; - } - - get issueDate() { - return this.props.issueDate; - } - - /*get senderId(): UniqueID { - return this.props.senderId; - }*/ - - get customer(): InvoiceCustomer | undefined { - return this.props.customer; - } - - get operationDate() { - return this.props.operationDate; - } - - /*get language() { - return this.props.language; - }*/ - - get dueDate() { - return undefined; - } - - get tax() { - return undefined; - } - - get status() { - return this.props.status; - } - - get items() { - return this._items; - } - - /*get purchareOrderNumber() { - return this.props.purchareOrderNumber; - } - - get paymentInstructions() { - return this.props.paymentInstructions; - } - - get paymentTerms() { - return this.props.paymentTerms; - } - - get billTo() { - return this.props.billTo; - } - - get shipTo() { - return this.props.shipTo; - }*/ - - get invoiceCurrency() { - return this.props.invoiceCurrency; - } - - /*get notes() { - return this.props.notes; - }*/ - - // Method to get the complete list of line items - /*get lineItems(): InvoiceLineItem[] { - return this._lineItems; - } - - addLineItem(lineItem: InvoiceLineItem, position?: number): void { - if (position === undefined) { - this._lineItems.push(lineItem); - } else { - this._lineItems.splice(position, 0, lineItem); - } - }*/ - - calculateSubtotal(): MoneyValue { - const invoiceSubtotal = MoneyValue.create({ - amount: 0, - currency_code: this.props.invoiceCurrency, - scale: 2, - }).data; - - return this._items.getAll().reduce((subtotal, item) => { - return subtotal.add(item.calculateTotal()); - }, invoiceSubtotal); - } - - // Method to calculate the total tax in the invoice - calculateTaxTotal(): MoneyValue { - const taxTotal = MoneyValue.create({ - amount: 0, - currency_code: this.props.invoiceCurrency, - scale: 2, - }).data; - - return taxTotal; - } - - // Method to calculate the total invoice amount, including taxes - calculateTotal(): MoneyValue { - return this.calculateSubtotal().add(this.calculateTaxTotal()); - } -} diff --git a/modules.bak/invoices/src/server/domain/entities/index.ts b/modules.bak/invoices/src/server/domain/entities/index.ts deleted file mode 100644 index 4c02277f..00000000 --- a/modules.bak/invoices/src/server/domain/entities/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./invoice-customer"; -export * from "./invoice-items"; diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-customer/index.ts b/modules.bak/invoices/src/server/domain/entities/invoice-customer/index.ts deleted file mode 100644 index 1f5a7b22..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-customer/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./invoice-address"; -export * from "./invoice-customer"; diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-address.ts b/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-address.ts deleted file mode 100644 index 2d3ebbae..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-address.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { EmailAddress, Name, PostalAddress, ValueObject } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { PhoneNumber } from "libphonenumber-js"; -import { InvoiceAddressType } from "../../value-objects"; - -export interface IInvoiceAddressProps { - type: InvoiceAddressType; - title: Name; - address: PostalAddress; - email: EmailAddress; - phone: PhoneNumber; -} - -export interface IInvoiceAddress { - type: InvoiceAddressType; - title: Name; - address: PostalAddress; - email: EmailAddress; - phone: PhoneNumber; -} - -export class InvoiceAddress extends ValueObject implements IInvoiceAddress { - public static create(props: IInvoiceAddressProps) { - return Result.ok(new this(props)); - } - - public static createShippingAddress(props: IInvoiceAddressProps) { - return Result.ok( - new this({ - ...props, - type: InvoiceAddressType.create("shipping").data, - }) - ); - } - - public static createBillingAddress(props: IInvoiceAddressProps) { - return Result.ok( - new this({ - ...props, - type: InvoiceAddressType.create("billing").data, - }) - ); - } - - get title(): Name { - return this.props.title; - } - - get address(): PostalAddress { - return this.props.address; - } - - get email(): EmailAddress { - return this.props.email; - } - - get phone(): PhoneNumber { - return this.props.phone; - } - - get type(): InvoiceAddressType { - return this.props.type; - } - - getValue(): IInvoiceAddressProps { - return this.props; - } - - toPrimitive() { - return { - type: this.type.toString(), - title: this.title.toString(), - address: this.address.toString(), - email: this.email.toString(), - phone: this.phone.toString(), - }; - } -} diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-customer.ts b/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-customer.ts deleted file mode 100644 index a9eb085c..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-customer/invoice-customer.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { DomainEntity, Name, TINNumber, UniqueID } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { InvoiceAddress } from "./invoice-address"; - -export interface IInvoiceCustomerProps { - tin: TINNumber; - companyName: Name; - firstName: Name; - lastName: Name; - - billingAddress?: InvoiceAddress; - shippingAddress?: InvoiceAddress; -} - -export interface IInvoiceCustomer { - id: UniqueID; - tin: TINNumber; - companyName: Name; - firstName: Name; - lastName: Name; - - billingAddress?: InvoiceAddress; - shippingAddress?: InvoiceAddress; -} - -export class InvoiceCustomer - extends DomainEntity - implements IInvoiceCustomer -{ - public static create( - props: IInvoiceCustomerProps, - id?: UniqueID - ): Result { - const participant = new InvoiceCustomer(props, id); - return Result.ok(participant); - } - - get tin(): TINNumber { - return this.props.tin; - } - - get companyName(): Name { - return this.props.companyName; - } - - get firstName(): Name { - return this.props.firstName; - } - - get lastName(): Name { - return this.props.lastName; - } - - get billingAddress() { - return this.props.billingAddress; - } - - get shippingAddress() { - return this.props.shippingAddress; - } -} diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-items/index.ts b/modules.bak/invoices/src/server/domain/entities/invoice-items/index.ts deleted file mode 100644 index f95bd889..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-items/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./invoice-item"; -export * from "./invoice-items"; diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.test.ts b/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.test.ts deleted file mode 100644 index 965426ec..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { MoneyValue, Percentage, Quantity } from "core/common/domain"; -import { InvoiceItemDescription } from "../../value-objects"; -import { InvoiceItem } from "./invoice-item"; - -describe("InvoiceItem", () => { - it("debería calcular correctamente el subtotal (unitPrice * quantity)", () => { - const props = { - description: InvoiceItemDescription.create("Producto A"), - quantity: Quantity.create({ amount: 200, scale: 2 }), - unitPrice: MoneyValue.create(50), - discount: Percentage.create(0), - }; - - const result = InvoiceItem.create(props); - - expect(result.isOk()).toBe(true); - const invoiceItem = result.unwrap(); - expect(invoiceItem.subtotalPrice.value).toBe(100); // 50 * 2 - }); - - it("debería calcular correctamente el total con descuento", () => { - const props = { - description: new InvoiceItemDescription("Producto B"), - quantity: new Quantity(3), - unitPrice: new MoneyValue(30), - discount: new Percentage(10), // 10% - }; - - const result = InvoiceItem.create(props); - - expect(result.isOk()).toBe(true); - const invoiceItem = result.unwrap(); - expect(invoiceItem.totalPrice.value).toBe(81); // (30 * 3) - 10% de (30 * 3) - }); - - it("debería devolver los valores correctos de las propiedades", () => { - const props = { - description: new InvoiceItemDescription("Producto C"), - quantity: new Quantity(1), - unitPrice: new MoneyValue(100), - discount: new Percentage(5), - }; - - const result = InvoiceItem.create(props); - - expect(result.isOk()).toBe(true); - const invoiceItem = result.unwrap(); - expect(invoiceItem.description.value).toBe("Producto C"); - expect(invoiceItem.quantity.value).toBe(1); - expect(invoiceItem.unitPrice.value).toBe(100); - expect(invoiceItem.discount.value).toBe(5); - }); - - it("debería manejar correctamente un descuento del 0%", () => { - const props = { - description: new InvoiceItemDescription("Producto D"), - quantity: new Quantity(4), - unitPrice: new MoneyValue(25), - discount: new Percentage(0), - }; - - const result = InvoiceItem.create(props); - - expect(result.isOk()).toBe(true); - const invoiceItem = result.unwrap(); - expect(invoiceItem.totalPrice.value).toBe(100); // 25 * 4 - }); - - it("debería manejar correctamente un descuento del 100%", () => { - const props = { - description: new InvoiceItemDescription("Producto E"), - quantity: new Quantity(2), - unitPrice: new MoneyValue(50), - discount: new Percentage(100), - }; - - const result = InvoiceItem.create(props); - - expect(result.isOk()).toBe(true); - const invoiceItem = result.unwrap(); - expect(invoiceItem.totalPrice.value).toBe(0); // (50 * 2) - 100% de (50 * 2) - }); -}); diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.ts b/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.ts deleted file mode 100644 index 268a3c3c..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-item.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { DomainEntity, MoneyValue, Percentage, Quantity, UniqueID } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { InvoiceItemDescription } from "../../value-objects"; - -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 - discount: Percentage; // % descuento - //totalPrice?: MoneyValue; -} - -export interface IInvoiceItem { - id: UniqueID; - description: InvoiceItemDescription; - quantity: Quantity; - unitPrice: MoneyValue; - subtotalPrice: MoneyValue; - discount: Percentage; - totalPrice: MoneyValue; -} - -export class InvoiceItem extends DomainEntity implements IInvoiceItem { - private _subtotalPrice!: MoneyValue; - private _totalPrice!: MoneyValue; - - 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 { - return this.props.description; - } - - get quantity(): Quantity { - return this.props.quantity; - } - - get unitPrice(): MoneyValue { - return this.props.unitPrice; - } - - get subtotalPrice(): MoneyValue { - if (!this._subtotalPrice) { - this._subtotalPrice = this.calculateSubtotal(); - } - return this._subtotalPrice; - } - - get discount(): Percentage { - return this.props.discount; - } - - get totalPrice(): MoneyValue { - if (!this._totalPrice) { - this._totalPrice = this.calculateTotal(); - } - return this._totalPrice; - } - - getValue() { - return this.props; - } - - toPrimitive() { - return { - description: this.description.toPrimitive(), - quantity: this.quantity.toPrimitive(), - unit_price: this.unitPrice.toPrimitive(), - subtotal_price: this.subtotalPrice.toPrimitive(), - discount: this.discount.toPrimitive(), - total_price: this.totalPrice.toPrimitive(), - }; - } - - calculateSubtotal(): MoneyValue { - return this.unitPrice.multiply(this.quantity.toNumber()); // Precio unitario * Cantidad - } - - calculateTotal(): MoneyValue { - return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber())); - } -} diff --git a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-items.ts b/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-items.ts deleted file mode 100644 index 5a0c749b..00000000 --- a/modules.bak/invoices/src/server/domain/entities/invoice-items/invoice-items.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Collection } from "core/common/helpers"; -import { InvoiceItem } from "./invoice-item"; - -export class InvoiceItems extends Collection { - public static create(items?: InvoiceItem[]): InvoiceItems { - return new InvoiceItems(items); - } -} diff --git a/modules.bak/invoices/src/server/domain/index.ts b/modules.bak/invoices/src/server/domain/index.ts deleted file mode 100644 index 2c5c423d..00000000 --- a/modules.bak/invoices/src/server/domain/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./aggregates"; -export * from "./entities"; -export * from "./repositories"; -export * from "./services"; -export * from "./value-objects"; diff --git a/modules.bak/invoices/src/server/domain/repositories/index.ts b/modules.bak/invoices/src/server/domain/repositories/index.ts deleted file mode 100644 index 7a8b94a0..00000000 --- a/modules.bak/invoices/src/server/domain/repositories/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./invoice-repository.interface"; diff --git a/modules.bak/invoices/src/server/domain/repositories/invoice-repository.interface.ts b/modules.bak/invoices/src/server/domain/repositories/invoice-repository.interface.ts deleted file mode 100644 index e448078f..00000000 --- a/modules.bak/invoices/src/server/domain/repositories/invoice-repository.interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { Collection, Result } from "core/common/helpers"; -import { Invoice } from "../aggregates"; - -export interface IInvoiceRepository { - findAll(transaction?: any): Promise, Error>>; - getById(id: UniqueID, transaction?: any): Promise>; - deleteByIdInCompany(id: UniqueID, transaction?: any): Promise>; - - create(invoice: Invoice, transaction?: any): Promise; - update(invoice: Invoice, transaction?: any): Promise; -} diff --git a/modules.bak/invoices/src/server/domain/services/index.ts b/modules.bak/invoices/src/server/domain/services/index.ts deleted file mode 100644 index 73a5d9ba..00000000 --- a/modules.bak/invoices/src/server/domain/services/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./invoice-service.interface"; -export * from "./invoice.service"; diff --git a/modules.bak/invoices/src/server/domain/services/invoice-service.interface.ts b/modules.bak/invoices/src/server/domain/services/invoice-service.interface.ts deleted file mode 100644 index 4c42d8dd..00000000 --- a/modules.bak/invoices/src/server/domain/services/invoice-service.interface.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { Collection, Result } from "core/common/helpers"; -import { IInvoiceProps, Invoice } from "../aggregates"; - -export interface IInvoiceService { - findInvoices(transaction?: any): Promise, Error>>; - findInvoiceById(invoiceId: UniqueID, transaction?: any): Promise>; - - updateInvoiceById( - invoiceId: UniqueID, - data: Partial, - transaction?: any - ): Promise>; - - createInvoice( - invoiceId: UniqueID, - data: IInvoiceProps, - transaction?: any - ): Promise>; - - deleteInvoiceById(invoiceId: UniqueID, transaction?: any): Promise>; -} diff --git a/modules.bak/invoices/src/server/domain/services/invoice.service.ts b/modules.bak/invoices/src/server/domain/services/invoice.service.ts deleted file mode 100644 index 306d963a..00000000 --- a/modules.bak/invoices/src/server/domain/services/invoice.service.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { Collection, Result } from "core/common/helpers"; -import { Transaction } from "sequelize"; -import { IInvoiceProps, Invoice } from "../aggregates"; -import { IInvoiceRepository } from "../repositories"; -import { IInvoiceService } from "./invoice-service.interface"; - -export class InvoiceService implements IInvoiceService { - constructor(private readonly repo: IInvoiceRepository) {} - deleteInvoiceById(invoiceId: UniqueID, transaction?: any): Promise> { - throw new Error("Method not implemented."); - } - - async findInvoices(transaction?: Transaction): Promise, Error>> { - const invoicesOrError = await this.repo.findAll(transaction); - if (invoicesOrError.isFailure) { - return Result.fail(invoicesOrError.error); - } - - // Solo devolver usuarios activos - //const allInvoices = invoicesOrError.data.filter((invoice) => invoice.isActive); - //return Result.ok(new Collection(allInvoices)); - - return invoicesOrError; - } - - async findInvoiceById(invoiceId: UniqueID, transaction?: Transaction): Promise> { - return await this.repo.getById(invoiceId, transaction); - } - - async updateInvoiceById( - invoiceId: UniqueID, - data: Partial, - transaction?: Transaction - ): Promise> { - // Verificar si la factura existe - const invoiceOrError = await this.repo.getById(invoiceId, transaction); - if (invoiceOrError.isFailure) { - return Result.fail(new Error("Invoice not found")); - } - - const updatedInvoiceOrError = Invoice.update(invoiceOrError.data, data); - if (updatedInvoiceOrError.isFailure) { - return Result.fail( - new Error(`Error updating invoice: ${updatedInvoiceOrError.error.message}`) - ); - } - - const updateInvoice = updatedInvoiceOrError.data; - - await this.repo.update(updateInvoice, transaction); - return Result.ok(updateInvoice); - } - - async createInvoice( - invoiceId: UniqueID, - data: IInvoiceProps, - transaction?: Transaction - ): Promise> { - // Verificar si la factura existe - const invoiceOrError = await this.repo.getById(invoiceId, transaction); - if (invoiceOrError.isSuccess) { - return Result.fail(new Error("Invoice exists")); - } - - const newInvoiceOrError = Invoice.create(data, invoiceId); - if (newInvoiceOrError.isFailure) { - return Result.fail(new Error(`Error creating invoice: ${newInvoiceOrError.error.message}`)); - } - - const newInvoice = newInvoiceOrError.data; - - await this.repo.create(newInvoice, transaction); - return Result.ok(newInvoice); - } - - async deleteInvoiceByIdInCompnay( - companyId: UniqueID, - invoiceId: UniqueID, - transaction?: Transaction - ): Promise> { - return this.repo.deleteByIdInCompany(companyId, invoiceId, transaction); - } -} diff --git a/modules.bak/invoices/src/server/domain/value-objects/index.ts b/modules.bak/invoices/src/server/domain/value-objects/index.ts deleted file mode 100644 index 4169e9d8..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./invoice-address-type"; -export * from "./invoice-item-description"; -export * from "./invoice-number"; -export * from "./invoice-serie"; -export * from "./invoice-status"; diff --git a/modules.bak/invoices/src/server/domain/value-objects/invoice-address-type.ts b/modules.bak/invoices/src/server/domain/value-objects/invoice-address-type.ts deleted file mode 100644 index 04a0f97b..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/invoice-address-type.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ValueObject } from "core/common/domain"; -import { Result } from "core/common/helpers"; - -interface IInvoiceAddressTypeProps { - value: string; -} - -export enum INVOICE_ADDRESS_TYPE { - SHIPPING = "shipping", - BILLING = "billing", -} - -export class InvoiceAddressType extends ValueObject { - private static readonly ALLOWED_TYPES = ["shipping", "billing"]; - - static create(value: string): Result { - if (!this.ALLOWED_TYPES.includes(value)) { - return Result.fail( - new Error( - `Invalid address type: ${value}. Allowed types are: ${this.ALLOWED_TYPES.join(", ")}` - ) - ); - } - return Result.ok(new InvoiceAddressType({ value })); - } - - getValue(): string { - return this.props.value; - } - - toString(): string { - return this.getValue(); - } - - toPrimitive(): string { - return this.getValue(); - } -} diff --git a/modules.bak/invoices/src/server/domain/value-objects/invoice-item-description.ts b/modules.bak/invoices/src/server/domain/value-objects/invoice-item-description.ts deleted file mode 100644 index a0e3c952..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/invoice-item-description.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ValueObject } from "core/common/domain"; -import { Maybe, Result } from "core/common/helpers"; -import * as z from "zod/v4"; - -interface IInvoiceItemDescriptionProps { - value: string; -} - -export class InvoiceItemDescription extends ValueObject { - private static readonly MAX_LENGTH = 255; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .max(InvoiceItemDescription.MAX_LENGTH, { - message: `Description must be at most ${InvoiceItemDescription.MAX_LENGTH} characters long`, - }); - return schema.safeParse(value); - } - - static create(value: string) { - const valueIsValid = InvoiceItemDescription.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.issues[0].message)); - } - return Result.ok(new InvoiceItemDescription({ value })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return InvoiceItemDescription.create(value).map((value) => Maybe.some(value)); - } - - getValue(): string { - return this.props.value; - } - - toString(): string { - return this.getValue(); - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/modules.bak/invoices/src/server/domain/value-objects/invoice-number.ts b/modules.bak/invoices/src/server/domain/value-objects/invoice-number.ts deleted file mode 100644 index a2337eff..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/invoice-number.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValueObject } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import * as z from "zod/v4"; - -interface IInvoiceNumberProps { - value: string; -} - -export class InvoiceNumber extends ValueObject { - private static readonly MAX_LENGTH = 255; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .max(InvoiceNumber.MAX_LENGTH, { - message: `Name must be at most ${InvoiceNumber.MAX_LENGTH} characters long`, - }); - return schema.safeParse(value); - } - - static create(value: string) { - const valueIsValid = InvoiceNumber.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.issues[0].message)); - } - return Result.ok(new InvoiceNumber({ value })); - } - - getValue(): string { - return this.props.value; - } - - toString(): string { - return this.getValue(); - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/modules.bak/invoices/src/server/domain/value-objects/invoice-serie.ts b/modules.bak/invoices/src/server/domain/value-objects/invoice-serie.ts deleted file mode 100644 index 9b6ab0f2..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/invoice-serie.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ValueObject } from "core/common/domain"; -import { Maybe, Result } from "core/common/helpers"; -import * as z from "zod/v4"; - -interface IInvoiceSerieProps { - value: string; -} - -export class InvoiceSerie extends ValueObject { - private static readonly MAX_LENGTH = 255; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .max(InvoiceSerie.MAX_LENGTH, { - message: `Name must be at most ${InvoiceSerie.MAX_LENGTH} characters long`, - }); - return schema.safeParse(value); - } - - static create(value: string) { - const valueIsValid = InvoiceSerie.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.issues[0].message)); - } - return Result.ok(new InvoiceSerie({ value })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return InvoiceSerie.create(value).map((value) => Maybe.some(value)); - } - - getValue(): string { - return this.props.value; - } - - toString(): string { - return this.getValue(); - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/modules.bak/invoices/src/server/domain/value-objects/invoice-status.ts b/modules.bak/invoices/src/server/domain/value-objects/invoice-status.ts deleted file mode 100644 index 15ad5d43..00000000 --- a/modules.bak/invoices/src/server/domain/value-objects/invoice-status.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { ValueObject } from "core/common/domain"; -import { Result } from "core/common/helpers"; - -interface IInvoiceStatusProps { - value: string; -} - -export enum INVOICE_STATUS { - DRAFT = "draft", - EMITTED = "emitted", - SENT = "sent", - REJECTED = "rejected", -} -export class InvoiceStatus extends ValueObject { - private static readonly ALLOWED_STATUSES = ["draft", "emitted", "sent", "rejected"]; - - private static readonly TRANSITIONS: Record = { - draft: [INVOICE_STATUS.EMITTED], - emitted: [INVOICE_STATUS.SENT, INVOICE_STATUS.REJECTED, INVOICE_STATUS.DRAFT], - sent: [INVOICE_STATUS.REJECTED], - rejected: [], - }; - - static create(value: string): Result { - if (!this.ALLOWED_STATUSES.includes(value)) { - return Result.fail(new Error(`Estado de la factura no válido: ${value}`)); - } - - return Result.ok( - value === "rejected" - ? InvoiceStatus.createRejected() - : value === "sent" - ? InvoiceStatus.createSent() - : value === "emitted" - ? InvoiceStatus.createSent() - : InvoiceStatus.createDraft() - ); - } - - public static createDraft(): InvoiceStatus { - return new InvoiceStatus({ value: INVOICE_STATUS.DRAFT }); - } - - public static createEmitted(): InvoiceStatus { - return new InvoiceStatus({ value: INVOICE_STATUS.EMITTED }); - } - - public static createSent(): InvoiceStatus { - return new InvoiceStatus({ value: INVOICE_STATUS.SENT }); - } - - public static createRejected(): InvoiceStatus { - return new InvoiceStatus({ value: INVOICE_STATUS.REJECTED }); - } - - getValue(): string { - return this.props.value; - } - - toPrimitive() { - return this.getValue(); - } - - canTransitionTo(nextStatus: string): boolean { - return InvoiceStatus.TRANSITIONS[this.props.value].includes(nextStatus); - } - - transitionTo(nextStatus: string): Result { - if (!this.canTransitionTo(nextStatus)) { - return Result.fail( - new Error(`Transición no permitida de ${this.props.value} a ${nextStatus}`) - ); - } - return InvoiceStatus.create(nextStatus); - } - - toString(): string { - return this.getValue(); - } -} diff --git a/modules.bak/invoices/src/server/index.ts b/modules.bak/invoices/src/server/index.ts deleted file mode 100644 index a8e88dc7..00000000 --- a/modules.bak/invoices/src/server/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* import { getService } from "@apps/server/src/core/service-registry"; */ -import { IPackageServer } from "@packages/package"; -import { invoicesRouter } from "./intrastructure"; -import initInvoiceModel from "./intrastructure/sequelize/invoice.model"; - -export const InvoicesPackage: IPackageServer = { - metadata: { - name: "invoices", - version: "1.0.0", - dependencies: ["contacts"], - }, - init(app) { - // const contacts = getService("contacts"); - invoicesRouter(app); - }, - registerDependencies() { - return { - models: [(sequelize) => initInvoiceModel(sequelize)], - services: { - getInvoice: () => {}, - /*...*/ - }, - }; - }, -}; diff --git a/modules.bak/invoices/src/server/intrastructure/Contact.repository.ts b/modules.bak/invoices/src/server/intrastructure/Contact.repository.ts deleted file mode 100644 index 9ccd432a..00000000 --- a/modules.bak/invoices/src/server/intrastructure/Contact.repository.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { - ISequelizeAdapter, - SequelizeRepository, -} from "@/contexts/common/infrastructure/sequelize"; -import { UniqueID } from "@shared/contexts"; -import { Transaction } from "sequelize"; -import { Contact, IContactRepository } from "../domain/Contact"; -import { IContactMapper } from "./mappers/contact.mapper"; - -export class ContactRepository - extends SequelizeRepository - implements IContactRepository -{ - protected mapper: IContactMapper; - - public constructor(props: { - mapper: IContactMapper; - adapter: ISequelizeAdapter; - transaction: Transaction; - }) { - const { adapter, mapper, transaction } = props; - super({ adapter, transaction }); - this.mapper = mapper; - } - - public async getById2( - id: UniqueID, - billingAddressId: UniqueID, - shippingAddressId: UniqueID, - ) { - const Contact_Model = this.adapter.getModel("Contact_Model"); - const ContactAddress_Model = this.adapter.getModel("ContactAddress_Model"); - - const rawContact: any = await Contact_Model.findOne({ - where: { id: id.toString() }, - include: [ - { - model: ContactAddress_Model, - as: "billingAddress", - where: { - id: billingAddressId.toString(), - }, - }, - { - model: ContactAddress_Model, - as: "shippingAddress", - where: { - id: shippingAddressId.toString(), - }, - }, - ], - transaction: this.transaction, - }); - - if (!rawContact === true) { - return null; - } - - return this.mapper.mapToDomain(rawContact); - } - - public async getById(id: UniqueID): Promise { - const rawContact: any = await this._getById("Contact_Model", id, { - include: [{ all: true }], - }); - - if (!rawContact === true) { - return null; - } - - return this.mapper.mapToDomain(rawContact); - } - - public async exists(id: UniqueID): Promise { - return this._exists("Customer", "id", id.toString()); - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/Invoice.repository.ts b/modules.bak/invoices/src/server/intrastructure/Invoice.repository.ts deleted file mode 100644 index edfb5b8f..00000000 --- a/modules.bak/invoices/src/server/intrastructure/Invoice.repository.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { SequelizeRepository } from "@/contexts/common/infrastructure/sequelize/SequelizeRepository"; - -import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize"; -import { ICollection, IQueryCriteria, UniqueID } from "@shared/contexts"; -import { Transaction } from "sequelize"; -import { IInvoiceRepository, Invoice } from "../domain"; -import { IInvoiceMapper } from "./mappers"; - -export type QueryParams = { - pagination: Record; - filters: Record; -}; - -export class InvoiceRepository extends SequelizeRepository implements IInvoiceRepository { - protected mapper: IInvoiceMapper; - - public constructor(props: { - mapper: IInvoiceMapper; - adapter: ISequelizeAdapter; - transaction: Transaction; - }) { - const { adapter, mapper, transaction } = props; - super({ adapter, transaction }); - this.mapper = mapper; - } - - public async getById(id: UniqueID): Promise { - const rawContact: any = await this._getById("Invoice_Model", id, { - include: [ - { association: "items" }, - { - association: "participants", - include: [{ association: "shippingAddress" }, { association: "billingAddress" }], - }, - ], - }); - - if (!rawContact === true) { - return null; - } - - return this.mapper.mapToDomain(rawContact); - } - - public async findAll(queryCriteria?: IQueryCriteria): Promise> { - const { rows, count } = await this._findAll("Invoice_Model", queryCriteria, { - include: [ - { - association: "participants", - separate: true, - }, - ], - }); - - return this.mapper.mapArrayAndCountToDomain(rows, count); - } - - public async save(invoice: Invoice): Promise { - const { items, participants, ...invoiceData } = this.mapper.mapToPersistence(invoice); - - await this.adapter - .getModel("Invoice_Model") - .create(invoiceData, { transaction: this.transaction }); - - await this.adapter - .getModel("InvoiceItem_Model") - .bulkCreate(items, { transaction: this.transaction }); - - await this.adapter - .getModel("InvoiceParticipant_Model") - .bulkCreate(participants, { transaction: this.transaction }); - - await this.adapter - .getModel("InvoiceParticipantAddress_Model") - .bulkCreate([participants[0].billingAddress, participants[0].shippingAddress], { - transaction: this.transaction, - }); - } - - public removeById(id: UniqueID): Promise { - return this._removeById("Invoice_Model", id); - } - - public async exists(id: UniqueID): Promise { - return this._exists("Invoice_Model", "id", id.toString()); - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/InvoiceParticipant.repository.ts b/modules.bak/invoices/src/server/intrastructure/InvoiceParticipant.repository.ts deleted file mode 100644 index 32e9b106..00000000 --- a/modules.bak/invoices/src/server/intrastructure/InvoiceParticipant.repository.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ISequelizeAdapter, SequelizeRepository } from "@/contexts/common/infrastructure/sequelize"; -import { Transaction } from "sequelize"; -import { InvoiceCustomer } from "../domain"; -import { IInvoiceParticipantMapper } from "./mappers"; - -export class InvoiceParticipantRepository extends SequelizeRepository { - protected mapper: IInvoiceParticipantMapper; - - public constructor(props: { - mapper: IInvoiceParticipantMapper; - adapter: ISequelizeAdapter; - transaction: Transaction; - }) { - const { adapter, mapper, transaction } = props; - super({ adapter, transaction }); - this.mapper = mapper; - } - - /*public async getParticipantById( - id: UniqueID, - ): Promise { - const rawParticipant: any = await this._getById( - "InvoiceParticipant_Model", - id, - { - include: [{ all: true }], - raw: true, - }, - ); - - if (!rawParticipant === true) { - return null; - } - - return this.mapper.mapToDomain(rawParticipant); - } - - public async getContactById(id: UniqueID): Promise { - const rawContact: any = await this._getById("Customer", id, { - include: [{ all: true }], - raw: true, - }); - - if (!rawContact === true) { - return null; - } - - return this.mapper.mapToDomain(rawContact); - } - - public async exists(id: UniqueID): Promise { - return this._exists("Customer", "id", id.toString()); - }*/ -} diff --git a/modules.bak/invoices/src/server/intrastructure/InvoiceParticipantAddress.repository.ts b/modules.bak/invoices/src/server/intrastructure/InvoiceParticipantAddress.repository.ts deleted file mode 100644 index a010fcbf..00000000 --- a/modules.bak/invoices/src/server/intrastructure/InvoiceParticipantAddress.repository.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - ISequelizeAdapter, - SequelizeRepository, -} from "@/contexts/common/infrastructure/sequelize"; -import { UniqueID } from "@shared/contexts"; -import { Transaction } from "sequelize"; -import { InvoiceParticipantAddress } from "../domain"; -import { IInvoiceParticipantAddressMapper } from "./mappers"; - -export class InvoiceParticipantAddressRepository extends SequelizeRepository { - protected mapper: IInvoiceParticipantAddressMapper; - - public constructor(props: { - mapper: IInvoiceParticipantAddressMapper; - adapter: ISequelizeAdapter; - transaction: Transaction; - }) { - const { adapter, mapper, transaction } = props; - super({ adapter, transaction }); - this.mapper = mapper; - } - - public async getById( - id: UniqueID, - ): Promise { - const rawParticipant: any = await this._getById( - "InvoiceParticipantAddress_Model", - id, - { - include: [{ all: true }], - }, - ); - - if (!rawParticipant === true) { - return null; - } - - return this.mapper.mapToDomain(rawParticipant); - } - - public async exists(id: UniqueID): Promise { - return this._exists("CustomerAddress", "id", id.toString()); - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/InvoicingContext.ts b/modules.bak/invoices/src/server/intrastructure/InvoicingContext.ts deleted file mode 100644 index 75ca5396..00000000 --- a/modules.bak/invoices/src/server/intrastructure/InvoicingContext.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - IRepositoryManager, - RepositoryManager, -} from "@/contexts/common/domain"; -import { - ISequelizeAdapter, - createSequelizeAdapter, -} from "@/contexts/common/infrastructure/sequelize"; -import { InvoicingServices, TInvoicingServices } from "../application"; - -export interface IInvoicingContext { - adapter: ISequelizeAdapter; - repositoryManager: IRepositoryManager; - services: TInvoicingServices; -} - -class InvoicingContext { - private static instance: InvoicingContext | null = null; - public static getInstance(): InvoicingContext { - if (!InvoicingContext.instance) { - InvoicingContext.instance = new InvoicingContext(); - } - - return InvoicingContext.instance; - } - - private context: IInvoicingContext; - - private constructor() { - this.context = { - adapter: createSequelizeAdapter(), - repositoryManager: RepositoryManager.getInstance(), - services: InvoicingServices, - }; - } - - public getContext(): IInvoicingContext { - return this.context; - } -} - -const sharedInvoicingContext = InvoicingContext.getInstance().getContext(); -export { sharedInvoicingContext }; diff --git a/modules.bak/invoices/src/server/intrastructure/express/index.ts b/modules.bak/invoices/src/server/intrastructure/express/index.ts deleted file mode 100644 index af28f816..00000000 --- a/modules.bak/invoices/src/server/intrastructure/express/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./invoices.routes"; diff --git a/modules.bak/invoices/src/server/intrastructure/express/invoices.routes.ts b/modules.bak/invoices/src/server/intrastructure/express/invoices.routes.ts deleted file mode 100644 index 2b4482c5..00000000 --- a/modules.bak/invoices/src/server/intrastructure/express/invoices.routes.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { validateAndParseBody } from "@repo/shared"; -import { Express } from "express"; -import { - buildCreateInvoiceController, - buildGetInvoiceController, - buildListInvoicesController, - ICreateInvoiceRequestSchema, -} from "../../presentation"; - -import { NextFunction, Request, Response, Router } from "express"; - -export const invoicesRouter = (app: Express) => { - const routes: Router = Router({ mergeParams: true }); - - routes.get( - "/", - //checkTabContext, - //checkUser, - (req: Request, res: Response, next: NextFunction) => { - buildListInvoicesController().execute(req, res, next); - } - ); - - routes.get( - "/:invoiceId", - //checkTabContext, - //checkUser, - (req: Request, res: Response, next: NextFunction) => { - buildGetInvoiceController().execute(req, res, next); - } - ); - - routes.post( - "/", - validateAndParseBody(ICreateInvoiceRequestSchema, { sanitize: false }), - //checkTabContext, - //checkUser, - (req: Request, res: Response, next: NextFunction) => { - buildCreateInvoiceController().execute(req, res, next); - } - ); - - /* - routes.put( - "/:invoiceId", - validateAndParseBody(IUpdateInvoiceRequestSchema), - checkTabContext, - //checkUser, - (req: Request, res: Response, next: NextFunction) => { - buildUpdateInvoiceController().execute(req, res, next); - } - ); - - routes.delete( - "/:invoiceId", - validateAndParseBody(IDeleteInvoiceRequestSchema), - checkTabContext, - //checkUser, - (req: Request, res: Response, next: NextFunction) => { - buildDeleteInvoiceController().execute(req, res, next); - } - );*/ - - app.use("/invoices", routes); -}; diff --git a/modules.bak/invoices/src/server/intrastructure/index.ts b/modules.bak/invoices/src/server/intrastructure/index.ts deleted file mode 100644 index f35c8878..00000000 --- a/modules.bak/invoices/src/server/intrastructure/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./express"; -export * from "./mappers"; -export * from "./sequelize"; diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/contact.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/contact.mapper.ts deleted file mode 100644 index 8fdf7ee9..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/contact.mapper.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure"; -import { Name, TINNumber, UniqueID } from "@shared/contexts"; - -import { Contact, IContactProps } from "../../domain"; -import { IInvoicingContext } from "../InvoicingContext"; -import { Contact_Model, TCreationContact_Model } from "../sequelize/contact.mo.del"; -import { IContactAddressMapper, createContactAddressMapper } from "./contactAddress.mapper"; - -export interface IContactMapper - extends ISequelizeMapper {} - -class ContactMapper - extends SequelizeMapper - implements IContactMapper -{ - public constructor(props: { addressMapper: IContactAddressMapper; context: IInvoicingContext }) { - super(props); - } - - protected toDomainMappingImpl(source: Contact_Model, params: any): Contact { - if (!source.billingAddress) { - this.handleRequiredFieldError( - "billingAddress", - new Error("Missing participant's billing address") - ); - } - - if (!source.shippingAddress) { - this.handleRequiredFieldError( - "shippingAddress", - new Error("Missing participant's shipping address") - ); - } - - const billingAddress = this.props.addressMapper.mapToDomain(source.billingAddress!, params); - - const shippingAddress = this.props.addressMapper.mapToDomain(source.shippingAddress!, params); - - const props: IContactProps = { - tin: this.mapsValue(source, "tin", TINNumber.create), - firstName: this.mapsValue(source, "first_name", Name.create), - lastName: this.mapsValue(source, "last_name", Name.create), - companyName: this.mapsValue(source, "company_name", Name.create), - billingAddress, - shippingAddress, - }; - - const id = this.mapsValue(source, "id", UniqueID.create); - const contactOrError = Contact.create(props, id); - - if (contactOrError.isFailure) { - throw contactOrError.error; - } - - return contactOrError.object; - } -} - -export const createContactMapper = (context: IInvoicingContext): IContactMapper => - new ContactMapper({ - addressMapper: createContactAddressMapper(context), - context, - }); diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/contactAddress.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/contactAddress.mapper.ts deleted file mode 100644 index 4e05d8f8..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/contactAddress.mapper.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - ISequelizeMapper, - SequelizeMapper, -} from "@/contexts/common/infrastructure"; -import { - City, - Country, - Email, - Note, - Phone, - PostalCode, - Province, - Street, - UniqueID, -} from "@shared/contexts"; -import { ContactAddress, IContactAddressProps } from "../../domain"; -import { IInvoicingContext } from "../InvoicingContext"; -import { - ContactAddress_Model, - TCreationContactAddress_Attributes, -} from "../sequelize"; - -export interface IContactAddressMapper - extends ISequelizeMapper< - ContactAddress_Model, - TCreationContactAddress_Attributes, - ContactAddress - > {} - -export const createContactAddressMapper = ( - context: IInvoicingContext -): IContactAddressMapper => new ContactAddressMapper({ context }); - -class ContactAddressMapper - extends SequelizeMapper< - ContactAddress_Model, - TCreationContactAddress_Attributes, - ContactAddress - > - implements IContactAddressMapper -{ - protected toDomainMappingImpl(source: ContactAddress_Model, params: any) { - const id = this.mapsValue(source, "id", UniqueID.create); - - const props: IContactAddressProps = { - type: source.type, - street: this.mapsValue(source, "street", Street.create), - city: this.mapsValue(source, "city", City.create), - province: this.mapsValue(source, "province", Province.create), - postalCode: this.mapsValue(source, "postal_code", PostalCode.create), - country: this.mapsValue(source, "country", Country.create), - email: this.mapsValue(source, "email", Email.create), - phone: this.mapsValue(source, "phone", Phone.create), - notes: this.mapsValue(source, "notes", Note.create), - }; - - const addressOrError = ContactAddress.create(props, id); - - if (addressOrError.isFailure) { - throw addressOrError.error; - } - - return addressOrError.object; - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/index.ts b/modules.bak/invoices/src/server/intrastructure/mappers/index.ts deleted file mode 100644 index 722a3c8b..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./invoice.mapper"; diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/invoice-item.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/invoice-item.mapper.ts deleted file mode 100644 index e645976e..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/invoice-item.mapper.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Invoice, InvoiceItem, InvoiceItemDescription } from "@contexts/invoices/domain/"; -import { MoneyValue, Percentage, Quantity, UniqueID } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { - ISequelizeMapper, - MapperParamsType, - SequelizeMapper, -} from "core/common/infrastructure/sequelize/sequelize-mapper"; -import { InferCreationAttributes } from "sequelize"; -import { InvoiceItemCreationAttributes, InvoiceItemModel, InvoiceModel } from "../sequelize"; - -export interface IInvoiceItemMapper - extends ISequelizeMapper {} - -export class InvoiceItemMapper - extends SequelizeMapper - implements IInvoiceItemMapper -{ - public mapToDomain( - source: InvoiceItemModel, - params?: MapperParamsType - ): Result { - const { sourceParent } = params as { sourceParent: InvoiceModel }; - - const idOrError = UniqueID.create(source.item_id); - - const descriptionOrError = InvoiceItemDescription.create(source.description); - - 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 InvoiceItem.create( - { - description: descriptionOrError.data, - quantity: quantityOrError.data, - unitPrice: unitPriceOrError.data, - discount: discountOrError.data, - }, - idOrError.data - //sourceParent - ); - } - - public mapToPersistence( - source: InvoiceItem, - params?: MapperParamsType - ): InferCreationAttributes { - const { index, sourceParent } = params as { - index: number; - sourceParent: Invoice; - }; - - const lineData = { - parent_id: undefined, - invoice_id: sourceParent.id.toPrimitive(), - item_type: "simple", - position: index, - - item_id: source.id.toPrimitive(), - description: source.description.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/modules.bak/invoices/src/server/intrastructure/mappers/invoice.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/invoice.mapper.ts deleted file mode 100644 index 25377f40..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/invoice.mapper.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "@contexts/invoices/domain/"; -import { UniqueID, UtcDate } from "core/common/domain"; -import { Result } from "core/common/helpers"; -import { - ISequelizeMapper, - MapperParamsType, - SequelizeMapper, -} from "core/common/infrastructure/sequelize/sequelize-mapper"; -import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize"; -import { InvoiceItemMapper } from "./invoice-item.mapper"; // Importar el mapper de items - -export interface IInvoiceMapper - extends ISequelizeMapper {} - -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); - const invoiceSeriesOrError = InvoiceSerie.create(source.invoice_series); - const invoiceNumberOrError = InvoiceNumber.create(source.invoice_number); - const issueDateOrError = UtcDate.create(source.issue_date); - const operationDateOrError = UtcDate.create(source.operation_date); - - const result = Result.combine([ - idOrError, - statusOrError, - invoiceSeriesOrError, - invoiceNumberOrError, - issueDateOrError, - operationDateOrError, - ]); - - 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( - { - status: statusOrError.data, - invoiceSeries: invoiceSeriesOrError.data, - invoiceNumber: invoiceNumberOrError.data, - issueDate: issueDateOrError.data, - operationDate: operationDateOrError.data, - invoiceCurrency, - items: itemsOrErrors.data, - }, - idOrError.data - ); - } - - public mapToPersistence(source: Invoice, params?: MapperParamsType): InvoiceCreationAttributes { - 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(), - invoice_series: source.invoiceSeries.toPrimitive(), - invoice_number: source.invoiceNumber.toPrimitive(), - issue_date: source.issueDate.toPrimitive(), - operation_date: source.operationDate.toPrimitive(), - invoice_language: "es", - invoice_currency: source.invoiceCurrency || "EUR", - - subtotal_amount: subtotal.amount, - subtotal_scale: subtotal.scale, - - total_amount: total.amount, - total_scale: total.scale, - - items, - }; - } -} - -const invoiceMapper: InvoiceMapper = new InvoiceMapper(); -export { invoiceMapper }; diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipant.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipant.mapper.ts deleted file mode 100644 index aa6944f3..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipant.mapper.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure"; -import { Name, TINNumber, UniqueID } from "@shared/contexts"; -import { - IInvoiceCustomerProps, - Invoice, - InvoiceCustomer, - InvoiceParticipantBillingAddress, - InvoiceParticipantShippingAddress, -} from "../../domain"; -import { IInvoicingContext } from "../InvoicingContext"; -import { InvoiceParticipant_Model, TCreationInvoiceParticipant_Model } from "../sequelize"; -import { - IInvoiceParticipantAddressMapper, - createInvoiceParticipantAddressMapper, -} from "./invoiceParticipantAddress.mapper"; - -export interface IInvoiceParticipantMapper - extends ISequelizeMapper< - InvoiceParticipant_Model, - TCreationInvoiceParticipant_Model, - InvoiceCustomer - > {} - -export const createInvoiceParticipantMapper = ( - context: IInvoicingContext -): IInvoiceParticipantMapper => - new InvoiceParticipantMapper({ - context, - addressMapper: createInvoiceParticipantAddressMapper(context), - }); - -class InvoiceParticipantMapper - extends SequelizeMapper< - InvoiceParticipant_Model, - TCreationInvoiceParticipant_Model, - InvoiceCustomer - > - implements IInvoiceParticipantMapper -{ - public constructor(props: { - addressMapper: IInvoiceParticipantAddressMapper; - context: IInvoicingContext; - }) { - super(props); - } - - protected toDomainMappingImpl(source: InvoiceParticipant_Model, params: any) { - /*if (!source.billingAddress) { - this.handleRequiredFieldError( - "billingAddress", - new Error("Missing participant's billing address"), - ); - } - - if (!source.shippingAddress) { - this.handleRequiredFieldError( - "shippingAddress", - new Error("Missing participant's shipping address"), - ); - } -*/ - const billingAddress = source.billingAddress - ? ((this.props.addressMapper as IInvoiceParticipantAddressMapper).mapToDomain( - source.billingAddress, - params - ) as InvoiceParticipantBillingAddress) - : undefined; - - const shippingAddress = source.shippingAddress - ? ((this.props.addressMapper as IInvoiceParticipantAddressMapper).mapToDomain( - source.shippingAddress, - params - ) as InvoiceParticipantShippingAddress) - : undefined; - - const props: IInvoiceCustomerProps = { - tin: this.mapsValue(source, "tin", TINNumber.create), - firstName: this.mapsValue(source, "first_name", Name.create), - lastName: this.mapsValue(source, "last_name", Name.create), - companyName: this.mapsValue(source, "company_name", Name.create), - billingAddress, - shippingAddress, - }; - - const id = this.mapsValue(source, "participant_id", UniqueID.create); - const participantOrError = InvoiceCustomer.create(props, id); - - if (participantOrError.isFailure) { - throw participantOrError.error; - } - - return participantOrError.object; - } - - protected toPersistenceMappingImpl( - source: InvoiceCustomer, - params: { sourceParent: Invoice } - ): TCreationInvoiceParticipant_Model { - const { sourceParent } = params; - - return { - invoice_id: sourceParent.id.toPrimitive(), - - participant_id: source.id.toPrimitive(), - tin: source.tin.toPrimitive(), - first_name: source.firstName.toPrimitive(), - last_name: source.lastName.toPrimitive(), - company_name: source.companyName.toPrimitive(), - - billingAddress: ( - this.props.addressMapper as IInvoiceParticipantAddressMapper - ).mapToPersistence(source.billingAddress!, { sourceParent: source }), - - shippingAddress: ( - this.props.addressMapper as IInvoiceParticipantAddressMapper - ).mapToPersistence(source.shippingAddress!, { sourceParent: source }), - }; - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipantAddress.mapper.ts b/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipantAddress.mapper.ts deleted file mode 100644 index 1e898f64..00000000 --- a/modules.bak/invoices/src/server/intrastructure/mappers/invoiceParticipantAddress.mapper.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure"; -import { - City, - Country, - Email, - Note, - Phone, - PostalCode, - Province, - Street, - UniqueID, -} from "@shared/contexts"; -import { - IInvoiceParticipantAddressProps, - InvoiceCustomer, - InvoiceParticipantAddress, -} from "../../domain"; -import { IInvoicingContext } from "../InvoicingContext"; -import { - InvoiceParticipantAddress_Model, - TCreationInvoiceParticipantAddress_Model, -} from "../sequelize"; - -export interface IInvoiceParticipantAddressMapper - extends ISequelizeMapper< - InvoiceParticipantAddress_Model, - TCreationInvoiceParticipantAddress_Model, - InvoiceParticipantAddress - > {} - -export const createInvoiceParticipantAddressMapper = ( - context: IInvoicingContext -): IInvoiceParticipantAddressMapper => new InvoiceParticipantAddressMapper({ context }); - -class InvoiceParticipantAddressMapper - extends SequelizeMapper< - InvoiceParticipantAddress_Model, - TCreationInvoiceParticipantAddress_Model, - InvoiceParticipantAddress - > - implements IInvoiceParticipantAddressMapper -{ - protected toDomainMappingImpl(source: InvoiceParticipantAddress_Model, params: any) { - const id = this.mapsValue(source, "address_id", UniqueID.create); - - const props: IInvoiceParticipantAddressProps = { - type: source.type, - street: this.mapsValue(source, "street", Street.create), - city: this.mapsValue(source, "city", City.create), - province: this.mapsValue(source, "province", Province.create), - postalCode: this.mapsValue(source, "postal_code", PostalCode.create), - country: this.mapsValue(source, "country", Country.create), - email: this.mapsValue(source, "email", Email.create), - phone: this.mapsValue(source, "phone", Phone.create), - notes: this.mapsValue(source, "notes", Note.create), - }; - - const addressOrError = InvoiceParticipantAddress.create(props, id); - - if (addressOrError.isFailure) { - throw addressOrError.error; - } - - return addressOrError.object; - } - - protected toPersistenceMappingImpl( - source: InvoiceParticipantAddress, - params: { sourceParent: InvoiceCustomer } - ) { - const { sourceParent } = params; - - return { - address_id: source.id.toPrimitive(), - participant_id: sourceParent.id.toPrimitive(), - type: String(source.type), - title: source.title, - street: source.street.toPrimitive(), - city: source.city.toPrimitive(), - postal_code: source.postalCode.toPrimitive(), - province: source.province.toPrimitive(), - country: source.country.toPrimitive(), - email: source.email.toPrimitive(), - phone: source.phone.toPrimitive(), - }; - } -} diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/contact.mo.del.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/contact.mo.del.ts deleted file mode 100644 index d5b11b17..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/contact.mo.del.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; - -import { ContactAddress_Model, TCreationContactAddress_Attributes } from "./contactAddress.mo.del"; - -export type TCreationContact_Model = InferCreationAttributes< - Contact_Model, - { omit: "shippingAddress" | "billingAddress" } -> & { - billingAddress: TCreationContactAddress_Attributes; - shippingAddress: TCreationContactAddress_Attributes; -}; - -export class Contact_Model extends Model< - InferAttributes, - InferCreationAttributes -> { - // To avoid table creation - static async sync(): Promise { - return Promise.resolve(); - } - - static associate(connection: Sequelize) { - const { Contact_Model, ContactAddress_Model } = connection.models; - - Contact_Model.hasOne(ContactAddress_Model, { - as: "shippingAddress", - foreignKey: "customer_id", - onDelete: "CASCADE", - }); - - Contact_Model.hasOne(ContactAddress_Model, { - as: "billingAddress", - foreignKey: "customer_id", - onDelete: "CASCADE", - }); - } - - declare id: string; - declare tin: CreationOptional; - declare company_name: CreationOptional; - declare first_name: CreationOptional; - declare last_name: CreationOptional; - - declare shippingAddress?: NonAttribute; - declare billingAddress?: NonAttribute; -} - -export default (sequelize: Sequelize) => { - Contact_Model.init( - { - id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - tin: { - type: new DataTypes.STRING(), - }, - company_name: { - type: new DataTypes.STRING(), - }, - first_name: { - type: new DataTypes.STRING(), - }, - last_name: { - type: new DataTypes.STRING(), - }, - }, - { - sequelize, - tableName: "customers", - timestamps: false, - } - ); - - return Contact_Model; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/contactAddress.mo.del.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/contactAddress.mo.del.ts deleted file mode 100644 index 49d7e269..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/contactAddress.mo.del.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - CreationOptional, - DataTypes, - ForeignKey, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { Contact_Model } from "./contact.mo.del"; - -export type TCreationContactAddress_Attributes = InferCreationAttributes< - ContactAddress_Model, - { omit: "customer" } ->; - -export class ContactAddress_Model extends Model< - InferAttributes, - TCreationContactAddress_Attributes -> { - // To avoid table creation - static async sync(): Promise { - return Promise.resolve(); - } - - static associate(connection: Sequelize) { - const { Contact_Model, ContactAddress_Model } = connection.models; - - ContactAddress_Model.belongsTo(Contact_Model, { - as: "customer", - foreignKey: "customer_id", - }); - } - - declare id: string; - declare customer_id: ForeignKey; - declare type: string; - declare street: CreationOptional; - declare postal_code: CreationOptional; - declare city: CreationOptional; - declare province: CreationOptional; - declare country: CreationOptional; - declare phone: CreationOptional; - declare email: CreationOptional; - - declare customer?: NonAttribute; -} - -export default (sequelize: Sequelize) => { - ContactAddress_Model.init( - { - id: { - type: DataTypes.UUID, - primaryKey: true, - }, - customer_id: new DataTypes.UUID(), - type: DataTypes.STRING(), - street: DataTypes.STRING(), - postal_code: DataTypes.STRING(), - city: DataTypes.STRING, - province: DataTypes.STRING, - country: DataTypes.STRING, - email: DataTypes.STRING, - phone: DataTypes.STRING, - }, - { - sequelize, - tableName: "customer_addresses", - timestamps: false, - } - ); - - return ContactAddress_Model; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/index.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/index.ts deleted file mode 100644 index d063103a..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { IInvoiceRepository } from "@contexts/invoices/domain"; -import { invoiceRepository } from "./invoice.repository"; - -export * from "./invoice-item.model"; -export * from "./invoice.model"; - -export * from "./invoice.repository"; - -export const createInvoiceRepository = (): IInvoiceRepository => { - return invoiceRepository; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice-item.model.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/invoice-item.model.ts deleted file mode 100644 index b63992b3..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice-item.model.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, -} from "sequelize"; - -export type InvoiceItemCreationAttributes = InferCreationAttributes & {}; - -export class InvoiceItemModel extends Model< - InferAttributes, - InvoiceItemCreationAttributes -> { - static associate(connection: Sequelize) { - /*const { Invoice_Model, InvoiceItem_Model } = connection.models; - - InvoiceItem_Model.belongsTo(Invoice_Model, { - as: "invoice", - foreignKey: "invoice_id", - onDelete: "CASCADE", - });*/ - } - - 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; - declare quantity_scale: CreationOptional; - - declare unit_price_amount: CreationOptional; - declare unit_price_scale: CreationOptional; - - 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; -} - -export default (sequelize: Sequelize) => { - InvoiceItemModel.init( - { - item_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - invoice_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - parent_id: { - type: new DataTypes.UUID(), - allowNull: true, // Puede ser nulo para elementos de nivel superior - }, - position: { - type: new DataTypes.MEDIUMINT(), - autoIncrement: false, - allowNull: false, - }, - item_type: { - type: new DataTypes.STRING(), - allowNull: false, - defaultValue: "simple", - }, - description: { - type: new DataTypes.TEXT(), - allowNull: true, - }, - - quantity_amount: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - quantity_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - - unit_price_amount: { - type: new DataTypes.BIGINT(), - allowNull: true, - defaultValue: null, - }, - unit_price_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - - /*tax_slug: { - type: new DataTypes.DECIMAL(3, 2), - allowNull: true, - }, - tax_rate: { - type: new DataTypes.DECIMAL(3, 2), - allowNull: true, - }, - tax_equalization: { - type: new DataTypes.DECIMAL(3, 2), - allowNull: true, - },*/ - - subtotal_amount: { - type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, - }, - subtotal_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - 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, - },*/ - total_amount: { - type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, - }, - total_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - }, - { - sequelize, - tableName: "invoice_items", - - defaultScope: {}, - - scopes: {}, - } - ); - - return InvoiceItemModel; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.model.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.model.ts deleted file mode 100644 index 1d4bb7ca..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.model.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { InvoiceItemCreationAttributes, InvoiceItemModel } from "./invoice-item.model"; - -export type InvoiceCreationAttributes = InferCreationAttributes & { - items?: InvoiceItemCreationAttributes[]; -}; - -export class InvoiceModel extends Model< - InferAttributes, - InferCreationAttributes -> { - declare id: string; - - declare invoice_status: string; - declare invoice_series: CreationOptional; - declare invoice_number: CreationOptional; - declare issue_date: CreationOptional; - declare operation_date: CreationOptional; - declare invoice_language: string; - declare invoice_currency: string; - - // Subtotal - declare subtotal_amount: CreationOptional; - declare subtotal_scale: CreationOptional; - - // Total - declare total_amount: CreationOptional; - declare total_scale: CreationOptional; - - // Relaciones - declare items: NonAttribute; - //declare customer: NonAttribute; - - static associate(database: Sequelize) { - const { InvoiceModel, InvoiceItemModel } = database.models; - - InvoiceModel.hasMany(InvoiceItemModel, { - as: "items", - foreignKey: "invoice_id", - onDelete: "CASCADE", - }); - } -} - -export default (database: Sequelize) => { - InvoiceModel.init( - { - id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - - invoice_status: { - type: new DataTypes.STRING(), - allowNull: false, - }, - - invoice_series: { - type: new DataTypes.STRING(), - allowNull: true, - defaultValue: null, - }, - - invoice_number: { - type: new DataTypes.STRING(), - allowNull: true, - defaultValue: null, - }, - - issue_date: { - type: new DataTypes.DATEONLY(), - allowNull: true, - defaultValue: null, - }, - - operation_date: { - type: new DataTypes.DATEONLY(), - allowNull: true, - defaultValue: null, - }, - - invoice_language: { - type: new DataTypes.STRING(), - allowNull: false, - }, - - invoice_currency: { - type: new DataTypes.STRING(3), // ISO 4217 - allowNull: false, - }, - - subtotal_amount: { - type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, - }, - subtotal_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - - total_amount: { - type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, - }, - total_scale: { - type: new DataTypes.SMALLINT(), - allowNull: true, - defaultValue: null, - }, - }, - { - sequelize: database, - tableName: "invoices", - - paranoid: true, // softs deletes - timestamps: true, - - createdAt: "created_at", - updatedAt: "updated_at", - deletedAt: "deleted_at", - - indexes: [{ unique: true, fields: ["invoice_number"] }], - - whereMergeStrategy: "and", // <- cómo tratar el merge de un scope - - defaultScope: {}, - - scopes: {}, - } - ); - - return InvoiceModel; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.repository.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.repository.ts deleted file mode 100644 index 49e2a00a..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/invoice.repository.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Invoice } from "@contexts/invoices/domain"; -import { IInvoiceRepository } from "@contexts/invoices/domain/repositories/invoice-repository.interface"; -import { UniqueID } from "core/common/domain"; -import { Collection, Result } from "core/common/helpers"; -import { SequelizeRepository } from "core/common/infrastructure"; -import { Transaction } from "sequelize"; -import { IInvoiceMapper, invoiceMapper } from "../mappers/invoice.mapper"; -import { InvoiceItemModel } from "./invoice-item.model"; -import { InvoiceModel } from "./invoice.model"; - -class InvoiceRepository extends SequelizeRepository implements IInvoiceRepository { - private readonly _mapper!: IInvoiceMapper; - - /** - * 🔹 Función personalizada para mapear errores de unicidad en autenticación - */ - private _customErrorMapper(error: Error): string | null { - if (error.name === "SequelizeUniqueConstraintError") { - return "Invoice with this email already exists"; - } - - return null; - } - - constructor(mapper: IInvoiceMapper) { - super(); - this._mapper = mapper; - } - - async invoiceExists(id: UniqueID, transaction?: Transaction): Promise> { - try { - const _invoice = await this._getById(InvoiceModel, id, {}, transaction); - - return Result.ok(Boolean(id.equals(_invoice.id))); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async findAll(transaction?: Transaction): Promise, Error>> { - try { - const rawInvoices: any = await this._findAll( - InvoiceModel, - { - include: [ - { - model: InvoiceItemModel, - as: "items", - }, - ], - }, - transaction - ); - - if (!rawInvoices === true) { - return Result.fail(new Error("Invoice with email not exists")); - } - - return this._mapper.mapArrayToDomain(rawInvoices); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async getById(id: UniqueID, transaction?: Transaction): Promise> { - try { - const rawInvoice: any = await this._getById( - InvoiceModel, - id, - { - include: [ - { - model: InvoiceItemModel, - as: "items", - }, - ], - }, - transaction - ); - - if (!rawInvoice === true) { - return Result.fail(new Error(`Invoice with id ${id.toString()} not exists`)); - } - - return this._mapper.mapToDomain(rawInvoice); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async deleteById(id: UniqueID, transaction?: Transaction): Promise> { - try { - this._deleteById(InvoiceModel, id); - return Result.ok(true); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async create(invoice: Invoice, transaction?: Transaction): Promise { - const invoiceData = this._mapper.mapToPersistence(invoice); - await this._save(InvoiceModel, invoice.id, invoiceData, {}, transaction); - } - - async update(invoice: Invoice, transaction?: Transaction): Promise { - const invoiceData = this._mapper.mapToPersistence(invoice); - await this._save(InvoiceModel, invoice.id, invoiceData, {}, transaction); - } -} - -const invoiceRepository = new InvoiceRepository(invoiceMapper); -export { invoiceRepository }; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipant.mo.del.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipant.mo.del.ts deleted file mode 100644 index 151b22c3..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipant.mo.del.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { InvoiceModel } from "./invoice.model"; -import { - InvoiceParticipantAddress_Model, - TCreationInvoiceParticipantAddress_Model, -} from "./invoiceParticipantAddress.mo.del"; - -export type TCreationInvoiceParticipant_Model = InferCreationAttributes< - InvoiceParticipant_Model, - { omit: "shippingAddress" | "billingAddress" | "invoice" } -> & { - billingAddress: TCreationInvoiceParticipantAddress_Model; - shippingAddress: TCreationInvoiceParticipantAddress_Model; -}; - -export class InvoiceParticipant_Model extends Model< - InferAttributes< - InvoiceParticipant_Model, - { omit: "shippingAddress" | "billingAddress" | "invoice" } - >, - InferCreationAttributes< - InvoiceParticipant_Model, - { omit: "shippingAddress" | "billingAddress" | "invoice" } - > -> { - static associate(connection: Sequelize) { - const { Invoice_Model, InvoiceParticipantAddress_Model, InvoiceParticipant_Model } = - connection.models; - - InvoiceParticipant_Model.belongsTo(Invoice_Model, { - as: "invoice", - foreignKey: "invoice_id", - onDelete: "CASCADE", - }); - - InvoiceParticipant_Model.hasOne(InvoiceParticipantAddress_Model, { - as: "shippingAddress", - foreignKey: "participant_id", - onDelete: "CASCADE", - }); - - InvoiceParticipant_Model.hasOne(InvoiceParticipantAddress_Model, { - as: "billingAddress", - foreignKey: "participant_id", - onDelete: "CASCADE", - }); - } - - declare participant_id: string; - declare invoice_id: string; - declare tin: CreationOptional; - declare company_name: CreationOptional; - declare first_name: CreationOptional; - declare last_name: CreationOptional; - - declare shippingAddress?: NonAttribute; - declare billingAddress?: NonAttribute; - - declare invoice?: NonAttribute; -} - -export default (sequelize: Sequelize) => { - InvoiceParticipant_Model.init( - { - participant_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - invoice_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - tin: { - type: new DataTypes.STRING(), - allowNull: true, - }, - company_name: { - type: new DataTypes.STRING(), - allowNull: true, - }, - first_name: { - type: new DataTypes.STRING(), - allowNull: true, - }, - last_name: { - type: new DataTypes.STRING(), - allowNull: true, - }, - }, - { - sequelize, - tableName: "invoice_participants", - timestamps: false, - } - ); - - return InvoiceParticipant_Model; -}; diff --git a/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipantAddress.mo.del.ts b/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipantAddress.mo.del.ts deleted file mode 100644 index 216e348a..00000000 --- a/modules.bak/invoices/src/server/intrastructure/sequelize/invoiceParticipantAddress.mo.del.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { InvoiceParticipant_Model } from "./invoiceParticipant.mo.del"; - -export type TCreationInvoiceParticipantAddress_Model = InferCreationAttributes< - InvoiceParticipantAddress_Model, - { omit: "participant" } ->; - -export class InvoiceParticipantAddress_Model extends Model< - InferAttributes, - InferCreationAttributes -> { - static associate(connection: Sequelize) { - const { InvoiceParticipantAddress_Model, InvoiceParticipant_Model } = connection.models; - InvoiceParticipantAddress_Model.belongsTo(InvoiceParticipant_Model, { - as: "participant", - foreignKey: "participant_id", - }); - } - - declare address_id: string; - declare participant_id: string; - declare type: string; - declare street: CreationOptional; - declare postal_code: CreationOptional; - declare city: CreationOptional; - declare province: CreationOptional; - declare country: CreationOptional; - declare phone: CreationOptional; - declare email: CreationOptional; - - declare participant?: NonAttribute; -} - -export default (sequelize: Sequelize) => { - InvoiceParticipantAddress_Model.init( - { - address_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - participant_id: { - type: new DataTypes.UUID(), - primaryKey: true, - }, - type: { - type: new DataTypes.STRING(), - allowNull: false, - }, - street: { - type: new DataTypes.STRING(), - allowNull: true, - }, - postal_code: { - type: new DataTypes.STRING(), - allowNull: true, - }, - city: { - type: new DataTypes.STRING(), - allowNull: true, - }, - province: { - type: new DataTypes.STRING(), - allowNull: true, - }, - country: { - type: new DataTypes.STRING(), - allowNull: true, - }, - email: { - type: new DataTypes.STRING(), - allowNull: true, - }, - phone: { - type: new DataTypes.STRING(), - allowNull: true, - }, - }, - { - sequelize, - tableName: "invoice_participant_addresses", - } - ); - - return InvoiceParticipantAddress_Model; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/create-invoice.controller.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/create-invoice.controller.ts deleted file mode 100644 index f848fd28..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/create-invoice.controller.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { UniqueID } from "core/common/domain"; -import { ExpressController } from "core/common/presentation"; -import { CreateInvoiceUseCase } from "../../../application"; -import { ICreateInvoiceRequestDTO } from "../../dto"; -import { ICreateInvoicePresenter } from "./presenter"; - -export class CreateInvoiceController extends ExpressController { - public constructor( - private readonly createInvoice: CreateInvoiceUseCase, - private readonly presenter: ICreateInvoicePresenter - ) { - super(); - } - - protected async executeImpl() { - const createDTO: ICreateInvoiceRequestDTO = this.req.body; - - // Validar ID - const invoiceIdOrError = UniqueID.create(createDTO.id); - if (invoiceIdOrError.isFailure) return this.invalidInputError("Invoice ID not valid"); - - const invoiceOrError = await this.createInvoice.execute(invoiceIdOrError.data, createDTO); - - if (invoiceOrError.isFailure) { - return this.handleError(invoiceOrError.error); - } - - return this.ok(this.presenter.toDTO(invoiceOrError.data)); - } - - private handleError(error: Error) { - const message = error.message; - - if ( - message.includes("Database connection lost") || - message.includes("Database request timed out") - ) { - return this.unavailableError( - "Database service is currently unavailable. Please try again later." - ); - } - - return this.conflictError(message); - } -} diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/index.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/index.ts deleted file mode 100644 index 3f3ac725..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CreateInvoiceUseCase } from "@contexts/invoices/application/create-invoice.use-case"; -import { InvoiceService } from "@contexts/invoices/domain"; -import { invoiceRepository } from "@contexts/invoices/intrastructure"; -import { SequelizeTransactionManager } from "core/common/infrastructure"; -import { CreateInvoiceController } from "./create-invoice.controller"; -import { createInvoicePresenter } from "./presenter"; - -export const buildCreateInvoiceController = () => { - const transactionManager = new SequelizeTransactionManager(); - const invoiceService = new InvoiceService(invoiceRepository); - - const useCase = new CreateInvoiceUseCase(invoiceService, transactionManager); - const presenter = createInvoicePresenter; - - return new CreateInvoiceController(useCase, presenter); -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceItem.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceItem.presenter.ts deleted file mode 100644 index 3177298b..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceItem.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceItem } from "@/contexts/invoicing/domain/InvoiceItems"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICollection, IMoney_Response_DTO } from "@shared/contexts"; - -export const invoiceItemPresenter = ( - items: ICollection, - context: IInvoicingContext -) => - items.totalCount > 0 - ? items.items.map((item: InvoiceItem) => ({ - description: item.description.toString(), - quantity: item.quantity.toString(), - unit_measure: "", - unit_price: item.unitPrice.toPrimitive() as IMoney_Response_DTO, - subtotal: item.calculateSubtotal().toPrimitive() as IMoney_Response_DTO, - tax_amount: item.calculateTaxAmount().toPrimitive() as IMoney_Response_DTO, - total: item.calculateTotal().toPrimitive() as IMoney_Response_DTO, - })) - : []; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipant.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipant.presenter.ts deleted file mode 100644 index ea628008..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipant.presenter.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { IInvoiceParticipant } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateInvoice_Participant_Response_DTO } from "@shared/contexts"; -import { InvoiceParticipantAddressPresenter } from "./InvoiceParticipantAddress.presenter"; - -export const InvoiceParticipantPresenter = ( - participant: IInvoiceParticipant, - context: IInvoicingContext, -): ICreateInvoice_Participant_Response_DTO | undefined => { - return { - id: participant.id.toString(), - tin: participant.tin.toString(), - first_name: participant.firstName.toString(), - last_name: participant.lastName.toString(), - company_name: participant.companyName.toString(), - - billing_address: InvoiceParticipantAddressPresenter( - participant.billingAddress!, - context, - ), - shipping_address: InvoiceParticipantAddressPresenter( - participant.shippingAddress!, - context, - ), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipantAddress.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipantAddress.presenter.ts deleted file mode 100644 index 4e637287..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/InvoiceParticipantAddress.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceParticipantAddress } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateInvoice_AddressParticipant_Response_DTO } from "@shared/contexts"; - -export const InvoiceParticipantAddressPresenter = ( - address: InvoiceParticipantAddress, - context: IInvoicingContext, -): ICreateInvoice_AddressParticipant_Response_DTO => { - return { - id: address.id.toString(), - street: address.street.toString(), - city: address.city.toString(), - postal_code: address.postalCode.toString(), - province: address.province.toString(), - country: address.country.toString(), - email: address.email.toString(), - phone: address.phone.toString(), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/create-invoice.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/create-invoice.presenter.ts deleted file mode 100644 index 811e676a..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/create-invoice.presenter.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Invoice } from "@contexts/invoices/domain"; -import { ICreateInvoiceResponseDTO } from "../../../dto"; - -export interface ICreateInvoicePresenter { - toDTO: (invoice: Invoice) => ICreateInvoiceResponseDTO; -} - -export const createInvoicePresenter: ICreateInvoicePresenter = { - toDTO: (invoice: Invoice): ICreateInvoiceResponseDTO => ({ - id: invoice.id.toString(), - - invoice_status: invoice.status.toString(), - invoice_number: invoice.invoiceNumber.toString(), - invoice_series: invoice.invoiceSeries.toString(), - issue_date: invoice.issueDate.toDateString(), - operation_date: invoice.operationDate.toDateString(), - language_code: "es", - currency: invoice.invoiceCurrency || "EUR", - subtotal: invoice.calculateSubtotal().toPrimitive(), - total: invoice.calculateTotal().toPrimitive(), - - //sender: {}, //await InvoiceParticipantPresenter(invoice.senderId, context), - - //customer: InvoiceParticipantPresenter(invoice.recipient, context), - - //items: invoiceItemPresenter(invoice.items, context), - }), -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/index.ts b/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/index.ts deleted file mode 100644 index 3677365d..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/create-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./create-invoice.presenter"; diff --git a/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/delete-invoice.controller.ts b/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/delete-invoice.controller.ts deleted file mode 100644 index b1c05d98..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/delete-invoice.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { DeleteInvoiceUseCase } from "@contexts/invoices/application"; -import { ExpressController } from "core/common/presentation"; - -export class DeleteInvoiceController extends ExpressController { - public constructor(private readonly deleteInvoice: DeleteInvoiceUseCase) { - super(); - } - - async executeImpl(): Promise { - return this.noContent(); - } -} diff --git a/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/index.ts b/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/index.ts deleted file mode 100644 index 3e31d065..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/delete-invoice/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { DeleteInvoiceUseCase } from "@contexts/invoices/application"; -import { InvoiceService } from "@contexts/invoices/domain"; -import { invoiceRepository } from "@contexts/invoices/intrastructure"; -import { SequelizeTransactionManager } from "core/common/infrastructure"; -import { DeleteInvoiceController } from "./delete-invoice.controller"; - -export const buildDeleteInvoiceController = () => { - const transactionManager = new SequelizeTransactionManager(); - const invoiceService = new InvoiceService(invoiceRepository); - - const useCase = new DeleteInvoiceUseCase(invoiceService, transactionManager); - - return new DeleteInvoiceController(useCase); -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/get-invoice.controller.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/get-invoice.controller.ts deleted file mode 100644 index 67e1964d..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/get-invoice.controller.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { GetInvoiceUseCase } from "@contexts/invoices/application"; -import { UniqueID } from "core/common/domain"; -import { ExpressController } from "core/common/presentation"; -import { IGetInvoicePresenter } from "./presenter"; - -export class GetInvoiceController extends ExpressController { - public constructor( - private readonly getInvoice: GetInvoiceUseCase, - private readonly presenter: IGetInvoicePresenter - ) { - super(); - } - - protected async executeImpl() { - const { invoiceId } = this.req.params; - - // Validar ID - const invoiceIdOrError = UniqueID.create(invoiceId); - if (invoiceIdOrError.isFailure) return this.invalidInputError("Invoice ID not valid"); - - const invoiceOrError = await this.getInvoice.execute(invoiceIdOrError.data); - - if (invoiceOrError.isFailure) { - return this.handleError(invoiceOrError.error); - } - - return this.ok(this.presenter.toDTO(invoiceOrError.data)); - } - - private handleError(error: Error) { - const message = error.message; - - if ( - message.includes("Database connection lost") || - message.includes("Database request timed out") - ) { - return this.unavailableError( - "Database service is currently unavailable. Please try again later." - ); - } - - return this.conflictError(message); - } -} diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/index.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/index.ts deleted file mode 100644 index 53c8898f..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GetInvoiceUseCase } from "@contexts/invoices/application"; -import { InvoiceService } from "@contexts/invoices/domain"; -import { invoiceRepository } from "@contexts/invoices/intrastructure"; -import { SequelizeTransactionManager } from "core/common/infrastructure"; -import { GetInvoiceController } from "./get-invoice.controller"; -import { getInvoicePresenter } from "./presenter"; - -export const buildGetInvoiceController = () => { - const transactionManager = new SequelizeTransactionManager(); - const invoiceService = new InvoiceService(invoiceRepository); - - const useCase = new GetInvoiceUseCase(invoiceService, transactionManager); - const presenter = getInvoicePresenter; - - return new GetInvoiceController(useCase, presenter); -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceItem.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceItem.presenter.ts deleted file mode 100644 index 3177298b..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceItem.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceItem } from "@/contexts/invoicing/domain/InvoiceItems"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICollection, IMoney_Response_DTO } from "@shared/contexts"; - -export const invoiceItemPresenter = ( - items: ICollection, - context: IInvoicingContext -) => - items.totalCount > 0 - ? items.items.map((item: InvoiceItem) => ({ - description: item.description.toString(), - quantity: item.quantity.toString(), - unit_measure: "", - unit_price: item.unitPrice.toPrimitive() as IMoney_Response_DTO, - subtotal: item.calculateSubtotal().toPrimitive() as IMoney_Response_DTO, - tax_amount: item.calculateTaxAmount().toPrimitive() as IMoney_Response_DTO, - total: item.calculateTotal().toPrimitive() as IMoney_Response_DTO, - })) - : []; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipant.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipant.presenter.ts deleted file mode 100644 index 635aa696..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipant.presenter.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { IInvoiceParticipant } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateInvoice_Participant_Response_DTO } from "@shared/contexts"; -import { InvoiceParticipantAddressPresenter } from "./InvoiceParticipantAddress.presenter"; - -export const InvoiceParticipantPresenter = async ( - participant: IInvoiceParticipant, - context: IInvoicingContext, -): Promise => { - return { - id: participant.id.toString(), - tin: participant.tin.toString(), - first_name: participant.firstName.toString(), - last_name: participant.lastName.toString(), - company_name: participant.companyName.toString(), - - billing_address: await InvoiceParticipantAddressPresenter( - participant.billingAddress!, - context, - ), - shipping_address: await InvoiceParticipantAddressPresenter( - participant.shippingAddress!, - context, - ), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipantAddress.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipantAddress.presenter.ts deleted file mode 100644 index 15478c1b..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/InvoiceParticipantAddress.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceParticipantAddress } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateInvoice_AddressParticipant_Response_DTO } from "@shared/contexts"; - -export const InvoiceParticipantAddressPresenter = async ( - address: InvoiceParticipantAddress, - context: IInvoicingContext, -): Promise => { - return { - id: address.id.toString(), - street: address.street.toString(), - city: address.city.toString(), - postal_code: address.postalCode.toString(), - province: address.province.toString(), - country: address.country.toString(), - email: address.email.toString(), - phone: address.phone.toString(), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/get-invoice.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/get-invoice.presenter.ts deleted file mode 100644 index 1598ac79..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/get-invoice.presenter.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Invoice, InvoiceItem } from "@contexts/invoices/domain"; -import { IGetInvoiceResponseDTO } from "../../../dto"; - -export interface IGetInvoicePresenter { - toDTO: (invoice: Invoice) => IGetInvoiceResponseDTO; -} - -export const getInvoicePresenter: IGetInvoicePresenter = { - toDTO: (invoice: Invoice): IGetInvoiceResponseDTO => ({ - id: invoice.id.toPrimitive(), - - invoice_status: invoice.status.toString(), - invoice_number: invoice.invoiceNumber.toString(), - invoice_series: invoice.invoiceSeries.toString(), - issue_date: invoice.issueDate.toDateString(), - operation_date: invoice.operationDate.toDateString(), - language_code: "ES", - currency: invoice.invoiceCurrency.toString(), - subtotal: invoice.calculateSubtotal().toPrimitive(), - total: invoice.calculateTotal().toPrimitive(), - - items: - invoice.items.size() > 0 - ? invoice.items.map((item: InvoiceItem) => ({ - description: item.description.toString(), - quantity: item.quantity.toPrimitive(), - unit_measure: "", - unit_price: item.unitPrice.toPrimitive(), - subtotal: item.calculateSubtotal().toPrimitive(), - //tax_amount: item.calculateTaxAmount().toPrimitive(), - total: item.calculateTotal().toPrimitive(), - })) - : [], - - //sender: {}, //await InvoiceParticipantPresenter(invoice.senderId, context), - - /*recipient: await InvoiceParticipantPresenter(invoice.recipient, context), - items: invoiceItemPresenter(invoice.items, context), - - payment_term: { - payment_type: "", - due_date: "", - }, - - due_amount: { - currency: invoice.currency.toString(), - precision: 2, - amount: 0, - }, - - custom_fields: [], - - metadata: { - create_time: "", - last_updated_time: "", - delete_time: "", - },*/ - }), -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/index.ts b/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/index.ts deleted file mode 100644 index 60624c19..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/get-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./get-invoice.presenter"; diff --git a/modules.bak/invoices/src/server/presentation/controllers/index.ts b/modules.bak/invoices/src/server/presentation/controllers/index.ts deleted file mode 100644 index 70c32af4..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./create-invoice"; -//export * from "./delete-invoice"; -export * from "./get-invoice"; -export * from "./list-invoices"; -//export * from "./update-invoice"; diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/index.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/index.ts deleted file mode 100644 index 775666b7..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { invoiceRepository } from "@contexts/invoices/intrastructure"; -import { SequelizeTransactionManager } from "core/common/infrastructure"; -import { ListInvoicesUseCase } from "../../../application"; -import { InvoiceService } from "../../../domain"; -import { ListInvoicesController } from "./list-invoices.controller"; -import { listInvoicesPresenter } from "./presenter"; - -export const buildListInvoicesController = () => { - const transactionManager = new SequelizeTransactionManager(); - const invoiceService = new InvoiceService(invoiceRepository); - - const useCase = new ListInvoicesUseCase(invoiceService, transactionManager); - const presenter = listInvoicesPresenter; - - return new ListInvoicesController(useCase, presenter); -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/list-invoices.controller.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/list-invoices.controller.ts deleted file mode 100644 index 64a69032..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/list-invoices.controller.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ListInvoicesUseCase } from "@contexts/invoices/application"; -import { ExpressController } from "core/common/presentation"; -import { IListInvoicesPresenter } from "./list-invoices.presenter"; - -export class ListInvoicesController extends ExpressController { - public constructor( - private readonly listInvoices: ListInvoicesUseCase, - private readonly presenter: IListInvoicesPresenter - ) { - super(); - } - - protected async executeImpl() { - const { query } = this.req; - //const queryCriteria: IQueryCriteria = QueryCriteriaService.parse(query); - - const invoicesOrError = await this.listInvoices.execute(/* queryCriteria */); - - if (invoicesOrError.isFailure) { - return this.handleError(invoicesOrError.error); - } - - return this.ok( - this.presenter.toDTO( - invoicesOrError.data /*, { - page: queryCriteria.pagination.offset, - limit: queryCriteria.pagination.limit, - }*/ - ) - ); - } - - private handleError(error: Error) { - const message = error.message; - - if ( - message.includes("Database connection lost") || - message.includes("Database request timed out") - ) { - return this.unavailableError( - "Database service is currently unavailable. Please try again later." - ); - } - - return this.conflictError(message); - } -} diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipant.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipant.presenter.ts deleted file mode 100644 index a6030b13..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipant.presenter.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { IInvoiceParticipant } from "@/contexts/invoicing/domain"; -import { IListInvoice_Participant_Response_DTO } from "@shared/contexts"; -import { InvoiceParticipantAddressPresenter } from "./InvoiceParticipantAddress.presenter"; - -export const InvoiceParticipantPresenter = ( - participant: IInvoiceParticipant, -): IListInvoice_Participant_Response_DTO => { - return { - participant_id: participant?.id?.toString(), - tin: participant?.tin?.toString(), - first_name: participant?.firstName?.toString(), - last_name: participant?.lastName?.toString(), - company_name: participant?.companyName?.toString(), - - billing_address: InvoiceParticipantAddressPresenter( - participant?.billingAddress!, - ), - shipping_address: InvoiceParticipantAddressPresenter( - participant?.shippingAddress!, - ), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipantAddress.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipantAddress.presenter.ts deleted file mode 100644 index 0dda05df..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/InvoiceParticipantAddress.presenter.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { InvoiceParticipantAddress } from "@/contexts/invoicing/domain"; -import { IListInvoice_AddressParticipant_Response_DTO } from "@shared/contexts"; - -export const InvoiceParticipantAddressPresenter = ( - address: InvoiceParticipantAddress, -): IListInvoice_AddressParticipant_Response_DTO => { - return { - address_id: address?.id.toString(), - street: address?.street.toString(), - city: address?.city.toString(), - postal_code: address?.postalCode.toString(), - province: address?.province.toString(), - country: address?.country.toString(), - email: address?.email.toString(), - phone: address?.phone.toString(), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/index.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/index.ts deleted file mode 100644 index 9ecb5c89..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./list-invoices.presenter"; diff --git a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/list-invoices.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/list-invoices.presenter.ts deleted file mode 100644 index 40f58c3f..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/list-invoices/presenter/list-invoices.presenter.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Invoice } from "@contexts/invoices/domain"; -import { IListInvoicesResponseDTO } from "@contexts/invoices/presentation/dto"; -import { Collection } from "core/common/helpers"; - -export interface IListInvoicesPresenter { - toDTO: (invoices: Collection) => IListInvoicesResponseDTO[]; -} - -export const listInvoicesPresenter: IListInvoicesPresenter = { - toDTO: (invoices: Collection): IListInvoicesResponseDTO[] => { - return invoices.map((invoice) => { - const result = { - id: invoice.id.toPrimitive(), - - invoice_status: invoice.status.toString(), - invoice_number: invoice.invoiceNumber.toString(), - invoice_series: invoice.invoiceSeries.toString(), - issue_date: invoice.issueDate.toISOString(), - operation_date: invoice.operationDate.toISOString(), - language_code: "ES", - currency: invoice.currency, - subtotal: invoice.calculateSubtotal().toPrimitive(), - total: invoice.calculateTotal().toPrimitive(), - - //recipient: InvoiceParticipantPresenter(invoice.recipient), - }; - - return result; - }); - }, -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/index.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/index.ts deleted file mode 100644 index dfe6e0b3..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { UpdateInvoiceUseCase } from "@/contexts/invoicing/application"; -import { - ContactRepository, - IInvoicingContext, - InvoiceParticipantAddressRepository, - InvoiceParticipantRepository, -} from "../../.."; -import { InvoiceRepository } from "../../../Invoice.repository"; -import { - createContactMapper, - createInvoiceMapper, - createInvoiceParticipantAddressMapper, - createInvoiceParticipantMapper, -} from "../../../mappers"; -import { updateInvoicePresenter } from "./presenter"; -import { UpdateInvoiceController } from "./update-invoice.controller"; - -export const updateInvoiceController = (context: IInvoicingContext) => { - const adapter = context.adapter; - const repoManager = context.repositoryManager; - - repoManager.registerRepository("Invoice", (params = { transaction: null }) => { - const { transaction } = params; - - return new InvoiceRepository({ - transaction, - adapter, - mapper: createInvoiceMapper(context), - }); - }); - - repoManager.registerRepository("Participant", (params = { transaction: null }) => { - const { transaction } = params; - - return new InvoiceParticipantRepository({ - transaction, - adapter, - mapper: createInvoiceParticipantMapper(context), - }); - }); - - repoManager.registerRepository("ParticipantAddress", (params = { transaction: null }) => { - const { transaction } = params; - - return new InvoiceParticipantAddressRepository({ - transaction, - adapter, - mapper: createInvoiceParticipantAddressMapper(context), - }); - }); - - repoManager.registerRepository("Contact", (params = { transaction: null }) => { - const { transaction } = params; - - return new ContactRepository({ - transaction, - adapter, - mapper: createContactMapper(context), - }); - }); - - const updateInvoiceUseCase = new UpdateInvoiceUseCase(context); - - return new UpdateInvoiceController( - { - useCase: updateInvoiceUseCase, - presenter: updateInvoicePresenter, - }, - context - ); -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceItem.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceItem.presenter.ts deleted file mode 100644 index 3177298b..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceItem.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceItem } from "@/contexts/invoicing/domain/InvoiceItems"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICollection, IMoney_Response_DTO } from "@shared/contexts"; - -export const invoiceItemPresenter = ( - items: ICollection, - context: IInvoicingContext -) => - items.totalCount > 0 - ? items.items.map((item: InvoiceItem) => ({ - description: item.description.toString(), - quantity: item.quantity.toString(), - unit_measure: "", - unit_price: item.unitPrice.toPrimitive() as IMoney_Response_DTO, - subtotal: item.calculateSubtotal().toPrimitive() as IMoney_Response_DTO, - tax_amount: item.calculateTaxAmount().toPrimitive() as IMoney_Response_DTO, - total: item.calculateTotal().toPrimitive() as IMoney_Response_DTO, - })) - : []; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipant.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipant.presenter.ts deleted file mode 100644 index b416c7ba..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipant.presenter.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { IInvoiceParticipant } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { IUpdateInvoice_Participant_Response_DTO } from "@shared/contexts"; -import { InvoiceParticipantAddressPresenter } from "./InvoiceParticipantAddress.presenter"; - -export const InvoiceParticipantPresenter = ( - participant: IInvoiceParticipant, - context: IInvoicingContext, -): IUpdateInvoice_Participant_Response_DTO | undefined => { - return { - id: participant.id.toString(), - tin: participant.tin.toString(), - first_name: participant.firstName.toString(), - last_name: participant.lastName.toString(), - company_name: participant.companyName.toString(), - - billing_address: InvoiceParticipantAddressPresenter( - participant.billingAddress!, - context, - ), - shipping_address: InvoiceParticipantAddressPresenter( - participant.shippingAddress!, - context, - ), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipantAddress.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipantAddress.presenter.ts deleted file mode 100644 index 376d491f..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/InvoiceParticipantAddress.presenter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { InvoiceParticipantAddress } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { IUpdateInvoice_AddressParticipant_Response_DTO } from "@shared/contexts"; - -export const InvoiceParticipantAddressPresenter = ( - address: InvoiceParticipantAddress, - context: IInvoicingContext, -): IUpdateInvoice_AddressParticipant_Response_DTO => { - return { - id: address.id.toString(), - street: address.street.toString(), - city: address.city.toString(), - postal_code: address.postalCode.toString(), - province: address.province.toString(), - country: address.country.toString(), - email: address.email.toString(), - phone: address.phone.toString(), - }; -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/UpdateInvoice.presenter.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/UpdateInvoice.presenter.ts deleted file mode 100644 index bd0a9815..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/UpdateInvoice.presenter.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Invoice } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { IUpdateInvoice_Response_DTO } from "@shared/contexts"; -import { invoiceItemPresenter } from "./InvoiceItem.presenter"; -import { InvoiceParticipantPresenter } from "./InvoiceParticipant.presenter"; - -export interface IUpdateInvoicePresenter { - map: (invoice: Invoice, context: IInvoicingContext) => IUpdateInvoice_Response_DTO; -} - -export const updateInvoicePresenter: IUpdateInvoicePresenter = { - map: (invoice: Invoice, context: IInvoicingContext): IUpdateInvoice_Response_DTO => { - return { - id: invoice.id.toString(), - - invoice_status: invoice.status.toString(), - invoice_number: invoice.invoiceNumber.toString(), - invoice_series: invoice.invoiceSeries.toString(), - issue_date: invoice.issueDate.toISO8601(), - operation_date: invoice.operationDate.toISO8601(), - language_code: invoice.language.toString(), - currency: invoice.currency.toString(), - subtotal: invoice.calculateSubtotal().toPrimitive(), - total: invoice.calculateTotal().toPrimitive(), - - //sender: {}, //await InvoiceParticipantPresenter(invoice.senderId, context), - - recipient: InvoiceParticipantPresenter(invoice.recipient, context), - - items: invoiceItemPresenter(invoice.items, context), - }; - }, -}; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/index.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/index.ts deleted file mode 100644 index 88e907ef..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./UpdateInvoice.presenter"; diff --git a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/update-invoice.controller.ts b/modules.bak/invoices/src/server/presentation/controllers/update-invoice/update-invoice.controller.ts deleted file mode 100644 index 381496a7..00000000 --- a/modules.bak/invoices/src/server/presentation/controllers/update-invoice/update-invoice.controller.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { UseCaseError } from "@/contexts/common/application/useCases"; -import { IServerError } from "@/contexts/common/domain"; -import { ExpressController } from "@/contexts/common/infrastructure/express"; -import { - IUpdateInvoice_DTO, - IUpdateInvoice_Response_DTO, - RuleValidator, - UniqueID, -} from "@shared/contexts"; - -import { Invoice } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "../../../InvoicingContext"; - -import { UpdateInvoiceUseCase } from "@/contexts/invoicing/application"; -import { IUpdateInvoicePresenter } from "./presenter"; - -export class UpdateInvoiceController extends ExpressController { - private useCase: UpdateInvoiceUseCase; - private presenter: IUpdateInvoicePresenter; - private context: IInvoicingContext; - - constructor( - props: { - useCase: UpdateInvoiceUseCase; - presenter: IUpdateInvoicePresenter; - }, - context: IInvoicingContext, - ) { - super(); - - const { useCase, presenter } = props; - this.useCase = useCase; - this.presenter = presenter; - this.context = context; - } - - async executeImpl(): Promise { - const { invoiceId } = this.req.params; - const request: IUpdateInvoice_DTO = this.req.body; - - if ( - RuleValidator.validate( - RuleValidator.RULE_NOT_NULL_OR_UNDEFINED, - invoiceId, - ).isFailure - ) { - return this.invalidInputError("Invoice Id param is required!"); - } - - const idOrError = UniqueID.create(invoiceId); - if (idOrError.isFailure) { - return this.invalidInputError("Invalid invoice Id param!"); - } - - try { - const result = await this.useCase.execute({ - id: idOrError.object, - data: request, - }); - - if (result.isFailure) { - const { error } = result; - - switch (error.code) { - case UseCaseError.NOT_FOUND_ERROR: - return this.notFoundError("Invoice not found", error); - - case UseCaseError.INVALID_INPUT_DATA: - return this.invalidInputError(error.message); - - case UseCaseError.UNEXCEPTED_ERROR: - return this.internalServerError(result.error.message, result.error); - - case UseCaseError.REPOSITORY_ERROR: - return this.conflictError(result.error, result.error.details); - - default: - return this.clientError(result.error.message); - } - } - - const invoice = result.object; - - return this.ok( - this.presenter.map(invoice, this.context), - ); - } catch (e: unknown) { - return this.fail(e as IServerError); - } - } -} diff --git a/modules.bak/invoices/src/server/presentation/dto/index.ts b/modules.bak/invoices/src/server/presentation/dto/index.ts deleted file mode 100644 index 804ee569..00000000 --- a/modules.bak/invoices/src/server/presentation/dto/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./invoices.request.dto"; -export * from "./invoices.response.dto"; -export * from "./invoices.schemas"; diff --git a/modules.bak/invoices/src/server/presentation/dto/invoices.request.dto.ts b/modules.bak/invoices/src/server/presentation/dto/invoices.request.dto.ts deleted file mode 100644 index 776096a0..00000000 --- a/modules.bak/invoices/src/server/presentation/dto/invoices.request.dto.ts +++ /dev/null @@ -1,37 +0,0 @@ -export type IListInvoicesRequestDTO = {}; - -export interface ICreateInvoiceRequestDTO { - id: string; - - invoice_number: string; - invoice_series: string; - issue_date: string; - operation_date: string; - language_code: string; - currency: string; -} - -export interface IUpdateInvoiceRequestDTO { - is_companyr: boolean; - name: string; - trade_name: string; - tin: string; - - street: string; - city: string; - state: string; - postal_code: string; - country: string; - - email: string; - phone: string; - fax: string; - website: string; - - legal_record: string; - - default_tax: number; - lang_code: string; - currency_code: string; - logo: string; -} diff --git a/modules.bak/invoices/src/server/presentation/dto/invoices.response.dto.ts b/modules.bak/invoices/src/server/presentation/dto/invoices.response.dto.ts deleted file mode 100644 index d1dddcea..00000000 --- a/modules.bak/invoices/src/server/presentation/dto/invoices.response.dto.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { IMoneyDTO, IQuantityDTO } from "core/common/presentation"; - -export interface IListInvoicesResponseDTO { - id: string; - - invoice_status: string; - invoice_number: string; - invoice_series: string; - issue_date: string; - operation_date: string; - language_code: string; - currency: string; - - subtotal: IMoneyDTO; - total: IMoneyDTO; -} - -export interface IGetInvoiceResponseDTO { - id: string; - - invoice_status: string; - invoice_number: string; - invoice_series: string; - issue_date: string; - operation_date: string; - language_code: string; - currency: string; - - subtotal: IMoneyDTO; - total: IMoneyDTO; - - items: { - description: string; - quantity: IQuantityDTO; - unit_measure: string; - unit_price: IMoneyDTO; - subtotal: IMoneyDTO; - //tax_amount: IMoneyDTO; - total: IMoneyDTO; - }[]; - - //customer: -} - -export interface ICreateInvoiceResponseDTO { - id: string; - - invoice_status: string; - invoice_number: string; - invoice_series: string; - issue_date: string; - operation_date: string; - language_code: string; - currency: string; - - subtotal: IMoneyDTO; - total: IMoneyDTO; -} - -// Inferir el tipo en TypeScript desde el esquema Zod -//export type IUpdateAcccountResponseDTO = z.infer; - -export interface IUpdateInvoiceResponseDTO { - id: string; - - invoice_status: string; - invoice_number: string; - invoice_series: string; - issue_date: string; - operation_date: string; - language_code: string; - currency: string; - - subtotal: IMoneyDTO; - total: IMoneyDTO; -} diff --git a/modules.bak/invoices/src/server/presentation/dto/invoices.schemas.ts b/modules.bak/invoices/src/server/presentation/dto/invoices.schemas.ts deleted file mode 100644 index b887ec47..00000000 --- a/modules.bak/invoices/src/server/presentation/dto/invoices.schemas.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as z from "zod/v4"; - -export const ICreateInvoiceRequestSchema = z.object({ - id: z.string().uuid(), - invoice_number: z.string().min(1), - invoice_series: z.string().min(1), - issue_date: z.string().refine((date) => { - const dateStr = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format"); - return dateStr.safeParse(date).success; - }), - operation_date: z.string().refine((date) => { - 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(), - lang_code: z.string().min(1), - currency_code: z.string().min(1), - - 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({}); - -export const IDeleteInvoiceRequestSchema = z.object({}); diff --git a/modules.bak/invoices/src/server/presentation/index.ts b/modules.bak/invoices/src/server/presentation/index.ts deleted file mode 100644 index a123289d..00000000 --- a/modules.bak/invoices/src/server/presentation/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./controllers"; -export * from "./dto"; diff --git a/modules.bak/invoices/tsconfig.json b/modules.bak/invoices/tsconfig.json deleted file mode 100644 index 18573208..00000000 --- a/modules.bak/invoices/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@repo/typescript-config/base.json", - "compilerOptions": { - "outDir": "dist", - "types": ["jest", "node"] - }, - "include": ["."], - "exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"] -} diff --git a/modules.bak/invoices/turbo.json b/modules.bak/invoices/turbo.json deleted file mode 100644 index 52a7d7ab..00000000 --- a/modules.bak/invoices/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } -} diff --git a/packages.bak/rdx-ddd-domain/package.json b/packages.bak/rdx-ddd-domain/package.json deleted file mode 100644 index 259fbc79..00000000 --- a/packages.bak/rdx-ddd-domain/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@rdx/ddd-domain", - "version": "0.0.0", - "private": true, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": ["dist/**"], - "scripts": { - "build": "tsc", - "dev": "tsc --watch", - "lint": "eslint src/", - "lint:fix": "eslint src/ --fix", - "typecheck": "tsc --noEmit", - "test": "jest" - }, - "jest": { - "preset": "@repo/jest-presets/node" - }, - "devDependencies": { - "@repo/typescript-config": "workspace:*", - "@rdx/utils": "workspace:*", - "@types/dinero.js": "^1.9.4", - "typescript": "^5.8.3" - }, - "dependencies": { - "dinero.js": "^1.9.1", - "libphonenumber-js": "^1.12.7", - "shallow-equal-object": "^1.1.1", - "uuid": "^11.1.0", - "zod": "^3.24.3" - } -} diff --git a/packages.bak/rdx-ddd-domain/src/aggregate-root-repository.interface.ts b/packages.bak/rdx-ddd-domain/src/aggregate-root-repository.interface.ts deleted file mode 100644 index 845c7ae7..00000000 --- a/packages.bak/rdx-ddd-domain/src/aggregate-root-repository.interface.ts +++ /dev/null @@ -1 +0,0 @@ -export interface IAggregateRootRepository {} diff --git a/packages.bak/rdx-ddd-domain/src/aggregate-root.ts b/packages.bak/rdx-ddd-domain/src/aggregate-root.ts deleted file mode 100644 index 3255fcd1..00000000 --- a/packages.bak/rdx-ddd-domain/src/aggregate-root.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { DomainEntity } from "./domain-entity"; -import { IDomainEvent } from "./events"; - -export abstract class AggregateRoot extends DomainEntity { - private _domainEvents: IDomainEvent[] = []; - - private logDomainEventAdded(event: IDomainEvent): void { - const thisClass = Reflect.getPrototypeOf(this); - const domainEventClass = Reflect.getPrototypeOf(event); - logger.info( - `[Domain Event Created]: ${thisClass?.constructor.name} ==> ${domainEventClass?.constructor.name}` - ); - } - - /** - * 🔹 Agregar un evento de dominio al agregado - */ - protected addDomainEvent(event: IDomainEvent): void { - this._domainEvents.push(event); - - // Log the domain event - this.logDomainEventAdded(event); - } - - /** - * 🔹 Obtener los eventos de dominio pendientes - */ - get domainEvents(): IDomainEvent[] { - return this._domainEvents; - } - - /** - * 🔹 Limpiar la lista de eventos después de procesarlos - */ - public clearDomainEvents(): void { - this._domainEvents.splice(0, this._domainEvents.length); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/domain-entity.ts b/packages.bak/rdx-ddd-domain/src/domain-entity.ts deleted file mode 100644 index d7d7dcf3..00000000 --- a/packages.bak/rdx-ddd-domain/src/domain-entity.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { UniqueID } from "./value-objects/unique-id"; - -export abstract class DomainEntity { - protected readonly props: T; - public readonly id: UniqueID; - - protected constructor(props: T, id?: UniqueID) { - this.id = id ? id : UniqueID.generateNewID().data; - this.props = props; - } - - protected _flattenProps(props: T): { [s: string]: any } { - return Object.entries(props).reduce((result: any, [key, valueObject]) => { - console.log(key, valueObject.value); - result[key] = valueObject.value; - - return result; - }, {}); - } - - equals(other: DomainEntity): boolean { - return other instanceof DomainEntity && this.id.equals(other.id); - } - - toString(): { [s: string]: string } { - const flattenProps = this._flattenProps(this.props); - - return { - id: this.id.toString(), - ...flattenProps.map((prop: any) => String(prop)), - }; - } -} diff --git a/packages.bak/rdx-ddd-domain/src/events/domain-event-handle.ts b/packages.bak/rdx-ddd-domain/src/events/domain-event-handle.ts deleted file mode 100644 index 4301cdc6..00000000 --- a/packages.bak/rdx-ddd-domain/src/events/domain-event-handle.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IHandle { - setupSubscriptions(): void; -} diff --git a/packages.bak/rdx-ddd-domain/src/events/domain-event.interface.ts b/packages.bak/rdx-ddd-domain/src/events/domain-event.interface.ts deleted file mode 100644 index 8a2730d9..00000000 --- a/packages.bak/rdx-ddd-domain/src/events/domain-event.interface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { UniqueID } from "../value-objects/unique-id"; - -export interface IDomainEvent { - eventName: string; // Nombre del evento - aggregateId: UniqueID; // ID del agregado que generó el evento - occurredAt: Date; // Fecha y hora del evento -} diff --git a/packages.bak/rdx-ddd-domain/src/events/domain-event.ts b/packages.bak/rdx-ddd-domain/src/events/domain-event.ts deleted file mode 100644 index cb989292..00000000 --- a/packages.bak/rdx-ddd-domain/src/events/domain-event.ts +++ /dev/null @@ -1,135 +0,0 @@ -// https://khalilstemmler.com/articles/typescript-domain-driven-design/chain-business-logic-domain-events/ - -import { AggregateRoot } from "../aggregate-root"; -import { UniqueID } from "../value-objects/unique-id"; -import { IDomainEvent } from "./domain-event.interface"; - -export class DomainEvents { - private static handlersMap: { [key: string]: Array<(event: IDomainEvent) => void> } = {}; - private static markedAggregates: AggregateRoot[] = []; - - /** - * @method markAggregateForDispatch - * @static - * @desc Called by aggregate root objects that have created domain - * events to eventually be dispatched when the infrastructure commits - * the unit of work. - */ - - public static markAggregateForDispatch(aggregate: AggregateRoot): void { - const aggregateFound = !!this.findMarkedAggregateByID(aggregate.id); - - if (!aggregateFound) { - this.markedAggregates.push(aggregate); - } - } - - /** - * @method dispatchAggregateEvents - * @static - * @private - * @desc Call all of the handlers for any domain events on this aggregate. - */ - - private static dispatchAggregateEvents(aggregate: AggregateRoot): void { - aggregate.domainEvents.forEach((event: IDomainEvent) => this.dispatch(event)); - } - - /** - * @method removeAggregateFromMarkedDispatchList - * @static - * @desc Removes an aggregate from the marked list. - */ - - private static removeAggregateFromMarkedDispatchList(aggregate: AggregateRoot): void { - const index = this.markedAggregates.findIndex((a) => a.equals(aggregate)); - - this.markedAggregates.splice(index, 1); - } - - /** - * @method findMarkedAggregateByID - * @static - * @desc Finds an aggregate within the list of marked aggregates. - */ - - private static findMarkedAggregateByID(id: UniqueID): AggregateRoot { - let found!: AggregateRoot; - - for (let aggregate of this.markedAggregates) { - if (aggregate.id.equals(id)) { - found = aggregate; - } - } - - return found; - } - - /** - * @method dispatchEventsForAggregate - * @static - * @desc When all we know is the ID of the aggregate, call this - * in order to dispatch any handlers subscribed to events on the - * aggregate. - */ - - public static dispatchEventsForAggregate(id: UniqueID): void { - const aggregate = this.findMarkedAggregateByID(id); - - if (aggregate) { - this.dispatchAggregateEvents(aggregate); - aggregate.clearDomainEvents(); - this.removeAggregateFromMarkedDispatchList(aggregate); - } - } - - /** - * @method register - * @static - * @desc Register a handler to a domain event. - */ - - public static register(callback: (event: IDomainEvent) => void, eventClassName: string): void { - if (!this.handlersMap.hasOwnProperty(eventClassName)) { - this.handlersMap[eventClassName] = []; - } - this.handlersMap[eventClassName].push(callback); - } - - /** - * @method clearHandlers - * @static - * @desc Useful for testing. - */ - - public static clearHandlers(): void { - this.handlersMap = {}; - } - - /** - * @method clearMarkedAggregates - * @static - * @desc Useful for testing. - */ - - public static clearMarkedAggregates(): void { - this.markedAggregates = []; - } - - /** - * @method dispatch - * @static - * @desc Invokes all of the subscribers to a particular domain event. - */ - - private static dispatch(event: IDomainEvent): void { - const eventClassName: string = event.constructor.name; - - if (this.handlersMap.hasOwnProperty(eventClassName)) { - const handlers: any[] = this.handlersMap[eventClassName]; - for (let handler of handlers) { - handler(event); - } - } - } -} diff --git a/packages.bak/rdx-ddd-domain/src/events/index.ts b/packages.bak/rdx-ddd-domain/src/events/index.ts deleted file mode 100644 index 1ba97866..00000000 --- a/packages.bak/rdx-ddd-domain/src/events/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./domain-event"; -export * from "./domain-event.interface"; diff --git a/packages.bak/rdx-ddd-domain/src/index.ts b/packages.bak/rdx-ddd-domain/src/index.ts deleted file mode 100644 index 8f115f96..00000000 --- a/packages.bak/rdx-ddd-domain/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./aggregate-root"; -export * from "./aggregate-root-repository.interface"; -export * from "./domain-entity"; -export * from "./events/domain-event.interface"; -export * from "./value-objects"; diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/email-address.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/email-address.test.ts deleted file mode 100644 index 20b59573..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/email-address.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { EmailAddress } from "./email-address"; - -describe("EmailAddress Value Object", () => { - it("should create a valid email", () => { - const result = EmailAddress.create("user@example.com"); - - expect(result.isSuccess).toBe(true); - expect(result.data.getValue()).toBe("user@example.com"); - }); - - it("should return an error for invalid email format", () => { - const result = EmailAddress.create("invalid-email"); - - expect(result.isFailure).toBe(true); - expect(result.error.message).toBe("Invalid email format"); - }); - - it("should allow null email", () => { - const result = EmailAddress.createNullable(); - expect(result.isSuccess).toBe(true); - expect(result.data.getOrUndefined()).toBeUndefined(); - }); - - it("should return an error for empty string", () => { - const result = EmailAddress.create(""); - - expect(result.isSuccess).toBe(false); - }); - - it("should compare two equal email objects correctly", () => { - const email1 = EmailAddress.create("test@example.com"); - const email2 = EmailAddress.create("test@example.com"); - - expect(email1.isSuccess).toBe(true); - expect(email2.isSuccess).toBe(true); - expect(email1.data.equals(email2.data)).toBe(true); - }); - - it("should compare two different email objects as not equal", () => { - const email1 = EmailAddress.create("test@example.com"); - const email2 = EmailAddress.create("other@example.com"); - - expect(email1.isSuccess).toBe(true); - expect(email2.isSuccess).toBe(true); - expect(email1.data.equals(email2.data)).toBe(false); - }); - - it("should detect empty email correctly", () => { - const email = EmailAddress.createNullable(); - - expect(email.isSuccess).toBe(true); - expect(email.data.isSome()).toBe(false); - }); - - it("should detect non-empty email correctly", () => { - const email = EmailAddress.create("test@example.com"); - - expect(email.isSuccess).toBe(true); - expect(email.data.getValue()).toBe("test@example.com"); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/email-address.ts b/packages.bak/rdx-ddd-domain/src/value-objects/email-address.ts deleted file mode 100644 index 96d4a770..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/email-address.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface EmailAddressProps { - value: string; -} - -export class EmailAddress extends ValueObject { - static create(value: string): Result { - const valueIsValid = EmailAddress.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.errors[0]?.message)); - } - return Result.ok(new EmailAddress({ value: valueIsValid.data! })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return EmailAddress.create(value).map((value) => Maybe.some(value)); - } - - private static validate(value: string) { - const schema = z.string().email({ message: "Invalid email format" }); - return schema.safeParse(value); - } - - getLocalPart(): string { - return this.props.value.split("@")[0] ?? ""; - } - - getDomain(): string { - return this.props.value.split("@")[1] ?? ""; - } - - getDomainExtension(): string { - return this.getDomain().split(".")[1] ?? ""; - } - - getDomainName(): string { - return this.getDomain().split(".")[0] ?? ""; - } - - getValue(): string { - return this.props.value; - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/index.ts b/packages.bak/rdx-ddd-domain/src/value-objects/index.ts deleted file mode 100644 index 5d341ab4..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from "./email-address"; -export * from "./money-value"; -export * from "./name"; -export * from "./percentage"; -export * from "./phone-number"; -export * from "./postal-address"; -export * from "./quantity"; -export * from "./slug"; -export * from "./tin-number"; -export * from "./unique-id"; -export * from "./utc-date"; -export * from "./value-object"; diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/money-value.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/money-value.test.ts deleted file mode 100644 index c990fb25..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/money-value.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { MoneyValue } from "./money-value"; - -describe("MoneyValue", () => { - test("should correctly instantiate with amount, scale, and currency", () => { - const money = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - expect(money.amount).toBe(100); - expect(money.currency).toBe("EUR"); - expect(money.scale).toBe(2); - }); - - test("should add two MoneyValue instances with the same currency", () => { - const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" }); - const result = money1.add(money2); - expect(result.amount).toBe(150); - }); - - test("should subtract two MoneyValue instances with the same currency", () => { - const money1 = new MoneyValue({ amount: 20000, scale: 2, currency_code: "EUR" }); - const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" }); - const result = money1.subtract(money2); - expect(result.amount).toBe(150); - }); - - test("should throw an error when adding different currencies", () => { - const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "USD" }); - expect(() => money1.add(money2)).toThrow( - "You must provide a Dinero instance with the same currency" - ); - }); - - test("should correctly convert scale", () => { - const money = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - const converted = money.convertScale(4); - expect(converted.amount).toBe(100); - expect(converted.scale).toBe(4); - }); - - test("should format correctly according to locale", () => { - const money = new MoneyValue({ amount: 123456, scale: 2, currency_code: "EUR" }); - expect(money.format("en-US")).toBe("€1,234.56"); - }); - - test("should compare MoneyValue instances correctly", () => { - const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - const money2 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" }); - const money3 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" }); - - expect(money1.equalsTo(money2)).toBe(true); - expect(money1.greaterThan(money3)).toBe(true); - expect(money3.lessThan(money1)).toBe(true); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/money-value.ts b/packages.bak/rdx-ddd-domain/src/value-objects/money-value.ts deleted file mode 100644 index a86bb443..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/money-value.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { Result } from "@rdx/utils"; -import DineroFactory, { Currency, Dinero } from "dinero.js"; -import { Percentage } from "./percentage"; -import { Quantity } from "./quantity"; -import { ValueObject } from "./value-object"; - -const DEFAULT_SCALE = 2; -const DEFAULT_CURRENCY_CODE = "EUR"; - -type CurrencyData = Currency; - -export type RoundingMode = - | "HALF_ODD" - | "HALF_EVEN" - | "HALF_UP" - | "HALF_DOWN" - | "HALF_TOWARDS_ZERO" - | "HALF_AWAY_FROM_ZERO" - | "DOWN"; - -interface IMoneyValueProps { - amount: number; - scale?: number; - currency_code?: string; -} - -interface IMoneyValue { - amount: number; - scale: number; - currency: Dinero.Currency; - - getValue(): IMoneyValueProps; - convertScale(newScale: number): MoneyValue; - add(addend: MoneyValue): MoneyValue; - subtract(subtrahend: MoneyValue): MoneyValue; - multiply(multiplier: number | Quantity, roundingMode?: RoundingMode): MoneyValue; - divide(divisor: number, roundingMode?: RoundingMode): MoneyValue; - percentage(percentage: number, roundingMode?: RoundingMode): MoneyValue; - equalsTo(comparator: MoneyValue): boolean; - greaterThan(comparator: MoneyValue): boolean; - lessThan(comparator: MoneyValue): boolean; - isZero(): boolean; - isPositive(): boolean; - isNegative(): boolean; - hasSameCurrency(comparator: MoneyValue): boolean; - hasSameAmount(comparator: MoneyValue): boolean; - format(locale: string): string; -} - -export class MoneyValue extends ValueObject implements IMoneyValue { - private readonly dinero: Dinero; - - static create(props: IMoneyValueProps) { - return Result.ok(new MoneyValue(props)); - } - - constructor(props: IMoneyValueProps) { - super(props); - const { amount, scale, currency_code } = props; - this.dinero = Object.freeze( - DineroFactory({ - amount, - precision: scale || DEFAULT_SCALE, - currency: (currency_code as Currency) || DEFAULT_CURRENCY_CODE, - }) - ); // 🔒 Garantiza inmutabilidad - } - - get amount(): number { - return this.dinero.getAmount() / Math.pow(10, this.dinero.getPrecision()); - } - - get currency(): CurrencyData { - return this.dinero.getCurrency(); - } - - get scale(): number { - return this.dinero.getPrecision(); - } - - getValue(): IMoneyValueProps { - return this.props; - } - - /** Serializa el VO a una cadena del tipo "EUR:123400:2" */ - toPersistence(): string { - return `${this.currency}:${this.dinero.getAmount()}:${this.scale}`; - } - - /** Reconstruye el VO desde la cadena persistida */ - static fromPersistence(value: string): MoneyValue { - const [currencyCode, amountStr, scaleStr] = value.split(":"); - const amount = parseInt(amountStr ?? "", 10); - const scale = parseInt(scaleStr ?? "", 10); - const currency = currencyCode; - return new MoneyValue({ amount, scale, currency_code: currency }); - } - - toPrimitive() { - return { - amount: this.amount, - scale: this.scale, - currency_code: this.currency, - }; - } - - convertScale(newScale: number, roundingMode: RoundingMode = "HALF_UP"): MoneyValue { - const _newDinero = this.dinero.convertPrecision(newScale, roundingMode); - return new MoneyValue({ - amount: _newDinero.getAmount(), - scale: _newDinero.getPrecision(), - currency_code: _newDinero.getCurrency(), - }); - } - - add(addend: MoneyValue): MoneyValue { - return new MoneyValue({ - amount: this.dinero.add(addend.dinero).getAmount(), - scale: this.scale, - currency_code: this.currency, - }); - } - - subtract(subtrahend: MoneyValue): MoneyValue { - return new MoneyValue({ - amount: this.dinero.subtract(subtrahend.dinero).getAmount(), - scale: this.scale, - currency_code: this.currency, - }); - } - - multiply(multiplier: number | Quantity, roundingMode?: RoundingMode): MoneyValue { - const _multiplier = typeof multiplier === "number" ? multiplier : multiplier.toNumber(); - - const _newDinero = this.dinero.multiply(_multiplier, roundingMode); - return new MoneyValue({ - amount: _newDinero.getAmount(), - scale: _newDinero.getPrecision(), - currency_code: _newDinero.getCurrency(), - }); - } - - divide(divisor: number | Quantity, roundingMode?: RoundingMode): MoneyValue { - const _divisor = typeof divisor === "number" ? divisor : divisor.toNumber(); - - const _newDinero = this.dinero.divide(_divisor, roundingMode); - return new MoneyValue({ - amount: _newDinero.getAmount(), - scale: _newDinero.getPrecision(), - currency_code: _newDinero.getCurrency(), - }); - } - - percentage(percentage: number | Percentage, roundingMode?: RoundingMode): MoneyValue { - const _percentage = typeof percentage === "number" ? percentage : percentage.toNumber(); - - const _newDinero = this.dinero.percentage(_percentage, roundingMode); - return new MoneyValue({ - amount: _newDinero.getAmount(), - scale: _newDinero.getPrecision(), - currency_code: _newDinero.getCurrency(), - }); - } - - equalsTo(comparator: MoneyValue): boolean { - return this.dinero.equalsTo(comparator.dinero); - } - - greaterThan(comparator: MoneyValue): boolean { - return this.dinero.greaterThan(comparator.dinero); - } - - lessThan(comparator: MoneyValue): boolean { - return this.dinero.lessThan(comparator.dinero); - } - - isZero(): boolean { - return this.dinero.isZero(); - } - - isPositive(): boolean { - return this.amount > 0; - } - - isNegative(): boolean { - return this.amount < 0; - } - - hasSameCurrency(comparator: MoneyValue): boolean { - return this.dinero.hasSameCurrency(comparator.dinero); - } - - hasSameAmount(comparator: MoneyValue): boolean { - return this.dinero.hasSameAmount(comparator.dinero); - } - - /** - * Devuelve una cadena con el importe formateado. - * Ejemplo: 123456 -> €1,234.56 - * @param locale Código de idioma y país (ej. "es-ES") - * @returns Importe formateado - */ - format(locale: string): string { - const amount = this.amount; - const currency = this.currency; - const scale = this.scale; - - return new Intl.NumberFormat(locale, { - style: "currency", - currency: currency, - minimumFractionDigits: scale, - maximumFractionDigits: scale, - useGrouping: true, - }).format(amount); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/name.spec.ts b/packages.bak/rdx-ddd-domain/src/value-objects/name.spec.ts deleted file mode 100644 index 0557f757..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/name.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Name } from "./name"; - -describe("Name Value Object", () => { - test("Debe crear un Name válido", () => { - const nameResult = Name.create("John Doe"); - expect(nameResult.isSuccess).toBe(true); - expect(nameResult.data.getValue()).toBe("John Doe"); - }); - - test("Debe fallar si el nombre excede los 255 caracteres", () => { - const longName = "A".repeat(256); - const nameResult = Name.create(longName); - expect(nameResult.isSuccess).toBe(false); - expect(nameResult.error).toBeInstanceOf(Error); - }); - - test("Debe permitir un Name nullable vacío", () => { - const nullableNameResult = Name.createNullable(""); - expect(nullableNameResult.isSuccess).toBe(true); - expect(nullableNameResult.data.isSome()).toBe(false); - }); - - test("Debe permitir un Name nullable con un valor válido", () => { - const nullableNameResult = Name.createNullable("Alice"); - expect(nullableNameResult.isSuccess).toBe(true); - expect(nullableNameResult.data.isSome()).toBe(true); - expect(nullableNameResult.data.getOrUndefined()?.toString()).toBe("Alice"); - }); - - test("Debe generar acrónimos correctamente", () => { - expect(Name.generateAcronym("John Doe")).toBe("JDXX"); - expect(Name.generateAcronym("Alice Bob Charlie")).toBe("ABCX"); - expect(Name.generateAcronym("A B C D E")).toBe("ABCD"); - expect(Name.generateAcronym("SingleWord")).toBe("SXXX"); - }); - - test("Debe obtener el acrónimo de una instancia de Name", () => { - const name = Name.create("John Doe").data; - expect(name.getAcronym()).toBe("JDXX"); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/name.ts b/packages.bak/rdx-ddd-domain/src/value-objects/name.ts deleted file mode 100644 index 7bc849e3..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/name.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Maybe, Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface INameProps { - value: string; -} - -export class Name extends ValueObject { - private static readonly MAX_LENGTH = 255; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .max(Name.MAX_LENGTH, { message: `Name must be at most ${Name.MAX_LENGTH} characters long` }); - return schema.safeParse(value); - } - - static create(value: string) { - const valueIsValid = Name.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.errors[0]?.message)); - } - return Result.ok(new Name({ value })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return Name.create(value).map((value) => Maybe.some(value)); - } - - static generateAcronym(name: string): string { - const words = name.split(" ").map((word) => word[0]?.toUpperCase()); - let acronym = words.join(""); - - // Asegurarse de que tenga 4 caracteres, recortando o añadiendo letras - if (acronym.length > 4) { - acronym = acronym.slice(0, 4); - } else if (acronym.length < 4) { - acronym = acronym.padEnd(4, "X"); // Se completa con 'X' si es necesario - } - - return acronym; - } - - getAcronym(): string { - return Name.generateAcronym(this.toString()); - } - - getValue(): string { - return this.props.value; - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/percentage.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/percentage.test.ts deleted file mode 100644 index 8b89ec03..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/percentage.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Percentage } from "./percentage"; // Ajusta la ruta según sea necesario - -describe("Percentage Value Object", () => { - test("Debe crear un porcentaje válido con escala por defecto", () => { - const result = Percentage.create({ amount: 200 }); // 2.00% - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBe("2.00%"); - }); - - test("Debe crear un porcentaje válido con escala definida", () => { - const result = Percentage.create({ amount: 2150, scale: 2 }); // 21.50% - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBe("21.50%"); - }); - - test("Debe devolver error si la cantidad supera el 100%", () => { - const result = Percentage.create({ amount: 48732000, scale: 4 }); - expect(result.isSuccess).toBe(false); - expect(result.error.message).toBe("La escala debe estar entre 0 y 2."); - }); - - test("Debe devolver error si la cantidad es negativa", () => { - const result = Percentage.create({ amount: -100, scale: 2 }); - expect(result.isSuccess).toBe(false); - expect(result.error.message).toContain("La cantidad no puede ser negativa."); - }); - - test("Debe devolver error si la escala es menor a 0", () => { - const result = Percentage.create({ amount: 100, scale: -1 }); - expect(result.isSuccess).toBe(false); - expect(result.error.message).toContain("Number must be greater than or equal to 0"); - }); - - test("Debe devolver error si la escala es mayor a 10", () => { - const result = Percentage.create({ amount: 100, scale: 11 }); - expect(result.isSuccess).toBe(false); - expect(result.error.message).toContain("La escala debe estar entre 0 y 2."); - }); - - test("Debe representar correctamente el valor como string", () => { - const result = Percentage.create({ amount: 750, scale: 2 }); // 7.50% - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBe("7.50%"); - }); - - test("Debe manejar correctamente el caso de 0%", () => { - const result = Percentage.create({ amount: 0, scale: 2 }); - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBe("0.00%"); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/percentage.ts b/packages.bak/rdx-ddd-domain/src/value-objects/percentage.ts deleted file mode 100644 index 4aac4435..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/percentage.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -const DEFAULT_SCALE = 2; - -interface IPercentageProps { - amount: number; - scale: number; -} - -interface IPercentage { - amount: number; - scale: number; - - getValue(): IPercentageProps; - toNumber(): number; - toString(): string; -} - -export class Percentage extends ValueObject implements IPercentage { - public static readonly DEFAULT_SCALE = DEFAULT_SCALE; - public static readonly MIN_VALUE = 0; - public static readonly MAX_VALUE = 100; - - public static readonly MIN_SCALE = 0; - public static readonly MAX_SCALE = 2; - - protected static validate(values: IPercentageProps) { - const schema = z.object({ - amount: z.number().int().min(Percentage.MIN_VALUE, "La cantidad no puede ser negativa."), - scale: z - .number() - .int() - .min(Percentage.MIN_SCALE) - .max( - Percentage.MAX_SCALE, - `La escala debe estar entre ${Percentage.MIN_SCALE} y ${Percentage.MAX_SCALE}.` - ), - }); - - return schema.safeParse(values); - } - - static create(props: { amount: number; scale?: number }): Result { - const { amount, scale = Percentage.DEFAULT_SCALE } = props; - - const validationResult = Percentage.validate({ amount, scale }); - if (!validationResult.success) { - return Result.fail(new Error(validationResult.error.issues.map((e) => e.message).join(", "))); - } - - // Cálculo del valor real del porcentaje - const realValue = amount / Math.pow(10, scale); - - // Validación de rango - if (realValue > Percentage.MAX_VALUE) { - return Result.fail(new Error("El porcentaje no puede ser mayor a 100%.")); - } - - return Result.ok(new Percentage({ amount, scale })); - } - - get amount(): number { - return this.props.amount; - } - - get scale(): number { - return this.props.scale; - } - - getValue(): IPercentageProps { - return this.props; - } - - toPrimitive() { - return this.getValue(); - } - - toNumber(): number { - return this.amount / Math.pow(10, this.scale); - } - - toString(): string { - return `${this.toNumber().toFixed(this.scale)}%`; - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.test.ts deleted file mode 100644 index e888dee6..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { parsePhoneNumberWithError } from "libphonenumber-js"; -import { Maybe } from "../../helpers/maybe"; -import { PhoneNumber } from "./phone-number"; - -describe("PhoneNumber", () => { - const validPhone = "+14155552671"; // Número válido en formato internacional - const invalidPhone = "12345"; // Número inválido - const nullablePhone = ""; - - test("debe crear un número de teléfono válido", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - expect(result.data).toBeInstanceOf(PhoneNumber); - }); - - test("debe fallar al crear un número de teléfono inválido", () => { - const result = PhoneNumber.create(invalidPhone); - expect(result.isFailure).toBe(true); - expect(result.getError()?.message).toBe( - "Please specify a valid phone number (include the international prefix)." - ); - }); - - test("debe devolver None para valores nulos o vacíos", () => { - const result = PhoneNumber.createNullable(nullablePhone); - expect(result.isSuccess).toBe(true); - expect(result.data).toEqual(Maybe.none()); - }); - - test("debe devolver Some con un número de teléfono válido", () => { - const result = PhoneNumber.createNullable(validPhone); - expect(result.isSuccess).toBe(true); - expect(result.data.isSome()).toBe(true); - }); - - test("debe obtener el valor del número de teléfono", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - const phoneNumber = result.data; - expect(phoneNumber?.getValue()).toBe(validPhone); - }); - - test("debe obtener el código de país del número", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - const phoneNumber = result.data; - expect(phoneNumber?.getCountryCode()).toBe("US"); - }); - - test("debe obtener el número nacional del teléfono", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - const phoneNumber = result.data; - expect(phoneNumber?.getNationalNumber()).toBe("4155552671"); - }); - - test("debe obtener el número formateado", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - const phoneNumber = result.data; - expect(phoneNumber?.getNumber()).toBe(parsePhoneNumberWithError(validPhone).number.toString()); - }); - - test("debe devolver undefined para la extensión si no hay una", () => { - const result = PhoneNumber.create(validPhone); - expect(result.isSuccess).toBe(true); - const phoneNumber = result.data; - expect(phoneNumber?.getExtension()).toBeUndefined(); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.ts b/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.ts deleted file mode 100644 index 8b58f047..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/phone-number.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Result } from "@rdx/utils"; -import { isValidPhoneNumber, parsePhoneNumberWithError } from "libphonenumber-js"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface PhoneNumberProps { - value: string; -} - -export class PhoneNumber extends ValueObject { - static create(value: string): Result { - const valueIsValid = PhoneNumber.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.errors[0]?.message)); - } - return Result.ok(new PhoneNumber({ value: valueIsValid.data! })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return PhoneNumber.create(value).map((value) => Maybe.some(value)); - } - - static validate(value: string) { - const schema = z - .string() - .refine( - isValidPhoneNumber, - "Please specify a valid phone number (include the international prefix)." - ) - .transform((value: string) => parsePhoneNumberWithError(value).number.toString()); - return schema.safeParse(value); - } - - getValue(): string { - return this.props.value; - } - - toPrimitive(): string { - return this.getValue(); - } - - getCountryCode(): string | undefined { - return parsePhoneNumberWithError(this.props.value).country; - } - - getNationalNumber(): string { - return parsePhoneNumberWithError(this.props.value).nationalNumber; - } - - getNumber(): string { - return parsePhoneNumberWithError(this.props.value).number.toString(); - } - - getExtension(): string | undefined { - return parsePhoneNumberWithError(this.props.value).ext; - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.test.ts deleted file mode 100644 index e1ca44e1..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { PostalAddress } from "./postal-address"; - -describe("PostalAddress Value Object", () => { - const validAddress = { - street: "123 Main St", - city: "Springfield", - postalCode: "12345", - state: "IL", - country: "USA", - }; - - test("✅ Debería crear un PostalAddress con valores válidos", () => { - const result = PostalAddress.create(validAddress); - - expect(result.isSuccess).toBe(true); - expect(result.data).toBeInstanceOf(PostalAddress); - }); - - test("❌ Debería fallar al crear un PostalAddress con código postal inválido", () => { - const invalidAddress = { ...validAddress, postalCode: "abc" }; // Código postal inválido - const result = PostalAddress.create(invalidAddress); - - expect(result.isFailure).toBe(true); - expect(result.error?.message).toBe("Invalid postal code format"); - }); - - test("✅ `createNullable` debería devolver Maybe.none si los valores son nulos o vacíos", () => { - expect(PostalAddress.createNullable().data.isSome()).toBe(false); - expect( - PostalAddress.createNullable({ - street: "", - city: "", - postalCode: "", - state: "", - country: "", - }).data.isSome() - ).toBe(false); - }); - - test("✅ `createNullable` debería devolver Maybe.some si los valores son válidos", () => { - const result = PostalAddress.createNullable(validAddress); - - expect(result.isSuccess).toBe(true); - expect(result.data.isSome()).toBe(true); - expect(result.data.unwrap()).toBeInstanceOf(PostalAddress); - }); - - test("✅ Métodos getters deberían devolver valores esperados", () => { - const address = PostalAddress.create(validAddress).data; - - expect(address.street).toBe(validAddress.street); - expect(address.city).toBe(validAddress.city); - expect(address.postalCode).toBe(validAddress.postalCode); - expect(address.state).toBe(validAddress.state); - expect(address.country).toBe(validAddress.country); - }); - - test("✅ `toString()` debería devolver la representación correcta", () => { - const address = PostalAddress.create(validAddress).data; - const expectedString = `${validAddress.street}, ${validAddress.city}, ${validAddress.postalCode}, ${validAddress.state}, ${validAddress.country}`; - - expect(address.toString()).toBe(expectedString); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.ts b/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.ts deleted file mode 100644 index f24eb194..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/postal-address.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Maybe, Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -// 📌 Validaciones usando `zod` -const postalCodeSchema = z - .string() - .min(4, "Invalid postal code format") - .max(10, "Invalid postal code format") - .regex(/^\d{4,10}$/, { - message: "Invalid postal code format", - }); - -const streetSchema = z.string().min(2).max(255); -const street2Schema = z.string().optional(); -const citySchema = z.string().min(2).max(50); -const stateSchema = z.string().min(2).max(50); -const countrySchema = z.string().min(2).max(56); - -interface IPostalAddressProps { - street: string; - street2?: string; - city: string; - postalCode: string; - state: string; - country: string; -} - -export class PostalAddress extends ValueObject { - protected static validate(values: IPostalAddressProps) { - return z - .object({ - street: streetSchema, - street2: street2Schema, - city: citySchema, - postalCode: postalCodeSchema, - state: stateSchema, - country: countrySchema, - }) - .safeParse(values); - } - - static create(values: IPostalAddressProps): Result { - const valueIsValid = PostalAddress.validate(values); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.errors[0]?.message)); - } - return Result.ok(new PostalAddress(values)); - } - - static createNullable(values?: IPostalAddressProps): Result, Error> { - if (!values || Object.values(values).every((value) => value.trim() === "")) { - return Result.ok(Maybe.none()); - } - - return PostalAddress.create(values).map((value) => Maybe.some(value)); - } - - static update( - oldAddress: PostalAddress, - data: Partial - ): Result { - return PostalAddress.create({ - street: data.street ?? oldAddress.street, - street2: data.street2?.getOrUndefined() ?? oldAddress.street2.getOrUndefined(), - city: data.city ?? oldAddress.city, - postalCode: data.postalCode ?? oldAddress.postalCode, - state: data.state ?? oldAddress.state, - country: data.country ?? oldAddress.country, - }).getOrElse(this); - } - - get street(): string { - return this.props.street; - } - - get street2(): Maybe { - return Maybe.fromNullable(this.props.street2); - } - - get city(): string { - return this.props.city; - } - - get postalCode(): string { - return this.props.postalCode; - } - - get state(): string { - return this.props.state; - } - - get country(): string { - return this.props.country; - } - - getValue(): IPostalAddressProps { - return this.props; - } - - toPrimitive() { - return this.getValue(); - } - - toString(): string { - return `${this.props.street}, ${this.props.street2}, ${this.props.city}, ${this.props.postalCode}, ${this.props.state}, ${this.props.country}`; - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/quantity.spec.ts b/packages.bak/rdx-ddd-domain/src/value-objects/quantity.spec.ts deleted file mode 100644 index 67e01d06..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/quantity.spec.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Quantity } from "./quantity"; - -describe("Quantity", () => { - describe("create", () => { - it("debería crear una cantidad válida", () => { - const result = Quantity.create({ amount: 100, scale: 2 }); - expect(result.isSuccess).toBe(true); - expect(result.data.amount).toBe(100); - expect(result.data.scale).toBe(2); - }); - - it("debería fallar si la escala es negativa", () => { - const result = Quantity.create({ amount: 100, scale: -1 }); - expect(result.isFailure).toBe(true); - }); - }); - - describe("toNumber & toString", () => { - it("debería convertir correctamente a número", () => { - const quantity = Quantity.create({ amount: 150, scale: 2 }).data; - expect(quantity.toNumber()).toBe(1.5); - }); - - it("debería convertir correctamente a string", () => { - const quantity = Quantity.create({ amount: 123, scale: 2 }).data; - expect(quantity.toString()).toBe("1.23"); - }); - }); - - describe("increment", () => { - it("debería incrementar en 1 si no se pasa otra cantidad", () => { - const quantity = Quantity.create({ amount: 100, scale: 2 }).data; - const incremented = quantity.increment().data; - expect(incremented.amount).toBe(101); - expect(incremented.scale).toBe(2); - }); - - it("debería sumar correctamente si tienen la misma escala", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 2 }).data; - - const result = quantity1.increment(quantity2); - expect(result.isSuccess).toBe(true); - expect(result.data.amount).toBe(150); - }); - - it("debería fallar si las escalas son diferentes", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 1 }).data; - - const result = quantity1.increment(quantity2); - expect(result.isFailure).toBe(true); - }); - }); - - describe("decrement", () => { - it("debería decrementar en 1 si no se pasa otra cantidad", () => { - const quantity = Quantity.create({ amount: 100, scale: 2 }).data; - const decremented = quantity.decrement().data; - expect(decremented.amount).toBe(99); - }); - - it("debería restar correctamente si tienen la misma escala", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 2 }).data; - - const result = quantity1.decrement(quantity2); - expect(result.isSuccess).toBe(true); - expect(result.data.amount).toBe(50); - }); - - it("debería fallar si las escalas son diferentes", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 1 }).data; - - const result = quantity1.decrement(quantity2); - expect(result.isFailure).toBe(true); - }); - }); - - describe("convertScale", () => { - it("debería convertir correctamente a una nueva escala", () => { - const quantity = Quantity.create({ amount: 100, scale: 2 }).data; - const result = quantity.convertScale(1); - expect(result.isSuccess).toBe(true); - expect(result.data.amount).toBe(10); - expect(result.data.scale).toBe(1); - }); - - it("debería fallar si la escala está fuera de rango", () => { - const quantity = Quantity.create({ amount: 100, scale: 2 }).data; - const result = quantity.convertScale(3); - expect(result.isFailure).toBe(true); - }); - }); - - describe("hasSameScale", () => { - it("debería retornar true si las escalas son iguales", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 2 }).data; - - expect(quantity1.hasSameScale(quantity2)).toBe(true); - }); - - it("debería retornar false si las escalas son diferentes", () => { - const quantity1 = Quantity.create({ amount: 100, scale: 2 }).data; - const quantity2 = Quantity.create({ amount: 50, scale: 1 }).data; - - expect(quantity1.hasSameScale(quantity2)).toBe(false); - }); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/quantity.ts b/packages.bak/rdx-ddd-domain/src/value-objects/quantity.ts deleted file mode 100644 index 86e06460..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/quantity.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -const DEFAULT_SCALE = 2; - -interface IQuantityProps { - amount: number; - scale: number; -} - -interface IQuantity { - amount: number; - scale: number; - - getValue(): IQuantityProps; - toNumber(): number; - toString(): string; - - isZero(): boolean; - isPositive(): boolean; - isNegative(): boolean; - - increment(anotherQuantity?: Quantity): Result; - decrement(anotherQuantity?: Quantity): Result; - hasSameScale(otherQuantity: Quantity): boolean; - convertScale(newScale: number): Result; -} - -export class Quantity extends ValueObject implements IQuantity { - protected static validate(values: IQuantityProps) { - const schema = z.object({ - amount: z.number().int(), - scale: z.number().int().min(Quantity.MIN_SCALE).max(Quantity.MAX_SCALE), - }); - - return schema.safeParse(values); - } - - public static readonly DEFAULT_SCALE = DEFAULT_SCALE; - public static readonly MIN_SCALE = 0; - public static readonly MAX_SCALE = 2; - - static create(props: IQuantityProps) { - const checkProps = Quantity.validate(props); - - if (!checkProps.success) { - return Result.fail(new Error(checkProps.error.errors[0].message)); - } - return Result.ok(new Quantity({ ...checkProps.data! })); - } - - get amount(): number { - return this.props.amount; - } - - get scale(): number { - return this.props.scale; - } - - getValue(): IQuantityProps { - return this.props; - } - - toPrimitive() { - return this.getValue(); - } - - toNumber(): number { - return this.amount / Math.pow(10, this.scale); - } - - toString(): string { - return this.toNumber().toFixed(this.scale); - } - - isZero(): boolean { - return this.amount === 0; - } - - isPositive(): boolean { - return this.amount > 0; - } - - isNegative(): boolean { - return this.amount < 0; - } - - increment(anotherQuantity?: Quantity): Result { - if (!anotherQuantity) { - return Quantity.create({ - amount: Number(this.amount) + 1, - scale: this.scale, - }); - } - - if (!this.hasSameScale(anotherQuantity)) { - return Result.fail(Error("No se pueden sumar cantidades con diferentes escalas.")); - } - - return Quantity.create({ - amount: Number(this.amount) + Number(anotherQuantity.amount), - scale: this.scale, - }); - } - - decrement(anotherQuantity?: Quantity): Result { - if (!anotherQuantity) { - return Quantity.create({ - amount: Number(this.amount) - 1, - scale: this.scale, - }); - } - - if (!this.hasSameScale(anotherQuantity)) { - return Result.fail(Error("No se pueden restar cantidades con diferentes escalas.")); - } - - return Quantity.create({ - amount: Number(this.amount) - Number(anotherQuantity.amount), - scale: this.scale, - }); - } - - hasSameScale(otherQuantity: Quantity): boolean { - return this.scale === otherQuantity.scale; - } - - convertScale(newScale: number): Result { - if (newScale < Quantity.MIN_SCALE || newScale > Quantity.MAX_SCALE) { - return Result.fail(new Error(`Scale out of range: ${newScale}`)); - } - - const oldFactor = Math.pow(10, this.scale); - const value = Number(this.amount) / oldFactor; - - const newFactor = Math.pow(10, newScale); - const newValue = Math.round(value * newFactor); - - return Quantity.create({ amount: newValue, scale: newScale }); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/slug.spec.ts b/packages.bak/rdx-ddd-domain/src/value-objects/slug.spec.ts deleted file mode 100644 index 9172ddf7..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/slug.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Slug } from "./slug"; // Ajusta la ruta según corresponda - -describe("Slug Value Object", () => { - test("Debe crear un Slug válido", () => { - const slugResult = Slug.create("valid-slug-123"); - expect(slugResult.isSuccess).toBe(true); - expect(slugResult.data.getValue()).toBe("valid-slug-123"); - }); - - test("Debe fallar si el Slug contiene caracteres inválidos", () => { - const slugResult = Slug.create("Invalid_Slug!"); - expect(slugResult.isSuccess).toBe(false); - expect(slugResult.error).toBeInstanceOf(Error); - }); - - test("Debe fallar si el Slug tiene menos de 2 caracteres", () => { - const slugResult = Slug.create("a"); - expect(slugResult.isSuccess).toBe(false); - expect(slugResult.error).toBeInstanceOf(Error); - }); - - test("Debe fallar si el Slug tiene más de 100 caracteres", () => { - const longSlug = "a".repeat(101); - const slugResult = Slug.create(longSlug); - expect(slugResult.isSuccess).toBe(false); - expect(slugResult.error).toBeInstanceOf(Error); - }); - - test("Debe permitir un Slug nullable vacío", () => { - const nullableSlugResult = Slug.createNullable(""); - expect(nullableSlugResult.isSuccess).toBe(true); - expect(nullableSlugResult.data.isSome()).toBe(false); - }); - - test("Debe permitir un Slug nullable con un valor válido", () => { - const nullableSlugResult = Slug.createNullable("my-slug"); - expect(nullableSlugResult.isSuccess).toBe(true); - expect(nullableSlugResult.data.isSome()).toBe(true); - expect(nullableSlugResult.data.getOrUndefined()?.toString()).toBe("my-slug"); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/slug.ts b/packages.bak/rdx-ddd-domain/src/value-objects/slug.ts deleted file mode 100644 index daab1772..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/slug.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Maybe, Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface SlugProps { - value: string; -} - -export class Slug extends ValueObject { - protected static readonly MIN_LENGTH = 2; - protected static readonly MAX_LENGTH = 100; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .regex(/^[a-z0-9-]+$/, { - message: "Slug must contain only lowercase letters, numbers, and hyphens", - }) - .min(Slug.MIN_LENGTH, { message: `Slug must be at least ${Slug.MIN_LENGTH} characters long` }) - .max(Slug.MAX_LENGTH, { message: `Slug must be at most ${Slug.MAX_LENGTH} characters long` }); - return schema.safeParse(value); - } - - static create(value: string) { - const valueIsValid = Slug.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.issues[0].message)); - } - return Result.ok(new Slug({ value: valueIsValid.data! })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return Slug.create(value).map((value: Slug) => Maybe.some(value)); - } - - getValue(): string { - return this.props.value; - } - - toPrimitive(): string { - return this.getValue(); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.test.ts deleted file mode 100644 index 39f7b6e1..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { TINNumber } from "./tin-number"; - -describe("TINNumber", () => { - it("debería crear un TINNumber válido", () => { - const result = TINNumber.create("12345"); - expect(result.isSuccess).toBe(true); - expect(result.data.getValue()).toBe("12345"); - }); - - it("debería fallar si el valor es demasiado corto", () => { - const result = TINNumber.create("1"); - expect(result.isFailure).toBe(true); - expect(result.error?.message).toBe("TIN must be at least 2 characters long"); - }); - - it("debería fallar si el valor es demasiado largo", () => { - const result = TINNumber.create("12345678901"); - expect(result.isFailure).toBe(true); - expect(result.error?.message).toBe("TIN must be at most 10 characters long"); - }); - - it("debería devolver None cuando el valor es nulo o vacío en createNullable", () => { - const result = TINNumber.createNullable(""); - expect(result.isSuccess).toBe(true); - expect(result.data.isNone()).toBe(true); - }); - - it("debería devolver Some cuando el valor es válido en createNullable", () => { - const result = TINNumber.createNullable("6789"); - expect(result.isSuccess).toBe(true); - expect(result.data.isSome()).toBe(true); - expect(result.data.unwrap()?.toString()).toBe("6789"); - }); - - it("debería devolver el valor correcto en toString()", () => { - const result = TINNumber.create("ABC123"); - expect(result.isSuccess).toBe(true); - expect(result.data.toString()).toBe("ABC123"); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.ts b/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.ts deleted file mode 100644 index 364d9800..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/tin-number.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Maybe, Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface TINNumberProps { - value: string; -} - -export class TINNumber extends ValueObject { - private static readonly MIN_LENGTH = 2; - private static readonly MAX_LENGTH = 10; - - protected static validate(value: string) { - const schema = z - .string() - .trim() - .min(TINNumber.MIN_LENGTH, { - message: `TIN must be at least ${TINNumber.MIN_LENGTH} characters long`, - }) - .max(TINNumber.MAX_LENGTH, { - message: `TIN must be at most ${TINNumber.MAX_LENGTH} characters long`, - }); - - return schema.safeParse(value); - } - - static create(value: string): Result { - const valueIsValid = TINNumber.validate(value); - - if (!valueIsValid.success) { - return Result.fail(new Error(valueIsValid.error.errors[0]?.message)); - } - return Result.ok(new TINNumber({ value: valueIsValid.data! })); - } - - static createNullable(value?: string): Result, Error> { - if (!value || value.trim() === "") { - return Result.ok(Maybe.none()); - } - - return TINNumber.create(value).map((value) => Maybe.some(value)); - } - - getValue(): string { - return this.props.value; - } - - toPrimitive(): string { - return this.props.value; - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.test.ts deleted file mode 100644 index c656b0aa..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { UniqueID } from "./unique-id"; - -// Mock UUID generation to ensure predictable tests -jest.mock("uuid", () => ({ v4: () => "123e4567-e89b-12d3-a456-426614174000" })); - -describe("UniqueID", () => { - test("should create a UniqueID with a valid UUID", () => { - const id = "123e4567-e89b-12d3-a456-426614174000"; - const result = UniqueID.create(id); - - expect(result.isSuccess).toBe(true); - expect(result.data.toString()).toBe(id); - }); - - test("should generate a UniqueID with a valid UUID", () => { - const result = UniqueID.generate(); - - expect(result.isSuccess).toBe(true); - expect(result.data.toString()).toBeTruthy(); - }); - - test("should fail to create UniqueID with an invalid UUID", () => { - const result = UniqueID.create("invalid-uuid"); - - expect(result.isFailure).toBe(true); - }); - - test("should fail when id is undefined and generateOnEmpty is false", () => { - const result = UniqueID.create(undefined, false); - - expect(result.isFailure).toBe(true); - }); - - test("should generate a new UUID when id is undefined and generateOnEmpty is true", () => { - const result = UniqueID.create(undefined, true); - - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBeTruthy(); - }); - - test("should fail when id is null", () => { - const result = UniqueID.create(null as any); - - expect(result.isFailure).toBe(true); - }); - - test("should create a UniqueID when id is an empty string and generateOnEmpty is true", () => { - const result = UniqueID.create(" ", true); - - expect(result.isSuccess).toBe(true); - expect(result.data?.toString()).toBeTruthy(); - }); - - test("should fail when id is an empty string and generateOnEmpty is false", () => { - const result = UniqueID.create(" ", false); - - expect(result.isFailure).toBe(true); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.ts b/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.ts deleted file mode 100644 index bfdf261f..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/unique-id.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Result } from "@rdx/utils"; -import { v4 as uuidv4 } from "uuid"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -export class UniqueID extends ValueObject { - static create(id?: string, generateOnEmpty = false): Result { - if (!id || id?.trim() === "") { - if (!generateOnEmpty) { - return Result.fail(new Error("ID cannot be undefined or null")); - } - return UniqueID.generateNewID(); - } - - const result = UniqueID.validate(id!); - - return result.success - ? Result.ok(new UniqueID(result.data)) - : Result.fail(new Error(result.error.errors[0]?.message)); - } - - static generate(): Result { - return Result.ok(new UniqueID(uuidv4())); - } - - static validate(id: string) { - const schema = z.string().trim().uuid({ message: "Invalid UUID format" }); - return schema.safeParse(id); - } - - static generateNewID(): Result { - return Result.ok(new UniqueID(uuidv4())); - } - - getValue(): string { - return this.props; - } - - toString(): string { - return this.getValue(); - } - - toPrimitive() { - return this.getValue(); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.test.ts deleted file mode 100644 index 4eb2b57e..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { UtcDate } from "./utc-date"; - -describe("UtcDate Value Object con Zod y Result", () => { - test("Debe crear una instancia con fecha y hora en UTC", () => { - const result = UtcDate.create("2025-01-06T19:36:18Z"); - expect(result.isSuccess).toBe(true); - expect(result.data?.toISOString()).toBe("2025-01-06T19:36:18.000Z"); - expect(result.data?.toDateString()).toBe("2025-01-06"); - }); - - test("Debe crear una instancia con solo fecha (sin hora)", () => { - const result = UtcDate.create("2020-11-12"); - expect(result.isSuccess).toBe(true); - expect(result.data?.toISOString()).toBe("2020-11-12T00:00:00.000Z"); // Normalizado con 00:00 UTC - expect(result.data?.toDateString()).toBe("2020-11-12"); - }); - - test("Debe devolver un Result.fail para formatos inválidos", () => { - expect(UtcDate.create("2020-07-32").isFailure).toBe(true); - expect(UtcDate.create("invalid-date").isFailure).toBe(true); - expect(UtcDate.create("2020/11/12").isFailure).toBe(true); - }); - - test("Debe comparar correctamente dos fechas idénticas", () => { - const date1 = UtcDate.create("2023-12-31T23:59:59Z").data!; - const date2 = UtcDate.create("2023-12-31T23:59:59Z").data!; - expect(date1.equals(date2)).toBe(true); - }); - - test("Debe comparar correctamente dos fechas diferentes", () => { - const date1 = UtcDate.create("2023-12-31T23:59:59Z").data!; - const date2 = UtcDate.create("2023-12-30T23:59:59Z").data!; - expect(date1.equals(date2)).toBe(false); - }); - - test("Debe manejar fechas sin hora correctamente en equals", () => { - const date1 = UtcDate.create("2020-11-12").data!; - const date2 = UtcDate.create("2020-11-12T00:00:00Z").data!; - expect(date1.equals(date2)).toBe(true); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.ts b/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.ts deleted file mode 100644 index 94648aef..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/utc-date.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Result } from "@rdx/utils"; -import * as z from "zod/v4"; -import { ValueObject } from "./value-object"; - -interface IUtcDateProps { - value: string; -} - -export class UtcDate extends ValueObject { - private readonly date!: Date; - - private constructor(props: IUtcDateProps) { - super(props); - const { value: dateString } = props; - this.date = Object.freeze(new Date(dateString)); - } - - static validate(dateString: string) { - const dateStr = z.union([ - z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/, "Invalid ISO 8601 format"), - z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format"), - ]); - - const dateStrToDate = dateStr.pipe(z.coerce.date()); - - return dateStrToDate.safeParse(dateString); - } - - /** - * Crea una instancia de UtcDate a partir de un string en formato UTC ISO 8601. - * @param dateString Fecha en formato UTC (con o sin hora YYYY-MM-DD) - * @returns UtcDate si es válida, Error en caso contrario. - */ - static create(dateString: string): Result { - const dateIsValid = UtcDate.validate(dateString); - if (!dateIsValid.success) { - return Result.fail(new Error(`Invalid UTC date format: ${dateString}`)); - } - - return Result.ok(new UtcDate({ value: dateString })); - } - - getValue(): string { - return this.props.value; - } - - /** - * Devuelve la fecha completa en formato UTC con hora (ISO 8601). Ejemplo: 2025-12-31T23:59:59Z. - */ - toPrimitive() { - return this.toISOString(); - } - - /** - * Devuelve la fecha en formato UTC sin hora (YYYY-MM-DD). - */ - toDateString(): string { - return this.date.toISOString().split("T")[0] ?? ""; - } - - /** - * Devuelve la fecha en formato UTC con hora (ISO 8601). Ejemplo: 2025-12-31T23:59:59Z. - */ - toISOString(): string { - return this.date.toISOString(); - } - - /** - * Compara si dos instancias de UtcDate son iguales. - */ - equals(other: UtcDate): boolean { - return this.toISOString() === other.toISOString(); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/value-object.ts b/packages.bak/rdx-ddd-domain/src/value-objects/value-object.ts deleted file mode 100644 index d356a178..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/value-object.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { shallowEqual } from "shallow-equal-object"; - -export abstract class ValueObject { - protected readonly props: T; - - protected constructor(props: T) { - this.props = Object.freeze(props); // 🔒 Garantiza inmutabilidad - } - - abstract getValue(): any; - - abstract toPrimitive(): any; - - equals(other: ValueObject): boolean { - if (!(other instanceof ValueObject)) { - return false; - } - - if (other.props === undefined || other.props === null) { - return false; - } - - return shallowEqual(this.props, other.props); - } -} diff --git a/packages.bak/rdx-ddd-domain/src/value-objects/value-objects.test.ts b/packages.bak/rdx-ddd-domain/src/value-objects/value-objects.test.ts deleted file mode 100644 index 6762c11a..00000000 --- a/packages.bak/rdx-ddd-domain/src/value-objects/value-objects.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ValueObject } from "./value-object"; - -interface ITestValueProps { - value: string; -} - -class TestValueObject extends ValueObject { - constructor(value: string) { - super({ value }); - } - - getValue() { - return this.props; - } -} - -describe("ValueObject", () => { - test("debe considerar dos ValueObjects con los mismos valores como iguales", () => { - const vo1 = new TestValueObject("test"); - const vo2 = new TestValueObject("test"); - expect(vo1.equals(vo2)).toBe(true); - }); - - test("debe considerar dos ValueObjects con valores diferentes como distintos", () => { - const vo1 = new TestValueObject("test1"); - const vo2 = new TestValueObject("test2"); - expect(vo1.equals(vo2)).toBe(false); - }); - - test("debe devolver false si el objeto comparado no es una instancia de ValueObject", () => { - const vo1 = new TestValueObject("test"); - expect(vo1.equals({ prop: "test" } as any)).toBe(false); - }); - - test("debe devolver false si el objeto comparado es null o undefined", () => { - const vo1 = new TestValueObject("test"); - expect(vo1.equals(null as any)).toBe(false); - expect(vo1.equals(undefined as any)).toBe(false); - }); - - test("debe garantizar la inmutabilidad de las propiedades", () => { - const vo = new TestValueObject("immutable"); - expect(() => { - (vo as any).props.prop = "mutated"; - }).toThrow(); - }); -}); diff --git a/packages.bak/rdx-ddd-domain/tsconfig.json b/packages.bak/rdx-ddd-domain/tsconfig.json deleted file mode 100644 index 18573208..00000000 --- a/packages.bak/rdx-ddd-domain/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@repo/typescript-config/base.json", - "compilerOptions": { - "outDir": "dist", - "types": ["jest", "node"] - }, - "include": ["."], - "exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"] -} diff --git a/packages.bak/rdx-ddd-domain/turbo.json b/packages.bak/rdx-ddd-domain/turbo.json deleted file mode 100644 index 52a7d7ab..00000000 --- a/packages.bak/rdx-ddd-domain/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } -} diff --git a/packages.bak/rdx-module/package.json b/packages.bak/rdx-module/package.json deleted file mode 100644 index 9ff75b02..00000000 --- a/packages.bak/rdx-module/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@rdx/module", - "version": "0.0.0", - "private": true, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": ["dist/**"], - "scripts": { - "build": "tsc", - "dev": "tsc --watch", - "lint": "eslint src/", - "lint:fix": "eslint src/ --fix", - "typecheck": "tsc --noEmit", - "test": "jest" - }, - "jest": { - "preset": "@repo/jest-presets/node" - }, - "devDependencies": { - "@repo/jest-presets": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/express": "^4.17.21", - "@types/jest": "^29.5.14", - "@types/node": "^22.14.0", - "@types/react": "^19.1.2", - "jest": "^29.7.0", - "typescript": "^5.8.3" - }, - "dependencies": { - "express": "^4.21.2", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "sequelize": "^6.37.5" - } -} diff --git a/packages.bak/rdx-module/src/index.ts b/packages.bak/rdx-module/src/index.ts deleted file mode 100644 index cb2c4139..00000000 --- a/packages.bak/rdx-module/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./module-client.interface"; -export * from "./module-server.interface"; -export * from "./types"; diff --git a/packages.bak/rdx-module/src/module-client.interface.ts b/packages.bak/rdx-module/src/module-client.interface.ts deleted file mode 100644 index 8fa0c672..00000000 --- a/packages.bak/rdx-module/src/module-client.interface.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Contrato para los packages frontend (React) - -import * as React from "react"; -import { ReactNode } from "react"; -import { PackageMetadata } from "./types"; - -export interface PackageClientMetadata extends PackageMetadata { - route: string; - icon?: ReactNode; -} - -export interface IPackageClient { - metadata: PackageClientMetadata; - component: React.FC; - setup?(): void; -} diff --git a/packages.bak/rdx-module/src/module-server.interface.ts b/packages.bak/rdx-module/src/module-server.interface.ts deleted file mode 100644 index 5fb98dc7..00000000 --- a/packages.bak/rdx-module/src/module-server.interface.ts +++ /dev/null @@ -1,10 +0,0 @@ -//Contrato para los packages backend (Node.js) - -import { Express } from "express"; -import { PackageDependencies, PackageMetadata } from "./types"; - -export interface IPackageServer { - metadata: PackageMetadata; - init(app: Express): void; - registerDependencies?(): PackageDependencies; -} diff --git a/packages.bak/rdx-module/src/types.ts b/packages.bak/rdx-module/src/types.ts deleted file mode 100644 index 06d6a8dc..00000000 --- a/packages.bak/rdx-module/src/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Contiene tipos comunes entre cliente y servidor - -import { Model, ModelStatic, Sequelize } from "sequelize"; - -type ModelInitializer = (sequelize: Sequelize) => ModelStatic>; - -export interface PackageMetadata { - name: string; - version: string; - description?: string; - dependencies?: string[]; -} - -export interface PackageDependencies { - models?: ModelInitializer[]; - services?: { [key: string]: any }; -} diff --git a/packages.bak/rdx-module/tsconfig.json b/packages.bak/rdx-module/tsconfig.json deleted file mode 100644 index 18573208..00000000 --- a/packages.bak/rdx-module/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@repo/typescript-config/base.json", - "compilerOptions": { - "outDir": "dist", - "types": ["jest", "node"] - }, - "include": ["."], - "exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"] -} diff --git a/packages.bak/rdx-module/turbo.json b/packages.bak/rdx-module/turbo.json deleted file mode 100644 index 35be9c68..00000000 --- a/packages.bak/rdx-module/turbo.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "outputs": ["dist/**"] - } - } -}