import 'job.dart'; import 'task.dart'; /// Combines server state with work confirmed locally while offline. class JobProgress { final Job job; final Map taskStatuses; final Set completedStationOrders; JobProgress( this.job, { this.taskStatuses = const {}, Set localCompletedStations = const {}, }) : completedStationOrders = { ...job.completedStationOrders, ...localCompletedStations, }; bool isTaskCompleted(Task task) => task.completed || taskStatuses[task.id] == true; bool get isCancelled => job.status.toUpperCase() == 'CANCELLED'; bool get isCompleted { if (isCancelled) return false; if (const {'COMPLETED', 'DONE'}.contains(job.status.toUpperCase())) { return true; } // Same rule as the backend: explicit final-station confirmation and all // mandatory tasks completed. Open optional tasks do not prevent completion. final lastStationOrder = job.deliveryStations.isEmpty ? 0 : job.deliveryStations .map((station) => station.stationOrder) .reduce((a, b) => a > b ? a : b); return completedStationOrders.contains(lastStationOrder) && job.tasks.where((task) => !task.optional).every(isTaskCompleted); } bool isStationClosed(int stationOrder) => isCancelled || isCompleted || completedStationOrders.contains(stationOrder); bool canCompleteTask(Task task) => !isStationClosed(task.stationOrder ?? 0) && !isTaskCompleted(task); int get completedTaskCount => job.tasks.where(isTaskCompleted).length; bool get hasProgress => completedTaskCount > 0 || completedStationOrders.isNotEmpty; }