ultimatepos/Modules/Tms/Services/TmsTrackingService.php

122 lines
4.0 KiB
PHP

<?php
namespace Modules\Tms\Services;
use Modules\Tms\Models\Driver;
use Modules\Tms\Models\LocationLog;
use Modules\Tms\Models\Shipment;
class TmsTrackingService
{
public function recordLocation(
int $business_id,
float $latitude,
float $longitude,
?int $driver_id = null,
?int $shipment_id = null,
?int $vehicle_id = null,
?float $accuracy = null,
?float $speed = null,
?float $heading = null
): LocationLog {
$log = LocationLog::create([
'business_id' => $business_id,
'driver_id' => $driver_id,
'shipment_id' => $shipment_id,
'vehicle_id' => $vehicle_id,
'latitude' => $latitude,
'longitude' => $longitude,
'accuracy' => $accuracy,
'speed' => $speed,
'heading' => $heading,
'logged_at' => now(),
]);
if ($driver_id) {
Driver::where('business_id', $business_id)
->where('id', $driver_id)
->update([
'last_latitude' => $latitude,
'last_longitude' => $longitude,
'last_location_at' => now(),
]);
}
return $log;
}
public function getLiveDrivers(int $business_id): array
{
return Driver::where('business_id', $business_id)
->where('is_active', true)
->whereNotNull('last_latitude')
->whereNotNull('last_longitude')
->where('last_location_at', '>=', now()->subHours(24))
->with(['user:id,first_name,last_name'])
->get()
->map(function ($driver) {
$activeShipment = Shipment::where('business_id', $driver->business_id)
->where('driver_id', $driver->id)
->whereIn('status', ['scheduled', 'in_transit'])
->latest()
->first();
return [
'id' => $driver->id,
'name' => $driver->name,
'lat' => (float) $driver->last_latitude,
'lng' => (float) $driver->last_longitude,
'updated_at' => $driver->last_location_at?->format('Y-m-d H:i:s'),
'shipment_ref' => $activeShipment?->ref_no,
'shipment_id' => $activeShipment?->id,
];
})
->values()
->all();
}
public function getShipmentTrack(int $business_id, int $shipment_id): array
{
$shipment = Shipment::where('business_id', $business_id)->findOrFail($shipment_id);
$points = LocationLog::where('business_id', $business_id)
->where('shipment_id', $shipment_id)
->orderBy('logged_at')
->get(['latitude', 'longitude', 'logged_at', 'speed'])
->map(fn ($p) => [
'lat' => (float) $p->latitude,
'lng' => (float) $p->longitude,
'at' => $p->logged_at?->format('Y-m-d H:i:s'),
'speed' => $p->speed,
])
->all();
$destination = null;
if ($shipment->destination_latitude && $shipment->destination_longitude) {
$destination = [
'lat' => (float) $shipment->destination_latitude,
'lng' => (float) $shipment->destination_longitude,
'address' => $shipment->destination_address,
];
}
return [
'shipment' => [
'id' => $shipment->id,
'ref_no' => $shipment->ref_no,
'status' => $shipment->status,
],
'points' => $points,
'destination' => $destination,
];
}
public function resolveDriverForUser(int $business_id, int $user_id): ?Driver
{
return Driver::where('business_id', $business_id)
->where('user_id', $user_id)
->where('is_active', true)
->first();
}
}