'decimal:8', 'longitude' => 'decimal:8', 'is_active' => 'boolean', ]; protected $attributes = [ 'is_active' => true, 'status' => self::STATUS_UNREGISTERED, ]; // ========================================================================= // 관계 정의 // ========================================================================= /** * 생성자 */ public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } /** * 수정자 */ public function updater(): BelongsTo { return $this->belongsTo(User::class, 'updated_by'); } /** * 거래처 */ public function client(): BelongsTo { return $this->belongsTo(Client::class); } // ========================================================================= // 헬퍼 메서드 // ========================================================================= /** * GPS 좌표 설정 여부 */ public function hasCoordinates(): bool { return $this->latitude !== null && $this->longitude !== null; } /** * 좌표가 허용 범위 내인지 확인 */ public function isWithinRadius(float $latitude, float $longitude, int $radiusMeters = 100): bool { if (! $this->hasCoordinates()) { return true; // 좌표 미설정 시 항상 허용 } $distance = $this->calculateDistance( $this->latitude, $this->longitude, $latitude, $longitude ); return $distance <= $radiusMeters; } /** * 두 좌표 간 거리 계산 (미터) */ private function calculateDistance(float $lat1, float $lon1, float $lat2, float $lon2): float { $earthRadius = 6371000; $lat1Rad = deg2rad($lat1); $lat2Rad = deg2rad($lat2); $deltaLat = deg2rad($lat2 - $lat1); $deltaLon = deg2rad($lon2 - $lon1); $a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($lat1Rad) * cos($lat2Rad) * sin($deltaLon / 2) * sin($deltaLon / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); return $earthRadius * $c; } }