Facturas de cliente
This commit is contained in:
parent
e65524ea3c
commit
206d5bf9d3
@ -1,8 +1,8 @@
|
|||||||
import { GetCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto";
|
import { UpdateCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto";
|
||||||
import { toEmptyString } from "@repo/rdx-ddd";
|
import { toEmptyString } from "@repo/rdx-ddd";
|
||||||
import { CustomerInvoice } from "../../../domain";
|
import { CustomerInvoice } from "../../../domain";
|
||||||
|
|
||||||
type GetCustomerInvoiceItemsByInvoiceIdResponseDTO = GetCustomerInvoiceByIdResponseDTO["items"];
|
type GetCustomerInvoiceItemsByInvoiceIdResponseDTO = UpdateCustomerInvoiceByIdResponseDTO["items"];
|
||||||
|
|
||||||
export class GetCustomerInvoiceItemsAssembler {
|
export class GetCustomerInvoiceItemsAssembler {
|
||||||
toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO {
|
toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { GetCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto";
|
import { UpdateCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto";
|
||||||
import { toEmptyString } from "@repo/rdx-ddd";
|
import { toEmptyString } from "@repo/rdx-ddd";
|
||||||
import { CustomerInvoice } from "../../../domain";
|
import { CustomerInvoice } from "../../../domain";
|
||||||
import { GetCustomerInvoiceItemsAssembler } from "./get-invoice-items.assembler";
|
import { GetCustomerInvoiceItemsAssembler } from "./get-invoice-items.assembler";
|
||||||
@ -10,7 +10,7 @@ export class GetCustomerInvoiceAssembler {
|
|||||||
this._itemsAssembler = new GetCustomerInvoiceItemsAssembler();
|
this._itemsAssembler = new GetCustomerInvoiceItemsAssembler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public toDTO(invoice: CustomerInvoice): GetCustomerInvoiceByIdResponseDTO {
|
public toDTO(invoice: CustomerInvoice): UpdateCustomerInvoiceByIdResponseDTO {
|
||||||
const items = this._itemsAssembler.toDTO(invoice);
|
const items = this._itemsAssembler.toDTO(invoice);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -2,4 +2,4 @@ export * from "./create-customer-invoice";
|
|||||||
export * from "./delete-customer-invoice";
|
export * from "./delete-customer-invoice";
|
||||||
export * from "./get-customer-invoice";
|
export * from "./get-customer-invoice";
|
||||||
export * from "./list-customer-invoices";
|
export * from "./list-customer-invoices";
|
||||||
//export * from "./update-customer-invoice";
|
export * from "./update-customer-invoice";
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { ITransactionManager } from "@erp/core/api";
|
import { ITransactionManager } from "@erp/core/api";
|
||||||
import { Criteria } from "@repo/rdx-criteria/server";
|
import { Criteria } from "@repo/rdx-criteria/server";
|
||||||
|
import { UniqueID } from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import { Transaction } from "sequelize";
|
import { Transaction } from "sequelize";
|
||||||
import { CustomerInvoiceListResponseDTO } from "../../../common/dto";
|
import { CustomerInvoiceListResponseDTO } from "../../../common/dto";
|
||||||
import { ICustomerInvoiceService } from "../../domain";
|
import { CustomerInvoiceService } from "../../domain";
|
||||||
import { ListCustomerInvoicesAssembler } from "./assembler";
|
import { ListCustomerInvoicesAssembler } from "./assembler";
|
||||||
|
|
||||||
type ListCustomerInvoicesUseCaseInput = {
|
type ListCustomerInvoicesUseCaseInput = {
|
||||||
tenantId: string;
|
companyId: UniqueID;
|
||||||
criteria: Criteria;
|
criteria: Criteria;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ListCustomerInvoicesUseCase {
|
export class ListCustomerInvoicesUseCase {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly customerInvoiceService: ICustomerInvoiceService,
|
private readonly service: CustomerInvoiceService,
|
||||||
private readonly transactionManager: ITransactionManager,
|
private readonly transactionManager: ITransactionManager,
|
||||||
private readonly assembler: ListCustomerInvoicesAssembler
|
private readonly assembler: ListCustomerInvoicesAssembler
|
||||||
) {}
|
) {}
|
||||||
@ -21,12 +22,15 @@ export class ListCustomerInvoicesUseCase {
|
|||||||
public execute(
|
public execute(
|
||||||
params: ListCustomerInvoicesUseCaseInput
|
params: ListCustomerInvoicesUseCaseInput
|
||||||
): Promise<Result<CustomerInvoiceListResponseDTO, Error>> {
|
): Promise<Result<CustomerInvoiceListResponseDTO, Error>> {
|
||||||
const { criteria, tenantId } = params;
|
const { criteria, companyId } = params;
|
||||||
|
|
||||||
return this.transactionManager.complete(async (transaction: Transaction) => {
|
return this.transactionManager.complete(async (transaction: Transaction) => {
|
||||||
try {
|
try {
|
||||||
//const { rows, total, limit, offset } = await this.repo.searchInCompany(criteria, tenantId);
|
const result = await this.service.findInvoiceByCriteriaInCompany(
|
||||||
const result = await this.customerInvoiceService.findByCriteria(criteria, transaction);
|
companyId,
|
||||||
|
criteria,
|
||||||
|
transaction
|
||||||
|
);
|
||||||
|
|
||||||
if (result.isFailure) {
|
if (result.isFailure) {
|
||||||
return Result.fail(result.error);
|
return Result.fail(result.error);
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
export * from "./update-invoice.assembler";
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import { toEmptyString } from "@repo/rdx-ddd";
|
||||||
|
import { UpdateCustomerInvoiceByIdResponseDTO } from "../../../../common/dto";
|
||||||
|
import { CustomerInvoice } from "../../../domain";
|
||||||
|
|
||||||
|
type UpdateCustomerInvoiceItemsByInvoiceIdResponseDTO =
|
||||||
|
UpdateCustomerInvoiceByIdResponseDTO["items"];
|
||||||
|
|
||||||
|
export class UpdateCustomerInvoiceItemsAssembler {
|
||||||
|
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(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
import { toEmptyString } from "@repo/rdx-ddd";
|
||||||
|
import { UpdateCustomerInvoiceByIdResponseDTO } from "../../../../common/dto";
|
||||||
|
import { CustomerInvoice } from "../../../domain";
|
||||||
|
import { UpdateCustomerInvoiceItemsAssembler } from "./update-invoice-items.assembler";
|
||||||
|
|
||||||
|
export class UpdateCustomerInvoiceAssembler {
|
||||||
|
private _itemsAssembler!: UpdateCustomerInvoiceItemsAssembler;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._itemsAssembler = new UpdateCustomerInvoiceItemsAssembler();
|
||||||
|
}
|
||||||
|
|
||||||
|
public toDTO(invoice: CustomerInvoice): UpdateCustomerInvoiceByIdResponseDTO {
|
||||||
|
const items = this._itemsAssembler.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(),
|
||||||
|
|
||||||
|
issue_date: invoice.issueDate.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 CustomerInvoiceParticipantAssembler(customerInvoice.senderId, context),
|
||||||
|
|
||||||
|
/*recipient: await CustomerInvoiceParticipantAssembler(customerInvoice.recipient, context),
|
||||||
|
items: customerInvoiceItemAssembler(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: "",
|
||||||
|
},*/
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import {
|
|||||||
CreateCustomerInvoiceUseCase,
|
CreateCustomerInvoiceUseCase,
|
||||||
CreateCustomerInvoicesAssembler,
|
CreateCustomerInvoicesAssembler,
|
||||||
DeleteCustomerInvoiceUseCase,
|
DeleteCustomerInvoiceUseCase,
|
||||||
|
GetCustomerInvoiceAssembler,
|
||||||
GetCustomerInvoiceItemsAssembler,
|
GetCustomerInvoiceItemsAssembler,
|
||||||
GetCustomerInvoiceUseCase,
|
GetCustomerInvoiceUseCase,
|
||||||
ListCustomerInvoicesAssembler,
|
ListCustomerInvoicesAssembler,
|
||||||
@ -54,7 +55,7 @@ export function getInvoiceDependencies(params: ModuleParams): InvoiceDeps {
|
|||||||
if (!_assemblers) {
|
if (!_assemblers) {
|
||||||
_assemblers = {
|
_assemblers = {
|
||||||
list: new ListCustomerInvoicesAssembler(), // transforma domain → ListDTO
|
list: new ListCustomerInvoicesAssembler(), // transforma domain → ListDTO
|
||||||
get: new GetCustomerInvoiceItemsAssembler(), // transforma domain → DetailDTO
|
get: new GetCustomerInvoiceAssembler(), // transforma domain → DetailDTO
|
||||||
create: new CreateCustomerInvoicesAssembler(), // transforma domain → CreatedDTO
|
create: new CreateCustomerInvoicesAssembler(), // transforma domain → CreatedDTO
|
||||||
update: new UpdateCustomerInvoiceAssembler(), // transforma domain -> UpdateDTO
|
update: new UpdateCustomerInvoiceAssembler(), // transforma domain -> UpdateDTO
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,18 +2,15 @@ import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from
|
|||||||
import { ListCustomerInvoicesUseCase } from "../../../application";
|
import { ListCustomerInvoicesUseCase } from "../../../application";
|
||||||
|
|
||||||
export class ListCustomerInvoicesController extends ExpressController {
|
export class ListCustomerInvoicesController extends ExpressController {
|
||||||
public constructor(
|
public constructor(private readonly useCase: ListCustomerInvoicesUseCase) {
|
||||||
private readonly useCase: ListCustomerInvoicesUseCase
|
|
||||||
/* private readonly presenter: any */
|
|
||||||
) {
|
|
||||||
super();
|
super();
|
||||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async executeImpl() {
|
protected async executeImpl() {
|
||||||
const tenantId = this.getTenantId()!; // garantizado por tenantGuard
|
const companyId = this.getTenantId()!; // garantizado por tenantGuard
|
||||||
const result = await this.useCase.execute({ criteria: this.criteria, tenantId });
|
const result = await this.useCase.execute({ criteria: this.criteria, companyId });
|
||||||
|
|
||||||
return result.match(
|
return result.match(
|
||||||
(data) => this.ok(data),
|
(data) => this.ok(data),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export * from "./customer-invoice-creation.response.dto";
|
export * from "./customer-invoice-creation.response.dto";
|
||||||
export * from "./customer-invoices-list.response.dto";
|
export * from "./customer-invoices-list.response.dto";
|
||||||
export * from "./get-customer-invoice-by-id.response.dto";
|
export * from "./get-customer-invoice-by-id.response.dto";
|
||||||
|
export * from "./update-customer-invoice-by-id.response.dto";
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { AmountSchema, MetadataSchema, PercentageSchema, QuantitySchema } from "@erp/core";
|
||||||
|
import * as z from "zod/v4";
|
||||||
|
|
||||||
|
export const UpdateCustomerInvoiceByIdResponseSchema = z.object({
|
||||||
|
id: z.uuid(),
|
||||||
|
company_id: z.uuid(),
|
||||||
|
|
||||||
|
invoice_number: z.string(),
|
||||||
|
status: z.string(),
|
||||||
|
series: z.string(),
|
||||||
|
|
||||||
|
issue_date: z.string(),
|
||||||
|
operation_date: z.string(),
|
||||||
|
|
||||||
|
notes: z.string(),
|
||||||
|
|
||||||
|
language_code: z.string(),
|
||||||
|
currency_code: z.string(),
|
||||||
|
|
||||||
|
subtotal_amount: AmountSchema,
|
||||||
|
discount_percentage: PercentageSchema,
|
||||||
|
discount_amount: AmountSchema,
|
||||||
|
taxable_amount: AmountSchema,
|
||||||
|
tax_amount: AmountSchema,
|
||||||
|
total_amount: AmountSchema,
|
||||||
|
|
||||||
|
items: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.uuid(),
|
||||||
|
position: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
quantity: QuantitySchema,
|
||||||
|
unit_amount: AmountSchema,
|
||||||
|
discount_percentage: PercentageSchema,
|
||||||
|
total_amount: AmountSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
|
||||||
|
metadata: MetadataSchema.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateCustomerInvoiceByIdResponseDTO = z.infer<
|
||||||
|
typeof UpdateCustomerInvoiceByIdResponseSchema
|
||||||
|
>;
|
||||||
Loading…
Reference in New Issue
Block a user