migrate to gtea from bistbucket
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\RestaurantDelivery\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class LocationLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public const TABLE_NAME = 'restaurant_rider_location_logs';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
protected $fillable = [
|
||||
'rider_id',
|
||||
'delivery_id',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'speed',
|
||||
'bearing',
|
||||
'accuracy',
|
||||
'altitude',
|
||||
'battery_level',
|
||||
'is_charging',
|
||||
'network_type',
|
||||
'source',
|
||||
'recorded_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'latitude' => 'decimal:7',
|
||||
'longitude' => 'decimal:7',
|
||||
'speed' => 'float',
|
||||
'bearing' => 'float',
|
||||
'accuracy' => 'float',
|
||||
'altitude' => 'float',
|
||||
'battery_level' => 'integer',
|
||||
'is_charging' => 'boolean',
|
||||
'recorded_at' => 'datetime',
|
||||
];
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Relationships
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function rider(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Rider::class, 'rider_id');
|
||||
}
|
||||
|
||||
public function delivery(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Delivery::class, 'delivery_id');
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Scopes
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function scopeForRider($query, int $riderId)
|
||||
{
|
||||
return $query->where('rider_id', $riderId);
|
||||
}
|
||||
|
||||
public function scopeForDelivery($query, int $deliveryId)
|
||||
{
|
||||
return $query->where('delivery_id', $deliveryId);
|
||||
}
|
||||
|
||||
public function scopeRecent($query, int $minutes = 60)
|
||||
{
|
||||
return $query->where('recorded_at', '>=', now()->subMinutes($minutes));
|
||||
}
|
||||
|
||||
public function scopeInDateRange($query, $startDate, $endDate)
|
||||
{
|
||||
return $query->whereBetween('recorded_at', [$startDate, $endDate]);
|
||||
}
|
||||
|
||||
public function scopeHighAccuracy($query, float $maxAccuracy = 50)
|
||||
{
|
||||
return $query->where('accuracy', '<=', $maxAccuracy);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Methods
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function getCoordinates(): array
|
||||
{
|
||||
return [
|
||||
'lat' => $this->latitude,
|
||||
'lng' => $this->longitude,
|
||||
];
|
||||
}
|
||||
|
||||
public function hasLowBattery(): bool
|
||||
{
|
||||
return $this->battery_level !== null && $this->battery_level < 20;
|
||||
}
|
||||
|
||||
public function hasPoorAccuracy(): bool
|
||||
{
|
||||
return $this->accuracy !== null && $this->accuracy > 50;
|
||||
}
|
||||
|
||||
public function distanceTo(float $latitude, float $longitude): float
|
||||
{
|
||||
$earthRadius = 6371; // km
|
||||
|
||||
$dLat = deg2rad($latitude - $this->latitude);
|
||||
$dLng = deg2rad($longitude - $this->longitude);
|
||||
|
||||
$a = sin($dLat / 2) * sin($dLat / 2) +
|
||||
cos(deg2rad($this->latitude)) * cos(deg2rad($latitude)) *
|
||||
sin($dLng / 2) * sin($dLng / 2);
|
||||
|
||||
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
||||
|
||||
return round($earthRadius * $c, 3);
|
||||
}
|
||||
|
||||
public static function getTrackingPath(int $deliveryId): array
|
||||
{
|
||||
return static::forDelivery($deliveryId)
|
||||
->orderBy('recorded_at')
|
||||
->get()
|
||||
->map(fn ($log) => [
|
||||
'lat' => $log->latitude,
|
||||
'lng' => $log->longitude,
|
||||
'timestamp' => $log->recorded_at->toIso8601String(),
|
||||
'speed' => $log->speed,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function calculateTotalDistance(int $deliveryId): float
|
||||
{
|
||||
$logs = static::forDelivery($deliveryId)
|
||||
->orderBy('recorded_at')
|
||||
->get();
|
||||
|
||||
if ($logs->count() < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$totalDistance = 0;
|
||||
$previousLog = null;
|
||||
|
||||
foreach ($logs as $log) {
|
||||
if ($previousLog) {
|
||||
$totalDistance += $log->distanceTo(
|
||||
$previousLog->latitude,
|
||||
$previousLog->longitude
|
||||
);
|
||||
}
|
||||
$previousLog = $log;
|
||||
}
|
||||
|
||||
return round($totalDistance, 2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user