/// Domain Entity: Quote Item /// /// Represents a single line item in a quotation. library; /// Quote Item Entity /// /// Contains item-level information in a quote: /// - Product reference /// - Quantity and pricing /// - Price negotiation /// - Discounts class QuoteItem { /// Unique quote item identifier final String quoteItemId; /// Quote ID this item belongs to final String quoteId; /// Product ID final String productId; /// Quantity quoted final double quantity; /// Original/list price per unit final double originalPrice; /// Negotiated price per unit final double negotiatedPrice; /// Discount percentage final double discountPercent; /// Subtotal (quantity * negotiatedPrice) final double subtotal; /// Item notes final String? notes; const QuoteItem({ required this.quoteItemId, required this.quoteId, required this.productId, required this.quantity, required this.originalPrice, required this.negotiatedPrice, required this.discountPercent, required this.subtotal, this.notes, }); /// Calculate subtotal at original price double get subtotalAtOriginalPrice => quantity * originalPrice; /// Calculate discount amount per unit double get discountPerUnit => originalPrice - negotiatedPrice; /// Calculate total discount amount double get totalDiscountAmount => (quantity * originalPrice) - (quantity * negotiatedPrice); /// Calculate effective discount percentage double get effectiveDiscountPercentage { if (originalPrice == 0) return 0; return ((originalPrice - negotiatedPrice) / originalPrice) * 100; } /// Check if item has discount bool get hasDiscount => negotiatedPrice < originalPrice; /// Check if price was negotiated bool get isNegotiated => negotiatedPrice != originalPrice; /// Copy with method for immutability QuoteItem copyWith({ String? quoteItemId, String? quoteId, String? productId, double? quantity, double? originalPrice, double? negotiatedPrice, double? discountPercent, double? subtotal, String? notes, }) { return QuoteItem( quoteItemId: quoteItemId ?? this.quoteItemId, quoteId: quoteId ?? this.quoteId, productId: productId ?? this.productId, quantity: quantity ?? this.quantity, originalPrice: originalPrice ?? this.originalPrice, negotiatedPrice: negotiatedPrice ?? this.negotiatedPrice, discountPercent: discountPercent ?? this.discountPercent, subtotal: subtotal ?? this.subtotal, notes: notes ?? this.notes, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is QuoteItem && other.quoteItemId == quoteItemId && other.quoteId == quoteId && other.productId == productId && other.quantity == quantity && other.originalPrice == originalPrice && other.negotiatedPrice == negotiatedPrice && other.subtotal == subtotal; } @override int get hashCode { return Object.hash( quoteItemId, quoteId, productId, quantity, originalPrice, negotiatedPrice, subtotal, ); } @override String toString() { return 'QuoteItem(quoteItemId: $quoteItemId, productId: $productId, ' 'quantity: $quantity, originalPrice: $originalPrice, ' 'negotiatedPrice: $negotiatedPrice, subtotal: $subtotal)'; } }