update database
This commit is contained in:
273
lib/features/orders/domain/entities/invoice.dart
Normal file
273
lib/features/orders/domain/entities/invoice.dart
Normal file
@@ -0,0 +1,273 @@
|
||||
/// Domain Entity: Invoice
|
||||
///
|
||||
/// Represents an invoice for an order.
|
||||
library;
|
||||
|
||||
/// Invoice type enum
|
||||
enum InvoiceType {
|
||||
/// Standard invoice
|
||||
standard,
|
||||
|
||||
/// Proforma invoice
|
||||
proforma,
|
||||
|
||||
/// Credit note
|
||||
creditNote,
|
||||
|
||||
/// Debit note
|
||||
debitNote;
|
||||
}
|
||||
|
||||
/// Invoice status enum
|
||||
enum InvoiceStatus {
|
||||
/// Draft invoice
|
||||
draft,
|
||||
|
||||
/// Invoice has been submitted
|
||||
submitted,
|
||||
|
||||
/// Partially paid
|
||||
partiallyPaid,
|
||||
|
||||
/// Fully paid
|
||||
paid,
|
||||
|
||||
/// Overdue invoice
|
||||
overdue,
|
||||
|
||||
/// Cancelled invoice
|
||||
cancelled;
|
||||
|
||||
/// Get display name for status
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case InvoiceStatus.draft:
|
||||
return 'Draft';
|
||||
case InvoiceStatus.submitted:
|
||||
return 'Submitted';
|
||||
case InvoiceStatus.partiallyPaid:
|
||||
return 'Partially Paid';
|
||||
case InvoiceStatus.paid:
|
||||
return 'Paid';
|
||||
case InvoiceStatus.overdue:
|
||||
return 'Overdue';
|
||||
case InvoiceStatus.cancelled:
|
||||
return 'Cancelled';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoice Entity
|
||||
///
|
||||
/// Contains complete invoice information:
|
||||
/// - Invoice identification
|
||||
/// - Associated order
|
||||
/// - Amounts and calculations
|
||||
/// - Payment tracking
|
||||
/// - Status and dates
|
||||
class Invoice {
|
||||
/// Unique invoice identifier
|
||||
final String invoiceId;
|
||||
|
||||
/// Invoice number (human-readable)
|
||||
final String invoiceNumber;
|
||||
|
||||
/// User ID
|
||||
final String userId;
|
||||
|
||||
/// Order ID
|
||||
final String? orderId;
|
||||
|
||||
/// Invoice type
|
||||
final InvoiceType invoiceType;
|
||||
|
||||
/// Issue date
|
||||
final DateTime issueDate;
|
||||
|
||||
/// Due date
|
||||
final DateTime dueDate;
|
||||
|
||||
/// Currency code (e.g., VND, USD)
|
||||
final String currency;
|
||||
|
||||
/// Subtotal amount
|
||||
final double subtotalAmount;
|
||||
|
||||
/// Tax amount
|
||||
final double taxAmount;
|
||||
|
||||
/// Discount amount
|
||||
final double discountAmount;
|
||||
|
||||
/// Shipping amount
|
||||
final double shippingAmount;
|
||||
|
||||
/// Total amount
|
||||
final double totalAmount;
|
||||
|
||||
/// Amount paid so far
|
||||
final double amountPaid;
|
||||
|
||||
/// Amount remaining to be paid
|
||||
final double amountRemaining;
|
||||
|
||||
/// Invoice status
|
||||
final InvoiceStatus status;
|
||||
|
||||
/// Payment terms
|
||||
final String? paymentTerms;
|
||||
|
||||
/// Invoice notes
|
||||
final String? notes;
|
||||
|
||||
/// ERPNext invoice reference
|
||||
final String? erpnextInvoice;
|
||||
|
||||
/// Creation timestamp
|
||||
final DateTime createdAt;
|
||||
|
||||
/// Last update timestamp
|
||||
final DateTime updatedAt;
|
||||
|
||||
/// Last reminder sent timestamp
|
||||
final DateTime? lastReminderSent;
|
||||
|
||||
const Invoice({
|
||||
required this.invoiceId,
|
||||
required this.invoiceNumber,
|
||||
required this.userId,
|
||||
this.orderId,
|
||||
required this.invoiceType,
|
||||
required this.issueDate,
|
||||
required this.dueDate,
|
||||
required this.currency,
|
||||
required this.subtotalAmount,
|
||||
required this.taxAmount,
|
||||
required this.discountAmount,
|
||||
required this.shippingAmount,
|
||||
required this.totalAmount,
|
||||
required this.amountPaid,
|
||||
required this.amountRemaining,
|
||||
required this.status,
|
||||
this.paymentTerms,
|
||||
this.notes,
|
||||
this.erpnextInvoice,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.lastReminderSent,
|
||||
});
|
||||
|
||||
/// Check if invoice is fully paid
|
||||
bool get isPaid => status == InvoiceStatus.paid || amountRemaining <= 0;
|
||||
|
||||
/// Check if invoice is overdue
|
||||
bool get isOverdue =>
|
||||
status == InvoiceStatus.overdue ||
|
||||
(!isPaid && DateTime.now().isAfter(dueDate));
|
||||
|
||||
/// Check if invoice is partially paid
|
||||
bool get isPartiallyPaid =>
|
||||
amountPaid > 0 && amountPaid < totalAmount;
|
||||
|
||||
/// Get payment percentage
|
||||
double get paymentPercentage {
|
||||
if (totalAmount == 0) return 0;
|
||||
return (amountPaid / totalAmount) * 100;
|
||||
}
|
||||
|
||||
/// Get days until due
|
||||
int get daysUntilDue => dueDate.difference(DateTime.now()).inDays;
|
||||
|
||||
/// Get days overdue
|
||||
int get daysOverdue {
|
||||
if (!isOverdue) return 0;
|
||||
return DateTime.now().difference(dueDate).inDays;
|
||||
}
|
||||
|
||||
/// Copy with method for immutability
|
||||
Invoice copyWith({
|
||||
String? invoiceId,
|
||||
String? invoiceNumber,
|
||||
String? userId,
|
||||
String? orderId,
|
||||
InvoiceType? invoiceType,
|
||||
DateTime? issueDate,
|
||||
DateTime? dueDate,
|
||||
String? currency,
|
||||
double? subtotalAmount,
|
||||
double? taxAmount,
|
||||
double? discountAmount,
|
||||
double? shippingAmount,
|
||||
double? totalAmount,
|
||||
double? amountPaid,
|
||||
double? amountRemaining,
|
||||
InvoiceStatus? status,
|
||||
String? paymentTerms,
|
||||
String? notes,
|
||||
String? erpnextInvoice,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
DateTime? lastReminderSent,
|
||||
}) {
|
||||
return Invoice(
|
||||
invoiceId: invoiceId ?? this.invoiceId,
|
||||
invoiceNumber: invoiceNumber ?? this.invoiceNumber,
|
||||
userId: userId ?? this.userId,
|
||||
orderId: orderId ?? this.orderId,
|
||||
invoiceType: invoiceType ?? this.invoiceType,
|
||||
issueDate: issueDate ?? this.issueDate,
|
||||
dueDate: dueDate ?? this.dueDate,
|
||||
currency: currency ?? this.currency,
|
||||
subtotalAmount: subtotalAmount ?? this.subtotalAmount,
|
||||
taxAmount: taxAmount ?? this.taxAmount,
|
||||
discountAmount: discountAmount ?? this.discountAmount,
|
||||
shippingAmount: shippingAmount ?? this.shippingAmount,
|
||||
totalAmount: totalAmount ?? this.totalAmount,
|
||||
amountPaid: amountPaid ?? this.amountPaid,
|
||||
amountRemaining: amountRemaining ?? this.amountRemaining,
|
||||
status: status ?? this.status,
|
||||
paymentTerms: paymentTerms ?? this.paymentTerms,
|
||||
notes: notes ?? this.notes,
|
||||
erpnextInvoice: erpnextInvoice ?? this.erpnextInvoice,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
lastReminderSent: lastReminderSent ?? this.lastReminderSent,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is Invoice &&
|
||||
other.invoiceId == invoiceId &&
|
||||
other.invoiceNumber == invoiceNumber &&
|
||||
other.userId == userId &&
|
||||
other.orderId == orderId &&
|
||||
other.invoiceType == invoiceType &&
|
||||
other.totalAmount == totalAmount &&
|
||||
other.amountPaid == amountPaid &&
|
||||
other.status == status;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
invoiceId,
|
||||
invoiceNumber,
|
||||
userId,
|
||||
orderId,
|
||||
invoiceType,
|
||||
totalAmount,
|
||||
amountPaid,
|
||||
status,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Invoice(invoiceId: $invoiceId, invoiceNumber: $invoiceNumber, '
|
||||
'status: $status, totalAmount: $totalAmount, amountPaid: $amountPaid, '
|
||||
'amountRemaining: $amountRemaining)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user