import { MoneyValue, type MoneyValueProps, type Percentage, type Quantity } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; type InvoiceAmountProps = Pick; export class InvoiceAmount extends MoneyValue { public static DEFAULT_SCALE = 2; static create({ value, currency_code }: InvoiceAmountProps) { const props = { value: Number(value), scale: InvoiceAmount.DEFAULT_SCALE, currency_code, }; return Result.ok(new InvoiceAmount(props)); } static zero(currency_code: string) { const props = { value: 0, currency_code, }; return InvoiceAmount.create(props).data; } toObjectString() { return { value: String(this.value), scale: String(this.scale), currency_code: this.currencyCode, }; } // Ensure fluent operations keep the subclass type roundUsingScale(intermediateScale: number) { const scaled = super.convertScale(intermediateScale); const normalized = scaled.convertScale(InvoiceAmount.DEFAULT_SCALE); const p = normalized.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } add(addend: MoneyValue) { const mv = super.add(addend); const p = mv.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } subtract(subtrahend: MoneyValue) { const mv = super.subtract(subtrahend); const p = mv.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } multiply(multiplier: number | Quantity) { const mv = super.multiply(multiplier); const p = mv.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } divide(divisor: number | Quantity) { const mv = super.divide(divisor); const p = mv.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } percentage(percentage: number | Percentage) { const mv = super.percentage(percentage); const p = mv.toPrimitive(); return new InvoiceAmount({ value: p.value, currency_code: p.currency_code, scale: InvoiceAmount.DEFAULT_SCALE, }); } }