.
This commit is contained in:
parent
b22845f8da
commit
8455ae43db
@ -46,11 +46,13 @@ export function createApp(): Application {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gestión global de errores
|
|
||||||
app.use(globalErrorHandler);
|
|
||||||
|
|
||||||
// Registrar rutas de la API
|
// Registrar rutas de la API
|
||||||
app.use("/api/v1", v1Routes());
|
app.use("/api/v1", v1Routes());
|
||||||
|
|
||||||
|
// Gestión global de errores.
|
||||||
|
// Siempre al final de la cadena de middlewares
|
||||||
|
// y después de las rutas.
|
||||||
|
app.use(globalErrorHandler);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,7 +84,7 @@ export class MoneyValue extends ValueObject<IMoneyValueProps> implements IMoneyV
|
|||||||
|
|
||||||
/** Serializa el VO a una cadena del tipo "EUR:123400:2" */
|
/** Serializa el VO a una cadena del tipo "EUR:123400:2" */
|
||||||
toPersistence(): string {
|
toPersistence(): string {
|
||||||
return `${this.currency()}:${this.value.getAmount()}:${this.getScale()}`;
|
return `${this.currency}:${this.dinero.getAmount()}:${this.scale}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reconstruye el VO desde la cadena persistida */
|
/** Reconstruye el VO desde la cadena persistida */
|
||||||
@ -92,8 +92,8 @@ export class MoneyValue extends ValueObject<IMoneyValueProps> implements IMoneyV
|
|||||||
const [currencyCode, amountStr, scaleStr] = value.split(":");
|
const [currencyCode, amountStr, scaleStr] = value.split(":");
|
||||||
const amount = parseInt(amountStr, 10);
|
const amount = parseInt(amountStr, 10);
|
||||||
const scale = parseInt(scaleStr, 10);
|
const scale = parseInt(scaleStr, 10);
|
||||||
const currency = getCurrencyByCode(currencyCode);
|
const currency = currencyCode;
|
||||||
return new MoneyValue(amount, scale, currency);
|
return new MoneyValue({ amount, scale, currency_code: currency });
|
||||||
}
|
}
|
||||||
|
|
||||||
toPrimitive() {
|
toPrimitive() {
|
||||||
|
|||||||
@ -2,7 +2,12 @@ import { logger } from "@common/infrastructure/logger";
|
|||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import { ApiError } from "../api-error";
|
import { ApiError } from "../api-error";
|
||||||
|
|
||||||
export const globalErrorHandler = (error: any, req: Request, res: Response, next: NextFunction) => {
|
export const globalErrorHandler = async (
|
||||||
|
error: Error,
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
// Si ya se envió una respuesta, delegamos al siguiente error handler
|
// Si ya se envió una respuesta, delegamos al siguiente error handler
|
||||||
if (res.headersSent) {
|
if (res.headersSent) {
|
||||||
return next(error);
|
return next(error);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ export const validateAndParseBody =
|
|||||||
(schema: ZodSchema, options?: { sanitize?: boolean }) =>
|
(schema: ZodSchema, options?: { sanitize?: boolean }) =>
|
||||||
(req: Request, res: Response, next: NextFunction) => {
|
(req: Request, res: Response, next: NextFunction) => {
|
||||||
const result = schema.safeParse(req.body);
|
const result = schema.safeParse(req.body);
|
||||||
|
try {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
// Construye errores detallados
|
// Construye errores detallados
|
||||||
const validationErrors = result.error.errors.map((err) => ({
|
const validationErrors = result.error.errors.map((err) => ({
|
||||||
@ -30,4 +31,8 @@ export const validateAndParseBody =
|
|||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
} catch (error: unknown) {
|
||||||
|
// Si ocurre un error, delega al manejador de errores global
|
||||||
|
next(error as ApiError);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export interface IInvoiceProps {
|
|||||||
//paymentTerms: string;
|
//paymentTerms: string;
|
||||||
|
|
||||||
customer?: InvoiceCustomer;
|
customer?: InvoiceCustomer;
|
||||||
items?: Collection<InvoiceItem>;
|
items?: InvoiceItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInvoice {
|
export interface IInvoice {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { MoneyValue, Percentage, Quantity, ValueObject } from "@common/domain";
|
import { DomainEntity, MoneyValue, Percentage, Quantity, UniqueID } from "@common/domain";
|
||||||
import { Result } from "@common/helpers";
|
import { Result } from "@common/helpers";
|
||||||
import { InvoiceItemDescription } from "../../value-objects";
|
import { InvoiceItemDescription } from "../../value-objects";
|
||||||
|
|
||||||
@ -6,12 +6,13 @@ export interface IInvoiceItemProps {
|
|||||||
description: InvoiceItemDescription;
|
description: InvoiceItemDescription;
|
||||||
quantity: Quantity; // Cantidad de unidades
|
quantity: Quantity; // Cantidad de unidades
|
||||||
unitPrice: MoneyValue; // Precio unitario en la moneda de la factura
|
unitPrice: MoneyValue; // Precio unitario en la moneda de la factura
|
||||||
subtotalPrice?: MoneyValue; // Precio unitario * Cantidad
|
//subtotalPrice?: MoneyValue; // Precio unitario * Cantidad
|
||||||
discount: Percentage; // % descuento
|
discount: Percentage; // % descuento
|
||||||
totalPrice?: MoneyValue;
|
//totalPrice?: MoneyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInvoiceItem {
|
export interface IInvoiceItem {
|
||||||
|
id: UniqueID;
|
||||||
description: InvoiceItemDescription;
|
description: InvoiceItemDescription;
|
||||||
quantity: Quantity;
|
quantity: Quantity;
|
||||||
unitPrice: MoneyValue;
|
unitPrice: MoneyValue;
|
||||||
@ -20,12 +21,22 @@ export interface IInvoiceItem {
|
|||||||
totalPrice: MoneyValue;
|
totalPrice: MoneyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvoiceItem extends ValueObject<IInvoiceItemProps> implements IInvoiceItem {
|
export class InvoiceItem extends DomainEntity<IInvoiceItemProps> implements IInvoiceItem {
|
||||||
private _subtotalPrice!: MoneyValue;
|
private _subtotalPrice!: MoneyValue;
|
||||||
private _totalPrice!: MoneyValue;
|
private _totalPrice!: MoneyValue;
|
||||||
|
|
||||||
public static create(props: IInvoiceItemProps): Result<InvoiceItem, Error> {
|
public static create(props: IInvoiceItemProps, id?: UniqueID): Result<InvoiceItem, Error> {
|
||||||
return Result.ok(new InvoiceItem(props));
|
const item = new InvoiceItem(props, id);
|
||||||
|
|
||||||
|
// Reglas de negocio / validaciones
|
||||||
|
// ...
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// 🔹 Disparar evento de dominio "InvoiceItemCreatedEvent"
|
||||||
|
//const { invoice } = props;
|
||||||
|
//user.addDomainEvent(new InvoiceAuthenticatedEvent(id, invoice.toString()));
|
||||||
|
|
||||||
|
return Result.ok(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
get description(): InvoiceItemDescription {
|
get description(): InvoiceItemDescription {
|
||||||
|
|||||||
@ -43,4 +43,8 @@ export class InvoiceItemDescription extends ValueObject<IInvoiceItemDescriptionP
|
|||||||
toString(): string {
|
toString(): string {
|
||||||
return this.getValue();
|
return this.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toPrimitive() {
|
||||||
|
return this.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,53 +1,79 @@
|
|||||||
import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure";
|
import { MoneyValue, Percentage, Quantity, UniqueID } from "@common/domain";
|
||||||
import { Description, Quantity, UniqueID, UnitPrice } from "@shared/contexts";
|
import { Result } from "@common/helpers";
|
||||||
import { Invoice } from "../../domain";
|
import {
|
||||||
import { IInvoiceSimpleItemProps, InvoiceItem, InvoiceSimpleItem } from "../../domain/entities";
|
ISequelizeMapper,
|
||||||
import { IInvoicingContext } from "../InvoicingContext";
|
MapperParamsType,
|
||||||
import { InvoiceItem_Model, InvoiceModel, TCreationInvoiceItem_Model } from "../sequelize";
|
SequelizeMapper,
|
||||||
|
} from "@common/infrastructure/sequelize/sequelize-mapper";
|
||||||
|
import { Invoice, InvoiceItem, InvoiceItemDescription } from "@contexts/invoices/domain/";
|
||||||
|
import { InferCreationAttributes } from "sequelize";
|
||||||
|
import { InvoiceItemCreationAttributes, InvoiceItemModel, InvoiceModel } from "../sequelize";
|
||||||
|
|
||||||
export interface IInvoiceItemMapper
|
export interface IInvoiceItemMapper
|
||||||
extends ISequelizeMapper<InvoiceItem_Model, TCreationInvoiceItem_Model, InvoiceItem> {}
|
extends ISequelizeMapper<InvoiceItemModel, InvoiceItemCreationAttributes, InvoiceItem> {}
|
||||||
|
|
||||||
export const createInvoiceItemMapper = (context: IInvoicingContext): IInvoiceItemMapper =>
|
export class InvoiceItemMapper
|
||||||
new InvoiceItemMapper({ context });
|
extends SequelizeMapper<InvoiceItemModel, InvoiceItemCreationAttributes, InvoiceItem>
|
||||||
|
|
||||||
class InvoiceItemMapper
|
|
||||||
extends SequelizeMapper<InvoiceItem_Model, TCreationInvoiceItem_Model, InvoiceItem>
|
|
||||||
implements IInvoiceItemMapper
|
implements IInvoiceItemMapper
|
||||||
{
|
{
|
||||||
protected toDomainMappingImpl(
|
public mapToDomain(
|
||||||
source: InvoiceItem_Model,
|
source: InvoiceItemModel,
|
||||||
params: { sourceParent: InvoiceModel }
|
params?: MapperParamsType
|
||||||
): InvoiceItem {
|
): Result<InvoiceItem, Error> {
|
||||||
const { sourceParent } = params;
|
const { sourceParent } = params as { sourceParent: InvoiceModel };
|
||||||
const id = this.mapsValue(source, "item_id", UniqueID.create);
|
|
||||||
|
|
||||||
const props: IInvoiceSimpleItemProps = {
|
const idOrError = UniqueID.create(source.item_id);
|
||||||
description: this.mapsValue(source, "description", Description.create),
|
|
||||||
quantity: this.mapsValue(source, "quantity", Quantity.create),
|
|
||||||
unitPrice: this.mapsValue(source, "unit_price", (unit_price) =>
|
|
||||||
UnitPrice.create({
|
|
||||||
amount: unit_price,
|
|
||||||
currencyCode: sourceParent.invoice_currency,
|
|
||||||
precision: 4,
|
|
||||||
})
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
const invoiceItemOrError = InvoiceSimpleItem.create(props, id);
|
const descriptionOrError = InvoiceItemDescription.create(source.description);
|
||||||
|
|
||||||
if (invoiceItemOrError.isFailure) {
|
const quantityOrError = Quantity.create({
|
||||||
throw invoiceItemOrError.error;
|
amount: source.quantity_amount,
|
||||||
|
scale: source.quantity_scale,
|
||||||
|
});
|
||||||
|
|
||||||
|
const unitPriceOrError = MoneyValue.create({
|
||||||
|
amount: source.unit_price_amount,
|
||||||
|
scale: source.unit_price_scale,
|
||||||
|
currency_code: sourceParent.invoice_currency,
|
||||||
|
});
|
||||||
|
|
||||||
|
const discountOrError = Percentage.create({
|
||||||
|
amount: source.discount_amount,
|
||||||
|
scale: source.discount_scale,
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = Result.combine([
|
||||||
|
idOrError,
|
||||||
|
descriptionOrError,
|
||||||
|
quantityOrError,
|
||||||
|
unitPriceOrError,
|
||||||
|
discountOrError,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (result.isFailure) {
|
||||||
|
return Result.fail(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return invoiceItemOrError.object;
|
return InvoiceItem.create(
|
||||||
|
{
|
||||||
|
description: descriptionOrError.data,
|
||||||
|
quantity: quantityOrError.data,
|
||||||
|
unitPrice: unitPriceOrError.data,
|
||||||
|
discount: discountOrError.data,
|
||||||
|
},
|
||||||
|
idOrError.data
|
||||||
|
//sourceParent
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected toPersistenceMappingImpl(
|
public mapToPersistence(
|
||||||
source: InvoiceItem,
|
source: InvoiceItem,
|
||||||
params: { index: number; sourceParent: Invoice }
|
params?: MapperParamsType
|
||||||
): TCreationInvoiceItem_Model {
|
): InferCreationAttributes<InvoiceItemModel, {}> {
|
||||||
const { index, sourceParent } = params;
|
const { index, sourceParent } = params as {
|
||||||
|
index: number;
|
||||||
|
sourceParent: Invoice;
|
||||||
|
};
|
||||||
|
|
||||||
const lineData = {
|
const lineData = {
|
||||||
parent_id: undefined,
|
parent_id: undefined,
|
||||||
@ -57,10 +83,21 @@ class InvoiceItemMapper
|
|||||||
|
|
||||||
item_id: source.id.toPrimitive(),
|
item_id: source.id.toPrimitive(),
|
||||||
description: source.description.toPrimitive(),
|
description: source.description.toPrimitive(),
|
||||||
quantity: source.quantity.toPrimitive(),
|
|
||||||
unit_price: source.unitPrice.toPrimitive(),
|
quantity_amount: source.quantity.toPrimitive().amount,
|
||||||
subtotal: source.calculateSubtotal().toPrimitive(),
|
quantity_scale: source.quantity.toPrimitive().scale,
|
||||||
total: source.calculateTotal().toPrimitive(),
|
|
||||||
|
unit_price_amount: source.unitPrice.toPrimitive().amount,
|
||||||
|
unit_price_scale: source.unitPrice.toPrimitive().scale,
|
||||||
|
|
||||||
|
subtotal_amount: source.subtotalPrice.toPrimitive().amount,
|
||||||
|
subtotal_scale: source.subtotalPrice.toPrimitive().scale,
|
||||||
|
|
||||||
|
discount_amount: source.discount.toPrimitive().amount,
|
||||||
|
discount_scale: source.discount.toPrimitive().scale,
|
||||||
|
|
||||||
|
total_amount: source.totalPrice.toPrimitive().amount,
|
||||||
|
total_scale: source.totalPrice.toPrimitive().scale,
|
||||||
};
|
};
|
||||||
return lineData;
|
return lineData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
} from "@common/infrastructure/sequelize/sequelize-mapper";
|
} from "@common/infrastructure/sequelize/sequelize-mapper";
|
||||||
import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "@contexts/invoices/domain/";
|
import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "@contexts/invoices/domain/";
|
||||||
import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize";
|
import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize";
|
||||||
|
import { InvoiceItemMapper } from "./invoice-item.mapper"; // Importar el mapper de items
|
||||||
|
|
||||||
export interface IInvoiceMapper
|
export interface IInvoiceMapper
|
||||||
extends ISequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice> {}
|
extends ISequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice> {}
|
||||||
@ -15,6 +16,13 @@ export class InvoiceMapper
|
|||||||
extends SequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice>
|
extends SequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice>
|
||||||
implements IInvoiceMapper
|
implements IInvoiceMapper
|
||||||
{
|
{
|
||||||
|
private invoiceItemMapper: InvoiceItemMapper;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.invoiceItemMapper = new InvoiceItemMapper(); // Instanciar el mapper de items
|
||||||
|
}
|
||||||
|
|
||||||
public mapToDomain(source: InvoiceModel, params?: MapperParamsType): Result<Invoice, Error> {
|
public mapToDomain(source: InvoiceModel, params?: MapperParamsType): Result<Invoice, Error> {
|
||||||
const idOrError = UniqueID.create(source.id);
|
const idOrError = UniqueID.create(source.id);
|
||||||
const statusOrError = InvoiceStatus.create(source.invoice_status);
|
const statusOrError = InvoiceStatus.create(source.invoice_status);
|
||||||
@ -23,18 +31,6 @@ export class InvoiceMapper
|
|||||||
const issueDateOrError = UtcDate.create(source.issue_date);
|
const issueDateOrError = UtcDate.create(source.issue_date);
|
||||||
const operationDateOrError = UtcDate.create(source.operation_date);
|
const operationDateOrError = UtcDate.create(source.operation_date);
|
||||||
|
|
||||||
/*const subtotalOrError = MoneyValue.create({
|
|
||||||
amount: source.subtotal,
|
|
||||||
scale: 2,
|
|
||||||
currency_code: source.invoice_currency,
|
|
||||||
});
|
|
||||||
|
|
||||||
const totalOrError = MoneyValue.create({
|
|
||||||
amount: source.total,
|
|
||||||
scale: 2,
|
|
||||||
currency_code: source.invoice_currency,
|
|
||||||
});*/
|
|
||||||
|
|
||||||
const result = Result.combine([
|
const result = Result.combine([
|
||||||
idOrError,
|
idOrError,
|
||||||
statusOrError,
|
statusOrError,
|
||||||
@ -42,14 +38,22 @@ export class InvoiceMapper
|
|||||||
invoiceNumberOrError,
|
invoiceNumberOrError,
|
||||||
issueDateOrError,
|
issueDateOrError,
|
||||||
operationDateOrError,
|
operationDateOrError,
|
||||||
//subtotalOrError,
|
|
||||||
//totalOrError,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (result.isFailure) {
|
if (result.isFailure) {
|
||||||
return Result.fail(result.error);
|
return Result.fail(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mapear los items de la factura
|
||||||
|
const itemsOrErrors = this.invoiceItemMapper.mapArrayToDomain(source.items, {
|
||||||
|
sourceParent: source,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (itemsOrErrors.isFailure) {
|
||||||
|
return Result.fail(itemsOrErrors.error);
|
||||||
|
}
|
||||||
|
|
||||||
const invoiceCurrency = source.invoice_currency || "EUR";
|
const invoiceCurrency = source.invoice_currency || "EUR";
|
||||||
|
|
||||||
return Invoice.create(
|
return Invoice.create(
|
||||||
@ -60,10 +64,7 @@ export class InvoiceMapper
|
|||||||
issueDate: issueDateOrError.data,
|
issueDate: issueDateOrError.data,
|
||||||
operationDate: operationDateOrError.data,
|
operationDate: operationDateOrError.data,
|
||||||
invoiceCurrency,
|
invoiceCurrency,
|
||||||
|
items: itemsOrErrors.data,
|
||||||
//currency: source.invoice_currency,
|
|
||||||
//subtotal: subtotalOrError.data,
|
|
||||||
//total: totalOrError.data,
|
|
||||||
},
|
},
|
||||||
idOrError.data
|
idOrError.data
|
||||||
);
|
);
|
||||||
@ -73,6 +74,8 @@ export class InvoiceMapper
|
|||||||
const subtotal = source.calculateSubtotal();
|
const subtotal = source.calculateSubtotal();
|
||||||
const total = source.calculateTotal();
|
const total = source.calculateTotal();
|
||||||
|
|
||||||
|
const items = this.invoiceItemMapper.mapCollectionToPersistence(source.items, params);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: source.id.toString(),
|
id: source.id.toString(),
|
||||||
invoice_status: source.status.toPrimitive(),
|
invoice_status: source.status.toPrimitive(),
|
||||||
@ -88,6 +91,8 @@ export class InvoiceMapper
|
|||||||
|
|
||||||
total_amount: total.amount,
|
total_amount: total.amount,
|
||||||
total_scale: total.scale,
|
total_scale: total.scale,
|
||||||
|
|
||||||
|
items,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { IInvoiceRepository } from "@contexts/invoices/domain";
|
import { IInvoiceRepository } from "@contexts/invoices/domain";
|
||||||
import { invoiceRepository } from "./invoice.repository";
|
import { invoiceRepository } from "./invoice.repository";
|
||||||
|
|
||||||
|
export * from "./invoice-item.model";
|
||||||
export * from "./invoice.model";
|
export * from "./invoice.model";
|
||||||
|
|
||||||
export * from "./invoice.repository";
|
export * from "./invoice.repository";
|
||||||
|
|||||||
@ -4,47 +4,32 @@ import {
|
|||||||
InferAttributes,
|
InferAttributes,
|
||||||
InferCreationAttributes,
|
InferCreationAttributes,
|
||||||
Model,
|
Model,
|
||||||
NonAttribute,
|
|
||||||
Sequelize,
|
Sequelize,
|
||||||
} from "sequelize";
|
} from "sequelize";
|
||||||
import { InvoiceModel } from "./invoice.model";
|
|
||||||
|
|
||||||
export type TCreationInvoiceItem_Model = InferCreationAttributes<
|
export type InvoiceItemCreationAttributes = InferCreationAttributes<InvoiceItemModel, {}> & {};
|
||||||
InvoiceItem_Model,
|
|
||||||
{
|
|
||||||
/*omit: "invoice"*/
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
export class InvoiceItem_Model extends Model<
|
export class InvoiceItemModel extends Model<
|
||||||
InferAttributes<
|
InferAttributes<InvoiceItemModel>,
|
||||||
InvoiceItem_Model,
|
InvoiceItemCreationAttributes
|
||||||
{
|
|
||||||
/*omit: "invoice"*/
|
|
||||||
}
|
|
||||||
>,
|
|
||||||
InferCreationAttributes<
|
|
||||||
InvoiceItem_Model,
|
|
||||||
{
|
|
||||||
/*omit: "invoice"*/
|
|
||||||
}
|
|
||||||
>
|
|
||||||
> {
|
> {
|
||||||
static associate(connection: Sequelize) {
|
static associate(connection: Sequelize) {
|
||||||
const { Invoice_Model, InvoiceItem_Model } = connection.models;
|
/*const { Invoice_Model, InvoiceItem_Model } = connection.models;
|
||||||
|
|
||||||
InvoiceItem_Model.belongsTo(Invoice_Model, {
|
InvoiceItem_Model.belongsTo(Invoice_Model, {
|
||||||
as: "invoice",
|
as: "invoice",
|
||||||
foreignKey: "invoice_id",
|
foreignKey: "invoice_id",
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
declare invoice_id: string;
|
|
||||||
declare item_id: string;
|
declare item_id: string;
|
||||||
|
declare invoice_id: string;
|
||||||
|
|
||||||
declare parent_id: CreationOptional<string>;
|
declare parent_id: CreationOptional<string>;
|
||||||
declare position: number;
|
declare position: number;
|
||||||
declare item_type: string;
|
declare item_type: string;
|
||||||
|
|
||||||
declare description: CreationOptional<string>;
|
declare description: CreationOptional<string>;
|
||||||
|
|
||||||
declare quantity_amount: CreationOptional<number>;
|
declare quantity_amount: CreationOptional<number>;
|
||||||
@ -56,14 +41,17 @@ export class InvoiceItem_Model extends Model<
|
|||||||
declare subtotal_amount: CreationOptional<number>;
|
declare subtotal_amount: CreationOptional<number>;
|
||||||
declare subtotal_scale: CreationOptional<number>;
|
declare subtotal_scale: CreationOptional<number>;
|
||||||
|
|
||||||
|
declare discount_amount: CreationOptional<number>;
|
||||||
|
declare discount_scale: CreationOptional<number>;
|
||||||
|
|
||||||
declare total_amount: CreationOptional<number>;
|
declare total_amount: CreationOptional<number>;
|
||||||
declare total_scale: CreationOptional<number>;
|
declare total_scale: CreationOptional<number>;
|
||||||
|
|
||||||
declare invoice?: NonAttribute<InvoiceModel>;
|
//declare invoice?: NonAttribute<InvoiceModel>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (sequelize: Sequelize) => {
|
export default (sequelize: Sequelize) => {
|
||||||
InvoiceItem_Model.init(
|
InvoiceItemModel.init(
|
||||||
{
|
{
|
||||||
item_id: {
|
item_id: {
|
||||||
type: new DataTypes.UUID(),
|
type: new DataTypes.UUID(),
|
||||||
@ -138,6 +126,17 @@ export default (sequelize: Sequelize) => {
|
|||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
discount_amount: {
|
||||||
|
type: new DataTypes.SMALLINT(),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
discount_scale: {
|
||||||
|
type: new DataTypes.SMALLINT(),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
|
||||||
/*tax_amount: {
|
/*tax_amount: {
|
||||||
type: new DataTypes.BIGINT(),
|
type: new DataTypes.BIGINT(),
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
@ -156,8 +155,12 @@ export default (sequelize: Sequelize) => {
|
|||||||
{
|
{
|
||||||
sequelize,
|
sequelize,
|
||||||
tableName: "invoice_items",
|
tableName: "invoice_items",
|
||||||
|
|
||||||
|
defaultScope: {},
|
||||||
|
|
||||||
|
scopes: {},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return InvoiceItem_Model;
|
return InvoiceItemModel;
|
||||||
};
|
};
|
||||||
@ -4,25 +4,24 @@ import {
|
|||||||
InferAttributes,
|
InferAttributes,
|
||||||
InferCreationAttributes,
|
InferCreationAttributes,
|
||||||
Model,
|
Model,
|
||||||
|
NonAttribute,
|
||||||
Sequelize,
|
Sequelize,
|
||||||
} from "sequelize";
|
} from "sequelize";
|
||||||
|
import { InvoiceItemCreationAttributes, InvoiceItemModel } from "./invoice-item.model";
|
||||||
|
|
||||||
export type InvoiceCreationAttributes = InferCreationAttributes<InvoiceModel, {}> & {};
|
export type InvoiceCreationAttributes = InferCreationAttributes<InvoiceModel, { omit: "items" }> & {
|
||||||
|
items?: InvoiceItemCreationAttributes[];
|
||||||
|
};
|
||||||
|
|
||||||
export class InvoiceModel extends Model<InferAttributes<InvoiceModel>, InvoiceCreationAttributes> {
|
export class InvoiceModel extends Model<InferAttributes<InvoiceModel>, InvoiceCreationAttributes> {
|
||||||
static associate(connection: Sequelize) {
|
static associate(connection: Sequelize) {
|
||||||
/*const { Invoice_Model, InvoiceItem_Model, InvoiceParticipant_Model } = connection.models;
|
const { InvoiceModel, InvoiceItemModel } = connection.models;
|
||||||
|
|
||||||
Invoice_Model.hasMany(InvoiceItem_Model, {
|
InvoiceModel.hasMany(InvoiceItemModel, {
|
||||||
as: "items",
|
as: "items",
|
||||||
foreignKey: "invoice_id",
|
foreignKey: "invoice_id",
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
});
|
});
|
||||||
Invoice_Model.hasMany(InvoiceParticipant_Model, {
|
|
||||||
as: "customer",
|
|
||||||
foreignKey: "invoice_id",
|
|
||||||
onDelete: "CASCADE",
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare id: string;
|
declare id: string;
|
||||||
@ -43,7 +42,8 @@ export class InvoiceModel extends Model<InferAttributes<InvoiceModel>, InvoiceCr
|
|||||||
declare total_amount: CreationOptional<number>;
|
declare total_amount: CreationOptional<number>;
|
||||||
declare total_scale: CreationOptional<number>;
|
declare total_scale: CreationOptional<number>;
|
||||||
|
|
||||||
//declare items: NonAttribute<InvoiceItem_Model[]>;
|
// Relationships
|
||||||
|
declare items: NonAttribute<InvoiceItemModel[]>;
|
||||||
//declare customer: NonAttribute<InvoiceParticipant_Model[]>;
|
//declare customer: NonAttribute<InvoiceParticipant_Model[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,24 +12,30 @@ export const ICreateInvoiceRequestSchema = z.object({
|
|||||||
const dateStr = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format");
|
const dateStr = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format");
|
||||||
return dateStr.safeParse(date).success;
|
return dateStr.safeParse(date).success;
|
||||||
}),
|
}),
|
||||||
customerId: z.string().uuid(),
|
//customerId: z.string().uuid(),
|
||||||
lang_code: z.string().min(1),
|
lang_code: z.string().min(1),
|
||||||
currency_code: z.string().min(1),
|
currency_code: z.string().min(1),
|
||||||
|
|
||||||
items: z.array(
|
items: z
|
||||||
|
.array(
|
||||||
z.object({
|
z.object({
|
||||||
//id: z.string().uuid(),
|
//id: z.string().uuid(),
|
||||||
description: z.string().min(1),
|
description: z.string().optional(),
|
||||||
unit_price: z.object({
|
unit_price: z
|
||||||
|
.object({
|
||||||
amount: z.number().positive(),
|
amount: z.number().positive(),
|
||||||
scale: z.number().positive(),
|
scale: z.number().positive(),
|
||||||
}),
|
|
||||||
quantity: z.object({
|
|
||||||
amount: z.number().positive(),
|
|
||||||
scale: z.number().positive(),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
),
|
.optional(),
|
||||||
|
quantity: z
|
||||||
|
.object({
|
||||||
|
amount: z.number().positive(),
|
||||||
|
scale: z.number().positive(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const IUpdateInvoiceRequestSchema = z.object({});
|
export const IUpdateInvoiceRequestSchema = z.object({});
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const serverError = (error: NodeJS.ErrnoException) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dependiendo de la criticidad, podrías forzar el proceso a salir
|
// Dependiendo de la criticidad, podrías forzar el proceso a salir
|
||||||
// process.exit(1);
|
process.exit(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Almacena en "connections" cada nueva conexión (descomentar si se quiere seguimiento)
|
// Almacena en "connections" cada nueva conexión (descomentar si se quiere seguimiento)
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { accountsRouter } from "./accounts.routes";
|
|
||||||
import { authRouter } from "./auth.routes";
|
|
||||||
import { invoicesRouter } from "./invoices.routes";
|
import { invoicesRouter } from "./invoices.routes";
|
||||||
import { usersRouter } from "./users.routes";
|
|
||||||
|
|
||||||
export const v1Routes = () => {
|
export const v1Routes = () => {
|
||||||
const routes = Router({ mergeParams: true });
|
const routes = Router({ mergeParams: true });
|
||||||
@ -11,9 +8,9 @@ export const v1Routes = () => {
|
|||||||
res.send("Hello world!");
|
res.send("Hello world!");
|
||||||
});
|
});
|
||||||
|
|
||||||
authRouter(routes);
|
//authRouter(routes);
|
||||||
usersRouter(routes);
|
//usersRouter(routes);
|
||||||
accountsRouter(routes);
|
//accountsRouter(routes);
|
||||||
|
|
||||||
// Sales
|
// Sales
|
||||||
invoicesRouter(routes);
|
invoicesRouter(routes);
|
||||||
|
|||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// 🔹 Disparar evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id, this.props.referencia));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(props: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createEmitted()) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineasDetalle(): any[] {
|
|
||||||
return this.props.lineasDetalle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get clienteOProveedor(): string {
|
|
||||||
return this.props.clienteOProveedor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createEmitted()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede enviar en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createEmitted()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede rechazar en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineasDetalle(): any[] {
|
|
||||||
return this.props.lineasDetalle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id, props.referencia));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
return Result.ok(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id, this.props.referencia));
|
|
||||||
return Result.ok(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id, this.props.referencia));
|
|
||||||
return Result.ok(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id, this.props.referencia));
|
|
||||||
return Result.ok(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id, this.props.referencia));
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Se puede definir una entidad específica para las líneas de detalle
|
|
||||||
clienteOProveedor: any; // Se puede definir una entidad específica para el cliente o proveedor
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.emitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.emitted) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.sent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.rejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(props: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(props: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.emitted;
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.emitted) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.sent;
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.rejected;
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineasDetalle(): any[] {
|
|
||||||
return this.props.lineasDetalle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get clienteOProveedor(): string {
|
|
||||||
return this.props.clienteOProveedor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: any; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(props: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createEmitted()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede enviar si ha sido emitida."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede rechazar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(props: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.emitted;
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.emitted) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.sent;
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.draft) {
|
|
||||||
return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.rejected;
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineasDetalle(): any[] {
|
|
||||||
return this.props.lineasDetalle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get clienteOProveedor(): string {
|
|
||||||
return this.props.clienteOProveedor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
// filepath: /home/rodax/Documentos/uecko-erp/apps/server/src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
|
|
||||||
// Emitir evento de dominio "FacturaDraft"
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id));
|
|
||||||
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(newProps: Partial<IFacturaProps>): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this.props, newProps);
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico para las líneas de detalle
|
|
||||||
clienteOProveedor: string; // Puede ser un ID o un objeto más complejo
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(props.id));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede emitir en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createEmitted()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede enviar en estado 'emitted'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede rechazar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.props.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
get referencia(): FacturaReference {
|
|
||||||
return this.props.referencia;
|
|
||||||
}
|
|
||||||
|
|
||||||
get estado(): FacturaStatus {
|
|
||||||
return this.props.estado;
|
|
||||||
}
|
|
||||||
|
|
||||||
get fecha(): UTCDate {
|
|
||||||
return this.props.fecha;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineasDetalle(): any[] {
|
|
||||||
return this.props.lineasDetalle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get clienteOProveedor(): string {
|
|
||||||
return this.props.clienteOProveedor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// filepath: src/contexts/billing/domain/aggregates/factura.ts
|
|
||||||
import { AggregateRoot, UniqueID, UTCDate } from "@common/domain";
|
|
||||||
import { Result } from "@common/helpers";
|
|
||||||
import { FacturaDraft } from "../events/factura-draft";
|
|
||||||
import { FacturaEmitted } from "../events/factura-emitted";
|
|
||||||
import { FacturaSent } from "../events/factura-sent";
|
|
||||||
import { FacturaRejected } from "../events/factura-rejected";
|
|
||||||
import { FacturaReference } from "../value-objects/factura-reference";
|
|
||||||
import { FacturaStatus } from "../value-objects/factura-status";
|
|
||||||
|
|
||||||
export interface IFacturaProps {
|
|
||||||
id: UniqueID;
|
|
||||||
referencia: FacturaReference;
|
|
||||||
lineasDetalle: any[]; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
clienteOProveedor: any; // Aquí puedes definir un tipo más específico si es necesario
|
|
||||||
estado: FacturaStatus;
|
|
||||||
fecha: UTCDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Factura extends AggregateRoot<IFacturaProps> {
|
|
||||||
static create(props: IFacturaProps): Result<Factura, Error> {
|
|
||||||
const factura = new Factura(props, props.id);
|
|
||||||
factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia));
|
|
||||||
return Result.ok(factura);
|
|
||||||
}
|
|
||||||
|
|
||||||
modify(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede modificar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para modificar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): Result<void, Error> {
|
|
||||||
if (this.props.estado !== FacturaStatus.createDraft()) {
|
|
||||||
return Result.fail(new Error("La factura solo se puede eliminar en estado 'draft'."));
|
|
||||||
}
|
|
||||||
// Lógica para eliminar la factura
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createEmitted();
|
|
||||||
this.addDomainEvent(new FacturaEmitted(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
send(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createSent();
|
|
||||||
this.addDomainEvent(new FacturaSent(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(): Result<void, Error> {
|
|
||||||
this.props.estado = FacturaStatus.createRejected();
|
|
||||||
this.addDomainEvent(new FacturaRejected(this.id));
|
|
||||||
return Result.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user