- All 5 batch steps: Picking, Sorting, Clarification, Slots, Handoff - go_router navigation with step indicator - graphql_flutter client wired up (endpoint via env var) - Mock data layer swappable with real GraphQL service - Item types: normal, cold, frozen, alcohol, clarify - Storage slot assignment (cell/freezer/fridge)
101 lines
3.3 KiB
Dart
101 lines
3.3 KiB
Dart
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<List<Order>> getOrderQueue({OrderStatus? status});
|
|
Future<Order> getOrderDetail(int orderId);
|
|
Future<void> markItemPicked(int itemId, double actualQty);
|
|
Future<void> markItemNotFound(int itemId);
|
|
Future<void> replaceItem(int itemId, String substituteSku, double actualQty);
|
|
Future<List<StorageSlot>> getAvailableSlots();
|
|
Future<void> assignSlots(int orderId, List<int> slotIds);
|
|
Future<void> finalizeOrder(int orderId);
|
|
}
|
|
|
|
/// Mock implementation — works entirely in-memory with fake data.
|
|
class MockOrderService implements OrderService {
|
|
final List<Order> _orders = MockData.orders;
|
|
|
|
@override
|
|
Future<List<Order>> 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<Order> getOrderDetail(int orderId) async {
|
|
await Future.delayed(const Duration(milliseconds: 200));
|
|
return _orders.firstWhere((o) => o.id == orderId);
|
|
}
|
|
|
|
@override
|
|
Future<void> 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<void> 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<void> 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<List<StorageSlot>> getAvailableSlots() async {
|
|
await Future.delayed(const Duration(milliseconds: 200));
|
|
return MockData.availableSlots;
|
|
}
|
|
|
|
@override
|
|
Future<void> assignSlots(int orderId, List<int> 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<void> finalizeOrder(int orderId) async {
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
final order = _orders.firstWhere((o) => o.id == orderId);
|
|
order.status = OrderStatus.issued;
|
|
}
|
|
}
|