1616use Illuminate \Http \Request ;
1717use Illuminate \Support \Arr ;
1818use Illuminate \Support \Facades \DB ;
19+ use Illuminate \Support \Facades \Log ;
1920use Illuminate \Support \Str ;
2021use Maatwebsite \Excel \Facades \Excel ;
2122
@@ -179,12 +180,31 @@ public function attachDevice(Request $request, string $id): JsonResponse
179180 {
180181 $ request ->validate (['device ' => 'required|string ' ]);
181182
182- $ vehicle = $ this ->findVehicle ($ id );
183- $ device = $ this ->findDevice ($ request ->input ('device ' ));
183+ $ deviceId = $ request ->input ('device ' );
184+ $ vehicle = $ this ->resolveVehicle ($ id );
185+ $ device = $ this ->resolveDevice ($ deviceId );
184186
185- $ device ->attachTo ($ vehicle );
186- $ device ->load (['telematic ' , 'warranty ' , 'attachable ' ]);
187- $ vehicle ->load (['driver ' , 'devices ' ]);
187+ if (!$ vehicle ) {
188+ $ this ->logDeviceAttachmentLookupFailure ('attach-device ' , 'vehicle ' , $ id , $ deviceId );
189+
190+ return response ()->error ('Vehicle not found or not available for this organization. ' , 404 );
191+ }
192+
193+ if (!$ device ) {
194+ $ this ->logDeviceAttachmentLookupFailure ('attach-device ' , 'device ' , $ id , $ deviceId );
195+
196+ return response ()->error ('Device not found or not available for this organization. ' , 404 );
197+ }
198+
199+ try {
200+ $ device ->attachTo ($ vehicle );
201+ $ device ->load (['telematic ' , 'warranty ' , 'attachable ' ]);
202+ $ vehicle ->load (['driver ' , 'devices ' ]);
203+ } catch (\Throwable $ e ) {
204+ $ this ->logDeviceAttachmentFailure ('attach-device ' , $ vehicle , $ device , $ e );
205+
206+ return response ()->error ('Unable to attach device to vehicle. Please try again or contact support. ' , 500 );
207+ }
188208
189209 return response ()->json ([
190210 'status ' => 'ok ' ,
@@ -198,16 +218,35 @@ public function detachDevice(Request $request, string $id): JsonResponse
198218 {
199219 $ request ->validate (['device ' => 'required|string ' ]);
200220
201- $ vehicle = $ this ->findVehicle ($ id );
202- $ device = $ this ->findDevice ($ request ->input ('device ' ));
221+ $ deviceId = $ request ->input ('device ' );
222+ $ vehicle = $ this ->resolveVehicle ($ id );
223+ $ device = $ this ->resolveDevice ($ deviceId );
224+
225+ if (!$ vehicle ) {
226+ $ this ->logDeviceAttachmentLookupFailure ('detach-device ' , 'vehicle ' , $ id , $ deviceId );
227+
228+ return response ()->error ('Vehicle not found or not available for this organization. ' , 404 );
229+ }
230+
231+ if (!$ device ) {
232+ $ this ->logDeviceAttachmentLookupFailure ('detach-device ' , 'device ' , $ id , $ deviceId );
233+
234+ return response ()->error ('Device not found or not available for this organization. ' , 404 );
235+ }
203236
204237 if ($ device ->attachable_uuid !== $ vehicle ->uuid ) {
205238 return response ()->error ('This device is not attached to the selected vehicle. ' );
206239 }
207240
208- $ device ->detach ();
209- $ device ->load (['telematic ' , 'warranty ' , 'attachable ' ]);
210- $ vehicle ->load (['driver ' , 'devices ' ]);
241+ try {
242+ $ device ->detach ();
243+ $ device ->load (['telematic ' , 'warranty ' , 'attachable ' ]);
244+ $ vehicle ->load (['driver ' , 'devices ' ]);
245+ } catch (\Throwable $ e ) {
246+ $ this ->logDeviceAttachmentFailure ('detach-device ' , $ vehicle , $ device , $ e );
247+
248+ return response ()->error ('Unable to detach device from vehicle. Please try again or contact support. ' , 500 );
249+ }
211250
212251 return response ()->json ([
213252 'status ' => 'ok ' ,
@@ -226,6 +265,15 @@ protected function findVehicle(string $id): Vehicle
226265 ->firstOrFail ();
227266 }
228267
268+ protected function resolveVehicle (string $ id ): ?Vehicle
269+ {
270+ return Vehicle::where (function ($ query ) use ($ id ) {
271+ $ query ->where ('uuid ' , $ id )->orWhere ('public_id ' , $ id );
272+ })
273+ ->where ('company_uuid ' , session ('company ' ))
274+ ->first ();
275+ }
276+
229277 protected function findDriver (string $ id ): Driver
230278 {
231279 return Driver::where (function ($ query ) use ($ id ) {
@@ -235,6 +283,42 @@ protected function findDriver(string $id): Driver
235283 ->firstOrFail ();
236284 }
237285
286+ protected function resolveDevice (string $ id ): ?Device
287+ {
288+ return Device::where (function ($ query ) use ($ id ) {
289+ $ query ->where ('uuid ' , $ id )->orWhere ('public_id ' , $ id );
290+ })
291+ ->where ('company_uuid ' , session ('company ' ))
292+ ->first ();
293+ }
294+
295+ protected function logDeviceAttachmentLookupFailure (string $ action , string $ missingResource , string $ vehicleId , ?string $ deviceId ): void
296+ {
297+ Log::warning ('Vehicle device attachment lookup failed ' , [
298+ 'action ' => $ action ,
299+ 'missing_resource ' => $ missingResource ,
300+ 'vehicle_id ' => $ vehicleId ,
301+ 'device_id ' => $ deviceId ,
302+ 'company_uuid ' => session ('company ' ),
303+ 'request_id ' => request ()->headers ->get ('X-Request-ID ' ) ?? request ()->headers ->get ('X-Correlation-ID ' ),
304+ ]);
305+ }
306+
307+ protected function logDeviceAttachmentFailure (string $ action , Vehicle $ vehicle , Device $ device , \Throwable $ exception ): void
308+ {
309+ Log::error ('Vehicle device attachment failed ' , [
310+ 'action ' => $ action ,
311+ 'vehicle_uuid ' => $ vehicle ->uuid ,
312+ 'vehicle_id ' => $ vehicle ->public_id ,
313+ 'device_uuid ' => $ device ->uuid ,
314+ 'device_id ' => $ device ->public_id ,
315+ 'company_uuid ' => session ('company ' ),
316+ 'request_id ' => request ()->headers ->get ('X-Request-ID ' ) ?? request ()->headers ->get ('X-Correlation-ID ' ),
317+ 'exception_class ' => get_class ($ exception ),
318+ 'exception ' => $ exception ->getMessage (),
319+ ]);
320+ }
321+
238322 protected function activeOrderUuid (Vehicle $ vehicle ): ?string
239323 {
240324 $ vehicle ->loadMissing ('driver.currentOrder ' );
0 commit comments