import '../models/models.dart'; import '../mock/mock_data.dart'; /// Abstract interface — swap MockOrderService for GraphQLOrderService /// when the backend is ready. No other code changes needed. abstract class OrderService { Future> getOrderQueue({OrderStatus? status}); Future getOrderDetail(int orderId); Future markItemPicked(int itemId, double actualQty); Future markItemNotFound(int itemId); Future replaceItem(int itemId, String substituteSku, double actualQty); Future> getAvailableSlots(); Future assignSlots(int orderId, List slotIds); Future finalizeOrder(int orderId); } /// Mock implementation — works entirely in-memory with fake data. class MockOrderService implements OrderService { final List _orders = MockData.orders; @override Future> getOrderQueue({OrderStatus? status}) async { await Future.delayed(const Duration(milliseconds: 300)); if (status == null) return List.from(_orders); return _orders.where((o) => o.status == status).toList(); } @override Future getOrderDetail(int orderId) async { await Future.delayed(const Duration(milliseconds: 200)); return _orders.firstWhere((o) => o.id == orderId); } @override Future markItemPicked(int itemId, double actualQty) async { await Future.delayed(const Duration(milliseconds: 150)); for (final order in _orders) { for (final segment in order.segments) { final item = segment.items.where((i) => i.id == itemId).firstOrNull; if (item != null) { item.status = ItemStatus.picked; item.actualQty = actualQty; return; } } } } @override Future markItemNotFound(int itemId) async { await Future.delayed(const Duration(milliseconds: 150)); for (final order in _orders) { for (final segment in order.segments) { final item = segment.items.where((i) => i.id == itemId).firstOrNull; if (item != null) { item.status = ItemStatus.notFound; return; } } } } @override Future replaceItem(int itemId, String substituteSku, double actualQty) async { await Future.delayed(const Duration(milliseconds: 150)); for (final order in _orders) { for (final segment in order.segments) { final item = segment.items.where((i) => i.id == itemId).firstOrNull; if (item != null) { item.status = ItemStatus.replaced; item.actualQty = actualQty; return; } } } } @override Future> getAvailableSlots() async { await Future.delayed(const Duration(milliseconds: 200)); return MockData.availableSlots; } @override Future assignSlots(int orderId, List slotIds) async { await Future.delayed(const Duration(milliseconds: 200)); final order = _orders.firstWhere((o) => o.id == orderId); final slots = MockData.availableSlots.where((s) => slotIds.contains(s.id)).toList(); order.assignedSlots ..clear() ..addAll(slots); } @override Future finalizeOrder(int orderId) async { await Future.delayed(const Duration(milliseconds: 300)); final order = _orders.firstWhere((o) => o.id == orderId); order.status = OrderStatus.issued; } }