import { Money } from '../value-objects/Money.js'; import { TipoTributo } from '../value-objects/FiscalEnums.js'; import { ValidacionFiscalException } from '../exceptions/ValidacionFiscalException.js'; export interface ItemFacturaProps { id?: string; lineNumber: number; sku: string; description: string; quantity: number; unitCode?: string; unitPrice: number; taxPercentage?: number; taxTypeCode?: TipoTributo; discountAmount?: number; } export class ItemFactura { public readonly id?: string; public readonly lineNumber: number; public readonly sku: string; public readonly description: string; public readonly quantity: number; public readonly unitCode: string; public readonly unitPrice: Money; public readonly totalCost: Money; public readonly taxPercentage: number; public readonly taxAmount: Money; public readonly taxTypeCode: TipoTributo; public readonly discountAmount: Money; constructor(props: ItemFacturaProps) { if (props.quantity <= 0) { throw new ValidacionFiscalException(`La cantidad del item ${props.sku} debe ser mayor a 0.`); } if (props.unitPrice < 0) { throw new ValidacionFiscalException(`El precio unitario del item ${props.sku} no puede ser negativo.`); } this.id = props.id; this.lineNumber = props.lineNumber; this.sku = props.sku.trim(); this.description = props.description.trim(); this.quantity = props.quantity; this.unitCode = props.unitCode || 'EA'; // EA: Cada / Unidad this.unitPrice = Money.from(props.unitPrice); // Subtotal lĂ­nea = cantidad * precio unitario this.totalCost = this.unitPrice.multiply(this.quantity); this.discountAmount = Money.from(props.discountAmount || 0); this.taxPercentage = props.taxPercentage ?? 19.0; this.taxTypeCode = props.taxTypeCode || TipoTributo.IVA; // Base imponible = totalCost - discountAmount const baseImponible = this.totalCost.subtract(this.discountAmount); this.taxAmount = baseImponible.calculateTax(this.taxPercentage); } public get subtotalNeto(): Money { return this.totalCost.subtract(this.discountAmount); } public get totalConImpuesto(): Money { return this.subtotalNeto.add(this.taxAmount); } }