fix(api): force Manila timezone for upcoming pickups evaluation
This commit is contained in:
@@ -28,11 +28,12 @@ class HouseholdController extends ApiController
|
||||
$data = $request->validated();
|
||||
$user = $request->user();
|
||||
|
||||
$existing = Household::where('head_user_id', $user->id)->first();
|
||||
if ($existing) {
|
||||
$existingHead = Household::where('head_user_id', $user->id)->exists();
|
||||
$existingMember = HouseholdMember::where('user_id', $user->id)->exists();
|
||||
if ($existingHead || $existingMember) {
|
||||
return $this->fail(
|
||||
'You already have a household. Update it instead.',
|
||||
['head_user_id' => ['already_has_household']],
|
||||
'You are already part of a household.',
|
||||
['head_user_id' => ['You are already in a household.']],
|
||||
409,
|
||||
);
|
||||
}
|
||||
@@ -173,13 +174,39 @@ class HouseholdController extends ApiController
|
||||
$this->authorizeOwn($request->user(), $household);
|
||||
|
||||
$data = $request->validated();
|
||||
$member = HouseholdMember::create([
|
||||
'household_id' => $household->id,
|
||||
'user_id' => $data['user_id'] ?? null,
|
||||
'relationship' => $data['relationship'],
|
||||
'full_name' => $data['full_name'] ?? null,
|
||||
'date_of_birth' => $data['date_of_birth'] ?? null,
|
||||
]);
|
||||
|
||||
$userToAdd = User::where('email', $data['email'])->first();
|
||||
|
||||
// Check if this user is already a member of any household or the head of one
|
||||
$isMember = HouseholdMember::where('user_id', $userToAdd->id)->exists();
|
||||
$isHead = Household::where('head_user_id', $userToAdd->id)->exists();
|
||||
|
||||
if ($isMember || $isHead) {
|
||||
return $this->fail('This user is already part of a household.', ['email' => ['Already in a household.']], 422);
|
||||
}
|
||||
|
||||
$existingSoftDeleted = HouseholdMember::withTrashed()
|
||||
->where('household_id', $household->id)
|
||||
->where('user_id', $userToAdd->id)
|
||||
->first();
|
||||
|
||||
if ($existingSoftDeleted) {
|
||||
$existingSoftDeleted->restore();
|
||||
$existingSoftDeleted->update([
|
||||
'relationship' => HouseholdMember::RELATIONSHIP_OTHER,
|
||||
'full_name' => $userToAdd->full_name,
|
||||
'date_of_birth' => $data['date_of_birth'] ?? null,
|
||||
]);
|
||||
$member = $existingSoftDeleted;
|
||||
} else {
|
||||
$member = HouseholdMember::create([
|
||||
'household_id' => $household->id,
|
||||
'user_id' => $userToAdd->id,
|
||||
'relationship' => HouseholdMember::RELATIONSHIP_OTHER,
|
||||
'full_name' => $userToAdd->full_name,
|
||||
'date_of_birth' => $data['date_of_birth'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->created(
|
||||
new HouseholdResource(
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\V1\Me;
|
||||
use App\Http\Controllers\Api\V1\ApiController;
|
||||
use App\Models\Household;
|
||||
use App\Models\Trip;
|
||||
use App\Services\DropOff\DropOffPointFinder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -16,36 +17,70 @@ class UpcomingPickupsController extends ApiController
|
||||
* always included so the resident sees a "truck on the way"
|
||||
* card even mid-day.
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
public function index(Request $request, DropOffPointFinder $finder): JsonResponse
|
||||
{
|
||||
$household = Household::with('assignedDropOffPoint')
|
||||
->where('head_user_id', $request->user()->id)
|
||||
->first();
|
||||
|
||||
if (! $household || ! $household->assigned_drop_off_point_id) {
|
||||
if (! $household) {
|
||||
return $this->ok([
|
||||
'household_assigned' => false,
|
||||
'pickups' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
$dopId = $household->assigned_drop_off_point_id;
|
||||
$nearbyDopIds = [];
|
||||
|
||||
if ($household->coordinates) {
|
||||
$nearbyDops = $finder->nearby(
|
||||
$household->coordinates->latitude,
|
||||
$household->coordinates->longitude,
|
||||
2.0, // 2km radius
|
||||
10 // max 10 nearby drop-off points
|
||||
);
|
||||
$nearbyDopIds = $nearbyDops->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
if ($household->assigned_drop_off_point_id) {
|
||||
$nearbyDopIds[] = $household->assigned_drop_off_point_id;
|
||||
}
|
||||
|
||||
$nearbyDopIds = array_unique($nearbyDopIds);
|
||||
|
||||
if (empty($nearbyDopIds)) {
|
||||
return $this->ok([
|
||||
'household_assigned' => (bool) $household->assigned_drop_off_point_id,
|
||||
'drop_off_point' => null,
|
||||
'pickups' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
$trips = Trip::query()
|
||||
->with(['route:id,name,code', 'team:id,name,driver_id', 'team.driver:id,first_name,last_name', 'truck:id,plate_number'])
|
||||
->whereHas('route.stops', fn ($q) => $q->where('drop_off_point_id', $dopId))
|
||||
->where(function ($q) {
|
||||
$q->where('scheduled_date', '>=', now()->toDateString())
|
||||
->orWhereIn('status', [Trip::STATUS_IN_PROGRESS, Trip::STATUS_AT_DUMPSITE]);
|
||||
})
|
||||
->whereHas('route.stops', fn ($q) => $q->whereIn('drop_off_point_id', $nearbyDopIds))
|
||||
->whereNotIn('status', [Trip::STATUS_CANCELLED, Trip::STATUS_COMPLETED])
|
||||
->where(function ($query) {
|
||||
// Future dates are always upcoming (evaluated in Manila time)
|
||||
$query->where('scheduled_date', '>', now('Asia/Manila')->toDateString())
|
||||
// For today, check the time
|
||||
->orWhere(function ($q) {
|
||||
$q->where('scheduled_date', now('Asia/Manila')->toDateString())
|
||||
->where(function ($sub) {
|
||||
// Keep if the time hasn't passed yet (evaluated in Manila time)
|
||||
$sub->where('scheduled_start_time', '>=', now('Asia/Manila')->toTimeString())
|
||||
// OR if the driver has already started the trip
|
||||
->orWhereIn('status', [Trip::STATUS_IN_PROGRESS, Trip::STATUS_AT_DUMPSITE]);
|
||||
});
|
||||
});
|
||||
})
|
||||
->orderBy('scheduled_date')
|
||||
->orderBy('scheduled_start_time')
|
||||
->limit(10)
|
||||
->get();
|
||||
|
||||
$pickups = $trips->map(function (Trip $trip) use ($dopId) {
|
||||
$myStop = $trip->route?->stops()->where('drop_off_point_id', $dopId)->first();
|
||||
$pickups = $trips->map(function (Trip $trip) use ($nearbyDopIds) {
|
||||
$myStop = $trip->route?->stops()->whereIn('drop_off_point_id', $nearbyDopIds)->first();
|
||||
|
||||
return [
|
||||
'trip_id' => $trip->uuid,
|
||||
@@ -61,11 +96,11 @@ class UpcomingPickupsController extends ApiController
|
||||
});
|
||||
|
||||
return $this->ok([
|
||||
'household_assigned' => true,
|
||||
'drop_off_point' => [
|
||||
'id' => $household->assignedDropOffPoint?->uuid,
|
||||
'name' => $household->assignedDropOffPoint?->name,
|
||||
],
|
||||
'household_assigned' => (bool) $household->assigned_drop_off_point_id,
|
||||
'drop_off_point' => $household->assignedDropOffPoint ? [
|
||||
'id' => $household->assignedDropOffPoint->uuid,
|
||||
'name' => $household->assignedDropOffPoint->name,
|
||||
] : null,
|
||||
'pickups' => $pickups,
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user