import 'package:pad_scanner/pages/boxing/boxing_models.dart'; import 'package:pad_scanner/services/api_service.dart'; class BoxMutationResult { final List boxes; final int maxBoxNo; const BoxMutationResult({required this.boxes, required this.maxBoxNo}); } int maxBoxNoFor(List boxes) { return boxes.fold(0, (max, box) => box.boxNo > max ? box.boxNo : max); } BoxMutationResult addExistingBoxItem({ required List existingBoxes, required int boxNo, required int quantity, required int? boxItemId, required String zongpaiNo, required String? workOrderNo, required int? totalQuantity, }) { final item = BoxItemData( boxItemId: boxItemId, zongpaiNo: zongpaiNo, workOrderNo: workOrderNo, quantity: quantity, totalQuantity: totalQuantity, ); final index = existingBoxes.indexWhere((box) => box.boxNo == boxNo); if (index < 0) { final boxes = [ ...existingBoxes, BoxDetailData(boxNo: boxNo, items: [item]), ]..sort((a, b) => a.boxNo.compareTo(b.boxNo)); return BoxMutationResult(boxes: boxes, maxBoxNo: maxBoxNoFor(boxes)); } final boxes = List.from(existingBoxes); final box = boxes[index]; boxes[index] = BoxDetailData(boxNo: box.boxNo, items: [...box.items, item]); return BoxMutationResult(boxes: boxes, maxBoxNo: maxBoxNoFor(boxes)); } BoxMutationResult replaceExistingBoxItem({ required List existingBoxes, required CurrentZongpaiBoxData editing, required int boxNo, required int quantity, required String zongpaiNo, required String? workOrderNo, required int? totalQuantity, }) { final updatedItem = BoxItemData( boxItemId: editing.boxItemId, zongpaiNo: zongpaiNo, workOrderNo: workOrderNo, quantity: quantity, totalQuantity: totalQuantity, ); return _replaceItemById( existingBoxes: existingBoxes, boxItemId: editing.boxItemId, targetBoxNo: boxNo, updatedItem: updatedItem, ); } BoxMutationResult replaceExistingPackedItem({ required List existingBoxes, required ManyToOnePackedItem item, required int boxNo, required int quantity, }) { final updatedItem = BoxItemData( boxItemId: item.boxItemId, zongpaiNo: item.zongpaiNo, workOrderNo: item.workOrderNo, quantity: quantity, totalQuantity: item.totalQuantity, ); return _replaceItemById( existingBoxes: existingBoxes, boxItemId: item.boxItemId, targetBoxNo: boxNo, updatedItem: updatedItem, ); } BoxMutationResult removeExistingBoxItem({ required List existingBoxes, required int boxItemId, }) { final boxes = []; for (final box in existingBoxes) { final items = box.items .where((item) => item.boxItemId != boxItemId) .toList(); if (items.isNotEmpty) { boxes.add(BoxDetailData(boxNo: box.boxNo, items: items)); } } return BoxMutationResult(boxes: boxes, maxBoxNo: maxBoxNoFor(boxes)); } BoxMutationResult _replaceItemById({ required List existingBoxes, required int boxItemId, required int targetBoxNo, required BoxItemData updatedItem, }) { final boxes = []; for (final box in existingBoxes) { final items = box.items.where((item) { return item.boxItemId != boxItemId; }).toList(); if (items.isNotEmpty) { boxes.add(BoxDetailData(boxNo: box.boxNo, items: items)); } } final targetIndex = boxes.indexWhere((box) => box.boxNo == targetBoxNo); if (targetIndex >= 0) { final target = boxes[targetIndex]; boxes[targetIndex] = BoxDetailData( boxNo: target.boxNo, items: [...target.items, updatedItem], ); } else { boxes.add(BoxDetailData(boxNo: targetBoxNo, items: [updatedItem])); } boxes.sort((a, b) => a.boxNo.compareTo(b.boxNo)); return BoxMutationResult(boxes: boxes, maxBoxNo: maxBoxNoFor(boxes)); }