From d7dc148439ed69598650e2f9d20e389fbcaf1989 Mon Sep 17 00:00:00 2001 From: david Date: Sat, 13 Sep 2025 20:45:55 +0200 Subject: [PATCH] Facturas de cliente --- .../presenter-registry.interface.ts | 8 +- .../presenters/presenter-registry.ts | 32 ++-- .../api/application/presenters/presenter.ts | 6 +- .../repositories/repository.interface.ts | 2 +- .../mappers/mapper-registry.interface.ts | 32 ++-- .../infrastructure/mappers/mapper-registry.ts | 80 ++++++-- .../mappers/sequelize-mapper.interface.ts | 5 +- .../mappers/sequelize-read-model-mapper.ts | 6 +- .../sequelize/sequelize-repository.ts | 11 +- ...create-customer-invoice-items.presenter.ts | 45 ----- .../create-customer-invoices.presenter.ts | 69 ------- .../presenter/index.ts | 1 - .../delete-customer-invoice/index.ts | 1 - .../application/get-customer-invoice/index.ts | 2 - .../presenter/InvoiceItem.presenter.ts.bak | 16 -- .../InvoiceParticipant.presenter.ts.bak | 26 --- ...InvoiceParticipantAddress.presenter.ts.bak | 19 -- .../presenter/get-invoice-items.presenter.ts | 47 ----- .../presenter/get-invoice.presenter.ts | 76 -------- .../get-customer-invoice/presenter/index.ts | 1 - .../src/api/application/index.ts | 7 +- .../list-customer-invoices/index.ts | 2 - .../customer-invoice-items.full.presenter.ts | 0 .../customer-invoice.full.presenter.ts | 0 .../{full-domain => domain}/index.ts | 0 .../src/api/application/presenters/index.ts | 4 +- .../list/customer-invoices.list.presenter.ts | 74 -------- .../api/application/presenters/list/index.ts | 1 - .../presenter => presenters/queries}/index.ts | 0 .../list-customer-invoices.presenter.ts | 0 .../update-customer-invoice/index.ts | 2 - .../presenter/index.ts | 1 - .../update-invoice-items.presenter.ts | 46 ----- .../presenter/update-invoice.presenter.ts | 110 ----------- .../create-customer-invoice.use-case.ts | 7 +- .../create}/index.ts | 1 - ...ap-dto-to-create-customer-invoice-props.ts | 19 +- .../delete-customer-invoice.use-case.ts | 0 .../get-customer-invoice.use-case.ts | 2 +- .../src/api/application/use-cases/index.ts | 5 + .../list-customer-invoices.use-case.ts | 4 +- .../delete-customer-invoice.use-case.ts | 54 ++++++ .../report}/index.ts | 0 .../report-customer-invoice.use-case.ts | 2 +- .../reporter/customer-invoice.report.html.ts | 2 +- .../reporter/customer-invoice.report.pdf.ts | 2 +- .../report}/reporter/index.ts | 0 .../templates/customer-invoice/template.hbs | 0 .../customer-invoice/uecko-footer-logos.jpg | Bin .../templates/customer-invoice/uecko-logo.svg | 0 .../update-customer-invoice.use-case.ts | 0 .../src/api/infrastructure/dependencies.ts | 171 ++++++++---------- .../express/customer-invoices.routes.ts | 12 +- .../customer-invoice-item.mapper.ts} | 12 +- .../customer-invoice.mapper.ts} | 12 +- .../infrastructure/mappers/domain/index.ts | 1 + .../invoice-recipient.mapper.ts} | 2 +- .../item-taxes.mapper.ts} | 6 +- .../taxes.mapper.ts} | 6 +- .../mappers/full-domain/index.ts | 1 - .../src/api/infrastructure/mappers/index.ts | 4 +- .../customer-invoice.list.mapper.ts | 8 +- .../mappers/{list => queries}/index.ts | 0 .../invoice-recipient.list.mapper.ts | 8 +- .../sequelize/customer-invoice.repository.ts | 36 ++-- .../src/api/infrastructure/sequelize/index.ts | 13 +- .../customer-invoice-criteria-whitelist.ts | 0 .../customer-invoice-item-tax.model.ts | 2 +- .../customer-invoice-item.model.ts | 0 .../customer-invoice-tax.model.ts | 2 +- .../{ => models}/customer-invoice.model.ts | 0 .../infrastructure/sequelize/models/index.ts | 4 + .../src/api/infrastructure/dependencies.ts | 65 +++---- .../customer.full.mapper.ts} | 14 +- .../infrastructure/mappers/domain/index.ts | 1 + .../src/api/infrastructure/mappers/index.ts | 3 +- .../infrastructure/mappers/queries/index.ts | 0 .../src/api/infrastructure/sequelize/index.ts | 6 +- .../sequelize/{ => models}/customer.model.ts | 0 .../infrastructure/sequelize/models/index.ts | 1 + .../{ => repositories}/customer.repository.ts | 39 ++-- .../sequelize/repositories/index.ts | 1 + 82 files changed, 416 insertions(+), 844 deletions(-) delete mode 100644 modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoice-items.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts delete mode 100644 modules/customer-invoices/src/api/application/delete-customer-invoice/index.ts delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/index.ts delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceItem.presenter.ts.bak delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipant.presenter.ts.bak delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipantAddress.presenter.ts.bak delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice-items.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/get-customer-invoice/presenter/index.ts delete mode 100644 modules/customer-invoices/src/api/application/list-customer-invoices/index.ts rename modules/customer-invoices/src/api/application/presenters/{full-domain => domain}/customer-invoice-items.full.presenter.ts (100%) rename modules/customer-invoices/src/api/application/presenters/{full-domain => domain}/customer-invoice.full.presenter.ts (100%) rename modules/customer-invoices/src/api/application/presenters/{full-domain => domain}/index.ts (100%) delete mode 100644 modules/customer-invoices/src/api/application/presenters/list/customer-invoices.list.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/presenters/list/index.ts rename modules/customer-invoices/src/api/application/{list-customer-invoices/presenter => presenters/queries}/index.ts (100%) rename modules/customer-invoices/src/api/application/{list-customer-invoices/presenter => presenters/queries}/list-customer-invoices.presenter.ts (100%) delete mode 100644 modules/customer-invoices/src/api/application/update-customer-invoice/index.ts delete mode 100644 modules/customer-invoices/src/api/application/update-customer-invoice/presenter/index.ts delete mode 100644 modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice-items.presenter.ts delete mode 100644 modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice.presenter.ts rename modules/customer-invoices/src/api/application/{create-customer-invoice => use-cases/create}/create-customer-invoice.use-case.ts (93%) rename modules/customer-invoices/src/api/application/{create-customer-invoice => use-cases/create}/index.ts (64%) rename modules/customer-invoices/src/api/application/{create-customer-invoice => use-cases/create}/map-dto-to-create-customer-invoice-props.ts (93%) rename modules/customer-invoices/src/api/application/{delete-customer-invoice => use-cases}/delete-customer-invoice.use-case.ts (100%) rename modules/customer-invoices/src/api/application/{get-customer-invoice => use-cases}/get-customer-invoice.use-case.ts (95%) create mode 100644 modules/customer-invoices/src/api/application/use-cases/index.ts rename modules/customer-invoices/src/api/application/{list-customer-invoices => use-cases}/list-customer-invoices.use-case.ts (93%) create mode 100644 modules/customer-invoices/src/api/application/use-cases/report/delete-customer-invoice.use-case.ts rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/index.ts (100%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/report-customer-invoice.use-case.ts (96%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/customer-invoice.report.html.ts (93%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/customer-invoice.report.pdf.ts (96%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/index.ts (100%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/templates/customer-invoice/template.hbs (100%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/templates/customer-invoice/uecko-footer-logos.jpg (100%) rename modules/customer-invoices/src/api/application/{report-customer-invoice => use-cases/report}/reporter/templates/customer-invoice/uecko-logo.svg (100%) rename modules/customer-invoices/src/api/application/{update-customer-invoice => use-cases}/update-customer-invoice.use-case.ts (100%) rename modules/customer-invoices/src/api/infrastructure/mappers/{full-domain/customer-invoice-item.full.mapper.ts => domain/customer-invoice-item.mapper.ts} (95%) rename modules/customer-invoices/src/api/infrastructure/mappers/{full-domain/customer-invoice.full.mapper.ts => domain/customer-invoice.mapper.ts} (95%) create mode 100644 modules/customer-invoices/src/api/infrastructure/mappers/domain/index.ts rename modules/customer-invoices/src/api/infrastructure/mappers/{full-domain/invoice-recipient.full.mapper.ts => domain/invoice-recipient.mapper.ts} (98%) rename modules/customer-invoices/src/api/infrastructure/mappers/{full-domain/item-taxes.full.mapper.ts => domain/item-taxes.mapper.ts} (94%) rename modules/customer-invoices/src/api/infrastructure/mappers/{full-domain/taxes.full.mapper.ts => domain/taxes.mapper.ts} (95%) delete mode 100644 modules/customer-invoices/src/api/infrastructure/mappers/full-domain/index.ts rename modules/customer-invoices/src/api/infrastructure/mappers/{list => queries}/customer-invoice.list.mapper.ts (96%) rename modules/customer-invoices/src/api/infrastructure/mappers/{list => queries}/index.ts (100%) rename modules/customer-invoices/src/api/infrastructure/mappers/{list => queries}/invoice-recipient.list.mapper.ts (94%) rename modules/customer-invoices/src/api/infrastructure/sequelize/{ => models}/customer-invoice-criteria-whitelist.ts (100%) rename modules/customer-invoices/src/api/infrastructure/sequelize/{ => models}/customer-invoice-item-tax.model.ts (97%) rename modules/customer-invoices/src/api/infrastructure/sequelize/{ => models}/customer-invoice-item.model.ts (100%) rename modules/customer-invoices/src/api/infrastructure/sequelize/{ => models}/customer-invoice-tax.model.ts (98%) rename modules/customer-invoices/src/api/infrastructure/sequelize/{ => models}/customer-invoice.model.ts (100%) create mode 100644 modules/customer-invoices/src/api/infrastructure/sequelize/models/index.ts rename modules/customers/src/api/infrastructure/mappers/{customer.mapper.ts => domain/customer.full.mapper.ts} (95%) create mode 100644 modules/customers/src/api/infrastructure/mappers/domain/index.ts create mode 100644 modules/customers/src/api/infrastructure/mappers/queries/index.ts rename modules/customers/src/api/infrastructure/sequelize/{ => models}/customer.model.ts (100%) create mode 100644 modules/customers/src/api/infrastructure/sequelize/models/index.ts rename modules/customers/src/api/infrastructure/sequelize/{ => repositories}/customer.repository.ts (84%) create mode 100644 modules/customers/src/api/infrastructure/sequelize/repositories/index.ts diff --git a/modules/core/src/api/application/presenters/presenter-registry.interface.ts b/modules/core/src/api/application/presenters/presenter-registry.interface.ts index 286b15a6..81c5e344 100644 --- a/modules/core/src/api/application/presenters/presenter-registry.interface.ts +++ b/modules/core/src/api/application/presenters/presenter-registry.interface.ts @@ -45,17 +45,19 @@ export interface IPresenterRegistry { /** * Obtiene un mapper de dominio por clave de proyección. */ - getPresenter(key: PresenterKey): IPresenter; + getPresenter( + key: PresenterKey + ): IPresenter; /** * Registra un mapper de dominio bajo una clave de proyección. */ - registerPresenter( + registerPresenter( key: PresenterKey, presenter: IPresenter ): this; registerPresenters( - presenters: Array<{ key: PresenterKey; presenter: IPresenter }> + presenters: Array<{ key: PresenterKey; presenter: IPresenter }> ): this; } diff --git a/modules/core/src/api/application/presenters/presenter-registry.ts b/modules/core/src/api/application/presenters/presenter-registry.ts index 8f7245a1..ca304168 100644 --- a/modules/core/src/api/application/presenters/presenter-registry.ts +++ b/modules/core/src/api/application/presenters/presenter-registry.ts @@ -12,6 +12,20 @@ export class InMemoryPresenterRegistry implements IPresenterRegistry { }; } + /** + * 🔹 Construye la clave única para el registro. + */ + private _buildKey(key: PresenterKey): string { + const { resource, projection, format, version, locale } = key; + return [ + resource.toLowerCase(), + projection.toLowerCase(), + format!.toLowerCase(), + version ?? "latest", + locale ?? "default", + ].join("::"); + } + private _registerPresenter( key: PresenterKey, presenter: IPresenter @@ -54,7 +68,9 @@ export class InMemoryPresenterRegistry implements IPresenterRegistry { ); } - throw new ApplicationError(`Error. Presenter ${key.resource} ${key.projection} not registred!`); + throw new ApplicationError( + `Error. Presenter ${key.resource} / ${key.projection} not registred!` + ); } registerPresenter( @@ -73,18 +89,4 @@ export class InMemoryPresenterRegistry implements IPresenterRegistry { presenters.forEach(({ key, presenter }) => this._registerPresenter(key, presenter)); return this; } - - /** - * 🔹 Construye la clave única para el registro. - */ - private _buildKey(key: PresenterKey): string { - const { resource, projection, format, version, locale } = key; - return [ - resource.toLowerCase(), - projection.toLowerCase(), - format!.toLowerCase(), - version ?? "latest", - locale ?? "default", - ].join("::"); - } } diff --git a/modules/core/src/api/application/presenters/presenter.ts b/modules/core/src/api/application/presenters/presenter.ts index 870bc02a..d48228b5 100644 --- a/modules/core/src/api/application/presenters/presenter.ts +++ b/modules/core/src/api/application/presenters/presenter.ts @@ -5,7 +5,9 @@ export type IPresenterParams = { presenterRegistry: IPresenterRegistry; } & Record; -export abstract class Presenter implements IPresenter { +export abstract class Presenter + implements IPresenter +{ constructor(protected presenterRegistry: IPresenterRegistry) {} - abstract toOutput(source: T): S; + abstract toOutput(source: TSource): TOutput; } diff --git a/modules/core/src/api/domain/repositories/repository.interface.ts b/modules/core/src/api/domain/repositories/repository.interface.ts index b7c99902..5ac3d3e3 100644 --- a/modules/core/src/api/domain/repositories/repository.interface.ts +++ b/modules/core/src/api/domain/repositories/repository.interface.ts @@ -61,7 +61,7 @@ export type DomainMapperWithBulk = IDomainMapper { +export interface IQueryMapperWithBulk { /** * Convierte un registro crudo en un DTO de lectura. */ diff --git a/modules/core/src/api/infrastructure/mappers/mapper-registry.interface.ts b/modules/core/src/api/infrastructure/mappers/mapper-registry.interface.ts index b4491030..03d9d71a 100644 --- a/modules/core/src/api/infrastructure/mappers/mapper-registry.interface.ts +++ b/modules/core/src/api/infrastructure/mappers/mapper-registry.interface.ts @@ -1,38 +1,42 @@ /** - * 🔑 Claves de proyección comunes para seleccionar mappers en lectura. - * Puedes extender con otras cadenas según tus necesidades ("SUMMARY", "EXPORT", etc.). + * 🔑 Claves de proyección comunes para seleccionar mappers de dominio y de consulta. */ -export type MapperProjectionKey = "FULL" | "LIST" | "REPORT" | (string & {}); + +export type MapperKey = { + resource: string; + query: "LIST" | "REPORT" | (string & {}); // "SUMMARY", "EXPORT", etc. +}; + +export type MapperDomainKey = Pick; + +export type MapperQueryKey = MapperKey; /** * 🏗️ Registro/Fábrica de mappers (Strategy/Factory) - * - Permite resolver diferentes mappers según la proyección (FULL, SUMMARY, etc.) + * - Permite resolver diferentes mappers según la consulta (FULL, SUMMARY, etc.) * - Facilita inyección y test (DIP), evitando dependencias duras en implementaciones concretas. * - * Ejemplo de uso: - * - registry.registerDomainMapper("FULL", customerInvoiceFullMapper); - * - registry.registerReadModelMapper("SUMMARY", customerInvoiceSummaryMapper); - * - registry.registerReadModelMapper("REPORT", customerInvoiceReportMapper); */ export interface IMapperRegistry { /** * Obtiene un mapper de dominio por clave de proyección. */ - getDomainMapper(key: MapperProjectionKey): T; + getDomainMapper(key: MapperDomainKey): T; /** * Obtiene un mapper de read model por clave de proyección. */ - getReadModelMapper(key: MapperProjectionKey): T; + getQueryMapper(key: MapperQueryKey): T; /** - * Registra un mapper de dominio bajo una clave de proyección. + * Registra mapper de dominio bajo una clave de proyección. */ - registerDomainMapper(key: MapperProjectionKey, mapper: T): void; + registerDomainMapper(key: MapperDomainKey, mapper: T): this; /** - * Registra un mapper de read model bajo una clave de proyección. + * Registra un mapper de query / read model bajo una clave de proyección. */ - registerReadModelMapper(key: MapperProjectionKey, mapper: T): void; + registerQueryMapper(key: MapperQueryKey, mapper: T): this; + registerQueryMappers(mappers: Array<{ key: MapperQueryKey; mapper: any }>): this; } diff --git a/modules/core/src/api/infrastructure/mappers/mapper-registry.ts b/modules/core/src/api/infrastructure/mappers/mapper-registry.ts index 9176de5b..07208373 100644 --- a/modules/core/src/api/infrastructure/mappers/mapper-registry.ts +++ b/modules/core/src/api/infrastructure/mappers/mapper-registry.ts @@ -1,30 +1,78 @@ import { InfrastructureError } from "../errors"; -import { IMapperRegistry, MapperProjectionKey } from "./mapper-registry.interface"; +import { + IMapperRegistry, + MapperDomainKey, + MapperKey, + MapperQueryKey, +} from "./mapper-registry.interface"; export class InMemoryMapperRegistry implements IMapperRegistry { - private domainMappers: Map = new Map(); - private readModelMappers: Map = new Map(); + private _mappers: Map = new Map(); - getDomainMapper(key: MapperProjectionKey): T { - if (!this.domainMappers.has(key)) { - throw new InfrastructureError(`Error. Domain model mapper ${key} not registred!`); + private _normalizeKey(key: MapperDomainKey | MapperQueryKey): MapperKey { + const { resource, query } = key as { + resource: string; + query?: string; + }; + + return { + resource, + query: query ?? "DOMAIN", // 👈 valor por defecto + }; + } + + /** + * 🔹 Construye la clave única para el registro. + */ + private _buildKey(key: MapperKey): string { + const { resource, query } = key as { + resource: string; + query?: string; + }; + return [resource.toLowerCase(), query ?? "DOMAIN"].join("::"); + } + + private _getMapper(key: MapperKey): T { + const normalizedKey = this._normalizeKey(key); + const exactKey = this._buildKey(normalizedKey); + + if (!this._mappers.has(exactKey)) { + throw new InfrastructureError(`Error. Mapper ${normalizedKey.resource} not registred!`); } - return this.domainMappers.get(key); + return this._mappers.get(exactKey); } - getReadModelMapper(key: MapperProjectionKey): T { - if (!this.readModelMappers.has(key)) { - throw new InfrastructureError(`Error. Read model mapper ${key} not registred!`); - } - return this.readModelMappers.get(key); + getDomainMapper(key: MapperDomainKey): T { + const normalizedKey = this._normalizeKey({ + resource: key.resource, + query: "DOMAIN", + }); + return this._getMapper(normalizedKey); } - registerDomainMapper(key: MapperProjectionKey, mapper: T): void { - this.domainMappers.set(key, mapper); + getQueryMapper(key: MapperQueryKey): T { + const normalizedKey = this._normalizeKey({ + resource: key.resource, + query: "DOMAIN", + }); + return this._getMapper(normalizedKey); } - registerReadModelMapper(key: MapperProjectionKey, mapper: T): void { - this.readModelMappers.set(key, mapper); + registerDomainMapper(key: MapperDomainKey, mapper: T) { + const exactKey = this._buildKey(this._normalizeKey(key)); + this._mappers.set(exactKey, mapper); + return this; + } + + registerQueryMapper(key: MapperQueryKey, mapper: T) { + const exactKey = this._buildKey(this._normalizeKey(key)); + this._mappers.set(exactKey, mapper); + return this; + } + + registerQueryMappers(mappers: Array<{ key: MapperQueryKey; mapper: any }>): this { + mappers.forEach(({ key, mapper }) => this.registerQueryMapper(key, mapper)); + return this; } } diff --git a/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-mapper.interface.ts b/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-mapper.interface.ts index 236b7ffd..3b260c4f 100644 --- a/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-mapper.interface.ts +++ b/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-mapper.interface.ts @@ -1,7 +1,6 @@ -import { DomainMapperWithBulk, IReadModelMapperWithBulk } from "../../../domain"; +import { DomainMapperWithBulk, IQueryMapperWithBulk } from "../../../domain"; export interface ISequelizeDomainMapper extends DomainMapperWithBulk {} -export interface ISequelizeReadModelMapper - extends IReadModelMapperWithBulk {} +export interface ISequelizeQueryMapper extends IQueryMapperWithBulk {} diff --git a/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-read-model-mapper.ts b/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-read-model-mapper.ts index f5c308f0..455bb48d 100644 --- a/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-read-model-mapper.ts +++ b/modules/core/src/api/infrastructure/sequelize/mappers/sequelize-read-model-mapper.ts @@ -1,10 +1,10 @@ import { Collection, Result } from "@repo/rdx-utils"; import { Model } from "sequelize"; import { MapperParamsType } from "../../../domain"; -import { ISequelizeReadModelMapper } from "./sequelize-mapper.interface"; +import { ISequelizeQueryMapper } from "./sequelize-mapper.interface"; -export abstract class SequelizeReadModelMapper - implements ISequelizeReadModelMapper +export abstract class SequelizeQueryMapper + implements ISequelizeQueryMapper { public abstract mapToDTO(raw: TModel, params?: MapperParamsType): Result; diff --git a/modules/core/src/api/infrastructure/sequelize/sequelize-repository.ts b/modules/core/src/api/infrastructure/sequelize/sequelize-repository.ts index 1426dfb8..9d5a9f94 100644 --- a/modules/core/src/api/infrastructure/sequelize/sequelize-repository.ts +++ b/modules/core/src/api/infrastructure/sequelize/sequelize-repository.ts @@ -1,9 +1,18 @@ import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/server"; import { IAggregateRootRepository, UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; -import { FindOptions, ModelDefined, Transaction } from "sequelize"; +import { FindOptions, ModelDefined, Sequelize, Transaction } from "sequelize"; +import { IMapperRegistry } from "../mappers"; export abstract class SequelizeRepository implements IAggregateRootRepository { + protected readonly _database!: Sequelize; + protected readonly _registry!: IMapperRegistry; + + constructor(params: { mapperRegistry: IMapperRegistry; database: Sequelize }) { + this._registry = params.mapperRegistry; + this._database = params.database; + } + protected convertCriteria(criteria: Criteria): FindOptions { return new CriteriaToSequelizeConverter().convert(criteria); } diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoice-items.presenter.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoice-items.presenter.ts deleted file mode 100644 index 30fdb652..00000000 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoice-items.presenter.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { toEmptyString } from "@repo/rdx-ddd"; -import { CreateCustomerInvoiceResponseDTO } from "../../../../common/dto"; -import { CustomerInvoice } from "../../../domain"; - -type CreateCustomerInvoiceItemsByInvoiceIdResponseDTO = CreateCustomerInvoiceResponseDTO["items"]; - -export class CreateCustomerInvoiceItemsPresenter { - toDTO(invoice: CustomerInvoice): CreateCustomerInvoiceItemsByInvoiceIdResponseDTO { - const { items } = invoice; - return items.map((item, index) => ({ - id: item.id.toString(), - position: String(index), - description: toEmptyString(item.description, (value) => value.toPrimitive()), - - quantity: item.quantity.match( - (quantity) => { - const { value, scale } = quantity.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - unit_amount: item.unitAmount.match( - (unitAmount) => { - const { value, scale } = unitAmount.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - discount_percentage: item.discountPercentage.match( - (discountPercentage) => { - const { value, scale } = discountPercentage.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - total_amount: { - value: item.totalAmount.toPrimitive().value.toString(), - scale: item.totalAmount.toPrimitive().scale.toString(), - }, - })); - } -} diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts deleted file mode 100644 index ff878368..00000000 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { UpdateCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto"; -import { toEmptyString } from "@repo/rdx-ddd"; -import { CustomerInvoice } from "../../../domain"; -import { CreateCustomerInvoiceItemsPresenter } from "./create-customer-invoice-items.presenter"; - -export class CreateCustomerInvoicePresenter { - private _itemsPresenter!: CreateCustomerInvoiceItemsPresenter; - - constructor() { - this._itemsPresenter = new CreateCustomerInvoiceItemsPresenter(); - } - - public toDTO(invoice: CustomerInvoice): UpdateCustomerInvoiceByIdResponseDTO { - const items = this._itemsPresenter.toDTO(invoice); - - return { - id: invoice.id.toPrimitive(), - company_id: invoice.companyId.toPrimitive(), - - invoice_number: invoice.invoiceNumber.toString(), - status: invoice.status.toPrimitive(), - series: invoice.series.toString(), - - invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), - - notes: toEmptyString(invoice.notes, (value) => value.toPrimitive()), - - language_code: invoice.languageCode.toPrimitive(), - currency_code: invoice.currencyCode.toPrimitive(), - - subtotal_amount: { - value: invoice.subtotalAmount.value.toString(), - scale: invoice.subtotalAmount.scale.toString(), - }, - - discount_percentage: { - value: invoice.discountPercentage.value.toString(), - scale: invoice.discountPercentage.scale.toString(), - }, - - discount_amount: { - value: invoice.discountAmount.value.toString(), - scale: invoice.discountAmount.scale.toString(), - }, - - taxable_amount: { - value: invoice.taxableAmount.value.toString(), - scale: invoice.taxableAmount.scale.toString(), - }, - - tax_amount: { - value: invoice.taxAmount.value.toString(), - scale: invoice.taxAmount.scale.toString(), - }, - - total_amount: { - value: invoice.totalAmount.value.toString(), - scale: invoice.totalAmount.scale.toString(), - }, - - items, - - metadata: { - entity: "customer-invoices", - }, - }; - } -} diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts deleted file mode 100644 index 2ff37706..00000000 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./create-customer-invoices.presenter"; diff --git a/modules/customer-invoices/src/api/application/delete-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/delete-customer-invoice/index.ts deleted file mode 100644 index abc66bde..00000000 --- a/modules/customer-invoices/src/api/application/delete-customer-invoice/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./delete-customer-invoice.use-case"; diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/get-customer-invoice/index.ts deleted file mode 100644 index c9051f91..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./presenter"; -export * from "./get-customer-invoice.use-case"; diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceItem.presenter.ts.bak b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceItem.presenter.ts.bak deleted file mode 100644 index 2ee2211c..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceItem.presenter.ts.bak +++ /dev/null @@ -1,16 +0,0 @@ -import { CustomerInvoiceItem } from "#/server/domain"; -import { IInvoicingContext } from "#/server/intrastructure"; -import { Collection } from "@rdx/core"; - -export const customerInvoiceItemPresenter = (items: Collection, context: IInvoicingContext) => - items.totalCount > 0 - ? items.items.map((item: CustomerInvoiceItem) => ({ - 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/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipant.presenter.ts.bak b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipant.presenter.ts.bak deleted file mode 100644 index bc6cdebe..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipant.presenter.ts.bak +++ /dev/null @@ -1,26 +0,0 @@ -import { ICustomerInvoiceParticipant } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateCustomerInvoice_Participant_Response_DTO } from "@shared/contexts"; -import { CustomerInvoiceParticipantAddressPresenter } from "./CustomerInvoiceParticipantAddress.presenter"; - -export const CustomerInvoiceParticipantPresenter = async ( - participant: ICustomerInvoiceParticipant, - 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 CustomerInvoiceParticipantAddressPresenter( - participant.billingAddress!, - context, - ), - shipping_address: await CustomerInvoiceParticipantAddressPresenter( - participant.shippingAddress!, - context, - ), - }; -}; diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipantAddress.presenter.ts.bak b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipantAddress.presenter.ts.bak deleted file mode 100644 index b006790b..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/InvoiceParticipantAddress.presenter.ts.bak +++ /dev/null @@ -1,19 +0,0 @@ -import { CustomerInvoiceParticipantAddress } from "@/contexts/invoicing/domain"; -import { IInvoicingContext } from "@/contexts/invoicing/intrastructure/InvoicingContext"; -import { ICreateCustomerInvoice_AddressParticipant_Response_DTO } from "@shared/contexts"; - -export const CustomerInvoiceParticipantAddressPresenter = async ( - address: CustomerInvoiceParticipantAddress, - 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/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice-items.presenter.ts b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice-items.presenter.ts deleted file mode 100644 index 36a65e9d..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice-items.presenter.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { toEmptyString } from "@repo/rdx-ddd"; -import { GetCustomerInvoiceByIdResponseDTO } from "../../../../common/dto"; -import { CustomerInvoice } from "../../../domain"; - -type GetCustomerInvoiceItemsByInvoiceIdResponseDTO = GetCustomerInvoiceByIdResponseDTO["items"]; - -export class GetCustomerInvoiceItemsPresenter { - toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO { - const { items } = invoice; - - return items.map((item, index) => { - const amounts = item.getAllAmounts(); - - return { - id: item.id.toString(), - position: String(index), - description: toEmptyString(item.description, (value) => value.toPrimitive()), - - quantity: item.quantity.match( - (quantity) => { - const { value, scale } = quantity.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - unit_amount: item.unitAmount.match( - (unitAmount) => { - const { value, scale } = unitAmount.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - discount_percentage: item.discountPercentage.match( - (discountPercentage) => { - const { value, scale } = discountPercentage.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - total_amount: amounts.totalAmount.toPrimitive(), - }; - }); - } -} diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice.presenter.ts b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice.presenter.ts deleted file mode 100644 index 0e7fa2df..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/get-invoice.presenter.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { IPresenter, IPresenterRegistry } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; -import { GetCustomerInvoiceByIdResponseDTO } from "../../../../common/dto"; -import { CustomerInvoice } from "../../../domain"; -import { GetCustomerInvoiceItemsPresenter } from "./get-invoice-items.presenter"; - -export class GetCustomerInvoicePresentwer implements IPresenter { - private _itemsPresenter!: GetCustomerInvoiceItemsPresenter; - - constructor(private presenterRegistry: IPresenterRegistry) { - this._itemsPresenter = this.presenterRegistry.getPresenter({ - resource: "customer-invoice-item", - projection: "FULL", - }); - } - - toOutput(params: { - invoice: CustomerInvoice; - }): GetCustomerInvoiceByIdResponseDTO { - const { invoice } = params; - const items = this._itemsPresenter.toDTO(invoice); - - return { - id: invoice.id.toString(), - company_id: invoice.companyId.toString(), - - invoice_number: invoice.invoiceNumber.toString(), - status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (value) => value.toString()), - - invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), - - notes: toEmptyString(invoice.notes, (value) => value.toString()), - - language_code: invoice.languageCode.toString(), - currency_code: invoice.currencyCode.toString(), - - /*subtotal_amount: { - value: invoice.subtotalAmount.value.toString(), - scale: invoice.subtotalAmount.scale.toString(), - }, - - discount_percentage: { - value: invoice.discountPercentage.value.toString(), - scale: invoice.discountPercentage.scale.toString(), - }, - - discount_amount: { - value: invoice.discountAmount.value.toString(), - scale: invoice.discountAmount.scale.toString(), - }, - - taxable_amount: { - value: invoice.taxableAmount.value.toString(), - scale: invoice.taxableAmount.scale.toString(), - }, - - tax_amount: { - value: invoice.taxAmount.value.toString(), - scale: invoice.taxAmount.scale.toString(), - }, - - total_amount: { - value: invoice.totalAmount.value.toString(), - scale: invoice.totalAmount.scale.toString(), - },*/ - - items, - - metadata: { - entity: "customer-invoices", - }, - }; - } -} diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/index.ts b/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/index.ts deleted file mode 100644 index 60624c19..00000000 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./get-invoice.presenter"; diff --git a/modules/customer-invoices/src/api/application/index.ts b/modules/customer-invoices/src/api/application/index.ts index e3d93e2d..8643bc2a 100644 --- a/modules/customer-invoices/src/api/application/index.ts +++ b/modules/customer-invoices/src/api/application/index.ts @@ -1,7 +1,2 @@ -export * from "./create-customer-invoice"; -export * from "./delete-customer-invoice"; -export * from "./get-customer-invoice"; -export * from "./list-customer-invoices"; -export * from "./report-customer-invoice"; -//export * from "./update-customer-invoice"; export * from "./presenters"; +export * from "./use-cases"; diff --git a/modules/customer-invoices/src/api/application/list-customer-invoices/index.ts b/modules/customer-invoices/src/api/application/list-customer-invoices/index.ts deleted file mode 100644 index d290b557..00000000 --- a/modules/customer-invoices/src/api/application/list-customer-invoices/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./presenter"; -export * from "./list-customer-invoices.use-case"; diff --git a/modules/customer-invoices/src/api/application/presenters/full-domain/customer-invoice-items.full.presenter.ts b/modules/customer-invoices/src/api/application/presenters/domain/customer-invoice-items.full.presenter.ts similarity index 100% rename from modules/customer-invoices/src/api/application/presenters/full-domain/customer-invoice-items.full.presenter.ts rename to modules/customer-invoices/src/api/application/presenters/domain/customer-invoice-items.full.presenter.ts diff --git a/modules/customer-invoices/src/api/application/presenters/full-domain/customer-invoice.full.presenter.ts b/modules/customer-invoices/src/api/application/presenters/domain/customer-invoice.full.presenter.ts similarity index 100% rename from modules/customer-invoices/src/api/application/presenters/full-domain/customer-invoice.full.presenter.ts rename to modules/customer-invoices/src/api/application/presenters/domain/customer-invoice.full.presenter.ts diff --git a/modules/customer-invoices/src/api/application/presenters/full-domain/index.ts b/modules/customer-invoices/src/api/application/presenters/domain/index.ts similarity index 100% rename from modules/customer-invoices/src/api/application/presenters/full-domain/index.ts rename to modules/customer-invoices/src/api/application/presenters/domain/index.ts diff --git a/modules/customer-invoices/src/api/application/presenters/index.ts b/modules/customer-invoices/src/api/application/presenters/index.ts index cce380e7..9e03d7a9 100644 --- a/modules/customer-invoices/src/api/application/presenters/index.ts +++ b/modules/customer-invoices/src/api/application/presenters/index.ts @@ -1,2 +1,2 @@ -export * from "./full-domain"; -export * from "./list"; +export * from "./domain"; +export * from "./queries"; diff --git a/modules/customer-invoices/src/api/application/presenters/list/customer-invoices.list.presenter.ts b/modules/customer-invoices/src/api/application/presenters/list/customer-invoices.list.presenter.ts deleted file mode 100644 index 054f3067..00000000 --- a/modules/customer-invoices/src/api/application/presenters/list/customer-invoices.list.presenter.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Presenter } from "@erp/core/api"; -import { CustomerInvoiceListDTO } from "@erp/customer-invoices/api/infrastructure"; -import { Criteria } from "@repo/rdx-criteria/server"; -import { toEmptyString } from "@repo/rdx-ddd"; -import { ArrayElement, Collection } from "@repo/rdx-utils"; -import { CustomerInvoiceListResponseDTO } from "../../../../common/dto"; - -export class CustomerInvoicesListPresenter extends Presenter { - protected _map(invoice: CustomerInvoiceListDTO) { - const recipientDTO = invoice.recipient.toObjectString(); - - const invoiceDTO: ArrayElement = { - id: invoice.id.toString(), - company_id: invoice.companyId.toString(), - customer_id: invoice.customerId.toString(), - - invoice_number: invoice.invoiceNumber.toString(), - status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (value) => value.toString()), - - invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), - - recipient: { - customer_id: invoice.customerId.toString(), - ...recipientDTO, - }, - - language_code: invoice.languageCode.code, - currency_code: invoice.currencyCode.code, - - taxes: invoice.taxes, - - subtotal_amount: invoice.subtotalAmount.toObjectString(), - discount_amount: invoice.discountAmount.toObjectString(), - taxable_amount: invoice.taxableAmount.toObjectString(), - taxes_amount: invoice.taxesAmount.toObjectString(), - total_amount: invoice.totalAmount.toObjectString(), - - metadata: { - entity: "customer-invoice", - }, - }; - - return invoiceDTO; - } - - toOutput(params: { - customerInvoices: Collection; - criteria: Criteria; - }): CustomerInvoiceListResponseDTO { - const { customerInvoices, criteria } = params; - - const invoices = customerInvoices.map((invoice) => this._map(invoice)); - const totalItems = customerInvoices.total(); - - return { - page: criteria.pageNumber, - per_page: criteria.pageSize, - total_pages: Math.ceil(totalItems / criteria.pageSize), - total_items: totalItems, - items: invoices, - metadata: { - entity: "customer-invoices", - criteria: criteria.toJSON(), - //links: { - // self: `/api/customer-invoices?page=${criteria.pageNumber}&per_page=${criteria.pageSize}`, - // first: `/api/customer-invoices?page=1&per_page=${criteria.pageSize}`, - // last: `/api/customer-invoices?page=${Math.ceil(totalItems / criteria.pageSize)}&per_page=${criteria.pageSize}`, - //}, - }, - }; - } -} diff --git a/modules/customer-invoices/src/api/application/presenters/list/index.ts b/modules/customer-invoices/src/api/application/presenters/list/index.ts deleted file mode 100644 index 9798e040..00000000 --- a/modules/customer-invoices/src/api/application/presenters/list/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoices.list.presenter"; diff --git a/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/index.ts b/modules/customer-invoices/src/api/application/presenters/queries/index.ts similarity index 100% rename from modules/customer-invoices/src/api/application/list-customer-invoices/presenter/index.ts rename to modules/customer-invoices/src/api/application/presenters/queries/index.ts diff --git a/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-customer-invoices.presenter.ts b/modules/customer-invoices/src/api/application/presenters/queries/list-customer-invoices.presenter.ts similarity index 100% rename from modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-customer-invoices.presenter.ts rename to modules/customer-invoices/src/api/application/presenters/queries/list-customer-invoices.presenter.ts diff --git a/modules/customer-invoices/src/api/application/update-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/update-customer-invoice/index.ts deleted file mode 100644 index 17c138c9..00000000 --- a/modules/customer-invoices/src/api/application/update-customer-invoice/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./presenter"; -export * from "./update-customer-invoice.use-case"; diff --git a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/index.ts b/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/index.ts deleted file mode 100644 index 74e5dbdb..00000000 --- a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./update-invoice.presenter"; diff --git a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice-items.presenter.ts b/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice-items.presenter.ts deleted file mode 100644 index 6c58e592..00000000 --- a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice-items.presenter.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { toEmptyString } from "@repo/rdx-ddd"; -import { UpdateCustomerInvoiceByIdResponseDTO } from "../../../../common/dto"; -import { CustomerInvoice } from "../../../domain"; - -type UpdateCustomerInvoiceItemsByInvoiceIdResponseDTO = - UpdateCustomerInvoiceByIdResponseDTO["items"]; - -export class UpdateCustomerInvoiceItemsPresenter { - toDTO(invoice: CustomerInvoice): UpdateCustomerInvoiceItemsByInvoiceIdResponseDTO { - const { items } = invoice; - return items.map((item, index) => ({ - id: item.id.toString(), - position: String(index), - description: toEmptyString(item.description, (value) => value.toPrimitive()), - - quantity: item.quantity.match( - (quantity) => { - const { value, scale } = quantity.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - unit_amount: item.unitAmount.match( - (unitAmount) => { - const { value, scale } = unitAmount.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - discount_percentage: item.discountPercentage.match( - (discountPercentage) => { - const { value, scale } = discountPercentage.toPrimitive(); - return { value: value.toString(), scale: scale.toString() }; - }, - () => ({ value: "", scale: "" }) - ), - - total_amount: { - value: item.totalAmount.toPrimitive().value.toString(), - scale: item.totalAmount.toPrimitive().scale.toString(), - }, - })); - } -} diff --git a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice.presenter.ts b/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice.presenter.ts deleted file mode 100644 index 79573da4..00000000 --- a/modules/customer-invoices/src/api/application/update-customer-invoice/presenter/update-invoice.presenter.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { toEmptyString } from "@repo/rdx-ddd"; -import { UpdateCustomerInvoiceByIdResponseDTO } from "../../../../common/dto"; -import { CustomerInvoice } from "../../../domain"; -import { UpdateCustomerInvoiceItemsPresenter } from "./update-invoice-items.presenter"; - -export class UpdateCustomerInvoicePresenter { - private _itemsPresenter!: UpdateCustomerInvoiceItemsPresenter; - - constructor() { - this._itemsPresenter = new UpdateCustomerInvoiceItemsPresenter(); - } - - public toDTO(invoice: CustomerInvoice): UpdateCustomerInvoiceByIdResponseDTO { - const items = this._itemsPresenter.toDTO(invoice); - - return { - id: invoice.id.toPrimitive(), - company_id: invoice.companyId.toPrimitive(), - - invoice_number: invoice.invoiceNumber.toString(), - status: invoice.status.toPrimitive(), - series: invoice.series.toString(), - - invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), - - notes: toEmptyString(invoice.notes, (value) => value.toPrimitive()), - - language_code: invoice.languageCode.toPrimitive(), - currency_code: invoice.currencyCode.toPrimitive(), - - subtotal_amount: { - value: invoice.subtotalAmount.value.toString(), - scale: invoice.subtotalAmount.scale.toString(), - }, - - discount_percentage: { - value: invoice.discountPercentage.value.toString(), - scale: invoice.discountPercentage.scale.toString(), - }, - - discount_amount: { - value: invoice.discountAmount.value.toString(), - scale: invoice.discountAmount.scale.toString(), - }, - - taxable_amount: { - value: invoice.taxableAmount.value.toString(), - scale: invoice.taxableAmount.scale.toString(), - }, - - tax_amount: { - value: invoice.taxAmount.value.toString(), - scale: invoice.taxAmount.scale.toString(), - }, - - total_amount: { - value: invoice.totalAmount.value.toString(), - scale: invoice.totalAmount.scale.toString(), - }, - - items, - - metadata: { - entity: "customer-invoices", - }, - - //subtotal: customerInvoice.calculateSubtotal().toPrimitive(), - - //total: customerInvoice.calculateTotal().toPrimitive(), - - /*items: - customerInvoice.items.size() > 0 - ? customerInvoice.items.map((item: CustomerInvoiceItem) => ({ - 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 CustomerInvoiceParticipantPresenter(customerInvoice.senderId, context), - - /*recipient: await CustomerInvoiceParticipantPresenter(customerInvoice.recipient, context), - items: customerInvoiceItemPresenter(customerInvoice.items, context), - - payment_term: { - payment_type: "", - due_date: "", - }, - - due_amount: { - currency: customerInvoice.currency.toString(), - precision: 2, - amount: 0, - }, - - custom_fields: [], - - metadata: { - create_time: "", - last_updated_time: "", - delete_time: "", - },*/ - }; - } -} diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/create/create-customer-invoice.use-case.ts similarity index 93% rename from modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/create/create-customer-invoice.use-case.ts index a070d5ba..368ac1c4 100644 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts +++ b/modules/customer-invoices/src/api/application/use-cases/create/create-customer-invoice.use-case.ts @@ -3,8 +3,8 @@ import { DuplicateEntityError, ITransactionManager } from "@erp/core/api"; import { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; -import { CreateCustomerInvoiceRequestDTO } from "../../../common/dto"; -import { CustomerInvoiceService } from "../../domain"; +import { CreateCustomerInvoiceRequestDTO } from "../../../../common/dto"; +import { CustomerInvoiceService } from "../../../domain"; import { CreateCustomerInvoiceAssembler } from "./assembler"; import { CreateCustomerInvoicePropsMapper } from "./map-dto-to-create-customer-invoice-props"; @@ -18,8 +18,7 @@ export class CreateCustomerInvoiceUseCase { private readonly service: CustomerInvoiceService, private readonly transactionManager: ITransactionManager, private readonly assembler: CreateCustomerInvoiceAssembler, - private readonly taxCatalog: JsonTaxCatalogProvider, - + private readonly taxCatalog: JsonTaxCatalogProvider ) {} public execute(params: CreateCustomerInvoiceUseCaseInput) { diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/use-cases/create/index.ts similarity index 64% rename from modules/customer-invoices/src/api/application/create-customer-invoice/index.ts rename to modules/customer-invoices/src/api/application/use-cases/create/index.ts index ec56b240..e92f8281 100644 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts +++ b/modules/customer-invoices/src/api/application/use-cases/create/index.ts @@ -1,2 +1 @@ -export * from "./presenter"; export * from "./create-customer-invoice.use-case"; diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/map-dto-to-create-customer-invoice-props.ts b/modules/customer-invoices/src/api/application/use-cases/create/map-dto-to-create-customer-invoice-props.ts similarity index 93% rename from modules/customer-invoices/src/api/application/create-customer-invoice/map-dto-to-create-customer-invoice-props.ts rename to modules/customer-invoices/src/api/application/use-cases/create/map-dto-to-create-customer-invoice-props.ts index 33a8e223..988184ea 100644 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/map-dto-to-create-customer-invoice-props.ts +++ b/modules/customer-invoices/src/api/application/use-cases/create/map-dto-to-create-customer-invoice-props.ts @@ -20,7 +20,7 @@ import { Result } from "@repo/rdx-utils"; import { CreateCustomerInvoiceItemRequestDTO, CreateCustomerInvoiceRequestDTO, -} from "../../../common/dto"; +} from "../../../../common/dto"; import { CustomerInvoiceItem, CustomerInvoiceItemDescription, @@ -33,7 +33,7 @@ import { ItemAmount, ItemDiscount, ItemQuantity, -} from "../../domain"; +} from "../../../domain"; /** * Convierte el DTO a las props validadas (CustomerProps). @@ -51,7 +51,7 @@ export class CreateCustomerInvoicePropsMapper { private languageCode?: LanguageCode; private currencyCode?: CurrencyCode; - constructor(params: {taxCatalog: JsonTaxCatalogProvider}) { + constructor(params: { taxCatalog: JsonTaxCatalogProvider }) { this.taxCatalog = params.taxCatalog; this.errors = []; } @@ -63,8 +63,16 @@ export class CreateCustomerInvoicePropsMapper { const defaultStatus = CustomerInvoiceStatus.createDraft(); const invoiceId = extractOrPushError(UniqueID.create(dto.id), "id", this.errors); - const companyId = extractOrPushError(UniqueID.create(dto.company_id), "company_id", this.errors); - const customerId = extractOrPushError(UniqueID.create(dto.customer_id), "customer_id", this.errors); + const companyId = extractOrPushError( + UniqueID.create(dto.company_id), + "company_id", + this.errors + ); + const customerId = extractOrPushError( + UniqueID.create(dto.customer_id), + "customer_id", + this.errors + ); const invoiceNumber = extractOrPushError( CustomerInvoiceNumber.create(dto.invoice_number), @@ -230,4 +238,3 @@ export class CreateCustomerInvoicePropsMapper { return taxes; } } - diff --git a/modules/customer-invoices/src/api/application/delete-customer-invoice/delete-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/delete-customer-invoice.use-case.ts similarity index 100% rename from modules/customer-invoices/src/api/application/delete-customer-invoice/delete-customer-invoice.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/delete-customer-invoice.use-case.ts diff --git a/modules/customer-invoices/src/api/application/get-customer-invoice/get-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/get-customer-invoice.use-case.ts similarity index 95% rename from modules/customer-invoices/src/api/application/get-customer-invoice/get-customer-invoice.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/get-customer-invoice.use-case.ts index 752da3bf..8867fc12 100644 --- a/modules/customer-invoices/src/api/application/get-customer-invoice/get-customer-invoice.use-case.ts +++ b/modules/customer-invoices/src/api/application/use-cases/get-customer-invoice.use-case.ts @@ -2,7 +2,7 @@ import { IPresenterRegistry, ITransactionManager } from "@erp/core/api"; import { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { CustomerInvoiceService } from "../../domain"; -import { CustomerInvoiceFullPresenter } from "../presenters/full-domain"; +import { CustomerInvoiceFullPresenter } from "../presenters/domain"; type GetCustomerInvoiceUseCaseInput = { companyId: UniqueID; diff --git a/modules/customer-invoices/src/api/application/use-cases/index.ts b/modules/customer-invoices/src/api/application/use-cases/index.ts new file mode 100644 index 00000000..b33437d3 --- /dev/null +++ b/modules/customer-invoices/src/api/application/use-cases/index.ts @@ -0,0 +1,5 @@ +export * from "./create"; +export * from "./get-customer-invoice.use-case"; +export * from "./list-customer-invoices.use-case"; +export * from "./report"; +//export * from "./update-customer-invoice.use-case"; diff --git a/modules/customer-invoices/src/api/application/list-customer-invoices/list-customer-invoices.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/list-customer-invoices.use-case.ts similarity index 93% rename from modules/customer-invoices/src/api/application/list-customer-invoices/list-customer-invoices.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/list-customer-invoices.use-case.ts index 5937c964..56230e46 100644 --- a/modules/customer-invoices/src/api/application/list-customer-invoices/list-customer-invoices.use-case.ts +++ b/modules/customer-invoices/src/api/application/use-cases/list-customer-invoices.use-case.ts @@ -5,7 +5,7 @@ import { Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; import { CustomerInvoiceListResponseDTO } from "../../../common/dto"; import { CustomerInvoiceService } from "../../domain"; -import { CustomerInvoicesListPresenter } from "../presenters/list"; +import { ListCustomerInvoicesPresenter } from "../presenters"; type ListCustomerInvoicesUseCaseInput = { companyId: UniqueID; @@ -26,7 +26,7 @@ export class ListCustomerInvoicesUseCase { const presenter = this.presenterRegistry.getPresenter({ resource: "customer-invoice", projection: "LIST", - }) as CustomerInvoicesListPresenter; + }) as ListCustomerInvoicesPresenter; return this.transactionManager.complete(async (transaction: Transaction) => { try { diff --git a/modules/customer-invoices/src/api/application/use-cases/report/delete-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/report/delete-customer-invoice.use-case.ts new file mode 100644 index 00000000..1b823daa --- /dev/null +++ b/modules/customer-invoices/src/api/application/use-cases/report/delete-customer-invoice.use-case.ts @@ -0,0 +1,54 @@ +import { EntityNotFoundError, ITransactionManager } from "@erp/core/api"; +import { UniqueID } from "@repo/rdx-ddd"; +import { Result } from "@repo/rdx-utils"; +import { CustomerInvoiceService } from "../../../domain"; + +type DeleteCustomerInvoiceUseCaseInput = { + companyId: UniqueID; + invoice_id: string; +}; + +export class DeleteCustomerInvoiceUseCase { + constructor( + private readonly service: CustomerInvoiceService, + private readonly transactionManager: ITransactionManager + ) {} + + public execute(params: DeleteCustomerInvoiceUseCaseInput) { + const { invoice_id, companyId } = params; + + const idOrError = UniqueID.create(invoice_id); + + if (idOrError.isFailure) { + return Result.fail(idOrError.error); + } + + const invoiceId = idOrError.data; + + return this.transactionManager.complete(async (transaction) => { + try { + const existsCheck = await this.service.existsByIdInCompany( + companyId, + invoiceId, + transaction + ); + + if (existsCheck.isFailure) { + return Result.fail(existsCheck.error); + } + + const invoiceExists = existsCheck.data; + + if (!invoiceExists) { + return Result.fail( + new EntityNotFoundError("Customer invoice", "id", invoiceId.toString()) + ); + } + + return await this.service.deleteInvoiceByIdInCompany(companyId, invoiceId, transaction); + } catch (error: unknown) { + return Result.fail(error as Error); + } + }); + } +} diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/use-cases/report/index.ts similarity index 100% rename from modules/customer-invoices/src/api/application/report-customer-invoice/index.ts rename to modules/customer-invoices/src/api/application/use-cases/report/index.ts diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/report-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/report/report-customer-invoice.use-case.ts similarity index 96% rename from modules/customer-invoices/src/api/application/report-customer-invoice/report-customer-invoice.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/report/report-customer-invoice.use-case.ts index ce865927..337d771f 100644 --- a/modules/customer-invoices/src/api/application/report-customer-invoice/report-customer-invoice.use-case.ts +++ b/modules/customer-invoices/src/api/application/use-cases/report/report-customer-invoice.use-case.ts @@ -1,7 +1,7 @@ import { IPresenterRegistry, ITransactionManager } from "@erp/core/api"; import { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; -import { CustomerInvoiceService } from "../../domain"; +import { CustomerInvoiceService } from "../../../domain"; import { CustomerInvoiceReportPDFPresenter } from "./reporter"; type ReportCustomerInvoiceUseCaseInput = { diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.html.ts b/modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.html.ts similarity index 93% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.html.ts rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.html.ts index 795c61ab..fc932571 100644 --- a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.html.ts +++ b/modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.html.ts @@ -2,7 +2,7 @@ import { Presenter } from "@erp/core/api"; import * as handlebars from "handlebars"; import { readFileSync } from "node:fs"; import path from "node:path"; -import { CustomerInvoice } from "../../../domain"; +import { CustomerInvoice } from "../../../../domain"; export class CustomerInvoiceReportHTMLPresenter extends Presenter { toOutput(customerInvoice: CustomerInvoice): string { diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.pdf.ts b/modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.pdf.ts similarity index 96% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.pdf.ts rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.pdf.ts index cb6c4488..62addfac 100644 --- a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/customer-invoice.report.pdf.ts +++ b/modules/customer-invoices/src/api/application/use-cases/report/reporter/customer-invoice.report.pdf.ts @@ -1,7 +1,7 @@ import { Presenter } from "@erp/core/api"; import puppeteer from "puppeteer"; import report from "puppeteer-report"; -import { CustomerInvoice } from "../../../domain"; +import { CustomerInvoice } from "../../../../domain"; import { CustomerInvoiceReportHTMLPresenter } from "./customer-invoice.report.html"; // https://plnkr.co/edit/lWk6Yd?preview diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/index.ts b/modules/customer-invoices/src/api/application/use-cases/report/reporter/index.ts similarity index 100% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/index.ts rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/index.ts diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/template.hbs b/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs similarity index 100% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/template.hbs rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/uecko-footer-logos.jpg b/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/uecko-footer-logos.jpg similarity index 100% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/uecko-footer-logos.jpg rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/uecko-footer-logos.jpg diff --git a/modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/uecko-logo.svg b/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/uecko-logo.svg similarity index 100% rename from modules/customer-invoices/src/api/application/report-customer-invoice/reporter/templates/customer-invoice/uecko-logo.svg rename to modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/uecko-logo.svg diff --git a/modules/customer-invoices/src/api/application/update-customer-invoice/update-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/use-cases/update-customer-invoice.use-case.ts similarity index 100% rename from modules/customer-invoices/src/api/application/update-customer-invoice/update-customer-invoice.use-case.ts rename to modules/customer-invoices/src/api/application/use-cases/update-customer-invoice.use-case.ts diff --git a/modules/customer-invoices/src/api/infrastructure/dependencies.ts b/modules/customer-invoices/src/api/infrastructure/dependencies.ts index c8e75595..84b68c67 100644 --- a/modules/customer-invoices/src/api/infrastructure/dependencies.ts +++ b/modules/customer-invoices/src/api/infrastructure/dependencies.ts @@ -1,28 +1,31 @@ -import { JsonTaxCatalogProvider, spainTaxCatalogProvider } from "@erp/core"; +// modules/invoice/infrastructure/invoice-dependencies.factory.ts + import type { IMapperRegistry, IPresenterRegistry, ModuleParams } from "@erp/core/api"; + import { InMemoryMapperRegistry, InMemoryPresenterRegistry, SequelizeTransactionManager, } from "@erp/core/api"; + import { CreateCustomerInvoiceUseCase, CustomerInvoiceFullPresenter, CustomerInvoiceItemsFullPresenter, CustomerInvoiceReportHTMLPresenter, CustomerInvoiceReportPDFPresenter, - DeleteCustomerInvoiceUseCase, GetCustomerInvoiceUseCase, ListCustomerInvoicesPresenter, ListCustomerInvoicesUseCase, ReportCustomerInvoiceUseCase, } from "../application"; +import { JsonTaxCatalogProvider, spainTaxCatalogProvider } from "@erp/core"; import { CustomerInvoiceService } from "../domain"; -import { CustomerInvoiceFullMapper, CustomerInvoiceListMapper } from "./mappers"; +import { CustomerInvoiceDomainMapper, CustomerInvoiceListMapper } from "./mappers"; import { CustomerInvoiceRepository } from "./sequelize"; -type InvoiceDeps = { +export type CustomerInvoiceDeps = { transactionManager: SequelizeTransactionManager; mapperRegistry: IMapperRegistry; presenterRegistry: IPresenterRegistry; @@ -36,111 +39,97 @@ type InvoiceDeps = { get: () => GetCustomerInvoiceUseCase; create: () => CreateCustomerInvoiceUseCase; //update: () => UpdateCustomerInvoiceUseCase; - delete: () => DeleteCustomerInvoiceUseCase; + //delete: () => DeleteCustomerInvoiceUseCase; report: () => ReportCustomerInvoiceUseCase; }; }; -let _presenterRegistry: IPresenterRegistry | null = null; -let _mapperRegistry: IMapperRegistry | null = null; - -let _repo: CustomerInvoiceRepository | null = null; -let _service: CustomerInvoiceService | null = null; -let _catalogs: InvoiceDeps["catalogs"] | null = null; - -export function getInvoiceDependencies(params: ModuleParams): InvoiceDeps { +export function buildCustomerInvoiceDependencies(params: ModuleParams): CustomerInvoiceDeps { const { database } = params; const transactionManager = new SequelizeTransactionManager(database); - if (!_catalogs) _catalogs = { taxes: spainTaxCatalogProvider }; + const catalogs = { taxes: spainTaxCatalogProvider }; - if (!_mapperRegistry) { - _mapperRegistry = new InMemoryMapperRegistry(); - _mapperRegistry.registerDomainMapper( - "FULL", - new CustomerInvoiceFullMapper({ - taxCatalog: _catalogs!.taxes, - }) - ); - _mapperRegistry.registerReadModelMapper("LIST", new CustomerInvoiceListMapper()); - } - if (!_repo) _repo = new CustomerInvoiceRepository({ mapperRegistry: _mapperRegistry, database }); - if (!_service) _service = new CustomerInvoiceService(_repo); - - if (!_presenterRegistry) { - _presenterRegistry = new InMemoryPresenterRegistry(); - _presenterRegistry.registerPresenters([ + // Mapper Registry + const mapperRegistry = new InMemoryMapperRegistry(); + mapperRegistry + .registerDomainMapper( + { resource: "customer-invoice" }, + new CustomerInvoiceDomainMapper({ taxCatalog: catalogs.taxes }) + ) + .registerQueryMappers([ { - key: { - resource: "customer-invoice-items", - projection: "FULL", - }, - presenter: new CustomerInvoiceItemsFullPresenter(_presenterRegistry), - }, - { - key: { - resource: "customer-invoice", - projection: "FULL", - }, - presenter: new CustomerInvoiceFullPresenter(_presenterRegistry), - }, - - { - key: { - resource: "customer-invoice", - projection: "LIST", - }, - presenter: new ListCustomerInvoicesPresenter(_presenterRegistry), - }, - - { - key: { - resource: "customer-invoice", - projection: "REPORT", - format: "HTML", - }, - presenter: new CustomerInvoiceReportHTMLPresenter(_presenterRegistry), - }, - - { - key: { - resource: "customer-invoice", - projection: "REPORT", - format: "PDF", - }, - presenter: new CustomerInvoiceReportPDFPresenter(_presenterRegistry), + key: { resource: "customer-invoice", query: "LIST" }, + mapper: new CustomerInvoiceListMapper(), }, ]); - } + + // Repository & Services + const repo = new CustomerInvoiceRepository({ mapperRegistry, database }); + const service = new CustomerInvoiceService(repo); + + // Presenter Registry + const presenterRegistry = new InMemoryPresenterRegistry(); + presenterRegistry.registerPresenters([ + { + key: { + resource: "customer-invoice-items", + projection: "FULL", + }, + presenter: new CustomerInvoiceItemsFullPresenter(presenterRegistry), + }, + { + key: { + resource: "customer-invoice", + projection: "FULL", + }, + presenter: new CustomerInvoiceFullPresenter(presenterRegistry), + }, + { + key: { + resource: "customer-invoice", + projection: "LIST", + }, + presenter: new ListCustomerInvoicesPresenter(presenterRegistry), + }, + { + key: { + resource: "customer-invoice", + projection: "REPORT", + format: "HTML", + }, + presenter: new CustomerInvoiceReportHTMLPresenter(presenterRegistry), + }, + { + key: { + resource: "customer-invoice", + projection: "REPORT", + format: "PDF", + }, + presenter: new CustomerInvoiceReportPDFPresenter(presenterRegistry), + }, + ]); return { transactionManager, - repo: _repo, - mapperRegistry: _mapperRegistry, - presenterRegistry: _presenterRegistry, - service: _service, - catalogs: _catalogs, - + repo, + mapperRegistry, + presenterRegistry, + service, + catalogs, build: { - list: () => - new ListCustomerInvoicesUseCase(_service!, transactionManager!, _presenterRegistry!), - get: () => new GetCustomerInvoiceUseCase(_service!, transactionManager!, _presenterRegistry!), + list: () => new ListCustomerInvoicesUseCase(service, transactionManager, presenterRegistry), + get: () => new GetCustomerInvoiceUseCase(service, transactionManager, presenterRegistry), create: () => new CreateCustomerInvoiceUseCase( - _service!, - transactionManager!, - _presenterRegistry!, - _catalogs!.taxes + service, + transactionManager, + presenterRegistry, + catalogs.taxes ), - /*update: () => - new UpdateCustomerInvoiceUseCase( - _service!, - transactionManager!, - _presenterRegistry!, - _catalogs!.taxes - ),*/ - delete: () => new DeleteCustomerInvoiceUseCase(_service!, transactionManager!), + // update: () => new UpdateCustomerInvoiceUseCase(service, transactionManager), + // delete: () => new DeleteCustomerInvoiceUseCase(service, transactionManager), report: () => - new ReportCustomerInvoiceUseCase(_service!, transactionManager!, _presenterRegistry!), + new ReportCustomerInvoiceUseCase(service, transactionManager, presenterRegistry), }, }; } diff --git a/modules/customer-invoices/src/api/infrastructure/express/customer-invoices.routes.ts b/modules/customer-invoices/src/api/infrastructure/express/customer-invoices.routes.ts index 11d8a99a..fc24ce9f 100644 --- a/modules/customer-invoices/src/api/infrastructure/express/customer-invoices.routes.ts +++ b/modules/customer-invoices/src/api/infrastructure/express/customer-invoices.routes.ts @@ -5,28 +5,26 @@ import { Sequelize } from "sequelize"; import { CreateCustomerInvoiceRequestSchema, CustomerInvoiceListRequestSchema, - DeleteCustomerInvoiceByIdRequestSchema, GetCustomerInvoiceByIdRequestSchema, ReportCustomerInvoiceByIdRequestSchema, } from "../../../common/dto"; -import { getInvoiceDependencies } from "../dependencies"; +import { buildCustomerInvoiceDependencies } from "../dependencies"; import { CreateCustomerInvoiceController, - DeleteCustomerInvoiceController, GetCustomerInvoiceController, ListCustomerInvoicesController, ReportCustomerInvoiceController, } from "./controllers"; export const customerInvoicesRouter = (params: ModuleParams) => { - const { app, database, baseRoutePath, logger } = params as { + const { app, baseRoutePath, logger } = params as { app: Application; database: Sequelize; baseRoutePath: string; logger: ILogger; }; - const deps = getInvoiceDependencies(params); + const deps = buildCustomerInvoiceDependencies(params); const router: Router = Router({ mergeParams: true }); @@ -94,7 +92,7 @@ export const customerInvoicesRouter = (params: ModuleParams) => { } );*/ - router.delete( + /*router.delete( "/:invoice_id", //checkTabContext, @@ -104,7 +102,7 @@ export const customerInvoicesRouter = (params: ModuleParams) => { const controller = new DeleteCustomerInvoiceController(useCase); return controller.execute(req, res, next); } - ); + );*/ router.get( "/:invoice_id/report", diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice-item.full.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice-item.mapper.ts similarity index 95% rename from modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice-item.full.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice-item.mapper.ts index 089538fe..946e1fe5 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice-item.full.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice-item.mapper.ts @@ -19,28 +19,28 @@ import { ItemTaxes, } from "../../../domain"; import { CustomerInvoiceItemCreationAttributes, CustomerInvoiceItemModel } from "../../sequelize"; -import { ItemTaxesMapper } from "./item-taxes.full.mapper"; +import { ItemTaxesDomainMapper } from "./item-taxes.mapper"; -export interface ICustomerInvoiceItemMapper +export interface ICustomerInvoiceItemDomainMapper extends ISequelizeDomainMapper< CustomerInvoiceItemModel, CustomerInvoiceItemCreationAttributes, CustomerInvoiceItem > {} -export class CustomerInvoiceItemMapper +export class CustomerInvoiceItemDomainMapper extends SequelizeDomainMapper< CustomerInvoiceItemModel, CustomerInvoiceItemCreationAttributes, CustomerInvoiceItem > - implements ICustomerInvoiceItemMapper + implements ICustomerInvoiceItemDomainMapper { - private _taxesMapper: ItemTaxesMapper; + private _taxesMapper: ItemTaxesDomainMapper; constructor(params: MapperParamsType) { super(); - this._taxesMapper = new ItemTaxesMapper(params); + this._taxesMapper = new ItemTaxesDomainMapper(params); } private mapAttributesToDomain(source: CustomerInvoiceItemModel, params?: MapperParamsType) { diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice.full.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice.mapper.ts similarity index 95% rename from modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice.full.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice.mapper.ts index 30135820..db7d70c1 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/customer-invoice.full.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/customer-invoice.mapper.ts @@ -26,24 +26,24 @@ import { } from "../../../domain"; import { InvoiceTaxes } from "../../../domain/entities/invoice-taxes"; import { CustomerInvoiceCreationAttributes, CustomerInvoiceModel } from "../../sequelize"; -import { CustomerInvoiceItemMapper as CustomerInvoiceItemFullMapper } from "./customer-invoice-item.full.mapper"; -import { InvoiceRecipientMapper as InvoiceRecipientFullMapper } from "./invoice-recipient.full.mapper"; -import { TaxesMapper as TaxesFullMapper } from "./taxes.full.mapper"; +import { CustomerInvoiceItemDomainMapper as CustomerInvoiceItemFullMapper } from "./customer-invoice-item.mapper"; +import { InvoiceRecipientDomainMapper as InvoiceRecipientFullMapper } from "./invoice-recipient.mapper"; +import { TaxesDomainMapper as TaxesFullMapper } from "./taxes.mapper"; -export interface ICustomerInvoiceFullMapper +export interface ICustomerInvoiceDomainMapper extends ISequelizeDomainMapper< CustomerInvoiceModel, CustomerInvoiceCreationAttributes, CustomerInvoice > {} -export class CustomerInvoiceFullMapper +export class CustomerInvoiceDomainMapper extends SequelizeDomainMapper< CustomerInvoiceModel, CustomerInvoiceCreationAttributes, CustomerInvoice > - implements ICustomerInvoiceFullMapper + implements ICustomerInvoiceDomainMapper { private _itemsMapper: CustomerInvoiceItemFullMapper; private _recipientMapper: InvoiceRecipientFullMapper; diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/domain/index.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/index.ts new file mode 100644 index 00000000..5d78e8fc --- /dev/null +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/index.ts @@ -0,0 +1 @@ +export * from "./customer-invoice.mapper"; diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/invoice-recipient.full.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/invoice-recipient.mapper.ts similarity index 98% rename from modules/customer-invoices/src/api/infrastructure/mappers/full-domain/invoice-recipient.full.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/domain/invoice-recipient.mapper.ts index 4ac0c50f..fb244660 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/invoice-recipient.full.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/invoice-recipient.mapper.ts @@ -19,7 +19,7 @@ import { Maybe, Result } from "@repo/rdx-utils"; import { CustomerInvoiceProps, InvoiceRecipient } from "../../../domain"; import { CustomerInvoiceModel } from "../../sequelize"; -export class InvoiceRecipientMapper { +export class InvoiceRecipientDomainMapper { public mapToDomain( source: CustomerInvoiceModel, params?: MapperParamsType diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/item-taxes.full.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/item-taxes.mapper.ts similarity index 94% rename from modules/customer-invoices/src/api/infrastructure/mappers/full-domain/item-taxes.full.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/domain/item-taxes.mapper.ts index 51afcf83..ba3c1829 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/item-taxes.full.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/item-taxes.mapper.ts @@ -14,7 +14,7 @@ import { CustomerInvoiceItemTaxModel, } from "../../sequelize"; -export class ItemTaxesMapper extends SequelizeDomainMapper< +export class ItemTaxesDomainMapper extends SequelizeDomainMapper< CustomerInvoiceItemTaxModel, CustomerInvoiceItemCreationAttributes, ItemTax @@ -62,10 +62,10 @@ export class ItemTaxesMapper extends SequelizeDomainMapper< return createResult; } - public mapToPersistence( + /*public mapToPersistence( source: ItemTax, params?: MapperParamsType ): CustomerInvoiceItemCreationAttributes { throw new Error("not implemented"); - } + }*/ } diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/taxes.full.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/domain/taxes.mapper.ts similarity index 95% rename from modules/customer-invoices/src/api/infrastructure/mappers/full-domain/taxes.full.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/domain/taxes.mapper.ts index 082149f2..9e9b10a9 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/taxes.full.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/domain/taxes.mapper.ts @@ -12,7 +12,7 @@ import { CustomerInvoiceProps } from "../../../domain"; import { InvoiceTax } from "../../../domain/entities/invoice-taxes"; import { CustomerInvoiceTaxCreationAttributes, CustomerInvoiceTaxModel } from "../../sequelize"; -export class TaxesMapper extends SequelizeDomainMapper< +export class TaxesDomainMapper extends SequelizeDomainMapper< CustomerInvoiceTaxModel, CustomerInvoiceTaxCreationAttributes, InvoiceTax @@ -64,10 +64,10 @@ export class TaxesMapper extends SequelizeDomainMapper< return createResult; } - public mapToPersistence( + /*public mapToPersistence( source: InvoiceTax, params?: MapperParamsType ): CustomerInvoiceTaxCreationAttributes { throw new Error("not implemented"); - } + }*/ } diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/index.ts b/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/index.ts deleted file mode 100644 index b2cbe530..00000000 --- a/modules/customer-invoices/src/api/infrastructure/mappers/full-domain/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./customer-invoice.full.mapper"; diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/index.ts b/modules/customer-invoices/src/api/infrastructure/mappers/index.ts index cce380e7..9e03d7a9 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/index.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/index.ts @@ -1,2 +1,2 @@ -export * from "./full-domain"; -export * from "./list"; +export * from "./domain"; +export * from "./queries"; diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/list/customer-invoice.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/queries/customer-invoice.list.mapper.ts similarity index 96% rename from modules/customer-invoices/src/api/infrastructure/mappers/list/customer-invoice.list.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/queries/customer-invoice.list.mapper.ts index 0aeb98de..d89ad78f 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/list/customer-invoice.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/queries/customer-invoice.list.mapper.ts @@ -1,7 +1,7 @@ import { - ISequelizeReadModelMapper, + ISequelizeQueryMapper, MapperParamsType, - SequelizeReadModelMapper, + SequelizeQueryMapper, ValidationErrorCollection, ValidationErrorDetail, extractOrPushError, @@ -56,10 +56,10 @@ export type CustomerInvoiceListDTO = { }; export interface ICustomerInvoiceListMapper - extends ISequelizeReadModelMapper {} + extends ISequelizeQueryMapper {} export class CustomerInvoiceListMapper - extends SequelizeReadModelMapper + extends SequelizeQueryMapper implements ICustomerInvoiceListMapper { private _recipientMapper: InvoiceRecipientListMapper; diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/list/index.ts b/modules/customer-invoices/src/api/infrastructure/mappers/queries/index.ts similarity index 100% rename from modules/customer-invoices/src/api/infrastructure/mappers/list/index.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/queries/index.ts diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/list/invoice-recipient.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/queries/invoice-recipient.list.mapper.ts similarity index 94% rename from modules/customer-invoices/src/api/infrastructure/mappers/list/invoice-recipient.list.mapper.ts rename to modules/customer-invoices/src/api/infrastructure/mappers/queries/invoice-recipient.list.mapper.ts index 4826e164..f707daf2 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/list/invoice-recipient.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/queries/invoice-recipient.list.mapper.ts @@ -10,9 +10,9 @@ import { } from "@repo/rdx-ddd"; import { - IReadModelMapperWithBulk, + IQueryMapperWithBulk, MapperParamsType, - SequelizeReadModelMapper, + SequelizeQueryMapper, ValidationErrorDetail, extractOrPushError, } from "@erp/core/api"; @@ -23,10 +23,10 @@ import { CustomerInvoiceModel } from "../../sequelize"; import { CustomerInvoiceListDTO } from "./customer-invoice.list.mapper"; interface IInvoiceRecipientListMapper - extends IReadModelMapperWithBulk {} + extends IQueryMapperWithBulk {} export class InvoiceRecipientListMapper - extends SequelizeReadModelMapper + extends SequelizeQueryMapper implements IInvoiceRecipientListMapper { public mapToDTO( diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts index 6bf3f4ec..94223864 100644 --- a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts @@ -1,37 +1,23 @@ -import { - EntityNotFoundError, - IMapperRegistry, - SequelizeRepository, - translateSequelizeError, -} from "@erp/core/api"; +import { EntityNotFoundError, SequelizeRepository, translateSequelizeError } from "@erp/core/api"; import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/server"; import { UniqueID } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; -import { Sequelize, Transaction } from "sequelize"; +import { Transaction } from "sequelize"; import { CustomerInvoice, ICustomerInvoiceRepository } from "../../domain"; import { CustomerInvoiceListDTO, - ICustomerInvoiceFullMapper, + ICustomerInvoiceDomainMapper, ICustomerInvoiceListMapper, } from "../mappers"; -import { CustomerInvoiceItemTaxModel } from "./customer-invoice-item-tax.model"; -import { CustomerInvoiceItemModel } from "./customer-invoice-item.model"; -import { CustomerInvoiceTaxModel } from "./customer-invoice-tax.model"; -import { CustomerInvoiceModel } from "./customer-invoice.model"; +import { CustomerInvoiceItemTaxModel } from "./models/customer-invoice-item-tax.model"; +import { CustomerInvoiceItemModel } from "./models/customer-invoice-item.model"; +import { CustomerInvoiceTaxModel } from "./models/customer-invoice-tax.model"; +import { CustomerInvoiceModel } from "./models/customer-invoice.model"; export class CustomerInvoiceRepository extends SequelizeRepository implements ICustomerInvoiceRepository { - private readonly _database!: Sequelize; - private readonly _registry!: IMapperRegistry; - - constructor(params: { mapperRegistry: IMapperRegistry; database: Sequelize }) { - super(); - this._registry = params.mapperRegistry; - this._database = params.database; - } - // Listado por tenant con criteria saneada /* async searchInCompany(criteria: any, companyId: string): Promise<{ rows: InvoiceListRow[]; @@ -78,7 +64,9 @@ export class CustomerInvoiceRepository transaction: Transaction ): Promise> { try { - const mapper: ICustomerInvoiceFullMapper = this._registry.getDomainMapper("FULL"); + const mapper: ICustomerInvoiceDomainMapper = this._registry.getDomainMapper({ + resource: "customer-invoice", + }); const mapperData = mapper.mapToPersistence(invoice); if (mapperData.isFailure) { @@ -134,7 +122,7 @@ export class CustomerInvoiceRepository transaction: Transaction ): Promise> { try { - const mapper: ICustomerInvoiceFullMapper = this._registry.getDomainMapper("FULL"); + const mapper: ICustomerInvoiceDomainMapper = this._registry.getDomainMapper("FULL"); const { CustomerModel } = this._database.models; const row = await CustomerInvoiceModel.findOne({ @@ -194,7 +182,7 @@ export class CustomerInvoiceRepository transaction: Transaction ): Promise, Error>> { try { - const mapper: ICustomerInvoiceListMapper = this._registry.getReadModelMapper("LIST"); + const mapper: ICustomerInvoiceListMapper = this._registry.getQueryMapper("LIST"); const { CustomerModel } = this._database.models; const converter = new CriteriaToSequelizeConverter(); const query = converter.convert(criteria); diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/index.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/index.ts index 684b5f52..a632cff3 100644 --- a/modules/customer-invoices/src/api/infrastructure/sequelize/index.ts +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/index.ts @@ -1,13 +1,10 @@ -import customerInvoiceItemTaxesModelInit from "./customer-invoice-item-tax.model"; -import customerInvoiceItemModelInit from "./customer-invoice-item.model"; -import customerInvoiceTaxesModelInit from "./customer-invoice-tax.model"; -import customerInvoiceModelInit from "./customer-invoice.model"; +import customerInvoiceItemTaxesModelInit from "./models/customer-invoice-item-tax.model"; +import customerInvoiceItemModelInit from "./models/customer-invoice-item.model"; +import customerInvoiceTaxesModelInit from "./models/customer-invoice-tax.model"; +import customerInvoiceModelInit from "./models/customer-invoice.model"; -export * from "./customer-invoice-item-tax.model"; -export * from "./customer-invoice-item.model"; -export * from "./customer-invoice-tax.model"; -export * from "./customer-invoice.model"; export * from "./customer-invoice.repository"; +export * from "./models"; // Array de inicializadores para que registerModels() lo use export const models = [ diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-criteria-whitelist.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-criteria-whitelist.ts similarity index 100% rename from modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-criteria-whitelist.ts rename to modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-criteria-whitelist.ts diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-item-tax.model.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-item-tax.model.ts similarity index 97% rename from modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-item-tax.model.ts rename to modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-item-tax.model.ts index bc699142..02dfe97f 100644 --- a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-item-tax.model.ts +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-item-tax.model.ts @@ -6,7 +6,7 @@ import { NonAttribute, Sequelize, } from "sequelize"; -import { CustomerInvoiceItem } from "../../domain"; +import { CustomerInvoiceItem } from "../../../domain"; export type CustomerInvoiceItemTaxCreationAttributes = InferCreationAttributes< CustomerInvoiceItemTaxModel, diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-item.model.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-item.model.ts similarity index 100% rename from modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-item.model.ts rename to modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-item.model.ts diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-tax.model.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-tax.model.ts similarity index 98% rename from modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-tax.model.ts rename to modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-tax.model.ts index 21fd2de4..a680547b 100644 --- a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice-tax.model.ts +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice-tax.model.ts @@ -6,7 +6,7 @@ import { NonAttribute, Sequelize, } from "sequelize"; -import { CustomerInvoice } from "../../domain"; +import { CustomerInvoice } from "../../../domain"; export type CustomerInvoiceTaxCreationAttributes = InferCreationAttributes< CustomerInvoiceTaxModel, diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.model.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice.model.ts similarity index 100% rename from modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.model.ts rename to modules/customer-invoices/src/api/infrastructure/sequelize/models/customer-invoice.model.ts diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/models/index.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/models/index.ts new file mode 100644 index 00000000..b3f2db3b --- /dev/null +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/models/index.ts @@ -0,0 +1,4 @@ +export * from "./customer-invoice-item-tax.model"; +export * from "./customer-invoice-item.model"; +export * from "./customer-invoice-tax.model"; +export * from "./customer-invoice.model"; diff --git a/modules/customers/src/api/infrastructure/dependencies.ts b/modules/customers/src/api/infrastructure/dependencies.ts index 7452829d..c29bd915 100644 --- a/modules/customers/src/api/infrastructure/dependencies.ts +++ b/modules/customers/src/api/infrastructure/dependencies.ts @@ -1,5 +1,9 @@ import type { IMapperRegistry, IPresenterRegistry, ModuleParams } from "@erp/core/api"; -import { InMemoryMapperRegistry, SequelizeTransactionManager } from "@erp/core/api"; +import { + InMemoryMapperRegistry, + InMemoryPresenterRegistry, + SequelizeTransactionManager, +} from "@erp/core/api"; import { CreateCustomerUseCase, @@ -9,10 +13,10 @@ import { UpdateCustomerUseCase, } from "../application"; import { CustomerService } from "../domain"; -import { CustomerMapper } from "./mappers"; +import { CustomerDomainMapper } from "./mappers"; import { CustomerRepository } from "./sequelize"; -type CustomerDeps = { +export type CustomerDeps = { transactionManager: SequelizeTransactionManager; mapperRegistry: IMapperRegistry; presenterRegistry: IPresenterRegistry; @@ -27,46 +31,37 @@ type CustomerDeps = { }; }; -const _presenterRegistry: IPresenterRegistry | null = null; -let _mapperRegistry: IMapperRegistry | null = null; - -let _repo: CustomerRepository | null = null; -let _service: CustomerService | null = null; - -export function getCustomerDependencies(params: ModuleParams): CustomerDeps { +export function buildCustomerDependencies(params: ModuleParams): CustomerDeps { const { database } = params; const transactionManager = new SequelizeTransactionManager(database); - if (!_mapperRegistry) { - _mapperRegistry = new InMemoryMapperRegistry(); - _mapperRegistry.registerDomainMapper("FULL", new CustomerMapper()); - } + // Mapper Registry + const mapperRegistry = new InMemoryMapperRegistry(); + mapperRegistry.registerDomainMapper({ resource: "customer" }, new CustomerDomainMapper()); - if (!_repo) _repo = new CustomerRepository({ mapperRegistry: _mapperRegistry }); - if (!_service) _service = new CustomerService(_repo); + // Repository & Services + const repo = new CustomerRepository({ mapperRegistry: _mapperRegistry, database }); + const service = new CustomerService(repo); - /*if (!_presenterRegistry) { - _presenterRegistry = new InMemoryPresenterRegistry(); - - _presenterRegistry.registerPresenters([ - { - key: { resource: "customer", projection: "FULL" }, - presenter: new ListCustomersAssembler(), - }, - { - key: { resource: "customer", projection: "LIST" }, - presenter: new GetCustomerAssembler(), - }, - ]); - }*/ + // Presenter Registry + const presenterRegistry = new InMemoryPresenterRegistry(); + presenterRegistry.registerPresenters([ + { + key: { resource: "customer", projection: "FULL" }, + presenter: new ListCustomersAssembler(), + }, + { + key: { resource: "customer", projection: "LIST" }, + presenter: new GetCustomerAssembler(), + }, + ]); return { transactionManager, - repo: _repo, - mapperRegistry: _mapperRegistry, - //presenterRegistry: _presenterRegistry, - service: _service, - + repo, + mapperRegistry, + presenterRegistry, + service, build: { /*list: () => new ListCustomersUseCase(_service!, transactionManager!, presenterRegistry!), get: () => new GetCustomerUseCase(_service!, transactionManager!, presenterRegistry!), diff --git a/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts b/modules/customers/src/api/infrastructure/mappers/domain/customer.full.mapper.ts similarity index 95% rename from modules/customers/src/api/infrastructure/mappers/customer.mapper.ts rename to modules/customers/src/api/infrastructure/mappers/domain/customer.full.mapper.ts index dd7132d4..3b9fd05c 100644 --- a/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts +++ b/modules/customers/src/api/infrastructure/mappers/domain/customer.full.mapper.ts @@ -1,5 +1,5 @@ import { - ISequelizeMapper, + ISequelizeDomainMapper, MapperParamsType, SequelizeDomainMapper, ValidationErrorCollection, @@ -27,15 +27,15 @@ import { toNullable, } from "@repo/rdx-ddd"; import { Collection, Result, isNullishOrEmpty } from "@repo/rdx-utils"; -import { Customer, CustomerProps, CustomerStatus } from "../../domain"; -import { CustomerCreationAttributes, CustomerModel } from "../sequelize"; +import { Customer, CustomerProps, CustomerStatus } from "../../../domain"; +import { CustomerCreationAttributes, CustomerModel } from "../../sequelize"; -export interface ICustomerMapper - extends ISequelizeMapper {} +export interface ICustomerDomainMapper + extends ISequelizeDomainMapper {} -export class CustomerMapper +export class CustomerDomainMapper extends SequelizeDomainMapper - implements ICustomerMapper + implements ICustomerDomainMapper { public mapToDomain(source: CustomerModel, params?: MapperParamsType): Result { try { diff --git a/modules/customers/src/api/infrastructure/mappers/domain/index.ts b/modules/customers/src/api/infrastructure/mappers/domain/index.ts new file mode 100644 index 00000000..c0f84fc5 --- /dev/null +++ b/modules/customers/src/api/infrastructure/mappers/domain/index.ts @@ -0,0 +1 @@ +export * from "./customer.full.mapper"; diff --git a/modules/customers/src/api/infrastructure/mappers/index.ts b/modules/customers/src/api/infrastructure/mappers/index.ts index 7f5fae75..9e03d7a9 100644 --- a/modules/customers/src/api/infrastructure/mappers/index.ts +++ b/modules/customers/src/api/infrastructure/mappers/index.ts @@ -1 +1,2 @@ -export * from "./customer.mapper"; +export * from "./domain"; +export * from "./queries"; diff --git a/modules/customers/src/api/infrastructure/mappers/queries/index.ts b/modules/customers/src/api/infrastructure/mappers/queries/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/modules/customers/src/api/infrastructure/sequelize/index.ts b/modules/customers/src/api/infrastructure/sequelize/index.ts index 10c5f64c..6d88de41 100644 --- a/modules/customers/src/api/infrastructure/sequelize/index.ts +++ b/modules/customers/src/api/infrastructure/sequelize/index.ts @@ -1,7 +1,7 @@ -import customerModelInit from "./customer.model"; +import customerModelInit from "./models/customer.model"; -export * from "./customer.model"; -export * from "./customer.repository"; +export * from "./models"; +export * from "./repositories"; // Array de inicializadores para que registerModels() lo use export const models = [customerModelInit]; diff --git a/modules/customers/src/api/infrastructure/sequelize/customer.model.ts b/modules/customers/src/api/infrastructure/sequelize/models/customer.model.ts similarity index 100% rename from modules/customers/src/api/infrastructure/sequelize/customer.model.ts rename to modules/customers/src/api/infrastructure/sequelize/models/customer.model.ts diff --git a/modules/customers/src/api/infrastructure/sequelize/models/index.ts b/modules/customers/src/api/infrastructure/sequelize/models/index.ts new file mode 100644 index 00000000..8141c8ae --- /dev/null +++ b/modules/customers/src/api/infrastructure/sequelize/models/index.ts @@ -0,0 +1 @@ +export * from "./customer.model"; diff --git a/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts b/modules/customers/src/api/infrastructure/sequelize/repositories/customer.repository.ts similarity index 84% rename from modules/customers/src/api/infrastructure/sequelize/customer.repository.ts rename to modules/customers/src/api/infrastructure/sequelize/repositories/customer.repository.ts index 8b5ae4d0..9262858c 100644 --- a/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts +++ b/modules/customers/src/api/infrastructure/sequelize/repositories/customer.repository.ts @@ -3,21 +3,13 @@ import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/serve import { UniqueID } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; -import { Customer, ICustomerRepository } from "../../domain"; -import { ICustomerMapper } from "../mappers/customer.mapper"; -import { CustomerModel } from "./customer.model"; +import { Customer, ICustomerRepository } from "../../../domain"; +import { CustomerModel } from "../models/customer.model"; export class CustomerRepository extends SequelizeRepository implements ICustomerRepository { - private readonly mapper!: ICustomerMapper; - - constructor(mapper: ICustomerMapper) { - super(); - this.mapper = mapper; - } - /** * * Guarda un nuevo cliente o actualiza uno existente. @@ -28,9 +20,20 @@ export class CustomerRepository */ async save(customer: Customer, transaction: Transaction): Promise> { try { - const data = this.mapper.mapToPersistence(customer); + const mapper: ICustomerDomainMapper = this._registry.getDomainMapper({ + resource: "customer", + }); + + const mapperData = mapper.mapToPersistence(customer); + + if (mapperData.isFailure) { + return Result.fail(mapperData.error); + } + + const { data } = mapperData; + const [instance] = await CustomerModel.upsert(data, { transaction, returning: true }); - const savedCustomer = this.mapper.mapToDomain(instance); + const savedCustomer = mapper.mapToDomain(instance); return savedCustomer; } catch (err: unknown) { return Result.fail(translateSequelizeError(err)); @@ -75,6 +78,10 @@ export class CustomerRepository transaction?: Transaction ): Promise> { try { + const mapper: ICustomerDomainMapper = this._registry.getDomainMapper({ + resource: "customer", + }); + const row = await CustomerModel.findOne({ where: { id: id.toString(), company_id: companyId.toString() }, transaction, @@ -84,7 +91,7 @@ export class CustomerRepository return Result.fail(new EntityNotFoundError("Customer", "id", id.toString())); } - const customer = this.mapper.mapToDomain(row); + const customer = mapper.mapToDomain(row); return customer; } catch (error: any) { return Result.fail(translateSequelizeError(error)); @@ -107,6 +114,10 @@ export class CustomerRepository transaction?: Transaction ): Promise>> { try { + const mapper: ICustomerDomainMapper = this._registry.getDomainMapper({ + resource: "customer", + }); + const converter = new CriteriaToSequelizeConverter(); const query = converter.convert(criteria); @@ -120,7 +131,7 @@ export class CustomerRepository transaction, }); - return this.mapper.mapArrayToDomain(instances); + return mapper.mapArrayToDomain(instances); } catch (err: unknown) { return Result.fail(translateSequelizeError(err)); } diff --git a/modules/customers/src/api/infrastructure/sequelize/repositories/index.ts b/modules/customers/src/api/infrastructure/sequelize/repositories/index.ts new file mode 100644 index 00000000..8eeb32c4 --- /dev/null +++ b/modules/customers/src/api/infrastructure/sequelize/repositories/index.ts @@ -0,0 +1 @@ +export * from "./customer.repository";