273 lines
6.2 KiB
Dart
273 lines
6.2 KiB
Dart
/// Domain Entity: Invoice
|
|
///
|
|
/// Represents an invoice from the API.
|
|
/// Used for both list and detail views.
|
|
library;
|
|
|
|
import 'package:equatable/equatable.dart';
|
|
|
|
/// Seller/Company Information
|
|
class SellerInfo extends Equatable {
|
|
final String? phone;
|
|
final String? email;
|
|
final String? fax;
|
|
final String? taxCode;
|
|
final String? companyName;
|
|
final String? addressLine1;
|
|
final String? cityCode;
|
|
final String? wardCode;
|
|
final String? cityName;
|
|
final String? wardName;
|
|
|
|
const SellerInfo({
|
|
this.phone,
|
|
this.email,
|
|
this.fax,
|
|
this.taxCode,
|
|
this.companyName,
|
|
this.addressLine1,
|
|
this.cityCode,
|
|
this.wardCode,
|
|
this.cityName,
|
|
this.wardName,
|
|
});
|
|
|
|
/// Get formatted full address
|
|
String get fullAddress {
|
|
final parts = <String>[];
|
|
if (addressLine1 != null && addressLine1!.isNotEmpty) {
|
|
parts.add(addressLine1!);
|
|
}
|
|
if (wardName != null && wardName!.isNotEmpty) {
|
|
parts.add(wardName!);
|
|
}
|
|
if (cityName != null && cityName!.isNotEmpty) {
|
|
parts.add(cityName!);
|
|
}
|
|
return parts.join(', ');
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
phone,
|
|
email,
|
|
fax,
|
|
taxCode,
|
|
companyName,
|
|
addressLine1,
|
|
cityCode,
|
|
wardCode,
|
|
cityName,
|
|
wardName,
|
|
];
|
|
}
|
|
|
|
/// Buyer/Customer Information
|
|
class BuyerInfo extends Equatable {
|
|
final String? name;
|
|
final String? addressTitle;
|
|
final String? addressLine1;
|
|
final String? phone;
|
|
final String? email;
|
|
final String? fax;
|
|
final String? taxCode;
|
|
final String? cityCode;
|
|
final String? wardCode;
|
|
final String? cityName;
|
|
final String? wardName;
|
|
|
|
const BuyerInfo({
|
|
this.name,
|
|
this.addressTitle,
|
|
this.addressLine1,
|
|
this.phone,
|
|
this.email,
|
|
this.fax,
|
|
this.taxCode,
|
|
this.cityCode,
|
|
this.wardCode,
|
|
this.cityName,
|
|
this.wardName,
|
|
});
|
|
|
|
/// Get formatted full address
|
|
String get fullAddress {
|
|
final parts = <String>[];
|
|
if (addressLine1 != null && addressLine1!.isNotEmpty) {
|
|
parts.add(addressLine1!);
|
|
}
|
|
if (wardName != null && wardName!.isNotEmpty) {
|
|
parts.add(wardName!);
|
|
}
|
|
if (cityName != null && cityName!.isNotEmpty) {
|
|
parts.add(cityName!);
|
|
}
|
|
return parts.join(', ');
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
name,
|
|
addressTitle,
|
|
addressLine1,
|
|
phone,
|
|
email,
|
|
fax,
|
|
taxCode,
|
|
cityCode,
|
|
wardCode,
|
|
cityName,
|
|
wardName,
|
|
];
|
|
}
|
|
|
|
/// Invoice Line Item
|
|
class InvoiceItem extends Equatable {
|
|
final String itemName;
|
|
final String itemCode;
|
|
final double qty;
|
|
final double rate;
|
|
final double amount;
|
|
|
|
const InvoiceItem({
|
|
required this.itemName,
|
|
required this.itemCode,
|
|
required this.qty,
|
|
required this.rate,
|
|
required this.amount,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [itemName, itemCode, qty, rate, amount];
|
|
}
|
|
|
|
/// Invoice Entity
|
|
///
|
|
/// Contains invoice information from API:
|
|
/// - name: Invoice ID (e.g., "ACC-SINV-2025-00041")
|
|
/// - postingDate: Invoice date
|
|
/// - status: Status label (Vietnamese)
|
|
/// - statusColor: Status color (Danger, Success, etc.)
|
|
/// - orderId: Related order ID (nullable)
|
|
/// - grandTotal: Total amount
|
|
/// - customerName: Customer name (detail only)
|
|
/// - sellerInfo: Seller company info (detail only)
|
|
/// - buyerInfo: Buyer info (detail only)
|
|
/// - items: Invoice line items (detail only)
|
|
/// - total: Subtotal before discount (detail only)
|
|
/// - discountAmount: Discount amount (detail only)
|
|
class Invoice extends Equatable {
|
|
/// Invoice ID (e.g., "ACC-SINV-2025-00041")
|
|
final String name;
|
|
|
|
/// Invoice posting date
|
|
final DateTime postingDate;
|
|
|
|
/// Status label (Vietnamese)
|
|
final String status;
|
|
|
|
/// Status color (Danger, Success, Warning, etc.)
|
|
final String statusColor;
|
|
|
|
/// Related order ID (nullable)
|
|
final String? orderId;
|
|
|
|
/// Grand total amount
|
|
final double grandTotal;
|
|
|
|
// Detail-only fields (nullable for list view)
|
|
|
|
/// Customer name
|
|
final String? customerName;
|
|
|
|
/// Seller company information
|
|
final SellerInfo? sellerInfo;
|
|
|
|
/// Buyer information
|
|
final BuyerInfo? buyerInfo;
|
|
|
|
/// Invoice line items
|
|
final List<InvoiceItem>? items;
|
|
|
|
/// Subtotal before discount
|
|
final double? total;
|
|
|
|
/// Discount amount
|
|
final double? discountAmount;
|
|
|
|
const Invoice({
|
|
required this.name,
|
|
required this.postingDate,
|
|
required this.status,
|
|
required this.statusColor,
|
|
this.orderId,
|
|
required this.grandTotal,
|
|
this.customerName,
|
|
this.sellerInfo,
|
|
this.buyerInfo,
|
|
this.items,
|
|
this.total,
|
|
this.discountAmount,
|
|
});
|
|
|
|
/// Check if this is a detail invoice (has all detail fields)
|
|
bool get isDetail => sellerInfo != null && buyerInfo != null && items != null;
|
|
|
|
/// Get formatted posting date
|
|
String get formattedDate {
|
|
return '${postingDate.day.toString().padLeft(2, '0')}/${postingDate.month.toString().padLeft(2, '0')}/${postingDate.year}';
|
|
}
|
|
|
|
/// Copy with method for immutability
|
|
Invoice copyWith({
|
|
String? name,
|
|
DateTime? postingDate,
|
|
String? status,
|
|
String? statusColor,
|
|
String? orderId,
|
|
double? grandTotal,
|
|
String? customerName,
|
|
SellerInfo? sellerInfo,
|
|
BuyerInfo? buyerInfo,
|
|
List<InvoiceItem>? items,
|
|
double? total,
|
|
double? discountAmount,
|
|
}) {
|
|
return Invoice(
|
|
name: name ?? this.name,
|
|
postingDate: postingDate ?? this.postingDate,
|
|
status: status ?? this.status,
|
|
statusColor: statusColor ?? this.statusColor,
|
|
orderId: orderId ?? this.orderId,
|
|
grandTotal: grandTotal ?? this.grandTotal,
|
|
customerName: customerName ?? this.customerName,
|
|
sellerInfo: sellerInfo ?? this.sellerInfo,
|
|
buyerInfo: buyerInfo ?? this.buyerInfo,
|
|
items: items ?? this.items,
|
|
total: total ?? this.total,
|
|
discountAmount: discountAmount ?? this.discountAmount,
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
name,
|
|
postingDate,
|
|
status,
|
|
statusColor,
|
|
orderId,
|
|
grandTotal,
|
|
customerName,
|
|
sellerInfo,
|
|
buyerInfo,
|
|
items,
|
|
total,
|
|
discountAmount,
|
|
];
|
|
|
|
@override
|
|
String toString() {
|
|
return 'Invoice(name: $name, status: $status, grandTotal: $grandTotal)';
|
|
}
|
|
}
|