source_id && $mission->source_type !== 'standalone') { $projectId = match ($mission->source_type) { 'overhaul' => Overhaul::where('business_id', $mission->business_id)->find($mission->source_id)?->project_id, 'rebuild' => RebuildProject::where('business_id', $mission->business_id)->find($mission->source_id)?->project_id, 'work_order' => WorkOrder::where('business_id', $mission->business_id)->find($mission->source_id)?->project_id, 'inspection_visit' => InspectionVisit::where('business_id', $mission->business_id)->find($mission->source_id)?->project_id, default => null, }; if ($projectId) { return (int) $projectId; } } if ($mission->equipment_id) { return Equipment::where('business_id', $mission->business_id) ->find($mission->equipment_id)?->project_id; } return null; } public function findShipmentForMission(FieldMission $mission): ?Shipment { return Shipment::where('business_id', $mission->business_id) ->where('source_type', 'field_mission') ->where('source_id', $mission->id) ->where('status', '!=', 'cancelled') ->orderByDesc('id') ->first(); } public function resolveDriverId(FieldMission $mission): ?int { $mission->loadMissing('crewMembers'); $driverCrew = $mission->crewMembers->first(fn (MissionCrewMember $m) => $m->role === 'driver' && $m->user_id); if ($driverCrew?->user_id) { $driver = Driver::where('business_id', $mission->business_id) ->where('user_id', $driverCrew->user_id) ->where('is_active', true) ->first(); if ($driver) { return (int) $driver->id; } } if ($mission->lead_user_id) { $driver = Driver::where('business_id', $mission->business_id) ->where('user_id', $mission->lead_user_id) ->where('is_active', true) ->first(); return $driver ? (int) $driver->id : null; } return null; } public function resolveMissionDestination(FieldMission $mission): ?string { if (! empty($mission->destination_site)) { return $mission->destination_site; } $mission->loadMissing('destinationLocation'); $loc = $mission->destinationLocation; if (! $loc) { return null; } return trim(implode(' ', array_filter([ $loc->name, $loc->landmark ?? null, $loc->city ?? null, ]))) ?: null; } public function buildCargoDescription(FieldMission $mission): string { $mission->loadMissing(['items.sparePart']); $parts = $mission->items ->map(fn ($item) => $item->part_name ?: $item->sparePart?->name) ->filter() ->take(5) ->values() ->all(); if (empty($parts)) { return $mission->title; } return $mission->title.' — '.implode(', ', $parts); } public function syncMissionFromShipment(Shipment $shipment): void { if ($shipment->source_type !== 'field_mission' || ! $shipment->source_id) { return; } $settings = $this->tmsUtil->getTmsSettings((int) $shipment->business_id); if (empty($settings['sync_mission_status'])) { return; } if (! class_exists(FieldMission::class)) { return; } $mission = FieldMission::where('business_id', $shipment->business_id) ->find($shipment->source_id); if (! $mission || in_array($mission->status, ['closed', 'cancelled'], true)) { return; } $missionStatus = match ($shipment->status) { 'in_transit' => 'dispatched', 'delivered' => 'on_site', 'cancelled' => 'cancelled', default => null, }; if (! $missionStatus) { return; } $order = [ 'draft' => 0, 'planned' => 1, 'dispatched' => 2, 'on_site' => 3, 'returning' => 4, 'closed' => 5, 'cancelled' => 6, ]; if (($order[$missionStatus] ?? 0) <= ($order[$mission->status] ?? 0)) { return; } $updates = ['status' => $missionStatus]; if ($missionStatus === 'dispatched' && ! $mission->actual_departure_at) { $updates['actual_departure_at'] = $shipment->pickup_at ?? now(); } $mission->update($updates); } }