Facturas de cliente
This commit is contained in:
parent
5064494b12
commit
e65524ea3c
@ -14,6 +14,6 @@ export const NumericStringSchema = z
|
||||
|
||||
// Cantidad de dinero (base): solo para la cantidad y la escala, sin moneda
|
||||
export const AmountBaseSchema = z.object({
|
||||
amount: NumericStringSchema,
|
||||
value: NumericStringSchema,
|
||||
scale: NumericStringSchema,
|
||||
});
|
||||
|
||||
@ -7,7 +7,7 @@ import { NumericStringSchema } from "./base.schemas";
|
||||
*/
|
||||
|
||||
export const PercentageSchema = z.object({
|
||||
amount: NumericStringSchema,
|
||||
value: NumericStringSchema,
|
||||
scale: NumericStringSchema,
|
||||
});
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { NumericStringSchema } from "./base.schemas";
|
||||
*/
|
||||
|
||||
export const QuantitySchema = z.object({
|
||||
amount: NumericStringSchema,
|
||||
value: NumericStringSchema,
|
||||
scale: NumericStringSchema,
|
||||
});
|
||||
|
||||
|
||||
@ -8,41 +8,38 @@ export class GetCustomerInvoiceItemsAssembler {
|
||||
toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO {
|
||||
const { items } = invoice;
|
||||
return items.map((item, index) => ({
|
||||
//id: item.
|
||||
position: index,
|
||||
id: item.id.toString(),
|
||||
position: String(index),
|
||||
description: toEmptyString(item.description, (value) => value.toPrimitive()),
|
||||
|
||||
quantity: item.quantity.match(
|
||||
(quantity) => {
|
||||
const { amount, scale } = quantity.toPrimitive();
|
||||
return { amount: amount.toString(), scale: scale.toString() };
|
||||
const { value, scale } = quantity.toPrimitive();
|
||||
return { value: value.toString(), scale: scale.toString() };
|
||||
},
|
||||
() => ({ amount: "", scale: "" })
|
||||
() => ({ value: "", scale: "" })
|
||||
),
|
||||
|
||||
unit_price_amount: item.unitAmount.match(
|
||||
(unitPrice) => {
|
||||
const { amount, scale } = unitPrice.toPrimitive();
|
||||
return { amount: amount.toString(), scale: scale.toString() };
|
||||
unit_amount: item.unitAmount.match(
|
||||
(unitAmount) => {
|
||||
const { value, scale } = unitAmount.toPrimitive();
|
||||
return { value: value.toString(), scale: scale.toString() };
|
||||
},
|
||||
() => ({ amount: "", scale: "" })
|
||||
() => ({ value: "", scale: "" })
|
||||
),
|
||||
|
||||
discount: item.discount.match(
|
||||
(discount) => {
|
||||
const { amount, scale } = discount.toPrimitive();
|
||||
return { amount: amount.toString(), scale: scale.toString() };
|
||||
discount_percentage: item.discountPercentage.match(
|
||||
(discountPercentage) => {
|
||||
const { value, scale } = discountPercentage.toPrimitive();
|
||||
return { value: value.toString(), scale: scale.toString() };
|
||||
},
|
||||
() => ({ amount: "", scale: "" })
|
||||
() => ({ value: "", scale: "" })
|
||||
),
|
||||
|
||||
total_amount: item.totalPrice.match(
|
||||
(discount) => {
|
||||
const { amount, scale } = discount.toPrimitive();
|
||||
return { amount: amount.toString(), scale: scale.toString() };
|
||||
},
|
||||
() => ({ amount: "", scale: "" })
|
||||
),
|
||||
total_amount: {
|
||||
value: item.totalAmount.toPrimitive().value.toString(),
|
||||
scale: item.totalAmount.toPrimitive().scale.toString(),
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
import { GetCustomerInvoiceByIdResponseDTO } from "@erp/customer-invoices/common/dto";
|
||||
import { toEmptyString } from "@repo/rdx-ddd";
|
||||
import { CustomerInvoice } from "../../../domain";
|
||||
import { GetCustomerInvoiceItemsAssembler } from "./get-invoice-items.assembler";
|
||||
|
||||
export class GetCustomerInvoiceAssembler {
|
||||
private _itemsAssembler!: GetCu;
|
||||
constructor() {}
|
||||
private _itemsAssembler!: GetCustomerInvoiceItemsAssembler;
|
||||
|
||||
constructor() {
|
||||
this._itemsAssembler = new GetCustomerInvoiceItemsAssembler();
|
||||
}
|
||||
|
||||
public toDTO(invoice: CustomerInvoice): GetCustomerInvoiceByIdResponseDTO {
|
||||
//const items = invoice.items.
|
||||
const items = this._itemsAssembler.toDTO(invoice);
|
||||
|
||||
return {
|
||||
id: invoice.id.toPrimitive(),
|
||||
@ -25,6 +29,38 @@ export class GetCustomerInvoiceAssembler {
|
||||
language_code: invoice.languageCode.toPrimitive(),
|
||||
currency_code: invoice.currencyCode.toPrimitive(),
|
||||
|
||||
subtotal_amount: {
|
||||
value: invoice.subtotalAmount.value.toString(),
|
||||
scale: invoice.subtotalAmount.scale.toString(),
|
||||
},
|
||||
|
||||
discount_percentage: {
|
||||
value: invoice.discountPercentage.value.toString(),
|
||||
scale: invoice.discountPercentage.scale.toString(),
|
||||
},
|
||||
|
||||
discount_amount: {
|
||||
value: invoice.discountAmount.value.toString(),
|
||||
scale: invoice.discountAmount.scale.toString(),
|
||||
},
|
||||
|
||||
taxable_amount: {
|
||||
value: invoice.taxableAmount.value.toString(),
|
||||
scale: invoice.taxableAmount.scale.toString(),
|
||||
},
|
||||
|
||||
tax_amount: {
|
||||
value: invoice.taxAmount.value.toString(),
|
||||
scale: invoice.taxAmount.scale.toString(),
|
||||
},
|
||||
|
||||
total_amount: {
|
||||
value: invoice.totalAmount.value.toString(),
|
||||
scale: invoice.totalAmount.scale.toString(),
|
||||
},
|
||||
|
||||
items,
|
||||
|
||||
metadata: {
|
||||
entity: "customer-invoices",
|
||||
},
|
||||
|
||||
@ -2,7 +2,7 @@ import { ITransactionManager } from "@erp/core/api";
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { CustomerInvoiceService } from "../../domain";
|
||||
import { GetCustomerInvoiceItemsAssembler } from "./assembler";
|
||||
import { GetCustomerInvoiceAssembler } from "./assembler";
|
||||
|
||||
type GetCustomerInvoiceUseCaseInput = {
|
||||
companyId: UniqueID;
|
||||
@ -13,7 +13,7 @@ export class GetCustomerInvoiceUseCase {
|
||||
constructor(
|
||||
private readonly service: CustomerInvoiceService,
|
||||
private readonly transactionManager: ITransactionManager,
|
||||
private readonly assembler: GetCustomerInvoiceItemsAssembler
|
||||
private readonly assembler: GetCustomerInvoiceAssembler
|
||||
) {}
|
||||
|
||||
public execute(params: GetCustomerInvoiceUseCaseInput) {
|
||||
|
||||
@ -37,7 +37,7 @@ export function mapDTOToCustomerInvoiceItemsProps(
|
||||
|
||||
const unitPrice = extractOrPushError(
|
||||
CustomerInvoiceItemUnitAmount.create({
|
||||
amount: item.unitPrice.amount,
|
||||
value: item.unitPrice.amount,
|
||||
scale: item.unitPrice.scale,
|
||||
currency_code: item.unitPrice.currency,
|
||||
}),
|
||||
@ -47,7 +47,7 @@ export function mapDTOToCustomerInvoiceItemsProps(
|
||||
|
||||
const discount = extractOrPushError(
|
||||
CustomerInvoiceItemDiscount.create({
|
||||
amount: item.discount.amount,
|
||||
value: item.discount.amount,
|
||||
scale: item.discount.scale,
|
||||
}),
|
||||
path("discount"),
|
||||
|
||||
@ -59,11 +59,11 @@ export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps>
|
||||
return this._subtotalAmount;
|
||||
}
|
||||
|
||||
get discount(): Maybe<CustomerInvoiceItemDiscount> {
|
||||
get discountPercentage(): Maybe<CustomerInvoiceItemDiscount> {
|
||||
return this.props.discount;
|
||||
}
|
||||
|
||||
get totalPrice(): CustomerInvoiceItemTotalAmount {
|
||||
get totalAmount(): CustomerInvoiceItemTotalAmount {
|
||||
if (!this._totalAmount) {
|
||||
this._totalAmount = this.calculateTotal();
|
||||
}
|
||||
|
||||
@ -19,7 +19,10 @@ export interface ICustomerInvoiceAddress {
|
||||
phone: PhoneNumber;
|
||||
}
|
||||
|
||||
export class CustomerInvoiceAddress extends ValueObject<ICustomerInvoiceAddressProps> implements ICustomerInvoiceAddress {
|
||||
export class CustomerInvoiceAddress
|
||||
extends ValueObject<ICustomerInvoiceAddressProps>
|
||||
implements ICustomerInvoiceAddress
|
||||
{
|
||||
public static create(props: ICustomerInvoiceAddressProps) {
|
||||
return Result.ok(new CustomerInvoiceAddress(props));
|
||||
}
|
||||
@ -62,7 +65,7 @@ export class CustomerInvoiceAddress extends ValueObject<ICustomerInvoiceAddressP
|
||||
return this.props.type;
|
||||
}
|
||||
|
||||
getValue(): ICustomerInvoiceAddressProps {
|
||||
getProps(): ICustomerInvoiceAddressProps {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
|
||||
@ -24,15 +24,15 @@ export class CustomerInvoiceAddressType extends ValueObject<ICustomerInvoiceAddr
|
||||
return Result.ok(new CustomerInvoiceAddressType({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,15 +46,15 @@ export class CustomerInvoiceItemDescription extends ValueObject<CustomerInvoiceI
|
||||
return CustomerInvoiceItemDescription.create(value).map((value) => Maybe.some(value));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
||||
export class CustomerInvoiceItemSubtotalAmount extends MoneyValue {
|
||||
public static DEFAULT_SCALE = 4;
|
||||
|
||||
static create({ amount, currency_code, scale }: MoneyValueProps) {
|
||||
static create({ value: amount, currency_code, scale }: MoneyValueProps) {
|
||||
const props = {
|
||||
amount: Number(amount),
|
||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
||||
|
||||
@ -3,9 +3,9 @@ import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
||||
export class CustomerInvoiceItemTotalAmount extends MoneyValue {
|
||||
public static DEFAULT_SCALE = 4;
|
||||
|
||||
static create({ amount, currency_code, scale }: MoneyValueProps) {
|
||||
static create({ value, currency_code, scale }: MoneyValueProps) {
|
||||
const props = {
|
||||
amount: Number(amount),
|
||||
value: Number(value),
|
||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
||||
currency_code,
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@ import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
||||
export class CustomerInvoiceItemUnitAmount extends MoneyValue {
|
||||
public static DEFAULT_SCALE = 4;
|
||||
|
||||
static create({ amount, currency_code, scale }: MoneyValueProps) {
|
||||
static create({ value: amount, currency_code, scale }: MoneyValueProps) {
|
||||
const props = {
|
||||
amount: Number(amount),
|
||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
||||
@ -14,7 +14,7 @@ export class CustomerInvoiceItemUnitAmount extends MoneyValue {
|
||||
|
||||
static zero(currency_code: string, scale: number = CustomerInvoiceItemUnitAmount.DEFAULT_SCALE) {
|
||||
const props: MoneyValueProps = {
|
||||
amount: 0,
|
||||
value: 0,
|
||||
scale,
|
||||
currency_code,
|
||||
};
|
||||
|
||||
@ -38,15 +38,15 @@ export class CustomerInvoiceNumber extends ValueObject<ICustomerInvoiceNumberPro
|
||||
return Result.ok(new CustomerInvoiceNumber({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,15 +46,15 @@ export class CustomerInvoiceSerie extends ValueObject<ICustomerInvoiceSerieProps
|
||||
return CustomerInvoiceSerie.create(value).map((value) => Maybe.some(value));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,12 +71,12 @@ export class CustomerInvoiceStatus extends ValueObject<ICustomerInvoiceStatusPro
|
||||
return new CustomerInvoiceStatus({ value: INVOICE_STATUS.REJECTED });
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
canTransitionTo(nextStatus: string): boolean {
|
||||
@ -93,6 +93,6 @@ export class CustomerInvoiceStatus extends ValueObject<ICustomerInvoiceStatusPro
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ export class CustomerInvoiceItemMapper
|
||||
|
||||
// Validación y creación de precio unitario
|
||||
const unitPriceOrError = CustomerInvoiceItemUnitAmount.create({
|
||||
amount: source.unit_price_amount,
|
||||
value: source.unit_price_amount,
|
||||
scale: source.unit_price_scale,
|
||||
currency_code: sourceParent.invoice_currency,
|
||||
});
|
||||
@ -70,7 +70,7 @@ export class CustomerInvoiceItemMapper
|
||||
|
||||
// Validación y creación de descuento
|
||||
const discountOrError = CustomerInvoiceItemDiscount.create({
|
||||
amount: source.discount_amount || 0,
|
||||
value: source.discount_amount || 0,
|
||||
scale: source.discount_scale || 0,
|
||||
});
|
||||
if (discountOrError.isFailure) {
|
||||
@ -132,8 +132,8 @@ export class CustomerInvoiceItemMapper
|
||||
discount_amount: source.discount.toPrimitive().amount,
|
||||
discount_scale: source.discount.toPrimitive().scale,
|
||||
|
||||
total_amount: source.totalPrice.toPrimitive().amount,
|
||||
total_scale: source.totalPrice.toPrimitive().scale,
|
||||
total_amount: source.totalAmount.toPrimitive().amount,
|
||||
total_scale: source.totalAmount.toPrimitive().scale,
|
||||
};
|
||||
return lineData;
|
||||
}
|
||||
|
||||
@ -15,18 +15,18 @@ export const CreateCustomerInvoiceRequestSchema = z.object({
|
||||
z.object({
|
||||
description: z.string().min(1, "Item description is required"),
|
||||
quantity: z.object({
|
||||
amount: z.number().positive("Quantity amount must be positive"),
|
||||
value: z.number().positive("Quantity amount must be positive"),
|
||||
scale: z.number().int().nonnegative("Quantity scale must be a non-negative integer"),
|
||||
}),
|
||||
unit_price: z.object({
|
||||
amount: z.number().positive("Unit price amount must be positive"),
|
||||
unit_amount: z.object({
|
||||
value: z.number().positive("Unit price amount must be positive"),
|
||||
scale: z.number().int().nonnegative("Unit price scale must be a non-negative integer"),
|
||||
currency_code: z
|
||||
.string()
|
||||
.min(3, "Unit price currency code must be at least 3 characters long"),
|
||||
}),
|
||||
discount: z.object({
|
||||
amount: z.number().nonnegative("Discount amount cannot be negative"),
|
||||
discount_percentage: z.object({
|
||||
value: z.number().nonnegative("Discount amount cannot be negative"),
|
||||
scale: z.number().int().nonnegative("Discount scale must be a non-negative integer"),
|
||||
}),
|
||||
})
|
||||
|
||||
@ -17,13 +17,21 @@ export const GetCustomerInvoiceByIdResponseSchema = z.object({
|
||||
language_code: z.string(),
|
||||
currency_code: z.string(),
|
||||
|
||||
subtotal_amount: AmountSchema,
|
||||
discount_percentage: PercentageSchema,
|
||||
discount_amount: AmountSchema,
|
||||
taxable_amount: AmountSchema,
|
||||
tax_amount: AmountSchema,
|
||||
total_amount: AmountSchema,
|
||||
|
||||
items: z.array(
|
||||
z.object({
|
||||
id: z.uuid(),
|
||||
position: z.string(),
|
||||
description: z.string(),
|
||||
quantity: QuantitySchema,
|
||||
unit_price_amount: AmountSchema,
|
||||
discount: PercentageSchema,
|
||||
unit_amount: AmountSchema,
|
||||
discount_percentage: PercentageSchema,
|
||||
total_amount: AmountSchema,
|
||||
})
|
||||
),
|
||||
|
||||
@ -24,15 +24,15 @@ export class CustomerAddressType extends ValueObject<ICustomerAddressTypeProps>
|
||||
return Result.ok(new CustomerAddressType({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,15 +34,15 @@ export class CustomerNumber extends ValueObject<ICustomerNumberProps> {
|
||||
return Result.ok(new CustomerNumber({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,15 +42,15 @@ export class CustomerSerie extends ValueObject<ICustomerSerieProps> {
|
||||
return CustomerSerie.create(value).map((value) => Maybe.some(value));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,12 +45,12 @@ export class CustomerStatus extends ValueObject<ICustomerStatusProps> {
|
||||
return this.props.value === CUSTOMER_STATUS.ACTIVE;
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
canTransitionTo(nextStatus: string): boolean {
|
||||
@ -67,6 +67,6 @@ export class CustomerStatus extends ValueObject<ICustomerStatusProps> {
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ describe("EmailAddress Value Object", () => {
|
||||
const result = EmailAddress.create("user@example.com");
|
||||
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data.getValue()).toBe("user@example.com");
|
||||
expect(result.data.getProps()).toBe("user@example.com");
|
||||
});
|
||||
|
||||
it("should return an error for invalid email format", () => {
|
||||
@ -43,6 +43,6 @@ describe("EmailAddress Value Object", () => {
|
||||
const email = EmailAddress.create("test@example.com");
|
||||
|
||||
expect(email.isSuccess).toBe(true);
|
||||
expect(email.data.getValue()).toBe("test@example.com");
|
||||
expect(email.data.getProps()).toBe("test@example.com");
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,50 +2,50 @@ import { MoneyValue } from "../money-value";
|
||||
|
||||
describe("MoneyValue", () => {
|
||||
test("should correctly instantiate with amount, scale, and currency", () => {
|
||||
const money = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
expect(money.amount).toBe(100);
|
||||
const money = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
expect(money.value).toBe(100);
|
||||
expect(money.currency).toBe("EUR");
|
||||
expect(money.scale).toBe(2);
|
||||
});
|
||||
|
||||
test("should add two MoneyValue instances with the same currency", () => {
|
||||
const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" });
|
||||
const money1 = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ value: 5000, scale: 2, currency_code: "EUR" });
|
||||
const result = money1.add(money2);
|
||||
expect(result.amount).toBe(150);
|
||||
expect(result.value).toBe(150);
|
||||
});
|
||||
|
||||
test("should subtract two MoneyValue instances with the same currency", () => {
|
||||
const money1 = new MoneyValue({ amount: 20000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" });
|
||||
const money1 = new MoneyValue({ value: 20000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ value: 5000, scale: 2, currency_code: "EUR" });
|
||||
const result = money1.subtract(money2);
|
||||
expect(result.amount).toBe(150);
|
||||
expect(result.value).toBe(150);
|
||||
});
|
||||
|
||||
test("should throw an error when adding different currencies", () => {
|
||||
const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "USD" });
|
||||
const money1 = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ value: 5000, scale: 2, currency_code: "USD" });
|
||||
expect(() => money1.add(money2)).toThrow(
|
||||
"You must provide a Dinero instance with the same currency"
|
||||
);
|
||||
});
|
||||
|
||||
test("should correctly convert scale", () => {
|
||||
const money = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
const converted = money.convertScale(4);
|
||||
expect(converted.amount).toBe(100);
|
||||
expect(converted.value).toBe(100);
|
||||
expect(converted.scale).toBe(4);
|
||||
});
|
||||
|
||||
test("should format correctly according to locale", () => {
|
||||
const money = new MoneyValue({ amount: 123456, scale: 2, currency_code: "EUR" });
|
||||
const money = new MoneyValue({ value: 123456, scale: 2, currency_code: "EUR" });
|
||||
expect(money.format("en-US")).toBe("€1,234.56");
|
||||
});
|
||||
|
||||
test("should compare MoneyValue instances correctly", () => {
|
||||
const money1 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ amount: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money3 = new MoneyValue({ amount: 5000, scale: 2, currency_code: "EUR" });
|
||||
const money1 = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money2 = new MoneyValue({ value: 10000, scale: 2, currency_code: "EUR" });
|
||||
const money3 = new MoneyValue({ value: 5000, scale: 2, currency_code: "EUR" });
|
||||
|
||||
expect(money1.equalsTo(money2)).toBe(true);
|
||||
expect(money1.greaterThan(money3)).toBe(true);
|
||||
|
||||
@ -2,49 +2,49 @@ import { Percentage } from "../percentage"; // Ajusta la ruta según sea necesar
|
||||
|
||||
describe("Percentage Value Object", () => {
|
||||
test("Debe crear un porcentaje válido con escala por defecto", () => {
|
||||
const result = Percentage.create({ amount: 200 }); // 2.00%
|
||||
const result = Percentage.create({ value: 200 }); // 2.00%
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data?.toString()).toBe("2.00%");
|
||||
});
|
||||
|
||||
test("Debe crear un porcentaje válido con escala definida", () => {
|
||||
const result = Percentage.create({ amount: 2150, scale: 2 }); // 21.50%
|
||||
const result = Percentage.create({ value: 2150, scale: 2 }); // 21.50%
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data?.toString()).toBe("21.50%");
|
||||
});
|
||||
|
||||
test("Debe devolver error si la cantidad supera el 100%", () => {
|
||||
const result = Percentage.create({ amount: 48732000, scale: 4 });
|
||||
const result = Percentage.create({ value: 48732000, scale: 4 });
|
||||
expect(result.isSuccess).toBe(false);
|
||||
expect(result.error.message).toBe("La escala debe estar entre 0 y 2.");
|
||||
});
|
||||
|
||||
test("Debe devolver error si la cantidad es negativa", () => {
|
||||
const result = Percentage.create({ amount: -100, scale: 2 });
|
||||
const result = Percentage.create({ value: -100, scale: 2 });
|
||||
expect(result.isSuccess).toBe(false);
|
||||
expect(result.error.message).toContain("La cantidad no puede ser negativa.");
|
||||
});
|
||||
|
||||
test("Debe devolver error si la escala es menor a 0", () => {
|
||||
const result = Percentage.create({ amount: 100, scale: -1 });
|
||||
const result = Percentage.create({ value: 100, scale: -1 });
|
||||
expect(result.isSuccess).toBe(false);
|
||||
expect(result.error.message).toContain("Number must be greater than or equal to 0");
|
||||
});
|
||||
|
||||
test("Debe devolver error si la escala es mayor a 10", () => {
|
||||
const result = Percentage.create({ amount: 100, scale: 11 });
|
||||
const result = Percentage.create({ value: 100, scale: 11 });
|
||||
expect(result.isSuccess).toBe(false);
|
||||
expect(result.error.message).toContain("La escala debe estar entre 0 y 2.");
|
||||
});
|
||||
|
||||
test("Debe representar correctamente el valor como string", () => {
|
||||
const result = Percentage.create({ amount: 750, scale: 2 }); // 7.50%
|
||||
const result = Percentage.create({ value: 750, scale: 2 }); // 7.50%
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data?.toString()).toBe("7.50%");
|
||||
});
|
||||
|
||||
test("Debe manejar correctamente el caso de 0%", () => {
|
||||
const result = Percentage.create({ amount: 0, scale: 2 });
|
||||
const result = Percentage.create({ value: 0, scale: 2 });
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data?.toString()).toBe("0.00%");
|
||||
});
|
||||
|
||||
@ -24,7 +24,7 @@ describe("PhoneNumber", () => {
|
||||
const result = PhoneNumber.create(validPhone);
|
||||
expect(result.isSuccess).toBe(true);
|
||||
const phoneNumber = result.data;
|
||||
expect(phoneNumber?.getValue()).toBe(validPhone);
|
||||
expect(phoneNumber?.getProps()).toBe(validPhone);
|
||||
});
|
||||
|
||||
test("debe obtener el código de país del número", () => {
|
||||
|
||||
@ -4,7 +4,7 @@ describe("Slug Value Object", () => {
|
||||
test("Debe crear un Slug válido", () => {
|
||||
const slugResult = Slug.create("valid-slug-123");
|
||||
expect(slugResult.isSuccess).toBe(true);
|
||||
expect(slugResult.data.getValue()).toBe("valid-slug-123");
|
||||
expect(slugResult.data.getProps()).toBe("valid-slug-123");
|
||||
});
|
||||
|
||||
test("Debe fallar si el Slug contiene caracteres inválidos", () => {
|
||||
|
||||
@ -4,7 +4,7 @@ describe("TINNumber", () => {
|
||||
it("debería crear un TINNumber válido", () => {
|
||||
const result = TINNumber.create("12345");
|
||||
expect(result.isSuccess).toBe(true);
|
||||
expect(result.data.getValue()).toBe("12345");
|
||||
expect(result.data.getProps()).toBe("12345");
|
||||
});
|
||||
|
||||
it("debería fallar si el valor es demasiado corto", () => {
|
||||
|
||||
@ -28,11 +28,11 @@ export class City extends ValueObject<CityProps> {
|
||||
return Result.ok(new City({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +28,11 @@ export class Country extends ValueObject<CountryProps> {
|
||||
return Result.ok(new Country({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ export class CurrencyCode extends ValueObject<CurrencyCodeProps> {
|
||||
return Result.ok(new CurrencyCode({ value: valueIsValid.data }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
|
||||
@ -38,11 +38,11 @@ export class EmailAddress extends ValueObject<EmailAddressProps> {
|
||||
return this.getDomain().split(".")[0];
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ export class LanguageCode extends ValueObject<LanguageCodeProps> {
|
||||
return Result.ok(new LanguageCode({ value: valueIsValid.data }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
|
||||
@ -19,17 +19,17 @@ export type RoundingMode =
|
||||
| "DOWN";
|
||||
|
||||
export interface MoneyValueProps {
|
||||
amount: number;
|
||||
value: number;
|
||||
scale?: number;
|
||||
currency_code?: string;
|
||||
}
|
||||
|
||||
export interface IMoneyValue {
|
||||
amount: number;
|
||||
value: number;
|
||||
scale: number;
|
||||
currency: Dinero.Currency;
|
||||
|
||||
getValue(): MoneyValueProps;
|
||||
getProps(): MoneyValueProps;
|
||||
convertScale(newScale: number): MoneyValue;
|
||||
add(addend: MoneyValue): MoneyValue;
|
||||
subtract(subtrahend: MoneyValue): MoneyValue;
|
||||
@ -53,9 +53,9 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
static DEFAULT_SCALE = DEFAULT_SCALE;
|
||||
static DEFAULT_CURRENCY_CODE = DEFAULT_CURRENCY_CODE;
|
||||
|
||||
static create({ amount, currency_code, scale }: MoneyValueProps) {
|
||||
static create({ value, currency_code, scale }: MoneyValueProps) {
|
||||
const props = {
|
||||
amount: Number(amount),
|
||||
value: Number(value),
|
||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
||||
currency_code: currency_code ?? MoneyValue.DEFAULT_CURRENCY_CODE,
|
||||
};
|
||||
@ -64,7 +64,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
constructor(props: MoneyValueProps) {
|
||||
super(props);
|
||||
const { amount, scale, currency_code } = props;
|
||||
const { value: amount, scale, currency_code } = props;
|
||||
this.dinero = Object.freeze(
|
||||
DineroFactory({
|
||||
amount,
|
||||
@ -74,7 +74,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
); // 🔒 Garantiza inmutabilidad
|
||||
}
|
||||
|
||||
get amount(): number {
|
||||
get value(): number {
|
||||
return this.dinero.getAmount() / 10 ** this.dinero.getPrecision(); // ** => Math.pow
|
||||
}
|
||||
|
||||
@ -86,27 +86,22 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
return this.dinero.getPrecision();
|
||||
}
|
||||
|
||||
getValue(): MoneyValueProps {
|
||||
getProps(): MoneyValueProps {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
/** Serializa el VO a una cadena del tipo "EUR:123400:2" */
|
||||
toPersistence(): string {
|
||||
return `${this.currency}:${this.dinero.getAmount()}:${this.scale}`;
|
||||
}
|
||||
|
||||
/** Reconstruye el VO desde la cadena persistida */
|
||||
static fromPersistence(value: string): MoneyValue {
|
||||
const [currencyCode, amountStr, scaleStr] = value.split(":");
|
||||
const amount = Number.parseInt(amountStr, 10);
|
||||
const scale = Number.parseInt(scaleStr, 10);
|
||||
const currency = currencyCode;
|
||||
return new MoneyValue({ amount, scale, currency_code: currency });
|
||||
return new MoneyValue({ value: amount, scale, currency_code: currency });
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return {
|
||||
amount: this.amount,
|
||||
value: this.value,
|
||||
scale: this.scale,
|
||||
currency_code: this.currency,
|
||||
};
|
||||
@ -115,7 +110,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
convertScale(newScale: number, roundingMode: RoundingMode = "HALF_UP"): MoneyValue {
|
||||
const _newDinero = this.dinero.convertPrecision(newScale, roundingMode);
|
||||
return new MoneyValue({
|
||||
amount: _newDinero.getAmount(),
|
||||
value: _newDinero.getAmount(),
|
||||
scale: _newDinero.getPrecision(),
|
||||
currency_code: _newDinero.getCurrency(),
|
||||
});
|
||||
@ -123,7 +118,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
add(addend: MoneyValue): MoneyValue {
|
||||
return new MoneyValue({
|
||||
amount: this.dinero.add(addend.dinero).getAmount(),
|
||||
value: this.dinero.add(addend.dinero).getAmount(),
|
||||
scale: this.scale,
|
||||
currency_code: this.currency,
|
||||
});
|
||||
@ -131,7 +126,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
subtract(subtrahend: MoneyValue): MoneyValue {
|
||||
return new MoneyValue({
|
||||
amount: this.dinero.subtract(subtrahend.dinero).getAmount(),
|
||||
value: this.dinero.subtract(subtrahend.dinero).getAmount(),
|
||||
scale: this.scale,
|
||||
currency_code: this.currency,
|
||||
});
|
||||
@ -142,7 +137,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
const _newDinero = this.dinero.multiply(_multiplier, roundingMode);
|
||||
return new MoneyValue({
|
||||
amount: _newDinero.getAmount(),
|
||||
value: _newDinero.getAmount(),
|
||||
scale: _newDinero.getPrecision(),
|
||||
currency_code: _newDinero.getCurrency(),
|
||||
});
|
||||
@ -153,7 +148,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
const _newDinero = this.dinero.divide(_divisor, roundingMode);
|
||||
return new MoneyValue({
|
||||
amount: _newDinero.getAmount(),
|
||||
value: _newDinero.getAmount(),
|
||||
scale: _newDinero.getPrecision(),
|
||||
currency_code: _newDinero.getCurrency(),
|
||||
});
|
||||
@ -164,7 +159,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
|
||||
const _newDinero = this.dinero.percentage(_percentage, roundingMode);
|
||||
return new MoneyValue({
|
||||
amount: _newDinero.getAmount(),
|
||||
value: _newDinero.getAmount(),
|
||||
scale: _newDinero.getPrecision(),
|
||||
currency_code: _newDinero.getCurrency(),
|
||||
});
|
||||
@ -187,11 +182,11 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
}
|
||||
|
||||
isPositive(): boolean {
|
||||
return this.amount > 0;
|
||||
return this.value > 0;
|
||||
}
|
||||
|
||||
isNegative(): boolean {
|
||||
return this.amount < 0;
|
||||
return this.value < 0;
|
||||
}
|
||||
|
||||
hasSameCurrency(comparator: MoneyValue): boolean {
|
||||
@ -209,7 +204,7 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
* @returns Importe formateado
|
||||
*/
|
||||
format(locale: string): string {
|
||||
const amount = this.amount;
|
||||
const value = this.value;
|
||||
const currency = this.currency;
|
||||
const scale = this.scale;
|
||||
|
||||
@ -219,6 +214,6 @@ export class MoneyValue extends ValueObject<MoneyValueProps> implements IMoneyVa
|
||||
minimumFractionDigits: scale,
|
||||
maximumFractionDigits: scale,
|
||||
useGrouping: true,
|
||||
}).format(amount);
|
||||
}).format(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,11 +44,11 @@ export class Name extends ValueObject<NameProps> {
|
||||
return Name.generateAcronym(this.toString());
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ const DEFAULT_MIN_SCALE = 0;
|
||||
const DEFAULT_MAX_SCALE = 2;
|
||||
|
||||
export interface PercentageProps {
|
||||
amount: number;
|
||||
value: number;
|
||||
scale: number;
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ export class Percentage extends ValueObject<PercentageProps> {
|
||||
|
||||
protected static validate(values: PercentageProps) {
|
||||
const schema = z.object({
|
||||
amount: z.number().int().min(Percentage.MIN_VALUE, "La cantidad no puede ser negativa."),
|
||||
value: z.number().int().min(Percentage.MIN_VALUE, "La cantidad no puede ser negativa."),
|
||||
scale: z
|
||||
.number()
|
||||
.int()
|
||||
@ -39,43 +39,43 @@ export class Percentage extends ValueObject<PercentageProps> {
|
||||
return schema.safeParse(values);
|
||||
}
|
||||
|
||||
static create(props: { amount: number; scale?: number }): Result<Percentage> {
|
||||
const { amount, scale = Percentage.DEFAULT_SCALE } = props;
|
||||
static create(props: { value: number; scale?: number }): Result<Percentage> {
|
||||
const { value, scale = Percentage.DEFAULT_SCALE } = props;
|
||||
|
||||
const validationResult = Percentage.validate({ amount, scale });
|
||||
const validationResult = Percentage.validate({ value, scale });
|
||||
if (!validationResult.success) {
|
||||
return Result.fail(new Error(validationResult.error.issues.map((e) => e.message).join(", ")));
|
||||
}
|
||||
|
||||
// Cálculo del valor real del porcentaje
|
||||
const realValue = amount / 10 ** scale; // ** => Math.pow
|
||||
const realValue = value / 10 ** scale; // ** => Math.pow
|
||||
|
||||
// Validación de rango
|
||||
if (realValue > Percentage.MAX_VALUE) {
|
||||
return Result.fail(new Error("El porcentaje no puede ser mayor a 100%."));
|
||||
}
|
||||
|
||||
return Result.ok(new Percentage({ amount, scale }));
|
||||
return Result.ok(new Percentage({ value, scale }));
|
||||
}
|
||||
|
||||
get amount(): number {
|
||||
return this.props.amount;
|
||||
get value(): number {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
get scale(): number {
|
||||
return this.props.scale;
|
||||
}
|
||||
|
||||
getValue(): PercentageProps {
|
||||
getProps(): PercentageProps {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toNumber(): number {
|
||||
return this.amount / 10 ** this.scale; // ** => Math.pow
|
||||
return this.value / 10 ** this.scale; // ** => Math.pow
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
||||
@ -51,12 +51,12 @@ export class PhoneNumber extends ValueObject<PhoneNumberProps> {
|
||||
return Result.ok(new PhoneNumber({ value: valueIsValid.data }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
getCountryCode(): string | undefined {
|
||||
|
||||
@ -73,12 +73,12 @@ export class PostalAddress extends ValueObject<PostalAddressProps> {
|
||||
return this.props.country;
|
||||
}
|
||||
|
||||
getValue(): PostalAddressProps {
|
||||
getProps(): PostalAddressProps {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toFormat(): string {
|
||||
|
||||
@ -36,7 +36,7 @@ export class PostalCode extends ValueObject<PostalCodeProps> {
|
||||
return Result.ok(new PostalCode({ value: valueIsValid.data }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
|
||||
@ -28,11 +28,11 @@ export class Province extends ValueObject<ProvinceProps> {
|
||||
return Result.ok(new Province({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,14 +7,14 @@ const DEFAULT_MIN_SCALE = 0;
|
||||
const DEFAULT_MAX_SCALE = 2;
|
||||
|
||||
export interface QuantityProps {
|
||||
amount: number;
|
||||
value: number;
|
||||
scale: number;
|
||||
}
|
||||
|
||||
export class Quantity extends ValueObject<QuantityProps> {
|
||||
protected static validate(values: QuantityProps) {
|
||||
const schema = z.object({
|
||||
amount: z.number().int(),
|
||||
value: z.number().int(),
|
||||
scale: z.number().int().min(Quantity.MIN_SCALE).max(Quantity.MAX_SCALE),
|
||||
});
|
||||
|
||||
@ -25,9 +25,9 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
static MIN_SCALE = DEFAULT_MIN_SCALE;
|
||||
static MAX_SCALE = DEFAULT_MAX_SCALE;
|
||||
|
||||
static create({ amount, scale }: QuantityProps) {
|
||||
static create({ value, scale }: QuantityProps) {
|
||||
const props = {
|
||||
amount: Number(amount),
|
||||
value: Number(value),
|
||||
scale: scale ?? Quantity.DEFAULT_SCALE,
|
||||
};
|
||||
const checkProps = Quantity.validate(props);
|
||||
@ -38,24 +38,24 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
return Result.ok(new Quantity({ ...(checkProps.data as QuantityProps) }));
|
||||
}
|
||||
|
||||
get amount(): number {
|
||||
return this.props.amount;
|
||||
get value(): number {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
get scale(): number {
|
||||
return this.props.scale;
|
||||
}
|
||||
|
||||
getValue(): QuantityProps {
|
||||
getProps(): QuantityProps {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toNumber(): number {
|
||||
return this.amount / 10 ** this.scale; // ** => Math.pow
|
||||
return this.value / 10 ** this.scale; // ** => Math.pow
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
@ -63,21 +63,21 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
}
|
||||
|
||||
isZero(): boolean {
|
||||
return this.amount === 0;
|
||||
return this.value === 0;
|
||||
}
|
||||
|
||||
isPositive(): boolean {
|
||||
return this.amount > 0;
|
||||
return this.value > 0;
|
||||
}
|
||||
|
||||
isNegative(): boolean {
|
||||
return this.amount < 0;
|
||||
return this.value < 0;
|
||||
}
|
||||
|
||||
increment(anotherQuantity?: Quantity): Result<Quantity, Error> {
|
||||
if (!anotherQuantity) {
|
||||
return Quantity.create({
|
||||
amount: Number(this.amount) + 1,
|
||||
value: Number(this.value) + 1,
|
||||
scale: this.scale,
|
||||
});
|
||||
}
|
||||
@ -87,7 +87,7 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
}
|
||||
|
||||
return Quantity.create({
|
||||
amount: Number(this.amount) + Number(anotherQuantity.amount),
|
||||
value: Number(this.value) + Number(anotherQuantity.value),
|
||||
scale: this.scale,
|
||||
});
|
||||
}
|
||||
@ -95,7 +95,7 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
decrement(anotherQuantity?: Quantity): Result<Quantity, Error> {
|
||||
if (!anotherQuantity) {
|
||||
return Quantity.create({
|
||||
amount: Number(this.amount) - 1,
|
||||
value: Number(this.value) - 1,
|
||||
scale: this.scale,
|
||||
});
|
||||
}
|
||||
@ -105,7 +105,7 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
}
|
||||
|
||||
return Quantity.create({
|
||||
amount: Number(this.amount) - Number(anotherQuantity.amount),
|
||||
value: Number(this.value) - Number(anotherQuantity.value),
|
||||
scale: this.scale,
|
||||
});
|
||||
}
|
||||
@ -120,11 +120,11 @@ export class Quantity extends ValueObject<QuantityProps> {
|
||||
}
|
||||
|
||||
const oldFactor = 10 ** this.scale; // ** => Math.pow
|
||||
const value = Number(this.amount) / oldFactor;
|
||||
const value = Number(this.value) / oldFactor;
|
||||
|
||||
const newFactor = 10 ** newScale; // ** => Math.pow
|
||||
const newValue = Math.round(value * newFactor);
|
||||
|
||||
return Quantity.create({ amount: newValue, scale: newScale });
|
||||
return Quantity.create({ value: newValue, scale: newScale });
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,11 +32,11 @@ export class Slug extends ValueObject<SlugProps> {
|
||||
return Result.ok(new Slug({ value: valueIsValid.data! }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +28,11 @@ export class Street extends ValueObject<StreetProps> {
|
||||
return Result.ok(new Street({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,11 +36,11 @@ export class TaxCode extends ValueObject<TaxCodeProps> {
|
||||
return Result.ok(new TaxCode({ value: valueIsValid.data! }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,11 +29,11 @@ export class TextValue extends ValueObject<TextValueProps> {
|
||||
return Result.ok(new TextValue({ value }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ export class TINNumber extends ValueObject<TINNumberProps> {
|
||||
return Result.ok(new TINNumber({ value: valueIsValid.data }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
|
||||
@ -32,15 +32,15 @@ export class UniqueID extends ValueObject<string> {
|
||||
return Result.ok(new UniqueID(generateUUIDv4()));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,11 +22,11 @@ export class URLAddress extends ValueObject<URLAddressProps> {
|
||||
return schema.safeParse(value);
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
toPrimitive() {
|
||||
return this.getValue();
|
||||
return this.getProps();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ export class UtcDate extends ValueObject<UtcDateProps> {
|
||||
return Result.ok(new UtcDate({ value: isoDateString }));
|
||||
}
|
||||
|
||||
getValue(): string {
|
||||
getProps(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ export abstract class ValueObject<T> {
|
||||
this.props = Object.freeze(props); // 🔒 Garantiza inmutabilidad
|
||||
}
|
||||
|
||||
abstract getValue(): any;
|
||||
abstract getProps(): any;
|
||||
|
||||
abstract toPrimitive(): any;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user