NIM_E31222534/Androidnya/app/Http/Controllers/Api/JadwalApiController.php

505 lines
19 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\JadwalPemeriksaan;
use App\Models\JadwalImunisasi;
use App\Models\JadwalVitamin;
use App\Models\JenisImunisasi;
use App\Models\JenisVitamin;
use Carbon\Carbon;
use App\Models\Imunisasi;
use App\Models\Vitamin;
use App\Models\Anak;
use Illuminate\Support\Facades\Validator;
class JadwalApiController extends Controller
{
/**
* Get all schedules (combined from all types)
*/
public function index()
{
$pemeriksaan = JadwalPemeriksaan::select(
'id',
'judul',
\DB::raw("'pemeriksaan rutin' as jenis"),
'tanggal',
'waktu',
'created_at'
)
->orderBy('tanggal', 'desc')
->get();
$imunisasi = JadwalImunisasi::select(
'jadwal_imunisasi.id',
'jenis_imunisasi.nama as judul',
\DB::raw("'imunisasi' as jenis"),
'jadwal_imunisasi.tanggal',
'jadwal_imunisasi.waktu',
'jadwal_imunisasi.created_at'
)
->join('jenis_imunisasi', 'jadwal_imunisasi.jenis_imunisasi_id', '=', 'jenis_imunisasi.id')
->orderBy('jadwal_imunisasi.tanggal', 'desc')
->get();
$vitamin = JadwalVitamin::select(
'jadwal_vitamin.id',
'jenis_vitamin.nama as judul',
\DB::raw("'vitamin' as jenis"),
'jadwal_vitamin.tanggal',
'jadwal_vitamin.waktu',
'jadwal_vitamin.created_at'
)
->join('jenis_vitamin', 'jadwal_vitamin.jenis_vitamin_id', '=', 'jenis_vitamin.id')
->orderBy('jadwal_vitamin.tanggal', 'desc')
->get();
$jadwal = $pemeriksaan->concat($imunisasi)->concat($vitamin)
->sortByDesc('tanggal')
->values()
->all();
return response()->json([
'status' => 'success',
'data' => $jadwal
]);
}
/**
* Get upcoming schedules (all types)
*/
public function upcoming()
{
$today = Carbon::today()->format('Y-m-d');
$pemeriksaan = JadwalPemeriksaan::select(
'id',
'judul',
\DB::raw("'pemeriksaan rutin' as jenis"),
'tanggal',
'waktu',
'created_at'
)
->where('tanggal', '>=', $today)
->orderBy('tanggal', 'asc')
->get();
$imunisasi = JadwalImunisasi::select(
'jadwal_imunisasi.id',
'jenis_imunisasi.nama as judul',
\DB::raw("'imunisasi' as jenis"),
'jadwal_imunisasi.tanggal',
'jadwal_imunisasi.waktu',
'jadwal_imunisasi.created_at'
)
->join('jenis_imunisasi', 'jadwal_imunisasi.jenis_imunisasi_id', '=', 'jenis_imunisasi.id')
->where('jadwal_imunisasi.tanggal', '>=', $today)
->orderBy('jadwal_imunisasi.tanggal', 'asc')
->get();
$vitamin = JadwalVitamin::select(
'jadwal_vitamin.id',
'jenis_vitamin.nama as judul',
\DB::raw("'vitamin' as jenis"),
'jadwal_vitamin.tanggal',
'jadwal_vitamin.waktu',
'jadwal_vitamin.created_at'
)
->join('jenis_vitamin', 'jadwal_vitamin.jenis_vitamin_id', '=', 'jenis_vitamin.id')
->where('jadwal_vitamin.tanggal', '>=', $today)
->orderBy('jadwal_vitamin.tanggal', 'asc')
->get();
$jadwal = $pemeriksaan->concat($imunisasi)->concat($vitamin)
->sortBy('tanggal')
->values()
->all();
return response()->json([
'status' => 'success',
'data' => $jadwal
]);
}
/**
* Get upcoming schedules filtered by child's age
*/
public function upcomingForChild($anakId)
{
$today = Carbon::today()->format('Y-m-d');
try {
// Get child data to calculate age
$anak = Anak::findOrFail($anakId);
$tanggalLahir = Carbon::parse($anak->tanggal_lahir);
$usiaBulan = Carbon::now()->diffInMonths($tanggalLahir);
$usiaHari = Carbon::now()->diffInDays($tanggalLahir);
// Log child age for debugging
\Log::info("Anak ID: $anakId, Nama: {$anak->nama}, Tanggal Lahir: {$anak->tanggal_lahir}");
\Log::info("Usia: $usiaBulan bulan ($usiaHari hari)");
// Always include pemeriksaan rutin
$pemeriksaan = JadwalPemeriksaan::select(
'id',
'judul',
\DB::raw("'pemeriksaan rutin' as jenis"),
'tanggal',
'waktu',
'created_at'
)
->where('tanggal', '>=', $today)
->orderBy('tanggal', 'asc')
->get();
// Get imunisasi that are appropriate for child's age
$imunisasi = $this->getAgeAppropriateImunisasi($usiaBulan, $today);
// Get vitamin that are appropriate for child's age
$vitamin = $this->getAgeAppropriateVitamin($usiaBulan, $today);
$jadwal = $pemeriksaan->concat($imunisasi)->concat($vitamin)
->sortBy('tanggal')
->values()
->all();
\Log::info("Total jadwal: " . count($jadwal) .
" (Pemeriksaan: " . count($pemeriksaan) .
", Imunisasi: " . count($imunisasi) .
", Vitamin: " . count($vitamin) . ")");
return response()->json([
'status' => 'success',
'data' => $jadwal,
'child_info' => [
'id' => $anakId,
'nama' => $anak->nama,
'tanggal_lahir' => $anak->tanggal_lahir,
'age_months' => $usiaBulan,
'age_days' => $usiaHari
],
'filter_info' => [
'filter_applied' => true,
'records_found' => count($jadwal),
'pemeriksaan_count' => count($pemeriksaan),
'imunisasi_count' => count($imunisasi),
'vitamin_count' => count($vitamin)
]
]);
} catch (\Exception $e) {
\Log::error("Error getting age-appropriate schedules: " . $e->getMessage());
return response()->json([
'status' => 'error',
'message' => 'Failed to get age-appropriate schedules: ' . $e->getMessage(),
'debug_trace' => $e->getTraceAsString()
], 500);
}
}
/**
* Get imunisasi schedules filtered by child's age
*/
public function imunisasiForChild($anakId)
{
$today = Carbon::today()->format('Y-m-d');
try {
// Get child data to calculate age
$anak = Anak::findOrFail($anakId);
$tanggalLahir = Carbon::parse($anak->tanggal_lahir);
$usiaBulan = Carbon::now()->diffInMonths($tanggalLahir);
// Log child age for debugging
\Log::info("Anak ID: $anakId, Nama: {$anak->nama}, Tanggal Lahir: {$anak->tanggal_lahir}, Usia: $usiaBulan bulan");
// Get imunisasi that are appropriate for child's age
$jadwal = $this->getAgeAppropriateImunisasi($usiaBulan, $today);
return response()->json([
'status' => 'success',
'data' => $jadwal,
'child_info' => [
'id' => $anakId,
'nama' => $anak->nama,
'tanggal_lahir' => $anak->tanggal_lahir,
'age_months' => $usiaBulan
],
'filter_info' => [
'filter_applied' => true,
'records_found' => count($jadwal)
]
]);
} catch (\Exception $e) {
\Log::error("Error getting age-appropriate imunisasi: " . $e->getMessage());
return response()->json([
'status' => 'error',
'message' => 'Failed to get age-appropriate imunisasi: ' . $e->getMessage(),
'debug_trace' => $e->getTraceAsString()
], 500);
}
}
/**
* Get vitamin schedules filtered by child's age
*/
public function vitaminForChild($anakId)
{
$today = Carbon::today()->format('Y-m-d');
try {
// Get child data to calculate age
$anak = Anak::findOrFail($anakId);
$tanggalLahir = Carbon::parse($anak->tanggal_lahir);
$usiaBulan = Carbon::now()->diffInMonths($tanggalLahir);
// Log child age for debugging
\Log::info("Anak ID: $anakId, Nama: {$anak->nama}, Tanggal Lahir: {$anak->tanggal_lahir}, Usia: $usiaBulan bulan");
// Get vitamin that are appropriate for child's age
$jadwal = $this->getAgeAppropriateVitamin($usiaBulan, $today);
return response()->json([
'status' => 'success',
'data' => $jadwal,
'child_info' => [
'id' => $anakId,
'nama' => $anak->nama,
'tanggal_lahir' => $anak->tanggal_lahir,
'age_months' => $usiaBulan
],
'filter_info' => [
'filter_applied' => true,
'records_found' => count($jadwal)
]
]);
} catch (\Exception $e) {
\Log::error("Error getting age-appropriate vitamin: " . $e->getMessage());
return response()->json([
'status' => 'error',
'message' => 'Failed to get age-appropriate vitamin: ' . $e->getMessage(),
'debug_trace' => $e->getTraceAsString()
], 500);
}
}
/**
* Helper method to get age-appropriate imunisasi
*/
private function getAgeAppropriateImunisasi($usiaBulan, $today)
{
// Konversi usia bulan ke hari untuk imunisasi
$usiaHari = $usiaBulan * 30; // Perkiraan kasar 1 bulan = 30 hari
// Filter imunisasi berdasarkan data di database sesuai dengan umur dalam hari
$ageRanges = [
'HB-0' => [0, 7], // 0-7 hari
'BCG' => [0, 30], // 0-30 hari (1 bulan)
'Polio 1' => [0, 30], // 0-30 hari (1 bulan)
'DPT-HB-HIP 1' => [0, 60], // 0-60 hari (2 bulan)
'Polio 2' => [0, 60], // 0-60 hari (2 bulan)
'DPT-HB-HIP 2' => [0, 90], // 0-90 hari (3 bulan)
'Polio 3' => [0, 90], // 0-90 hari (3 bulan)
'DPT-HB-HIP 3' => [0, 120], // 0-120 hari (4 bulan)
'Polio 4' => [0, 120], // 0-120 hari (4 bulan)
'Campak' => [0, 270], // 0-270 hari (9 bulan)
];
// Base query untuk semua jadwal imunisasi yang akan datang
$query = JadwalImunisasi::select(
'jadwal_imunisasi.id',
'jenis_imunisasi.nama as judul',
\DB::raw("'imunisasi' as jenis"),
'jadwal_imunisasi.tanggal',
'jadwal_imunisasi.waktu',
'jadwal_imunisasi.created_at'
)
->join('jenis_imunisasi', 'jadwal_imunisasi.jenis_imunisasi_id', '=', 'jenis_imunisasi.id')
->where('jadwal_imunisasi.tanggal', '>=', $today)
->orderBy('jadwal_imunisasi.tanggal', 'asc');
// Add age filtering - we'll use a different approach to ensure strict filtering
if ($usiaHari !== null) {
// Start with an impossible condition to build "OR" conditions
$matchedAny = false;
$query->where(function($q) use ($ageRanges, $usiaHari, &$matchedAny) {
foreach ($ageRanges as $imunisasiName => [$minAge, $maxAge]) {
if ($usiaHari >= $minAge && $usiaHari <= $maxAge) {
if ($matchedAny) {
$q->orWhere('jenis_imunisasi.nama', 'like', "%$imunisasiName%");
} else {
$q->where('jenis_imunisasi.nama', 'like', "%$imunisasiName%");
$matchedAny = true;
}
}
}
// If no matches, ensure no results are returned
if (!$matchedAny) {
$q->where('jenis_imunisasi.id', 0); // This will ensure no results
}
});
}
// Log the SQL query for debugging
\Log::info('Imunisasi SQL query: ' . $query->toSql());
\Log::info('Imunisasi query bindings: ' . json_encode($query->getBindings()));
\Log::info('Usia anak dalam hari: ' . $usiaHari);
$results = $query->get();
// Log the results
\Log::info('Imunisasi results: ' . $results->count() . ' records found for age ' . $usiaBulan . ' months (' . $usiaHari . ' days)');
return $results;
}
/**
* Helper method to get age-appropriate vitamin
*/
private function getAgeAppropriateVitamin($usiaBulan, $today)
{
// Filter vitamin berdasarkan data di database
$ageRanges = [
'A Biru' => [6, 11], // 6-11 bulan
'A Merah' => [12, 59], // 12-59 bulan
];
// Base query for all upcoming vitamin
$query = JadwalVitamin::select(
'jadwal_vitamin.id',
'jenis_vitamin.nama as judul',
\DB::raw("'vitamin' as jenis"),
'jadwal_vitamin.tanggal',
'jadwal_vitamin.waktu',
'jadwal_vitamin.created_at'
)
->join('jenis_vitamin', 'jadwal_vitamin.jenis_vitamin_id', '=', 'jenis_vitamin.id')
->where('jadwal_vitamin.tanggal', '>=', $today)
->orderBy('jadwal_vitamin.tanggal', 'asc');
// Add age filtering - we'll use a different approach to ensure strict filtering
if ($usiaBulan !== null) {
// Start with an impossible condition to build "OR" conditions
$matchedAny = false;
$query->where(function($q) use ($ageRanges, $usiaBulan, &$matchedAny) {
foreach ($ageRanges as $vitaminName => [$minAge, $maxAge]) {
if ($usiaBulan >= $minAge && $usiaBulan <= $maxAge) {
if ($matchedAny) {
$q->orWhere('jenis_vitamin.nama', 'like', "%$vitaminName%");
} else {
$q->where('jenis_vitamin.nama', 'like', "%$vitaminName%");
$matchedAny = true;
}
}
}
// If no matches, ensure no results are returned
if (!$matchedAny) {
$q->where('jenis_vitamin.id', 0); // This will ensure no results
}
});
}
// Log the SQL query for debugging
\Log::info('Vitamin SQL query: ' . $query->toSql());
\Log::info('Vitamin query bindings: ' . json_encode($query->getBindings()));
\Log::info('Usia anak dalam bulan: ' . $usiaBulan);
$results = $query->get();
// Log the results
\Log::info('Vitamin results: ' . $results->count() . ' records found for age ' . $usiaBulan . ' months');
return $results;
}
/**
* Get pemeriksaan schedules
*/
public function pemeriksaan()
{
// ... existing code ...
}
/**
* Get list of immunization types with age ranges
*/
public function imunisasiAgeRanges()
{
$ageRanges = [
'HB-0' => [0, 7], // 0-7 hari
'BCG' => [0, 30], // 0-30 hari (1 bulan)
'Polio 1' => [0, 30], // 0-30 hari (1 bulan)
'DPT-HB-HIP 1' => [0, 60], // 0-60 hari (2 bulan)
'Polio 2' => [0, 60], // 0-60 hari (2 bulan)
'DPT-HB-HIP 2' => [0, 90], // 0-90 hari (3 bulan)
'Polio 3' => [0, 90], // 0-90 hari (3 bulan)
'DPT-HB-HIP 3' => [0, 120], // 0-120 hari (4 bulan)
'Polio 4' => [0, 120], // 0-120 hari (4 bulan)
'Campak' => [0, 270], // 0-270 hari (9 bulan)
];
$formattedRanges = [];
foreach ($ageRanges as $name => $range) {
// Convert days to months for display (approximate)
$minMonths = floor($range[0] / 30);
$minDays = $range[0] % 30;
$maxMonths = floor($range[1] / 30);
$maxDays = $range[1] % 30;
$minAgeText = $minMonths > 0 ? "$minMonths bulan " : "";
$minAgeText .= $minDays > 0 ? "$minDays hari" : "";
$minAgeText = $minAgeText ?: "0 hari";
$maxAgeText = $maxMonths > 0 ? "$maxMonths bulan " : "";
$maxAgeText .= $maxDays > 0 ? "$maxDays hari" : "";
$maxAgeText = $maxAgeText ?: "0 hari";
$formattedRanges[] = [
'nama' => $name,
'usia_min_hari' => $range[0],
'usia_max_hari' => $range[1],
'usia_min_text' => $minAgeText,
'usia_max_text' => $maxAgeText,
'deskripsi' => "Untuk anak usia {$minAgeText} sampai {$maxAgeText}"
];
}
return response()->json([
'status' => 'success',
'data' => $formattedRanges
]);
}
/**
* Get list of vitamin types with age ranges
*/
public function vitaminAgeRanges()
{
$ageRanges = [
'A Biru' => [6, 11], // 6-11 bulan
'A Merah' => [12, 59], // 12-59 bulan
];
$formattedRanges = [];
foreach ($ageRanges as $name => $range) {
$formattedRanges[] = [
'nama' => $name,
'usia_min_bulan' => $range[0],
'usia_max_bulan' => $range[1],
'deskripsi' => "Untuk anak usia {$range[0]}-{$range[1]} bulan"
];
}
return response()->json([
'status' => 'success',
'data' => $formattedRanges
]);
}
}