.
This commit is contained in:
parent
b3c5e650fc
commit
3c1010adad
@ -1,8 +1,8 @@
|
||||
import { ITransactionManager } from "@erp/core/api";
|
||||
import { CustomerInvoiceListResponseDTO } from "@erp/customer-invoices/common/dto";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { Transaction } from "sequelize";
|
||||
import { CustomerInvoiceListResponseDTO } from "../../../common/dto";
|
||||
import { ICustomerInvoiceService } from "../../domain";
|
||||
import { ListCustomerInvoicesAssembler } from "./assembler";
|
||||
|
||||
@ -31,7 +31,7 @@ export class ListCustomerInvoicesUseCase {
|
||||
return Result.fail(result.error);
|
||||
}
|
||||
|
||||
const dto: CustomerInvoiceListResponseDTO = this.assembler.toDTO(result.data, criteria);
|
||||
const dto = this.assembler.toDTO(result.data, criteria);
|
||||
return Result.ok(dto);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@erp/auth": "workspace:*",
|
||||
"@erp/customers": "workspace:*",
|
||||
"@hookform/resolvers": "^5.0.1",
|
||||
"@repo/rdx-criteria": "workspace:*",
|
||||
|
||||
@ -2,20 +2,20 @@ import { Customer } from "@erp/customers/api/domain";
|
||||
import { CustomersCreationResultDTO } from "@erp/customers/common/dto";
|
||||
|
||||
export class CreateCustomersAssembler {
|
||||
public toDTO(invoice: Customer): CustomersCreationResultDTO {
|
||||
public toDTO(customer: Customer): CustomersCreationResultDTO {
|
||||
return {
|
||||
id: invoice.id.toPrimitive(),
|
||||
id: customer.id.toPrimitive(),
|
||||
|
||||
invoice_status: invoice.status.toString(),
|
||||
invoice_number: invoice.invoiceNumber.toString(),
|
||||
invoice_series: invoice.invoiceSeries.toString(),
|
||||
issue_date: invoice.issueDate.toISOString(),
|
||||
operation_date: invoice.operationDate.toISOString(),
|
||||
customer_status: customer.status.toString(),
|
||||
customer_number: customer.customerNumber.toString(),
|
||||
customer_series: customer.customerSeries.toString(),
|
||||
issue_date: customer.issueDate.toISOString(),
|
||||
operation_date: customer.operationDate.toISOString(),
|
||||
language_code: "ES",
|
||||
currency: "EUR",
|
||||
|
||||
//subtotal_price: invoice.calculateSubtotal().toPrimitive(),
|
||||
//total_price: invoice.calculateTotal().toPrimitive(),
|
||||
//subtotal_price: customer.calculateSubtotal().toPrimitive(),
|
||||
//total_price: customer.calculateTotal().toPrimitive(),
|
||||
|
||||
//recipient: CustomerParticipantAssembler(customer.recipient),
|
||||
|
||||
|
||||
@ -14,21 +14,21 @@ export class CreateCustomerUseCase {
|
||||
) {}
|
||||
|
||||
public execute(dto: CreateCustomerCommandDTO) {
|
||||
const invoicePropsOrError = mapDTOToCustomerProps(dto);
|
||||
const customerPropsOrError = mapDTOToCustomerProps(dto);
|
||||
|
||||
if (invoicePropsOrError.isFailure) {
|
||||
return Result.fail(invoicePropsOrError.error);
|
||||
if (customerPropsOrError.isFailure) {
|
||||
return Result.fail(customerPropsOrError.error);
|
||||
}
|
||||
|
||||
const { props, id } = invoicePropsOrError.data;
|
||||
const { props, id } = customerPropsOrError.data;
|
||||
|
||||
const invoiceOrError = this.service.build(props, id);
|
||||
const customerOrError = this.service.build(props, id);
|
||||
|
||||
if (invoiceOrError.isFailure) {
|
||||
return Result.fail(invoiceOrError.error);
|
||||
if (customerOrError.isFailure) {
|
||||
return Result.fail(customerOrError.error);
|
||||
}
|
||||
|
||||
const newInvoice = invoiceOrError.data;
|
||||
const newCustomer = customerOrError.data;
|
||||
|
||||
return this.transactionManager.complete(async (transaction: Transaction) => {
|
||||
try {
|
||||
@ -42,12 +42,12 @@ export class CreateCustomerUseCase {
|
||||
return Result.fail(new DuplicateEntityError("Customer", id.toString()));
|
||||
}
|
||||
|
||||
const result = await this.service.save(newInvoice, transaction);
|
||||
const result = await this.service.save(newCustomer, transaction);
|
||||
if (result.isFailure) {
|
||||
return Result.fail(result.error);
|
||||
}
|
||||
|
||||
const viewDTO = this.assembler.toDTO(newInvoice);
|
||||
const viewDTO = this.assembler.toDTO(newCustomer);
|
||||
return Result.ok(viewDTO);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
|
||||
@ -6,9 +6,9 @@ export class GetCustomerAssembler {
|
||||
return {
|
||||
id: customer.id.toPrimitive(),
|
||||
|
||||
invoice_status: customer.status.toString(),
|
||||
invoice_number: customer.invoiceNumber.toString(),
|
||||
invoice_series: customer.invoiceSeries.toString(),
|
||||
customer_status: customer.status.toString(),
|
||||
customer_number: customer.customerNumber.toString(),
|
||||
customer_series: customer.customerSeries.toString(),
|
||||
issue_date: customer.issueDate.toDateString(),
|
||||
operation_date: customer.operationDate.toDateString(),
|
||||
language_code: "ES",
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from "./get-invoice.assembler";
|
||||
export * from "./get-customer.assembler";
|
||||
|
||||
@ -21,12 +21,12 @@ export class GetCustomerUseCase {
|
||||
|
||||
return this.transactionManager.complete(async (transaction) => {
|
||||
try {
|
||||
const invoiceOrError = await this.service.getById(idOrError.data, transaction);
|
||||
if (invoiceOrError.isFailure) {
|
||||
return Result.fail(invoiceOrError.error);
|
||||
const customerOrError = await this.service.getById(idOrError.data, transaction);
|
||||
if (customerOrError.isFailure) {
|
||||
return Result.fail(customerOrError.error);
|
||||
}
|
||||
|
||||
const getDTO = this.assembler.toDTO(invoiceOrError.data);
|
||||
const getDTO = this.assembler.toDTO(customerOrError.data);
|
||||
return Result.ok(getDTO);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
|
||||
@ -19,16 +19,16 @@ import { mapDTOToCustomerItemsProps } from "./map-dto-to-customer-items-props";
|
||||
export function mapDTOToCustomerProps(dto: CreateCustomerCommandDTO) {
|
||||
const errors: ValidationErrorDetail[] = [];
|
||||
|
||||
const invoiceId = extractOrPushError(UniqueID.create(dto.id), "id", errors);
|
||||
const customerId = extractOrPushError(UniqueID.create(dto.id), "id", errors);
|
||||
|
||||
const invoiceNumber = extractOrPushError(
|
||||
CustomerNumber.create(dto.invoice_number),
|
||||
"invoice_number",
|
||||
const customerNumber = extractOrPushError(
|
||||
CustomerNumber.create(dto.customer_number),
|
||||
"customer_number",
|
||||
errors
|
||||
);
|
||||
const invoiceSeries = extractOrPushError(
|
||||
CustomerSerie.create(dto.invoice_series),
|
||||
"invoice_series",
|
||||
const customerSeries = extractOrPushError(
|
||||
CustomerSerie.create(dto.customer_series),
|
||||
"customer_series",
|
||||
errors
|
||||
);
|
||||
const issueDate = extractOrPushError(UtcDate.createFromISO(dto.issue_date), "issue_date", errors);
|
||||
@ -51,23 +51,23 @@ export function mapDTOToCustomerProps(dto: CreateCustomerCommandDTO) {
|
||||
return Result.fail(new ValidationErrorCollection(errors));
|
||||
}
|
||||
|
||||
const invoiceProps: CustomerProps = {
|
||||
invoiceNumber: invoiceNumber!,
|
||||
invoiceSeries: invoiceSeries!,
|
||||
const customerProps: CustomerProps = {
|
||||
customerNumber: customerNumber!,
|
||||
customerSeries: customerSeries!,
|
||||
issueDate: issueDate!,
|
||||
operationDate: operationDate!,
|
||||
status: CustomerStatus.createDraft(),
|
||||
currency,
|
||||
};
|
||||
|
||||
return Result.ok({ id: invoiceId!, props: invoiceProps });
|
||||
return Result.ok({ id: customerId!, props: customerProps });
|
||||
|
||||
/*if (hasNoUndefinedFields(invoiceProps)) {
|
||||
const invoiceOrError = Customer.create(invoiceProps, invoiceId);
|
||||
if (invoiceOrError.isFailure) {
|
||||
return Result.fail(invoiceOrError.error);
|
||||
/*if (hasNoUndefinedFields(customerProps)) {
|
||||
const customerOrError = Customer.create(customerProps, customerId);
|
||||
if (customerOrError.isFailure) {
|
||||
return Result.fail(customerOrError.error);
|
||||
}
|
||||
return Result.ok(invoiceOrError.data);
|
||||
return Result.ok(customerOrError.data);
|
||||
}
|
||||
|
||||
return Result.fail(
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from "./list-invoices.assembler";
|
||||
export * from "./list-customers.assembler";
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { Collection } from "@repo/rdx-utils";
|
||||
import { CustomerListResponsetDTO } from "../../../../common/dto";
|
||||
import { Customer } from "../../../domain";
|
||||
|
||||
export class ListCustomersAssembler {
|
||||
toDTO(customers: Collection<Customer>, criteria: Criteria): CustomerListResponsetDTO {
|
||||
const items: CustomerListResponsetDTO["items"] = customers.map((customer) => {
|
||||
const address = customer.address.toPrimitive();
|
||||
|
||||
return {
|
||||
id: customer.id.toPrimitive(),
|
||||
reference: customer.reference,
|
||||
|
||||
is_freelancer: customer.isFreelancer,
|
||||
name: customer.name,
|
||||
trade_name: customer.tradeName.getOrUndefined(),
|
||||
tin: customer.tin.toString(),
|
||||
|
||||
street: address.street,
|
||||
city: address.city,
|
||||
state: address.state,
|
||||
postal_code: address.postalCode,
|
||||
country: address.country,
|
||||
|
||||
email: customer.email.getValue(),
|
||||
phone: customer.phone.getValue(),
|
||||
fax: customer.fax.getOrUndefined(),
|
||||
website: customer.website.getOrUndefined(),
|
||||
|
||||
legal_record: customer.legalRecord,
|
||||
|
||||
default_tax: customer.defaultTax,
|
||||
status: customer.isActive ? 'active' : 'inactive',
|
||||
lang_code: customer.langCode,
|
||||
currency_code: customer.currencyCode,
|
||||
|
||||
metadata: {
|
||||
entity: "customer",
|
||||
id: customer.id.toPrimitive(),
|
||||
//created_at: customer.createdAt.toPrimitive(),
|
||||
//updated_at: customer.updatedAt.toPrimitive()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const totalItems = customers.total();
|
||||
|
||||
return {
|
||||
page: criteria.pageNumber,
|
||||
per_page: criteria.pageSize,
|
||||
total_pages: Math.ceil(totalItems / criteria.pageSize),
|
||||
total_items: totalItems,
|
||||
items: items,
|
||||
metadata: {
|
||||
entity: "customers",
|
||||
criteria: criteria.toJSON(),
|
||||
//links: {
|
||||
// self: `/api/customers?page=${criteria.pageNumber}&per_page=${criteria.pageSize}`,
|
||||
// first: `/api/customers?page=1&per_page=${criteria.pageSize}`,
|
||||
// last: `/api/customers?page=${Math.ceil(totalItems / criteria.pageSize)}&per_page=${criteria.pageSize}`,
|
||||
//},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { Collection } from "@repo/rdx-utils";
|
||||
import { CustomerListResponsetDTO } from "../../../../common/dto";
|
||||
import { Customer } from "../../../domain";
|
||||
|
||||
|
||||
export class ListCustomersAssembler {
|
||||
toDTO(customers: Collection<Customer>, criteria: Criteria): CustomerListResponsetDTO {
|
||||
const items = customers.map((invoice) => {
|
||||
return {
|
||||
id: invoice.id.toPrimitive(),
|
||||
|
||||
invoice_status: invoice.status.toString(),
|
||||
invoice_number: invoice.invoiceNumber.toString(),
|
||||
invoice_series: invoice.invoiceSeries.toString(),
|
||||
issue_date: invoice.issueDate.toISOString(),
|
||||
operation_date: invoice.operationDate.toISOString(),
|
||||
language_code: "ES",
|
||||
currency: "EUR",
|
||||
|
||||
subtotal_price: invoice.calculateSubtotal().toPrimitive(),
|
||||
total_price: invoice.calculateTotal().toPrimitive(),
|
||||
|
||||
//recipient: CustomerParticipantAssembler(customer.recipient),
|
||||
|
||||
metadata: {
|
||||
entity: "customer",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const totalItems = customers.total();
|
||||
|
||||
return {
|
||||
page: criteria.pageNumber,
|
||||
per_page: criteria.pageSize,
|
||||
total_pages: Math.ceil(totalItems / criteria.pageSize),
|
||||
total_items: totalItems,
|
||||
items: items,
|
||||
metadata: {
|
||||
entity: "customers",
|
||||
criteria: criteria.toJSON(),
|
||||
//links: {
|
||||
// self: `/api/customers?page=${criteria.pageNumber}&per_page=${criteria.pageSize}`,
|
||||
// first: `/api/customers?page=1&per_page=${criteria.pageSize}`,
|
||||
// last: `/api/customers?page=${Math.ceil(totalItems / criteria.pageSize)}&per_page=${criteria.pageSize}`,
|
||||
//},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -1,11 +1,16 @@
|
||||
import { ITransactionManager } from "@erp/core/api";
|
||||
import { ListCustomersResultDTO } from "@erp/customers/common/dto";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { Transaction } from "sequelize";
|
||||
import { CustomerListResponsetDTO } from "../../../common/dto";
|
||||
import { ICustomerService } from "../../domain";
|
||||
import { ListCustomersAssembler } from "./assembler";
|
||||
|
||||
type ListCustomersUseCaseInput = {
|
||||
tenantId: string;
|
||||
criteria: Criteria;
|
||||
};
|
||||
|
||||
export class ListCustomersUseCase {
|
||||
constructor(
|
||||
private readonly customerService: ICustomerService,
|
||||
@ -13,17 +18,20 @@ export class ListCustomersUseCase {
|
||||
private readonly assembler: ListCustomersAssembler
|
||||
) {}
|
||||
|
||||
public execute(criteria: Criteria): Promise<Result<ListCustomersResultDTO, Error>> {
|
||||
public execute(
|
||||
params: ListCustomersUseCaseInput
|
||||
): Promise<Result<CustomerListResponsetDTO, Error>> {
|
||||
const { criteria, tenantId } = params;
|
||||
|
||||
return this.transactionManager.complete(async (transaction: Transaction) => {
|
||||
try {
|
||||
const result = await this.customerService.findByCriteria(criteria, transaction);
|
||||
|
||||
if (result.isFailure) {
|
||||
console.error(result.error);
|
||||
return Result.fail(result.error);
|
||||
}
|
||||
|
||||
const dto: ListCustomersResultDTO = this.assembler.toDTO(result.data, criteria);
|
||||
const dto = this.assembler.toDTO(result.data, criteria);
|
||||
return Result.ok(dto);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error as Error);
|
||||
|
||||
@ -5,7 +5,7 @@ import {
|
||||
forbidQueryFieldGuard,
|
||||
tenantGuard,
|
||||
} from "@erp/core/api";
|
||||
import { ListCustomersUseCase } from "../../../../application";
|
||||
import { ListCustomersUseCase } from "../../../application";
|
||||
|
||||
export class ListCustomersController extends ExpressController {
|
||||
public constructor(private readonly listCustomers: ListCustomersUseCase) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { enforceTenant } from "@erp/auth/api";
|
||||
import { ILogger, ModuleParams, validateRequest } from "@erp/core/api";
|
||||
import { Application, NextFunction, Request, Response, Router } from "express";
|
||||
import { Sequelize } from "sequelize";
|
||||
|
||||
@ -3,7 +3,7 @@ import * as z from "zod/v4";
|
||||
|
||||
export const CustomerListResponseSchema = createListViewResponseSchema(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
id: z.uuid(),
|
||||
reference: z.string(),
|
||||
|
||||
is_freelancer: z.boolean(),
|
||||
|
||||
@ -583,6 +583,9 @@ importers:
|
||||
'@dnd-kit/utilities':
|
||||
specifier: ^3.2.2
|
||||
version: 3.2.2(react@19.1.0)
|
||||
'@erp/auth':
|
||||
specifier: workspace:*
|
||||
version: link:../auth
|
||||
'@erp/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
|
||||
Loading…
Reference in New Issue
Block a user