307 lines
8.2 KiB
Dart
307 lines
8.2 KiB
Dart
/// Data Model: Invoice Model
|
|
///
|
|
/// Model for invoice data with API serialization.
|
|
/// Not stored in local database.
|
|
library;
|
|
|
|
import 'package:worker/features/invoices/domain/entities/invoice.dart';
|
|
|
|
/// Seller Info Model
|
|
class SellerInfoModel {
|
|
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 SellerInfoModel({
|
|
this.phone,
|
|
this.email,
|
|
this.fax,
|
|
this.taxCode,
|
|
this.companyName,
|
|
this.addressLine1,
|
|
this.cityCode,
|
|
this.wardCode,
|
|
this.cityName,
|
|
this.wardName,
|
|
});
|
|
|
|
factory SellerInfoModel.fromJson(Map<String, dynamic> json) {
|
|
return SellerInfoModel(
|
|
phone: json['phone'] as String?,
|
|
email: json['email'] as String?,
|
|
fax: json['fax'] as String?,
|
|
taxCode: json['tax_code'] as String?,
|
|
companyName: json['company_name'] as String?,
|
|
addressLine1: json['address_line1'] as String?,
|
|
cityCode: json['city_code'] as String?,
|
|
wardCode: json['ward_code'] as String?,
|
|
cityName: json['city_name'] as String?,
|
|
wardName: json['ward_name'] as String?,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
'phone': phone,
|
|
'email': email,
|
|
'fax': fax,
|
|
'tax_code': taxCode,
|
|
'company_name': companyName,
|
|
'address_line1': addressLine1,
|
|
'city_code': cityCode,
|
|
'ward_code': wardCode,
|
|
'city_name': cityName,
|
|
'ward_name': wardName,
|
|
};
|
|
|
|
SellerInfo toEntity() => SellerInfo(
|
|
phone: phone,
|
|
email: email,
|
|
fax: fax,
|
|
taxCode: taxCode,
|
|
companyName: companyName,
|
|
addressLine1: addressLine1,
|
|
cityCode: cityCode,
|
|
wardCode: wardCode,
|
|
cityName: cityName,
|
|
wardName: wardName,
|
|
);
|
|
}
|
|
|
|
/// Buyer Info Model
|
|
class BuyerInfoModel {
|
|
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 BuyerInfoModel({
|
|
this.name,
|
|
this.addressTitle,
|
|
this.addressLine1,
|
|
this.phone,
|
|
this.email,
|
|
this.fax,
|
|
this.taxCode,
|
|
this.cityCode,
|
|
this.wardCode,
|
|
this.cityName,
|
|
this.wardName,
|
|
});
|
|
|
|
factory BuyerInfoModel.fromJson(Map<String, dynamic> json) {
|
|
return BuyerInfoModel(
|
|
name: json['name'] as String?,
|
|
addressTitle: json['address_title'] as String?,
|
|
addressLine1: json['address_line1'] as String?,
|
|
phone: json['phone'] as String?,
|
|
email: json['email'] as String?,
|
|
fax: json['fax'] as String?,
|
|
taxCode: json['tax_code'] as String?,
|
|
cityCode: json['city_code'] as String?,
|
|
wardCode: json['ward_code'] as String?,
|
|
cityName: json['city_name'] as String?,
|
|
wardName: json['ward_name'] as String?,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
'name': name,
|
|
'address_title': addressTitle,
|
|
'address_line1': addressLine1,
|
|
'phone': phone,
|
|
'email': email,
|
|
'fax': fax,
|
|
'tax_code': taxCode,
|
|
'city_code': cityCode,
|
|
'ward_code': wardCode,
|
|
'city_name': cityName,
|
|
'ward_name': wardName,
|
|
};
|
|
|
|
BuyerInfo toEntity() => BuyerInfo(
|
|
name: name,
|
|
addressTitle: addressTitle,
|
|
addressLine1: addressLine1,
|
|
phone: phone,
|
|
email: email,
|
|
fax: fax,
|
|
taxCode: taxCode,
|
|
cityCode: cityCode,
|
|
wardCode: wardCode,
|
|
cityName: cityName,
|
|
wardName: wardName,
|
|
);
|
|
}
|
|
|
|
/// Invoice Item Model
|
|
class InvoiceItemModel {
|
|
final String itemName;
|
|
final String itemCode;
|
|
final double qty;
|
|
final double rate;
|
|
final double amount;
|
|
|
|
const InvoiceItemModel({
|
|
required this.itemName,
|
|
required this.itemCode,
|
|
required this.qty,
|
|
required this.rate,
|
|
required this.amount,
|
|
});
|
|
|
|
factory InvoiceItemModel.fromJson(Map<String, dynamic> json) {
|
|
return InvoiceItemModel(
|
|
itemName: json['item_name'] as String? ?? '',
|
|
itemCode: json['item_code'] as String? ?? '',
|
|
qty: (json['qty'] as num?)?.toDouble() ?? 0.0,
|
|
rate: (json['rate'] as num?)?.toDouble() ?? 0.0,
|
|
amount: (json['amount'] as num?)?.toDouble() ?? 0.0,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
'item_name': itemName,
|
|
'item_code': itemCode,
|
|
'qty': qty,
|
|
'rate': rate,
|
|
'amount': amount,
|
|
};
|
|
|
|
InvoiceItem toEntity() => InvoiceItem(
|
|
itemName: itemName,
|
|
itemCode: itemCode,
|
|
qty: qty,
|
|
rate: rate,
|
|
amount: amount,
|
|
);
|
|
}
|
|
|
|
/// Invoice Model
|
|
///
|
|
/// Model for API parsing only (no Hive storage).
|
|
class InvoiceModel {
|
|
final String name;
|
|
final String postingDate;
|
|
final String status;
|
|
final String statusColor;
|
|
final String? orderId;
|
|
final double grandTotal;
|
|
|
|
// Detail-only fields
|
|
final String? customerName;
|
|
final SellerInfoModel? sellerInfo;
|
|
final BuyerInfoModel? buyerInfo;
|
|
final List<InvoiceItemModel>? items;
|
|
final double? total;
|
|
final double? discountAmount;
|
|
|
|
const InvoiceModel({
|
|
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,
|
|
});
|
|
|
|
/// Create from JSON (API response - list item)
|
|
factory InvoiceModel.fromJson(Map<String, dynamic> json) {
|
|
return InvoiceModel(
|
|
name: json['name'] as String? ?? '',
|
|
postingDate: json['posting_date'] as String? ?? '',
|
|
status: json['status'] as String? ?? '',
|
|
statusColor: json['status_color'] as String? ?? 'Secondary',
|
|
orderId: json['order_id'] as String?,
|
|
grandTotal: (json['grand_total'] as num?)?.toDouble() ?? 0.0,
|
|
customerName: json['customer_name'] as String?,
|
|
sellerInfo: json['seller_info'] != null
|
|
? SellerInfoModel.fromJson(json['seller_info'] as Map<String, dynamic>)
|
|
: null,
|
|
buyerInfo: json['buyer_info'] != null
|
|
? BuyerInfoModel.fromJson(json['buyer_info'] as Map<String, dynamic>)
|
|
: null,
|
|
items: json['items'] != null
|
|
? (json['items'] as List<dynamic>)
|
|
.map((e) => InvoiceItemModel.fromJson(e as Map<String, dynamic>))
|
|
.toList()
|
|
: null,
|
|
total: (json['total'] as num?)?.toDouble(),
|
|
discountAmount: (json['discount_amount'] as num?)?.toDouble(),
|
|
);
|
|
}
|
|
|
|
/// Convert to JSON
|
|
Map<String, dynamic> toJson() => {
|
|
'name': name,
|
|
'posting_date': postingDate,
|
|
'status': status,
|
|
'status_color': statusColor,
|
|
'order_id': orderId,
|
|
'grand_total': grandTotal,
|
|
'customer_name': customerName,
|
|
'seller_info': sellerInfo?.toJson(),
|
|
'buyer_info': buyerInfo?.toJson(),
|
|
'items': items?.map((e) => e.toJson()).toList(),
|
|
'total': total,
|
|
'discount_amount': discountAmount,
|
|
};
|
|
|
|
/// Convert to domain entity
|
|
Invoice toEntity() {
|
|
return Invoice(
|
|
name: name,
|
|
postingDate: DateTime.tryParse(postingDate) ?? DateTime.now(),
|
|
status: status,
|
|
statusColor: statusColor,
|
|
orderId: orderId,
|
|
grandTotal: grandTotal,
|
|
customerName: customerName,
|
|
sellerInfo: sellerInfo?.toEntity(),
|
|
buyerInfo: buyerInfo?.toEntity(),
|
|
items: items?.map((e) => e.toEntity()).toList(),
|
|
total: total,
|
|
discountAmount: discountAmount,
|
|
);
|
|
}
|
|
|
|
/// Create from domain entity
|
|
factory InvoiceModel.fromEntity(Invoice entity) {
|
|
return InvoiceModel(
|
|
name: entity.name,
|
|
postingDate: entity.postingDate.toIso8601String().split('T').first,
|
|
status: entity.status,
|
|
statusColor: entity.statusColor,
|
|
orderId: entity.orderId,
|
|
grandTotal: entity.grandTotal,
|
|
customerName: entity.customerName,
|
|
total: entity.total,
|
|
discountAmount: entity.discountAmount,
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'InvoiceModel(name: $name, status: $status, grandTotal: $grandTotal)';
|
|
}
|
|
}
|