.
This commit is contained in:
parent
05f048cc72
commit
220d57cb7b
@ -1,32 +1,13 @@
|
||||
// application/issued-invoices/di/snapshot-builders.di.ts
|
||||
|
||||
import { CustomerSummarySnapshotBuilder } from "../snapshot-builders";
|
||||
import { CustomerFullSnapshotBuilder, CustomerSummarySnapshotBuilder } from "../snapshot-builders";
|
||||
|
||||
export function buildCustomerSnapshotBuilders() {
|
||||
/*const itemsBuilder = new CustomerItemsFullSnapshotBuilder();
|
||||
|
||||
const taxesBuilder = new CustomerTaxesFullSnapshotBuilder();
|
||||
|
||||
const recipientBuilder = new CustomerRecipientFullSnapshotBuilder();
|
||||
|
||||
const fullSnapshotBuilder = new CustomerFullSnapshotBuilder(
|
||||
itemsBuilder,
|
||||
recipientBuilder,
|
||||
taxesBuilder
|
||||
);*/
|
||||
|
||||
const fullSnapshotBuilder = new CustomerFullSnapshotBuilder();
|
||||
const summarySnapshotBuilder = new CustomerSummarySnapshotBuilder();
|
||||
|
||||
/*const itemsReportBuilder = new CustomerItemReportSnapshotBuilder();
|
||||
const taxesReportBuilder = new CustomerTaxReportSnapshotBuilder();
|
||||
const reportSnapshotBuilder = new CustomerReportSnapshotBuilder(
|
||||
itemsReportBuilder,
|
||||
taxesReportBuilder
|
||||
);*/
|
||||
|
||||
return {
|
||||
//full: fullSnapshotBuilder,
|
||||
full: fullSnapshotBuilder,
|
||||
summary: summarySnapshotBuilder,
|
||||
//report: reportSnapshotBuilder,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
import type { ITransactionManager } from "@erp/core/api";
|
||||
|
||||
import type { ICustomerFinder } from "../services";
|
||||
import type { ICustomerSummarySnapshotBuilder } from "../snapshot-builders";
|
||||
import { ListCustomersUseCase } from "../use-cases";
|
||||
import type {
|
||||
ICustomerFullSnapshotBuilder,
|
||||
ICustomerSummarySnapshotBuilder,
|
||||
} from "../snapshot-builders";
|
||||
import { GetCustomerByIdUseCase, ListCustomersUseCase } from "../use-cases";
|
||||
|
||||
/*export function buildGetCustomerByIdUseCase(deps: {
|
||||
export function buildGetCustomerByIdUseCase(deps: {
|
||||
finder: ICustomerFinder;
|
||||
fullSnapshotBuilder: ICustomerFullSnapshotBuilder;
|
||||
transactionManager: ITransactionManager;
|
||||
}) {
|
||||
return new GetCustomerByIdUseCase(deps.finder, deps.fullSnapshotBuilder, deps.transactionManager);
|
||||
}*/
|
||||
}
|
||||
|
||||
export function buildListCustomersUseCase(deps: {
|
||||
finder: ICustomerFinder;
|
||||
|
||||
@ -11,12 +11,10 @@ import type {
|
||||
} from "@repo/rdx-ddd";
|
||||
import type { Maybe } from "@repo/rdx-utils";
|
||||
|
||||
import type { CustomerStatus } from "../../domain";
|
||||
|
||||
export type CustomerSummary = {
|
||||
id: UniqueID;
|
||||
companyId: UniqueID;
|
||||
status: CustomerStatus;
|
||||
isActive: boolean;
|
||||
reference: Maybe<Name>;
|
||||
|
||||
isCompany: boolean;
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export * from "./customer.full.presenter";
|
||||
@ -1,24 +1,26 @@
|
||||
import { Presenter } from "@erp/core/api";
|
||||
import type { ISnapshotBuilder } from "@erp/core/api";
|
||||
import { maybeToEmptyString } from "@repo/rdx-ddd";
|
||||
|
||||
import type { GetCustomerByIdResponseDTO } from "../../../../common/dto";
|
||||
import type { Customer } from "../../../domain";
|
||||
|
||||
export class CustomerFullPresenter extends Presenter<Customer, GetCustomerByIdResponseDTO> {
|
||||
toOutput(customer: Customer): GetCustomerByIdResponseDTO {
|
||||
import type { ICustomerFullSnapshot } from "./customer-snapshot.interface";
|
||||
|
||||
export interface ICustomerFullSnapshotBuilder
|
||||
extends ISnapshotBuilder<Customer, ICustomerFullSnapshot> {}
|
||||
|
||||
export class CustomerFullSnapshotBuilder implements ICustomerFullSnapshotBuilder {
|
||||
toOutput(customer: Customer): ICustomerFullSnapshot {
|
||||
const address = customer.address.toPrimitive();
|
||||
|
||||
return {
|
||||
id: customer.id.toPrimitive(),
|
||||
company_id: customer.companyId.toPrimitive(),
|
||||
|
||||
status: customer.isActive ? "active" : "inactive",
|
||||
reference: maybeToEmptyString(customer.reference, (value) => value.toPrimitive()),
|
||||
|
||||
is_company: String(customer.isCompany),
|
||||
name: customer.name.toPrimitive(),
|
||||
|
||||
trade_name: maybeToEmptyString(customer.tradeName, (value) => value.toPrimitive()),
|
||||
|
||||
tin: maybeToEmptyString(customer.tin, (value) => value.toPrimitive()),
|
||||
|
||||
street: maybeToEmptyString(address.street, (value) => value.toPrimitive()),
|
||||
@ -30,8 +32,10 @@ export class CustomerFullPresenter extends Presenter<Customer, GetCustomerByIdRe
|
||||
|
||||
email_primary: maybeToEmptyString(customer.emailPrimary, (value) => value.toPrimitive()),
|
||||
email_secondary: maybeToEmptyString(customer.emailSecondary, (value) => value.toPrimitive()),
|
||||
|
||||
phone_primary: maybeToEmptyString(customer.phonePrimary, (value) => value.toPrimitive()),
|
||||
phone_secondary: maybeToEmptyString(customer.phoneSecondary, (value) => value.toPrimitive()),
|
||||
|
||||
mobile_primary: maybeToEmptyString(customer.mobilePrimary, (value) => value.toPrimitive()),
|
||||
mobile_secondary: maybeToEmptyString(customer.mobileSecondary, (value) =>
|
||||
value.toPrimitive()
|
||||
@ -44,7 +48,6 @@ export class CustomerFullPresenter extends Presenter<Customer, GetCustomerByIdRe
|
||||
|
||||
default_taxes: customer.defaultTaxes.getAll().map((tax) => tax.toString()),
|
||||
|
||||
status: customer.isActive ? "active" : "inactive",
|
||||
language_code: customer.languageCode.toPrimitive(),
|
||||
currency_code: customer.currencyCode.toPrimitive(),
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
export interface ICustomerFullSnapshot {
|
||||
id: string;
|
||||
company_id: string;
|
||||
status: string;
|
||||
reference: string;
|
||||
|
||||
is_company: string;
|
||||
name: string;
|
||||
trade_name: string;
|
||||
tin: string;
|
||||
|
||||
street: string;
|
||||
street2: string;
|
||||
city: string;
|
||||
province: string;
|
||||
postal_code: string;
|
||||
country: string;
|
||||
|
||||
email_primary: string;
|
||||
email_secondary: string;
|
||||
|
||||
phone_primary: string;
|
||||
phone_secondary: string;
|
||||
|
||||
mobile_primary: string;
|
||||
mobile_secondary: string;
|
||||
|
||||
fax: string;
|
||||
website: string;
|
||||
|
||||
legal_record: string;
|
||||
|
||||
default_taxes: string[];
|
||||
|
||||
language_code: string;
|
||||
currency_code: string;
|
||||
|
||||
metadata?: Record<string, string>;
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
export * from "./customer-snapshot.interface";
|
||||
export * from "./customer-snapshot-builder";
|
||||
@ -1,3 +1,2 @@
|
||||
//export * from "./full";
|
||||
export * from "./domain";
|
||||
export * from "./summary";
|
||||
//export * from "./report";
|
||||
|
||||
@ -15,7 +15,7 @@ export class CustomerSummarySnapshotBuilder implements ICustomerSummarySnapshotB
|
||||
return {
|
||||
id: customer.id.toString(),
|
||||
company_id: customer.companyId.toString(),
|
||||
status: customer.status.toString(),
|
||||
status: customer.isActive ? "active" : "inactive",
|
||||
reference: maybeToEmptyString(customer.reference, (value) => value.toString()),
|
||||
|
||||
is_company: String(customer.isCompany),
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
import { DuplicateEntityError, IPresenterRegistry, ITransactionManager } from "@erp/core/api";
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import {
|
||||
DuplicateEntityError,
|
||||
type IPresenterRegistry,
|
||||
type ITransactionManager,
|
||||
} from "@erp/core/api";
|
||||
import type { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { Transaction } from "sequelize";
|
||||
import { CreateCustomerRequestDTO } from "../../../../common";
|
||||
import type { Transaction } from "sequelize";
|
||||
|
||||
import type { CreateCustomerRequestDTO } from "../../../../common";
|
||||
import { logger } from "../../..//helpers";
|
||||
import { CustomerApplicationService } from "../../customer-application.service";
|
||||
import { CustomerFullPresenter } from "../../presenters";
|
||||
import type { CustomerApplicationService } from "../../customer-application.service";
|
||||
import type { CustomerFullSnapshotBuilder } from "../../presenters";
|
||||
import { CustomerNotExistsInCompanySpecification } from "../../specs";
|
||||
|
||||
import { mapDTOToCreateCustomerProps } from "./map-dto-to-create-customer-props";
|
||||
|
||||
type CreateCustomerUseCaseInput = {
|
||||
@ -26,7 +32,7 @@ export class CreateCustomerUseCase {
|
||||
const presenter = this.presenterRegistry.getPresenter({
|
||||
resource: "customer",
|
||||
projection: "FULL",
|
||||
}) as CustomerFullPresenter;
|
||||
}) as CustomerFullSnapshotBuilder;
|
||||
|
||||
// 1) Mapear DTO → props de dominio
|
||||
const dtoResult = mapDTOToCreateCustomerProps(dto);
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
import type { ITransactionManager } from "@erp/core/api";
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
|
||||
import type { ICustomerFinder } from "../services";
|
||||
import type { ICustomerFullSnapshotBuilder } from "../snapshot-builders";
|
||||
|
||||
type GetCustomerUseCaseInput = {
|
||||
companyId: UniqueID;
|
||||
customer_id: string;
|
||||
};
|
||||
|
||||
export class GetCustomerByIdUseCase {
|
||||
constructor(
|
||||
private readonly finder: ICustomerFinder,
|
||||
private readonly fullSnapshotBuilder: ICustomerFullSnapshotBuilder,
|
||||
private readonly transactionManager: ITransactionManager
|
||||
) {}
|
||||
|
||||
public execute(params: GetCustomerUseCaseInput) {
|
||||
const { customer_id, companyId } = params;
|
||||
|
||||
const idOrError = UniqueID.create(customer_id);
|
||||
if (idOrError.isFailure) {
|
||||
return Result.fail(idOrError.error);
|
||||
}
|
||||
|
||||
const customerId = idOrError.data;
|
||||
|
||||
return this.transactionManager.complete(async (transaction) => {
|
||||
try {
|
||||
const customerResult = await this.finder.findCustomerById(
|
||||
companyId,
|
||||
customerId,
|
||||
transaction
|
||||
);
|
||||
|
||||
if (customerResult.isFailure) {
|
||||
return Result.fail(customerResult.error);
|
||||
}
|
||||
|
||||
const fullSnapshot = this.fullSnapshotBuilder.toOutput(customerResult.data);
|
||||
|
||||
return Result.ok(fullSnapshot);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
import { IPresenterRegistry, ITransactionManager } from "@erp/core/api";
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { CustomerApplicationService } from "../../application";
|
||||
import { CustomerFullPresenter } from "../presenters";
|
||||
|
||||
type GetCustomerUseCaseInput = {
|
||||
companyId: UniqueID;
|
||||
customer_id: string;
|
||||
};
|
||||
|
||||
export class GetCustomerUseCase {
|
||||
constructor(
|
||||
private readonly service: CustomerApplicationService,
|
||||
private readonly transactionManager: ITransactionManager,
|
||||
private readonly presenterRegistry: IPresenterRegistry
|
||||
) {}
|
||||
|
||||
public execute(params: GetCustomerUseCaseInput) {
|
||||
const { customer_id, companyId } = params;
|
||||
|
||||
const idOrError = UniqueID.create(customer_id);
|
||||
if (idOrError.isFailure) {
|
||||
return Result.fail(idOrError.error);
|
||||
}
|
||||
|
||||
const customerId = idOrError.data;
|
||||
const presenter = this.presenterRegistry.getPresenter({
|
||||
resource: "customer",
|
||||
projection: "FULL",
|
||||
}) as CustomerFullPresenter;
|
||||
|
||||
return this.transactionManager.complete(async (transaction) => {
|
||||
try {
|
||||
const customerOrError = await this.service.getCustomerByIdInCompany(
|
||||
companyId,
|
||||
customerId,
|
||||
transaction
|
||||
);
|
||||
|
||||
if (customerOrError.isFailure) {
|
||||
return Result.fail(customerOrError.error);
|
||||
}
|
||||
|
||||
const customer = customerOrError.data;
|
||||
const dto = presenter.toOutput(customer);
|
||||
|
||||
return Result.ok(dto);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
export * from "./create";
|
||||
export * from "./delete-customer.use-case";
|
||||
export * from "./get-customer.use-case";
|
||||
export * from "./get-customer-by-id.use-case";
|
||||
export * from "./list-customers.use-case";
|
||||
export * from "./update";
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { IPresenterRegistry, ITransactionManager } from "@erp/core/api";
|
||||
import type { IPresenterRegistry, ITransactionManager } from "@erp/core/api";
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { Transaction } from "sequelize";
|
||||
import { UpdateCustomerByIdRequestDTO } from "../../../../common/dto";
|
||||
import { CustomerPatchProps } from "../../../domain";
|
||||
import { CustomerApplicationService } from "../../customer-application.service";
|
||||
import { CustomerFullPresenter } from "../../presenters";
|
||||
import type { Transaction } from "sequelize";
|
||||
|
||||
import type { UpdateCustomerByIdRequestDTO } from "../../../../common/dto";
|
||||
import type { CustomerPatchProps } from "../../../domain";
|
||||
import type { CustomerApplicationService } from "../../customer-application.service";
|
||||
import type { CustomerFullSnapshotBuilder } from "../../presenters";
|
||||
|
||||
import { mapDTOToUpdateCustomerPatchProps } from "./map-dto-to-update-customer-props";
|
||||
|
||||
type UpdateCustomerUseCaseInput = {
|
||||
@ -33,7 +35,7 @@ export class UpdateCustomerUseCase {
|
||||
const presenter = this.presenterRegistry.getPresenter({
|
||||
resource: "customer",
|
||||
projection: "FULL",
|
||||
}) as CustomerFullPresenter;
|
||||
}) as CustomerFullSnapshotBuilder;
|
||||
|
||||
// Mapear DTO → props de dominio
|
||||
const patchPropsResult = mapDTOToUpdateCustomerPatchProps(dto);
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { type ModuleParams, buildCatalogs, buildTransactionManager } from "@erp/core/api";
|
||||
|
||||
import {
|
||||
type GetCustomerByIdUseCase,
|
||||
type ListCustomersUseCase,
|
||||
buildCustomerFinder,
|
||||
buildCustomerSnapshotBuilders,
|
||||
buildGetCustomerByIdUseCase,
|
||||
buildListCustomersUseCase,
|
||||
} from "../../application";
|
||||
|
||||
@ -13,7 +15,7 @@ import { buildCustomerRepository } from "./customer-repositories.di";
|
||||
export type CustomersInternalDeps = {
|
||||
useCases: {
|
||||
listCustomers: () => ListCustomersUseCase;
|
||||
//getCustomerById: () => GetCustomerByIdUseCase;
|
||||
getCustomerById: () => GetCustomerByIdUseCase;
|
||||
//reportCustomer: () => ReportCustomerUseCase;
|
||||
//createCustomer: () => CreateCustomerUseCase;
|
||||
|
||||
@ -54,14 +56,14 @@ export function buildCustomersDependencies(params: ModuleParams): CustomersInter
|
||||
transactionManager,
|
||||
}),
|
||||
|
||||
/*getCustomerById: () =>
|
||||
getCustomerById: () =>
|
||||
buildGetCustomerByIdUseCase({
|
||||
finder,
|
||||
fullSnapshotBuilder: snapshotBuilders.full,
|
||||
transactionManager,
|
||||
}),
|
||||
|
||||
reportCustomer: () =>
|
||||
/*reportCustomer: () =>
|
||||
buildReportCustomerUseCase({
|
||||
finder,
|
||||
fullSnapshotBuilder: snapshotBuilders.full,
|
||||
|
||||
@ -7,11 +7,13 @@ import { type ModuleParams, RequestWithAuth, validateRequest } from "@erp/core/a
|
||||
import { type NextFunction, type Request, type Response, Router } from "express";
|
||||
|
||||
import {
|
||||
CustomerListRequestSchema
|
||||
CustomerListRequestSchema,
|
||||
GetCustomerByIdRequestSchema
|
||||
} from "../../../common/dto";
|
||||
import type { CustomersInternalDeps } from "../di";
|
||||
|
||||
import {
|
||||
GetCustomerController,
|
||||
ListCustomersController
|
||||
} from "./controllers";
|
||||
|
||||
@ -51,17 +53,17 @@ export const customersRouter = (params: ModuleParams, deps: CustomersInternalDep
|
||||
}
|
||||
);
|
||||
|
||||
/* router.get(
|
||||
router.get(
|
||||
"/:customer_id",
|
||||
//checkTabContext,
|
||||
|
||||
validateRequest(GetCustomerByIdRequestSchema, "params"),
|
||||
(req: Request, res: Response, next: NextFunction) => {
|
||||
const useCase = deps.useCases.get();
|
||||
const useCase = deps.useCases.getCustomerById();
|
||||
const controller = new GetCustomerController(useCase);
|
||||
return controller.execute(req, res, next);
|
||||
}
|
||||
); */
|
||||
);
|
||||
|
||||
/* router.post(
|
||||
"/",
|
||||
|
||||
@ -190,7 +190,7 @@ export class SequelizeCustomerSummaryMapper
|
||||
return Result.ok<CustomerSummary>({
|
||||
id: customerId!,
|
||||
companyId: companyId!,
|
||||
status: status!,
|
||||
isActive: status!.isActive(),
|
||||
reference: reference!,
|
||||
|
||||
isCompany: isCompany,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user