class DocumentModel { final String id; final String tanggal; final String noPo; final String noSo; final String noDo; final String kepadaYth; final String orderUntuk; final String alamat; final String platTruk; final String namaDriver; final String namaPenerima; final double? latitude; final double? longitude; final List items; final DateTime createdAt; DocumentModel({ required this.id, required this.tanggal, required this.noPo, required this.noSo, required this.noDo, required this.kepadaYth, required this.orderUntuk, required this.alamat, required this.platTruk, required this.namaDriver, required this.namaPenerima, this.latitude, this.longitude, required this.items, required this.createdAt, }); factory DocumentModel.fromJson(Map json) { var header = json['header'] ?? {}; var shipment = json['shipment'] ?? {}; var itemsList = json['items'] as List? ?? []; return DocumentModel( id: json['id'] ?? DateTime.now().millisecondsSinceEpoch.toString(), tanggal: header['tanggal']?.toString() ?? '', noPo: header['no_po']?.toString() ?? '', noSo: header['no_so']?.toString() ?? '', noDo: header['no_do']?.toString() ?? '', kepadaYth: shipment['kepada_yth']?.toString() ?? '', orderUntuk: shipment['order_untuk']?.toString() ?? '', alamat: shipment['alamat']?.toString() ?? '', platTruk: shipment['plat_truk']?.toString() ?? '', namaDriver: json['nama_driver']?.toString() ?? shipment['nama_driver']?.toString() ?? '', namaPenerima: json['nama_penerima']?.toString() ?? shipment['nama_penerima']?.toString() ?? '', latitude: json['latitude'] != null ? double.tryParse(json['latitude'].toString()) : null, longitude: json['longitude'] != null ? double.tryParse(json['longitude'].toString()) : null, items: itemsList.map((e) => DocumentItem.fromJson(Map.from(e))).toList(), createdAt: json['created_at'] != null ? DateTime.parse(json['created_at'].toString()) : (json['createdAt'] != null ? DateTime.parse(json['createdAt'].toString()) : DateTime.now()), ); } /// Round-trips with [fromJson]. Used to persist a document to Hive, both for /// the confirmed-documents box and the in-flight pending-documents queue. Map toJson() { return { 'id': id, 'created_at': createdAt.toIso8601String(), 'latitude': latitude, 'longitude': longitude, 'nama_driver': namaDriver, 'nama_penerima': namaPenerima, 'header': { 'tanggal': tanggal, 'no_po': noPo, 'no_so': noSo, 'no_do': noDo, }, 'shipment': { 'kepada_yth': kepadaYth, 'order_untuk': orderUntuk, 'alamat': alamat, 'plat_truk': platTruk, }, 'items': items.map((e) => { 'nomor_sku': e.nomorSku, 'nama_barang': e.namaBarang, 'banyak': e.banyak, 'jumlah': e.jumlah, }).toList(), }; } /// Body for `PUT /api/v1/documents/:id`. Shared by the editor's initial save and /// the pending-queue's sync retry so both send an identical payload shape. Map toPutPayload() { return { 'tanggal': tanggal, 'noPo': noPo, 'noSo': noSo, 'noDo': noDo, 'kepadaYth': kepadaYth, 'orderUntuk': orderUntuk, 'alamat': alamat, 'platTruk': platTruk, 'namaDriver': namaDriver, 'namaPenerima': namaPenerima, 'latitude': latitude, 'longitude': longitude, 'items': items.map((e) => { 'nomor_sku': e.nomorSku, 'nama_barang': e.namaBarang, 'banyak': e.banyak, 'jumlah': e.jumlah, }).toList(), }; } } class DocumentItem { final String nomorSku; final String namaBarang; final String banyak; final String jumlah; DocumentItem({ required this.nomorSku, required this.namaBarang, required this.banyak, required this.jumlah, }); factory DocumentItem.fromJson(Map json) { return DocumentItem( nomorSku: json['nomor_sku']?.toString() ?? '', namaBarang: json['nama_barang']?.toString() ?? '', banyak: json['banyak']?.toString() ?? '', jumlah: json['jumlah']?.toString() ?? '', ); } }