has('firstName') && $request->firstName !== 'all') { $query->where('christian_name', 'LIKE', "%{$request->firstName}%"); } if ($request->has('lastName') && $request->lastName !== 'all') { $query->where('surname', 'LIKE', "%{$request->lastName}%"); } // Filter by region of origin (place_of_birth in Person table) if ($request->has('regionOfOrigin') && $request->regionOfOrigin !== 'all') { $query->where('place_of_birth', 'LIKE', "%{$request->regionOfOrigin}%"); } // For filters that need to access related tables, use whereHas // Filter by Year of Arrival (in Migration table) if ($request->has('yearOfArrival') && $request->yearOfArrival !== 'all') { $year = $request->yearOfArrival; $query->whereHas('migration', function (Builder $query) use ($year) { $query->whereYear('date_of_arrival_aus', $year) ->orWhereYear('date_of_arrival_nt', $year); }); } // Filter by Age at Migration (requires calculation) if ($request->has('ageAtMigration') && $request->ageAtMigration !== 'all') { $ageAtMigration = (int) $request->ageAtMigration; $query->whereHas('migration', function (Builder $query) use ($ageAtMigration) { $query->whereRaw('YEAR(date_of_arrival_aus) - YEAR(person.date_of_birth) = ?', [$ageAtMigration]) ->orWhereRaw('YEAR(date_of_arrival_nt) - YEAR(person.date_of_birth) = ?', [$ageAtMigration]); }); } // Filter by settlement location (in Residence table) if ($request->has('settlementLocation') && $request->settlementLocation !== 'all') { $location = $request->settlementLocation; $query->whereHas('residence', function (Builder $query) use ($location) { $query->where(function ($q) use ($location) { $q->where('address', 'LIKE', "%{$location}%") ->orWhere('suburb', 'LIKE', "%{$location}%") ->orWhere('state', 'LIKE', "%{$location}%"); }); }); } // Paginate the results (default 10 per page, can be customized with the 'per_page' parameter) $perPage = $request->input('per_page', 10); $persons = $query->paginate($perPage); // Eager load related models for the collection $persons->getCollection()->each->load([ 'migration', 'naturalization', 'residence', 'family', 'internment' ]); return response()->json([ 'success' => true, 'data' => new PersonCollection($persons), 'message' => 'Public search results retrieved successfully' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to retrieve search results', 'error' => $e->getMessage() ], 500); } } /** * Find a person by ID card number. * * @param string $idCardNo * @return JsonResponse */ public function findByIdCard(string $idCardNo): JsonResponse { try { $person = Person::with(['migration', 'naturalization', 'residence', 'family', 'internment']) ->where('id_card_no', $idCardNo) ->first(); if (!$person) { return response()->json([ 'success' => false, 'message' => 'Person not found with the provided ID card number' ], 404); } return response()->json([ 'success' => true, 'data' => new PersonResource($person), 'message' => 'Person found by ID card number' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to retrieve person by ID card number', 'error' => $e->getMessage() ], 500); } } /** * Display a listing of the resource. * * @param Request $request * @return JsonResponse */ public function index(Request $request): JsonResponse { try { $query = Person::query(); // Apply search filters if provided if ($request->has('search')) { $searchTerm = $request->search; $query->where(function($q) use ($searchTerm) { $q->where('full_name', 'LIKE', "%{$searchTerm}%") ->orWhere('surname', 'LIKE', "%{$searchTerm}%") ->orWhere('occupation', 'LIKE', "%{$searchTerm}%"); }); } // Paginate results $persons = $query->paginate(10); // Eager load related models for each person in the collection $persons->getCollection()->each->load([ 'migration', 'naturalization', 'residence', 'family', 'internment' ]); return response()->json([ 'success' => true, 'data' => new PersonCollection($persons), 'message' => 'Persons retrieved successfully' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to retrieve persons', 'error' => $e->getMessage() ], 500); } } /** * Store a newly created resource in storage. * * @param StorePersonRequest $request * @return JsonResponse */ public function store(StorePersonRequest $request): JsonResponse { try { // Use DB transaction for atomic operations $result = DB::transaction(function () use ($request) { // Create person record $person = Person::create($request->only([ 'surname', 'christian_name', 'full_name', 'date_of_birth', 'place_of_birth', 'date_of_death', 'occupation', 'additional_notes', 'reference', 'id_card_no' ])); // Create migration record if data is provided if ($request->has('migration')) { $person->migration()->create($request->migration); } // Create naturalization record if data is provided if ($request->has('naturalization')) { $person->naturalization()->create($request->naturalization); } // Create residence record if data is provided if ($request->has('residence')) { $person->residence()->create($request->residence); } // Create family record if data is provided if ($request->has('family')) { $person->family()->create($request->family); } // Create internment record if data is provided if ($request->has('internment')) { $person->internment()->create($request->internment); } // Load all relationships for the response $person->load(['migration', 'naturalization', 'residence', 'family', 'internment']); return $person; }); return response()->json([ 'success' => true, 'data' => new PersonResource($result), 'message' => 'Person created successfully' ], 201); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to create person', 'error' => $e->getMessage() ], 500); } } /** * Display the specified resource. * * @param string $id * @return JsonResponse */ public function show(string $id): JsonResponse { try { // Find person by ID and eager load all relationships $person = Person::with(['migration', 'naturalization', 'residence', 'family', 'internment']) ->find($id); if (!$person) { return response()->json([ 'success' => false, 'message' => 'Person not found' ], 404); } return response()->json([ 'success' => true, 'data' => new PersonResource($person), 'message' => 'Person retrieved successfully' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to retrieve person', 'error' => $e->getMessage() ], 500); } } /** * Update the specified resource in storage. * * @param UpdatePersonRequest $request * @param string $id * @return JsonResponse */ public function update(UpdatePersonRequest $request, string $id): JsonResponse { try { // Use DB transaction for atomic operations $result = DB::transaction(function () use ($request, $id) { // Find person by ID $person = Person::findOrFail($id); // Update person record $person->update($request->only([ 'surname', 'christian_name', 'full_name', 'date_of_birth', 'place_of_birth', 'date_of_death', 'occupation', 'additional_notes', 'reference', 'id_card_no' ])); // Update migration record if data is provided if ($request->has('migration')) { if ($person->migration) { $person->migration->update($request->migration); } else { $person->migration()->create($request->migration); } } // Update naturalization record if data is provided if ($request->has('naturalization')) { if ($person->naturalization) { $person->naturalization->update($request->naturalization); } else { $person->naturalization()->create($request->naturalization); } } // Update residence record if data is provided if ($request->has('residence')) { if ($person->residence) { $person->residence->update($request->residence); } else { $person->residence()->create($request->residence); } } // Update family record if data is provided if ($request->has('family')) { if ($person->family) { $person->family->update($request->family); } else { $person->family()->create($request->family); } } // Update internment record if data is provided if ($request->has('internment')) { if ($person->internment) { $person->internment->update($request->internment); } else { $person->internment()->create($request->internment); } } // Load all relationships for the response $person->load(['migration', 'naturalization', 'residence', 'family', 'internment']); return $person; }); return response()->json([ 'success' => true, 'data' => new PersonResource($result), 'message' => 'Person updated successfully' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to update person', 'error' => $e->getMessage() ], 500); } } /** * Remove the specified resource from storage. * * @param string $id * @return JsonResponse */ public function destroy(string $id): JsonResponse { try { // Use DB transaction for atomic operations DB::transaction(function () use ($id) { // Find person by ID with related models $person = Person::with([ 'migration', 'naturalization', 'residence', 'family', 'internment' ])->findOrFail($id); // Manually delete each related model to ensure soft deletes work correctly if ($person->migration) { $person->migration->delete(); } if ($person->naturalization) { $person->naturalization->delete(); } if ($person->residence) { $person->residence->delete(); } if ($person->family) { $person->family->delete(); } if ($person->internment) { $person->internment->delete(); } // Now delete the person record $person->delete(); }); return response()->json([ 'success' => true, 'message' => 'Person deleted successfully' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Failed to delete person', 'error' => $e->getMessage() ], 500); } } }