/// Domain Entity: Payment Line /// /// Represents a payment transaction for an invoice. library; /// Payment method enum enum PaymentMethod { /// Cash payment cash, /// Bank transfer bankTransfer, /// Credit card creditCard, /// E-wallet (Momo, ZaloPay, etc.) ewallet, /// Check check, /// Other method other; /// Get display name for payment method String get displayName { switch (this) { case PaymentMethod.cash: return 'Cash'; case PaymentMethod.bankTransfer: return 'Bank Transfer'; case PaymentMethod.creditCard: return 'Credit Card'; case PaymentMethod.ewallet: return 'E-Wallet'; case PaymentMethod.check: return 'Check'; case PaymentMethod.other: return 'Other'; } } } /// Payment status enum enum PaymentStatus { /// Payment pending pending, /// Payment is being processed processing, /// Payment completed successfully completed, /// Payment failed failed, /// Payment refunded refunded, /// Payment cancelled cancelled; /// Get display name for status String get displayName { switch (this) { case PaymentStatus.pending: return 'Pending'; case PaymentStatus.processing: return 'Processing'; case PaymentStatus.completed: return 'Completed'; case PaymentStatus.failed: return 'Failed'; case PaymentStatus.refunded: return 'Refunded'; case PaymentStatus.cancelled: return 'Cancelled'; } } } /// Payment Line Entity /// /// Contains payment transaction information: /// - Payment details /// - Payment method /// - Bank information /// - Status tracking class PaymentLine { /// Unique payment line identifier final String paymentLineId; /// Invoice ID this payment is for final String invoiceId; /// Payment number (human-readable) final String paymentNumber; /// Payment date final DateTime paymentDate; /// Payment amount final double amount; /// Payment method final PaymentMethod paymentMethod; /// Bank name (for bank transfer) final String? bankName; /// Bank account number (for bank transfer) final String? bankAccount; /// Reference number (transaction ID, check number, etc.) final String? referenceNumber; /// Payment notes final String? notes; /// Payment status final PaymentStatus status; /// Receipt URL final String? receiptUrl; /// ERPNext payment entry reference final String? erpnextPaymentEntry; /// Creation timestamp final DateTime createdAt; /// Processing timestamp final DateTime? processedAt; const PaymentLine({ required this.paymentLineId, required this.invoiceId, required this.paymentNumber, required this.paymentDate, required this.amount, required this.paymentMethod, this.bankName, this.bankAccount, this.referenceNumber, this.notes, required this.status, this.receiptUrl, this.erpnextPaymentEntry, required this.createdAt, this.processedAt, }); /// Check if payment is completed bool get isCompleted => status == PaymentStatus.completed; /// Check if payment is pending bool get isPending => status == PaymentStatus.pending; /// Check if payment is being processed bool get isProcessing => status == PaymentStatus.processing; /// Check if payment failed bool get isFailed => status == PaymentStatus.failed; /// Check if payment has receipt bool get hasReceipt => receiptUrl != null && receiptUrl!.isNotEmpty; /// Copy with method for immutability PaymentLine copyWith({ String? paymentLineId, String? invoiceId, String? paymentNumber, DateTime? paymentDate, double? amount, PaymentMethod? paymentMethod, String? bankName, String? bankAccount, String? referenceNumber, String? notes, PaymentStatus? status, String? receiptUrl, String? erpnextPaymentEntry, DateTime? createdAt, DateTime? processedAt, }) { return PaymentLine( paymentLineId: paymentLineId ?? this.paymentLineId, invoiceId: invoiceId ?? this.invoiceId, paymentNumber: paymentNumber ?? this.paymentNumber, paymentDate: paymentDate ?? this.paymentDate, amount: amount ?? this.amount, paymentMethod: paymentMethod ?? this.paymentMethod, bankName: bankName ?? this.bankName, bankAccount: bankAccount ?? this.bankAccount, referenceNumber: referenceNumber ?? this.referenceNumber, notes: notes ?? this.notes, status: status ?? this.status, receiptUrl: receiptUrl ?? this.receiptUrl, erpnextPaymentEntry: erpnextPaymentEntry ?? this.erpnextPaymentEntry, createdAt: createdAt ?? this.createdAt, processedAt: processedAt ?? this.processedAt, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is PaymentLine && other.paymentLineId == paymentLineId && other.invoiceId == invoiceId && other.paymentNumber == paymentNumber && other.amount == amount && other.paymentMethod == paymentMethod && other.status == status; } @override int get hashCode { return Object.hash( paymentLineId, invoiceId, paymentNumber, amount, paymentMethod, status, ); } @override String toString() { return 'PaymentLine(paymentLineId: $paymentLineId, paymentNumber: $paymentNumber, ' 'amount: $amount, paymentMethod: $paymentMethod, status: $status)'; } }