/// 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 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 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 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 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 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 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? 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 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) : null, buyerInfo: json['buyer_info'] != null ? BuyerInfoModel.fromJson(json['buyer_info'] as Map) : null, items: json['items'] != null ? (json['items'] as List) .map((e) => InvoiceItemModel.fromJson(e as Map)) .toList() : null, total: (json['total'] as num?)?.toDouble(), discountAmount: (json['discount_amount'] as num?)?.toDouble(), ); } /// Convert to JSON Map 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)'; } }