.
This commit is contained in:
parent
b22845f8da
commit
8455ae43db
@ -46,11 +46,13 @@ export function createApp(): Application {
|
||||
next();
|
||||
});
|
||||
|
||||
// Gestión global de errores
|
||||
app.use(globalErrorHandler);
|
||||
|
||||
// Registrar rutas de la API
|
||||
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;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ export class MoneyValue extends ValueObject<IMoneyValueProps> implements IMoneyV
|
||||
|
||||
/** Serializa el VO a una cadena del tipo "EUR:123400:2" */
|
||||
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 */
|
||||
@ -92,8 +92,8 @@ export class MoneyValue extends ValueObject<IMoneyValueProps> implements IMoneyV
|
||||
const [currencyCode, amountStr, scaleStr] = value.split(":");
|
||||
const amount = parseInt(amountStr, 10);
|
||||
const scale = parseInt(scaleStr, 10);
|
||||
const currency = getCurrencyByCode(currencyCode);
|
||||
return new MoneyValue(amount, scale, currency);
|
||||
const currency = currencyCode;
|
||||
return new MoneyValue({ amount, scale, currency_code: currency });
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
|
||||
@ -2,7 +2,12 @@ import { logger } from "@common/infrastructure/logger";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
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
|
||||
if (res.headersSent) {
|
||||
return next(error);
|
||||
|
||||
@ -7,27 +7,32 @@ export const validateAndParseBody =
|
||||
(schema: ZodSchema, options?: { sanitize?: boolean }) =>
|
||||
(req: Request, res: Response, next: NextFunction) => {
|
||||
const result = schema.safeParse(req.body);
|
||||
if (!result.success) {
|
||||
// Construye errores detallados
|
||||
const validationErrors = result.error.errors.map((err) => ({
|
||||
field: err.path.join("."),
|
||||
message: err.message,
|
||||
}));
|
||||
try {
|
||||
if (!result.success) {
|
||||
// Construye errores detallados
|
||||
const validationErrors = result.error.errors.map((err) => ({
|
||||
field: err.path.join("."),
|
||||
message: err.message,
|
||||
}));
|
||||
|
||||
throw new ApiError({
|
||||
status: httpStatus.BAD_REQUEST, //400
|
||||
title: "Validation Error",
|
||||
detail: "Algunos campos no cumplen con los criterios de validación.",
|
||||
type: "https://example.com/probs/validation-error",
|
||||
instance: req.originalUrl,
|
||||
errors: validationErrors,
|
||||
});
|
||||
throw new ApiError({
|
||||
status: httpStatus.BAD_REQUEST, //400
|
||||
title: "Validation Error",
|
||||
detail: "Algunos campos no cumplen con los criterios de validación.",
|
||||
type: "https://example.com/probs/validation-error",
|
||||
instance: req.originalUrl,
|
||||
errors: validationErrors,
|
||||
});
|
||||
}
|
||||
|
||||
// Si pasa la validación, opcionalmente reescribe req.body
|
||||
if (options?.sanitize ?? true) {
|
||||
req.body = result.data;
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error: unknown) {
|
||||
// Si ocurre un error, delega al manejador de errores global
|
||||
next(error as ApiError);
|
||||
}
|
||||
|
||||
// Si pasa la validación, opcionalmente reescribe req.body
|
||||
if (options?.sanitize ?? true) {
|
||||
req.body = result.data;
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
@ -28,7 +28,7 @@ export interface IInvoiceProps {
|
||||
//paymentTerms: string;
|
||||
|
||||
customer?: InvoiceCustomer;
|
||||
items?: Collection<InvoiceItem>;
|
||||
items?: InvoiceItems;
|
||||
}
|
||||
|
||||
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 { InvoiceItemDescription } from "../../value-objects";
|
||||
|
||||
@ -6,12 +6,13 @@ export interface IInvoiceItemProps {
|
||||
description: InvoiceItemDescription;
|
||||
quantity: Quantity; // Cantidad de unidades
|
||||
unitPrice: MoneyValue; // Precio unitario en la moneda de la factura
|
||||
subtotalPrice?: MoneyValue; // Precio unitario * Cantidad
|
||||
//subtotalPrice?: MoneyValue; // Precio unitario * Cantidad
|
||||
discount: Percentage; // % descuento
|
||||
totalPrice?: MoneyValue;
|
||||
//totalPrice?: MoneyValue;
|
||||
}
|
||||
|
||||
export interface IInvoiceItem {
|
||||
id: UniqueID;
|
||||
description: InvoiceItemDescription;
|
||||
quantity: Quantity;
|
||||
unitPrice: MoneyValue;
|
||||
@ -20,12 +21,22 @@ export interface IInvoiceItem {
|
||||
totalPrice: MoneyValue;
|
||||
}
|
||||
|
||||
export class InvoiceItem extends ValueObject<IInvoiceItemProps> implements IInvoiceItem {
|
||||
export class InvoiceItem extends DomainEntity<IInvoiceItemProps> implements IInvoiceItem {
|
||||
private _subtotalPrice!: MoneyValue;
|
||||
private _totalPrice!: MoneyValue;
|
||||
|
||||
public static create(props: IInvoiceItemProps): Result<InvoiceItem, Error> {
|
||||
return Result.ok(new InvoiceItem(props));
|
||||
public static create(props: IInvoiceItemProps, id?: UniqueID): Result<InvoiceItem, Error> {
|
||||
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 {
|
||||
|
||||
@ -43,4 +43,8 @@ export class InvoiceItemDescription extends ValueObject<IInvoiceItemDescriptionP
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,53 +1,79 @@
|
||||
import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure";
|
||||
import { Description, Quantity, UniqueID, UnitPrice } from "@shared/contexts";
|
||||
import { Invoice } from "../../domain";
|
||||
import { IInvoiceSimpleItemProps, InvoiceItem, InvoiceSimpleItem } from "../../domain/entities";
|
||||
import { IInvoicingContext } from "../InvoicingContext";
|
||||
import { InvoiceItem_Model, InvoiceModel, TCreationInvoiceItem_Model } from "../sequelize";
|
||||
import { MoneyValue, Percentage, Quantity, UniqueID } from "@common/domain";
|
||||
import { Result } from "@common/helpers";
|
||||
import {
|
||||
ISequelizeMapper,
|
||||
MapperParamsType,
|
||||
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
|
||||
extends ISequelizeMapper<InvoiceItem_Model, TCreationInvoiceItem_Model, InvoiceItem> {}
|
||||
extends ISequelizeMapper<InvoiceItemModel, InvoiceItemCreationAttributes, InvoiceItem> {}
|
||||
|
||||
export const createInvoiceItemMapper = (context: IInvoicingContext): IInvoiceItemMapper =>
|
||||
new InvoiceItemMapper({ context });
|
||||
|
||||
class InvoiceItemMapper
|
||||
extends SequelizeMapper<InvoiceItem_Model, TCreationInvoiceItem_Model, InvoiceItem>
|
||||
export class InvoiceItemMapper
|
||||
extends SequelizeMapper<InvoiceItemModel, InvoiceItemCreationAttributes, InvoiceItem>
|
||||
implements IInvoiceItemMapper
|
||||
{
|
||||
protected toDomainMappingImpl(
|
||||
source: InvoiceItem_Model,
|
||||
params: { sourceParent: InvoiceModel }
|
||||
): InvoiceItem {
|
||||
const { sourceParent } = params;
|
||||
const id = this.mapsValue(source, "item_id", UniqueID.create);
|
||||
public mapToDomain(
|
||||
source: InvoiceItemModel,
|
||||
params?: MapperParamsType
|
||||
): Result<InvoiceItem, Error> {
|
||||
const { sourceParent } = params as { sourceParent: InvoiceModel };
|
||||
|
||||
const props: IInvoiceSimpleItemProps = {
|
||||
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 idOrError = UniqueID.create(source.item_id);
|
||||
|
||||
const invoiceItemOrError = InvoiceSimpleItem.create(props, id);
|
||||
const descriptionOrError = InvoiceItemDescription.create(source.description);
|
||||
|
||||
if (invoiceItemOrError.isFailure) {
|
||||
throw invoiceItemOrError.error;
|
||||
const quantityOrError = Quantity.create({
|
||||
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,
|
||||
params: { index: number; sourceParent: Invoice }
|
||||
): TCreationInvoiceItem_Model {
|
||||
const { index, sourceParent } = params;
|
||||
params?: MapperParamsType
|
||||
): InferCreationAttributes<InvoiceItemModel, {}> {
|
||||
const { index, sourceParent } = params as {
|
||||
index: number;
|
||||
sourceParent: Invoice;
|
||||
};
|
||||
|
||||
const lineData = {
|
||||
parent_id: undefined,
|
||||
@ -57,10 +83,21 @@ class InvoiceItemMapper
|
||||
|
||||
item_id: source.id.toPrimitive(),
|
||||
description: source.description.toPrimitive(),
|
||||
quantity: source.quantity.toPrimitive(),
|
||||
unit_price: source.unitPrice.toPrimitive(),
|
||||
subtotal: source.calculateSubtotal().toPrimitive(),
|
||||
total: source.calculateTotal().toPrimitive(),
|
||||
|
||||
quantity_amount: source.quantity.toPrimitive().amount,
|
||||
quantity_scale: source.quantity.toPrimitive().scale,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
} from "@common/infrastructure/sequelize/sequelize-mapper";
|
||||
import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "@contexts/invoices/domain/";
|
||||
import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize";
|
||||
import { InvoiceItemMapper } from "./invoice-item.mapper"; // Importar el mapper de items
|
||||
|
||||
export interface IInvoiceMapper
|
||||
extends ISequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice> {}
|
||||
@ -15,6 +16,13 @@ export class InvoiceMapper
|
||||
extends SequelizeMapper<InvoiceModel, InvoiceCreationAttributes, Invoice>
|
||||
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> {
|
||||
const idOrError = UniqueID.create(source.id);
|
||||
const statusOrError = InvoiceStatus.create(source.invoice_status);
|
||||
@ -23,18 +31,6 @@ export class InvoiceMapper
|
||||
const issueDateOrError = UtcDate.create(source.issue_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([
|
||||
idOrError,
|
||||
statusOrError,
|
||||
@ -42,14 +38,22 @@ export class InvoiceMapper
|
||||
invoiceNumberOrError,
|
||||
issueDateOrError,
|
||||
operationDateOrError,
|
||||
//subtotalOrError,
|
||||
//totalOrError,
|
||||
]);
|
||||
|
||||
if (result.isFailure) {
|
||||
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";
|
||||
|
||||
return Invoice.create(
|
||||
@ -60,10 +64,7 @@ export class InvoiceMapper
|
||||
issueDate: issueDateOrError.data,
|
||||
operationDate: operationDateOrError.data,
|
||||
invoiceCurrency,
|
||||
|
||||
//currency: source.invoice_currency,
|
||||
//subtotal: subtotalOrError.data,
|
||||
//total: totalOrError.data,
|
||||
items: itemsOrErrors.data,
|
||||
},
|
||||
idOrError.data
|
||||
);
|
||||
@ -73,6 +74,8 @@ export class InvoiceMapper
|
||||
const subtotal = source.calculateSubtotal();
|
||||
const total = source.calculateTotal();
|
||||
|
||||
const items = this.invoiceItemMapper.mapCollectionToPersistence(source.items, params);
|
||||
|
||||
return {
|
||||
id: source.id.toString(),
|
||||
invoice_status: source.status.toPrimitive(),
|
||||
@ -88,6 +91,8 @@ export class InvoiceMapper
|
||||
|
||||
total_amount: total.amount,
|
||||
total_scale: total.scale,
|
||||
|
||||
items,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { IInvoiceRepository } from "@contexts/invoices/domain";
|
||||
import { invoiceRepository } from "./invoice.repository";
|
||||
|
||||
export * from "./invoice-item.model";
|
||||
export * from "./invoice.model";
|
||||
|
||||
export * from "./invoice.repository";
|
||||
|
||||
@ -4,47 +4,32 @@ import {
|
||||
InferAttributes,
|
||||
InferCreationAttributes,
|
||||
Model,
|
||||
NonAttribute,
|
||||
Sequelize,
|
||||
} from "sequelize";
|
||||
import { InvoiceModel } from "./invoice.model";
|
||||
|
||||
export type TCreationInvoiceItem_Model = InferCreationAttributes<
|
||||
InvoiceItem_Model,
|
||||
{
|
||||
/*omit: "invoice"*/
|
||||
}
|
||||
>;
|
||||
export type InvoiceItemCreationAttributes = InferCreationAttributes<InvoiceItemModel, {}> & {};
|
||||
|
||||
export class InvoiceItem_Model extends Model<
|
||||
InferAttributes<
|
||||
InvoiceItem_Model,
|
||||
{
|
||||
/*omit: "invoice"*/
|
||||
}
|
||||
>,
|
||||
InferCreationAttributes<
|
||||
InvoiceItem_Model,
|
||||
{
|
||||
/*omit: "invoice"*/
|
||||
}
|
||||
>
|
||||
export class InvoiceItemModel extends Model<
|
||||
InferAttributes<InvoiceItemModel>,
|
||||
InvoiceItemCreationAttributes
|
||||
> {
|
||||
static associate(connection: Sequelize) {
|
||||
const { Invoice_Model, InvoiceItem_Model } = connection.models;
|
||||
/*const { Invoice_Model, InvoiceItem_Model } = connection.models;
|
||||
|
||||
InvoiceItem_Model.belongsTo(Invoice_Model, {
|
||||
as: "invoice",
|
||||
foreignKey: "invoice_id",
|
||||
onDelete: "CASCADE",
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
declare invoice_id: string;
|
||||
declare item_id: string;
|
||||
declare invoice_id: string;
|
||||
|
||||
declare parent_id: CreationOptional<string>;
|
||||
declare position: number;
|
||||
declare item_type: string;
|
||||
|
||||
declare description: CreationOptional<string>;
|
||||
|
||||
declare quantity_amount: CreationOptional<number>;
|
||||
@ -56,14 +41,17 @@ export class InvoiceItem_Model extends Model<
|
||||
declare subtotal_amount: CreationOptional<number>;
|
||||
declare subtotal_scale: CreationOptional<number>;
|
||||
|
||||
declare discount_amount: CreationOptional<number>;
|
||||
declare discount_scale: CreationOptional<number>;
|
||||
|
||||
declare total_amount: CreationOptional<number>;
|
||||
declare total_scale: CreationOptional<number>;
|
||||
|
||||
declare invoice?: NonAttribute<InvoiceModel>;
|
||||
//declare invoice?: NonAttribute<InvoiceModel>;
|
||||
}
|
||||
|
||||
export default (sequelize: Sequelize) => {
|
||||
InvoiceItem_Model.init(
|
||||
InvoiceItemModel.init(
|
||||
{
|
||||
item_id: {
|
||||
type: new DataTypes.UUID(),
|
||||
@ -138,6 +126,17 @@ export default (sequelize: Sequelize) => {
|
||||
defaultValue: null,
|
||||
},
|
||||
|
||||
discount_amount: {
|
||||
type: new DataTypes.SMALLINT(),
|
||||
allowNull: true,
|
||||
defaultValue: null,
|
||||
},
|
||||
discount_scale: {
|
||||
type: new DataTypes.SMALLINT(),
|
||||
allowNull: true,
|
||||
defaultValue: null,
|
||||
},
|
||||
|
||||
/*tax_amount: {
|
||||
type: new DataTypes.BIGINT(),
|
||||
allowNull: true,
|
||||
@ -156,8 +155,12 @@ export default (sequelize: Sequelize) => {
|
||||
{
|
||||
sequelize,
|
||||
tableName: "invoice_items",
|
||||
|
||||
defaultScope: {},
|
||||
|
||||
scopes: {},
|
||||
}
|
||||
);
|
||||
|
||||
return InvoiceItem_Model;
|
||||
return InvoiceItemModel;
|
||||
};
|
||||
@ -4,25 +4,24 @@ import {
|
||||
InferAttributes,
|
||||
InferCreationAttributes,
|
||||
Model,
|
||||
NonAttribute,
|
||||
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> {
|
||||
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",
|
||||
foreignKey: "invoice_id",
|
||||
onDelete: "CASCADE",
|
||||
});
|
||||
Invoice_Model.hasMany(InvoiceParticipant_Model, {
|
||||
as: "customer",
|
||||
foreignKey: "invoice_id",
|
||||
onDelete: "CASCADE",
|
||||
});*/
|
||||
}
|
||||
|
||||
declare id: string;
|
||||
@ -43,7 +42,8 @@ export class InvoiceModel extends Model<InferAttributes<InvoiceModel>, InvoiceCr
|
||||
declare total_amount: CreationOptional<number>;
|
||||
declare total_scale: CreationOptional<number>;
|
||||
|
||||
//declare items: NonAttribute<InvoiceItem_Model[]>;
|
||||
// Relationships
|
||||
declare items: NonAttribute<InvoiceItemModel[]>;
|
||||
//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");
|
||||
return dateStr.safeParse(date).success;
|
||||
}),
|
||||
customerId: z.string().uuid(),
|
||||
//customerId: z.string().uuid(),
|
||||
lang_code: z.string().min(1),
|
||||
currency_code: z.string().min(1),
|
||||
|
||||
items: z.array(
|
||||
z.object({
|
||||
//id: z.string().uuid(),
|
||||
description: z.string().min(1),
|
||||
unit_price: z.object({
|
||||
amount: z.number().positive(),
|
||||
scale: z.number().positive(),
|
||||
}),
|
||||
quantity: z.object({
|
||||
amount: z.number().positive(),
|
||||
scale: z.number().positive(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
//id: z.string().uuid(),
|
||||
description: z.string().optional(),
|
||||
unit_price: 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({});
|
||||
|
||||
@ -50,7 +50,7 @@ const serverError = (error: NodeJS.ErrnoException) => {
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
import { Router } from "express";
|
||||
import { accountsRouter } from "./accounts.routes";
|
||||
import { authRouter } from "./auth.routes";
|
||||
import { invoicesRouter } from "./invoices.routes";
|
||||
import { usersRouter } from "./users.routes";
|
||||
|
||||
export const v1Routes = () => {
|
||||
const routes = Router({ mergeParams: true });
|
||||
@ -11,9 +8,9 @@ export const v1Routes = () => {
|
||||
res.send("Hello world!");
|
||||
});
|
||||
|
||||
authRouter(routes);
|
||||
usersRouter(routes);
|
||||
accountsRouter(routes);
|
||||
//authRouter(routes);
|
||||
//usersRouter(routes);
|
||||
//accountsRouter(routes);
|
||||
|
||||
// Sales
|
||||
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