class InvoiceItem { final int? id; final int? invoiceId; final int? productId; final int? inventoryItemId; final String? productName; final String? categoryName; final String? commodityCode; final String? sku; final String? huid; final String? hsnCode; final String? description; final double quantity; final double? weight; final double unitPrice; // metal rate final double makingCharge; final String makingChargesType; // PER_GRAM, PER_PIECE, PERCENTAGE final double taxRate; final double cgst; final double sgst; final double igst; final double discount; final double otherCharges; final String? photoUrl; final String? localPhotoPath; final double total; InvoiceItem({ this.id, this.invoiceId, this.productId, this.inventoryItemId, this.productName, this.categoryName, this.commodityCode, this.hsnCode, this.sku, this.huid, this.description, required this.quantity, this.weight, required this.unitPrice, this.makingCharge = 0.0, this.makingChargesType = 'PER_GRAM', this.taxRate = 0.0, this.cgst = 0.0, this.sgst = 0.0, this.igst = 0.0, this.discount = 0.0, this.otherCharges = 0.0, this.photoUrl, this.localPhotoPath, required this.total, }); InvoiceItem copyWith({ int? id, int? invoiceId, int? productId, int? inventoryItemId, String? productName, String? categoryName, String? commodityCode, String? hsnCode, String? sku, String? huid, String? description, double? quantity, double? weight, double? unitPrice, double? makingCharge, String? makingChargesType, double? taxRate, double? cgst, double? sgst, double? igst, double? discount, double? otherCharges, String? photoUrl, String? localPhotoPath, double? total, }) { return InvoiceItem( id: id ?? this.id, invoiceId: invoiceId ?? this.invoiceId, productId: productId ?? this.productId, inventoryItemId: inventoryItemId ?? this.inventoryItemId, productName: productName ?? this.productName, categoryName: categoryName ?? this.categoryName, commodityCode: commodityCode ?? this.commodityCode, hsnCode: hsnCode ?? this.hsnCode, sku: sku ?? this.sku, huid: huid ?? this.huid, description: description ?? this.description, quantity: quantity ?? this.quantity, weight: weight ?? this.weight, unitPrice: unitPrice ?? this.unitPrice, makingCharge: makingCharge ?? this.makingCharge, makingChargesType: makingChargesType ?? this.makingChargesType, taxRate: taxRate ?? this.taxRate, cgst: cgst ?? this.cgst, sgst: sgst ?? this.sgst, igst: igst ?? this.igst, discount: discount ?? this.discount, otherCharges: otherCharges ?? this.otherCharges, photoUrl: photoUrl ?? this.photoUrl, localPhotoPath: localPhotoPath ?? this.localPhotoPath, total: total ?? this.total, ); } factory InvoiceItem.fromJson(Map json) { return InvoiceItem( id: json['id'], invoiceId: json['invoiceId'] ?? json['invoice_id'], productId: json['productId'] ?? json['product_id'], inventoryItemId: json['inventoryItemId'] ?? json['inventory_item_id'], productName: json['productName'] ?? json['product_name'], categoryName: json['categoryName'] ?? json['category_name'], commodityCode: json['commodityCode'] ?? json['commodity_code'], hsnCode: json['hsnCode'] ?? json['hsn_code'], sku: json['sku'], huid: json['huid'], description: json['description'], quantity: (json['quantity'] as num?)?.toDouble() ?? 1.0, weight: (json['weight'] as num?)?.toDouble(), unitPrice: (json['unitPrice'] ?? json['unit_price'] as num?)?.toDouble() ?? 0.0, makingCharge: (json['makingCharge'] ?? json['making_charge'] as num?)?.toDouble() ?? 0.0, makingChargesType: json['makingChargesType'] ?? json['making_charges_type'] ?? 'PER_GRAM', taxRate: (json['taxRate'] ?? json['tax_rate'] as num?)?.toDouble() ?? 0.0, cgst: (json['cgst'] as num?)?.toDouble() ?? 0.0, sgst: (json['sgst'] as num?)?.toDouble() ?? 0.0, igst: (json['igst'] as num?)?.toDouble() ?? 0.0, discount: (json['discount'] as num?)?.toDouble() ?? 0.0, otherCharges: (json['otherCharges'] ?? json['other_charges'] as num?)?.toDouble() ?? 0.0, photoUrl: json['photoUrl'] ?? json['photo_url'], total: (json['total'] as num?)?.toDouble() ?? 0.0, ); } Map toJson() { final Map data = {}; if (id != null) data['id'] = id; if (invoiceId != null) data['invoiceId'] = invoiceId; if (productId != null) data['productId'] = productId; if (inventoryItemId != null) data['inventoryItemId'] = inventoryItemId; if (productName != null) data['productName'] = productName; if (categoryName != null) data['categoryName'] = categoryName; if (commodityCode != null) data['commodityCode'] = commodityCode; if (hsnCode != null) data['hsnCode'] = hsnCode; if (sku != null) data['sku'] = sku; if (huid != null) data['huid'] = huid; if (description != null) data['description'] = description; data['quantity'] = quantity; if (weight != null) data['weight'] = weight; data['unitPrice'] = unitPrice; data['makingCharge'] = makingCharge; data['makingChargesType'] = makingChargesType; data['taxRate'] = taxRate; data['cgst'] = cgst; data['sgst'] = sgst; data['igst'] = igst; data['discount'] = discount; data['otherCharges'] = otherCharges; if (photoUrl != null) data['photoUrl'] = photoUrl; data['total'] = total; return data; } } class Invoice { final int? id; final int? customerId; final String invoiceNumber; final DateTime issueDate; final DateTime? dueDate; final double subtotal; final double taxTotal; final double cgstTotal; final double sgstTotal; final double igstTotal; final double discountTotal; final double totalAmount; final double amountPaid; final DateTime? nextPaymentDate; final String? paymentMethod; final int? paymentWalletId; final String status; final String? notes; final String? invoiceUrl; final bool isEmi; final double? emiAmount; final String? emiCycle; final DateTime? emiStartDate; final int? salesChannelId; final String? salesChannel; final String? marketplaceOrderId; final int? placeOfSupplyStateId; final String? placeOfSupply; final List items; final List? payments; Invoice({ this.id, this.customerId, required this.invoiceNumber, required this.issueDate, this.dueDate, required this.subtotal, this.taxTotal = 0.0, this.cgstTotal = 0.0, this.sgstTotal = 0.0, this.igstTotal = 0.0, this.discountTotal = 0.0, required this.totalAmount, this.amountPaid = 0.0, this.nextPaymentDate, this.paymentMethod, this.paymentWalletId, this.status = 'DRAFT', this.notes, this.invoiceUrl, this.isEmi = false, this.emiAmount, this.emiCycle, this.emiStartDate, this.salesChannelId, this.salesChannel, this.marketplaceOrderId, this.placeOfSupplyStateId, this.placeOfSupply, this.items = const [], this.payments, }); factory Invoice.fromJson(Map json) { return Invoice( id: json['id'], customerId: json['customerId'] ?? json['customer_id'], invoiceNumber: json['invoiceNumber'] ?? json['invoice_number'] ?? '', issueDate: json['issueDate'] != null ? DateTime.parse(json['issueDate']) : (json['issue_date'] != null ? DateTime.parse(json['issue_date']) : DateTime.now()), dueDate: json['dueDate'] != null ? DateTime.parse(json['dueDate']) : (json['due_date'] != null ? DateTime.parse(json['due_date']) : null), subtotal: (json['subtotal'] as num?)?.toDouble() ?? 0.0, taxTotal: (json['taxTotal'] ?? json['tax_total'] as num?)?.toDouble() ?? 0.0, cgstTotal: (json['cgstTotal'] ?? json['cgst_total'] as num?)?.toDouble() ?? 0.0, sgstTotal: (json['sgstTotal'] ?? json['sgst_total'] as num?)?.toDouble() ?? 0.0, igstTotal: (json['igstTotal'] ?? json['igst_total'] as num?)?.toDouble() ?? 0.0, discountTotal: (json['discountTotal'] ?? json['discount_total'] as num?)?.toDouble() ?? 0.0, totalAmount: (json['totalAmount'] ?? json['total_amount'] as num?)?.toDouble() ?? 0.0, amountPaid: (json['amountPaid'] ?? json['amount_paid'] as num?)?.toDouble() ?? 0.0, nextPaymentDate: json['nextPaymentDate'] != null ? DateTime.parse(json['nextPaymentDate']) : (json['next_payment_date'] != null ? DateTime.parse(json['next_payment_date']) : null), paymentMethod: json['paymentMethod'] ?? json['payment_method'], paymentWalletId: json['paymentWalletId'] ?? json['payment_wallet_id'], status: json['status'] ?? 'DRAFT', notes: json['notes'], invoiceUrl: json['invoiceUrl'] ?? json['invoice_url'], isEmi: json['isEmi'] ?? json['is_emi'] ?? false, emiAmount: (json['emiAmount'] ?? json['emi_amount'] as num?)?.toDouble(), emiCycle: json['emiCycle'] ?? json['emi_cycle'], emiStartDate: json['emiStartDate'] != null ? DateTime.parse(json['emiStartDate']) : (json['emi_start_date'] != null ? DateTime.parse(json['emi_start_date']) : null), salesChannelId: json['salesChannelId'] ?? json['sales_channel_id'], salesChannel: json['salesChannel'] ?? json['sales_channel'], marketplaceOrderId: json['marketplaceOrderId'] ?? json['marketplace_order_id'], placeOfSupplyStateId: json['placeOfSupplyStateId'] ?? json['place_of_supply_state_id'], placeOfSupply: json['placeOfSupply'] ?? json['place_of_supply'], items: json['items'] != null ? (json['items'] as List).map((i) => InvoiceItem.fromJson(i)).toList() : [], payments: json['payments'] != null ? (json['payments'] as List) .map((i) => InvoicePayment.fromJson(i)) .toList() : null, ); } Map toJson() { final Map data = {}; if (id != null) data['id'] = id; if (customerId != null) data['customerId'] = customerId; data['invoiceNumber'] = invoiceNumber; data['issueDate'] = issueDate.toIso8601String().split('T')[0]; if (dueDate != null) { data['dueDate'] = dueDate!.toIso8601String().split('T')[0]; } data['subtotal'] = subtotal; data['taxTotal'] = taxTotal; data['cgstTotal'] = cgstTotal; data['sgstTotal'] = sgstTotal; data['igstTotal'] = igstTotal; data['discountTotal'] = discountTotal; data['totalAmount'] = totalAmount; if (amountPaid > 0) data['amountPaid'] = amountPaid; if (nextPaymentDate != null) { data['nextPaymentDate'] = nextPaymentDate!.toIso8601String().split('T')[0]; } if (paymentMethod != null) data['paymentMethod'] = paymentMethod; if (paymentWalletId != null) data['paymentWalletId'] = paymentWalletId; data['status'] = status; if (notes != null) data['notes'] = notes; if (invoiceUrl != null) data['invoiceUrl'] = invoiceUrl; data['isEmi'] = isEmi; if (emiAmount != null) data['emiAmount'] = emiAmount; if (emiCycle != null) data['emiCycle'] = emiCycle; if (emiStartDate != null) { data['emiStartDate'] = emiStartDate!.toIso8601String().split('T')[0]; } if (salesChannelId != null) data['salesChannelId'] = salesChannelId; if (salesChannel != null) data['salesChannel'] = salesChannel; if (marketplaceOrderId != null) data['marketplaceOrderId'] = marketplaceOrderId; if (placeOfSupplyStateId != null) data['placeOfSupplyStateId'] = placeOfSupplyStateId; if (placeOfSupply != null) data['placeOfSupply'] = placeOfSupply; data['items'] = items.map((i) => i.toJson()).toList(); if (payments != null) { data['payments'] = payments!.map((i) => i.toJson()).toList(); } return data; } } class InvoicePayment { final int? id; final int? invoiceId; final double amount; final DateTime? paymentDate; final String paymentMethod; final int? emiInstallmentNumber; final int? walletId; InvoicePayment({ this.id, this.invoiceId, required this.amount, this.paymentDate, required this.paymentMethod, this.emiInstallmentNumber, this.walletId, }); factory InvoicePayment.fromJson(Map json) { return InvoicePayment( id: json['id'], invoiceId: json['invoiceId'] ?? json['invoice_id'], amount: (json['amount'] as num?)?.toDouble() ?? 0.0, paymentDate: json['paymentDate'] != null ? DateTime.parse(json['paymentDate']) : (json['payment_date'] != null ? DateTime.parse(json['payment_date']) : null), paymentMethod: json['paymentMethod'] ?? json['payment_method'] ?? 'Cash', emiInstallmentNumber: json['emiInstallmentNumber'] ?? json['emi_installment_number'], walletId: json['walletId'] ?? json['wallet_id'], ); } Map toJson() { final Map data = {}; if (id != null) data['id'] = id; if (invoiceId != null) data['invoiceId'] = invoiceId; data['amount'] = amount; if (paymentDate != null) { data['paymentDate'] = paymentDate!.toIso8601String().split('T')[0]; } data['paymentMethod'] = paymentMethod; if (emiInstallmentNumber != null) { data['emiInstallmentNumber'] = emiInstallmentNumber; } if (walletId != null) data['walletId'] = walletId; return data; } }