108 lines
2.9 KiB
TypeScript
108 lines
2.9 KiB
TypeScript
import { DomainEntity, MoneyValue, Percentage, UniqueID } from "@/core/common/domain";
|
|
import { Quantity } from "@/core/common/domain/value-objects/quantity";
|
|
import { Maybe, Result } from "@repo/rdx-utils";
|
|
|
|
export interface ICustomerInvoiceItemProps {
|
|
description: Maybe<string>; // Descripción del artículo o servicio
|
|
quantity: Maybe<Quantity>; // Cantidad de unidades
|
|
unitPrice: Maybe<MoneyValue>; // Precio unitario en la moneda de la factura
|
|
// subtotalPrice: MoneyValue; // Precio unitario * Cantidad
|
|
discount: Maybe<Percentage>; // % descuento
|
|
// totalPrice: MoneyValue;
|
|
}
|
|
|
|
export interface ICustomerInvoiceItem {
|
|
description: Maybe<string>;
|
|
quantity: Maybe<Quantity>;
|
|
unitPrice: Maybe<MoneyValue>;
|
|
subtotalPrice: Maybe<MoneyValue>;
|
|
discount: Maybe<Percentage>;
|
|
totalPrice: Maybe<MoneyValue>;
|
|
|
|
isEmptyLine(): boolean;
|
|
}
|
|
|
|
export class CustomerInvoiceItem
|
|
extends DomainEntity<ICustomerInvoiceItemProps>
|
|
implements ICustomerInvoiceItem
|
|
{
|
|
private readonly _subtotalPrice!: Maybe<MoneyValue>;
|
|
private readonly _totalPrice!: Maybe<MoneyValue>;
|
|
|
|
static validate(props: ICustomerInvoiceItemProps) {
|
|
return Result.ok(props);
|
|
}
|
|
|
|
static create(
|
|
props: ICustomerInvoiceItemProps,
|
|
id?: UniqueID
|
|
): Result<CustomerInvoiceItem, Error> {
|
|
const validation = CustomerInvoiceItem.validate(props);
|
|
if (!validation.isSuccess) {
|
|
Result.fail(new Error("Invalid invoice line data"));
|
|
}
|
|
|
|
return Result.ok(new CustomerInvoiceItem(props, id));
|
|
}
|
|
|
|
private constructor(props: ICustomerInvoiceItemProps, id?: UniqueID) {
|
|
super(props, id);
|
|
this._subtotalPrice = this.calculateSubtotal();
|
|
this._totalPrice = this.calculateTotal();
|
|
}
|
|
|
|
isEmptyLine(): boolean {
|
|
return this.quantity.isNone() && this.unitPrice.isNone() && this.discount.isNone();
|
|
}
|
|
|
|
calculateSubtotal(): Maybe<MoneyValue> {
|
|
if (this.quantity.isNone() || this.unitPrice.isNone()) {
|
|
return Maybe.none();
|
|
}
|
|
|
|
const _quantity = this.quantity.getOrUndefined()!;
|
|
const _unitPrice = this.unitPrice.getOrUndefined()!;
|
|
const _subtotal = _unitPrice.multiply(_quantity);
|
|
|
|
return Maybe.some(_subtotal);
|
|
}
|
|
|
|
calculateTotal(): Maybe<MoneyValue> {
|
|
const subtotal = this.calculateSubtotal();
|
|
|
|
if (subtotal.isNone()) {
|
|
return Maybe.none();
|
|
}
|
|
|
|
const _subtotal = subtotal.getOrUndefined()!;
|
|
const _discount = this.discount.getOrUndefined()!;
|
|
const _total = _subtotal.subtract(_subtotal.percentage(_discount));
|
|
|
|
return Maybe.some(_total);
|
|
}
|
|
|
|
get description(): Maybe<string> {
|
|
return this.props.description;
|
|
}
|
|
|
|
get quantity(): Maybe<Quantity> {
|
|
return this.props.quantity;
|
|
}
|
|
|
|
get unitPrice(): Maybe<MoneyValue> {
|
|
return this.props.unitPrice;
|
|
}
|
|
|
|
get subtotalPrice(): Maybe<MoneyValue> {
|
|
return this._subtotalPrice;
|
|
}
|
|
|
|
get discount(): Maybe<Percentage> {
|
|
return this.props.discount;
|
|
}
|
|
|
|
get totalPrice(): Maybe<MoneyValue> {
|
|
return this._totalPrice;
|
|
}
|
|
}
|