NIM_E31222534/app/Http/Controllers/Api/VitaminApiController.php

516 lines
18 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Vitamin;
use App\Models\JadwalVitamin;
use App\Models\Anak;
use App\Models\JenisVitamin;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
class VitaminApiController extends Controller
{
/**
* Get all vitamin records with filtering options
*/
public function index(Request $request)
{
$query = Vitamin::with(['anak', 'jenisVitamin']);
// Filter by anak_id if provided
if ($request->has('anak_id')) {
$query->where('anak_id', $request->anak_id);
}
// Filter by status if provided
if ($request->has('status')) {
$query->where('status', $request->status);
}
// Get paginated results or all if limit=0
if ($request->has('limit') && $request->limit > 0) {
$vitamin = $query->orderBy('tanggal', 'desc')->paginate($request->limit);
} else {
$vitamin = $query->orderBy('tanggal', 'desc')->get();
}
return response()->json([
'status' => 'success',
'data' => $vitamin
]);
}
/**
* Get a vitamin record by ID
*/
public function show($id)
{
$vitamin = Vitamin::with(['anak', 'jenisVitamin'])->find($id);
if (!$vitamin) {
return response()->json([
'status' => 'error',
'message' => 'Data vitamin tidak ditemukan'
], 404);
}
return response()->json([
'status' => 'success',
'data' => $vitamin
]);
}
/**
* Update vitamin status and date
*/
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'tanggal' => 'sometimes|date',
'status' => 'sometimes|in:' . implode(',', Vitamin::$statusList),
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => 'Validasi gagal',
'errors' => $validator->errors()
], 422);
}
$vitamin = Vitamin::find($id);
if (!$vitamin) {
return response()->json([
'status' => 'error',
'message' => 'Data vitamin tidak ditemukan'
], 404);
}
// Keep track of old status for comparison
$oldStatus = $vitamin->status;
// Only update tanggal and status fields
$updateData = [];
if ($request->has('tanggal')) {
$updateData['tanggal'] = $request->tanggal;
}
if ($request->has('status')) {
$updateData['status'] = $request->status;
}
$vitamin->update($updateData);
// If status changed and jadwal_vitamin_id is set, update jadwal status
if ($request->has('status') && $oldStatus !== $request->status && $vitamin->jadwal_vitamin_id) {
$this->updateJadwalStatus($vitamin->jadwal_vitamin_id);
}
return response()->json([
'status' => 'success',
'message' => 'Data vitamin berhasil diperbarui',
'data' => $vitamin->fresh()->load(['anak', 'jenisVitamin'])
]);
}
/**
* Get vitamin data for a specific child
*/
public function getByAnakId($anakId)
{
$anak = Anak::find($anakId);
if (!$anak) {
return response()->json([
'status' => 'error',
'message' => 'Data anak tidak ditemukan'
], 404);
}
$vitamin = Vitamin::with('jenisVitamin')
->where('anak_id', $anakId)
->orderBy('tanggal', 'desc')
->get();
return response()->json([
'status' => 'success',
'data' => $vitamin
]);
}
/**
* Get scheduled vitamin and check implementation status
*/
public function getJadwalWithStatus(Request $request)
{
// Get all scheduled vitamin
$query = JadwalVitamin::with('jenisVitamin')
->orderBy('tanggal', 'desc');
// Filter by date range if provided
if ($request->has('start_date') && $request->has('end_date')) {
$query->whereBetween('tanggal', [$request->start_date, $request->end_date]);
}
$jadwalVitamin = $query->get();
// Prepare response with implementation status
$result = [];
foreach ($jadwalVitamin as $jadwal) {
// For each jadwal, check if there are matching vitamin records
$implementedCount = Vitamin::where('jenis_id', $jadwal->jenis_vitamin_id)
->where('tanggal', $jadwal->tanggal)
->count();
// Add status information
$item = [
'jadwal' => $jadwal,
'jenis_vitamin' => $jadwal->jenisVitamin,
'implementation_count' => $implementedCount,
'is_implemented' => $implementedCount > 0
];
$result[] = $item;
}
return response()->json([
'status' => 'success',
'data' => $result
]);
}
/**
* Get jadwal vitamin for a specific child based on their age
*/
public function getJadwalForAnak($anakId)
{
$anak = Anak::find($anakId);
if (!$anak) {
return response()->json([
'status' => 'error',
'message' => 'Data anak tidak ditemukan'
], 404);
}
// Calculate child's age in days
$tanggalLahir = Carbon::parse($anak->tanggal_lahir);
$umurHari = $tanggalLahir->diffInDays(Carbon::now());
// Get upcoming scheduled vitamin
$jadwalVitamin = JadwalVitamin::with('jenisVitamin')
->whereHas('jenisVitamin', function($query) use ($umurHari) {
// Filter jadwal where child's age is within min and max age range
$query->where('min_umur_hari', '<=', $umurHari)
->where('max_umur_hari', '>=', $umurHari);
})
->where('tanggal', '>=', Carbon::today()->format('Y-m-d'))
->orderBy('tanggal', 'asc')
->get();
// Check if each jadwal is already implemented for this child
$result = [];
foreach ($jadwalVitamin as $jadwal) {
// Check if this vitamin is already scheduled/implemented for the child
$existingVitamin = Vitamin::where('anak_id', $anakId)
->where('jenis_id', $jadwal->jenis_vitamin_id)
->first();
$result[] = [
'jadwal' => $jadwal,
'jenis_vitamin' => $jadwal->jenisVitamin,
'child_age_days' => $umurHari,
'is_eligible' => true,
'is_implemented' => $existingVitamin ? true : false,
'vitamin' => $existingVitamin
];
}
return response()->json([
'status' => 'success',
'anak' => [
'id' => $anak->id,
'nama' => $anak->nama_anak,
'tanggal_lahir' => $anak->tanggal_lahir,
'umur_hari' => $umurHari
],
'data' => $result
]);
}
/**
* Check implementation status of a schedule
*/
public function checkImplementationStatus(Request $request)
{
$validator = Validator::make($request->all(), [
'jadwal_id' => 'required|exists:jadwal_vitamin,id',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$jadwalId = $request->jadwal_id;
$jadwal = JadwalVitamin::with('jenisVitamin')->findOrFail($jadwalId);
// Make sure jadwal implementation status is up-to-date
$this->updateJadwalStatus($jadwalId);
$jadwal->refresh();
// Count implementation even if jadwal_vitamin_id is not set
$implementationCount = Vitamin::where('jenis_id', $jadwal->jenis_vitamin_id)
->where('tanggal', $jadwal->tanggal)
->count();
// Count completed implementations
$completedCount = Vitamin::where('jenis_id', $jadwal->jenis_vitamin_id)
->where('tanggal', $jadwal->tanggal)
->where('status', Vitamin::STATUS_SELESAI)
->count();
$response = [
'success' => true,
'data' => [
[
'id' => $jadwal->id,
'jenis_vitamin' => $jadwal->jenisVitamin,
'is_implemented' => $jadwal->is_implemented,
'implementation_count' => $implementationCount,
'completed_count' => $completedCount
]
]
];
return response()->json($response);
}
/**
* Confirm implementation of a schedule
*/
public function confirmImplementation($id)
{
$jadwal = JadwalVitamin::findOrFail($id);
// Update jadwal implementation status based on completed vitamin records
$this->updateJadwalStatus($jadwal->id);
return response()->json([
'success' => true,
'message' => 'Jadwal vitamin berhasil diperiksa status implementasinya.'
]);
}
/**
* Get eligible children for a schedule
*/
public function getEligibleChildren($jadwalId)
{
$jadwal = JadwalVitamin::with('jenisVitamin')->findOrFail($jadwalId);
$jenisVitamin = $jadwal->jenisVitamin;
// Get all children
$allChildren = Anak::all();
$eligibleChildren = [];
foreach ($allChildren as $anak) {
// Calculate age in months
$birthDate = Carbon::parse($anak->tanggal_lahir);
$ageInMonths = $birthDate->diffInMonths(Carbon::now());
// Check if already registered
$isRegistered = Vitamin::where('anak_id', $anak->id)
->where('jadwal_vitamin_id', $jadwalId)
->exists();
$isImplemented = Vitamin::where('anak_id', $anak->id)
->where('jadwal_vitamin_id', $jadwalId)
->where('status', 'Sudah')
->exists();
// Check age eligibility with the correct field names
if ($ageInMonths >= $jenisVitamin->min_umur_bulan && $ageInMonths <= $jenisVitamin->max_umur_bulan) {
$eligibleChildren[] = [
'anak' => $anak,
'is_registered' => $isRegistered,
'is_implemented' => $isImplemented,
'child_age_months' => $ageInMonths
];
}
}
return response()->json([
'success' => true,
'data' => $eligibleChildren
]);
}
/**
* Create vitamin records from a jadwal
*/
public function createFromJadwal(Request $request)
{
$validator = Validator::make($request->all(), [
'jadwal_vitamin_id' => 'required|exists:jadwal_vitamin,id',
'anak_id' => 'required|exists:anak,id',
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => 'Validasi gagal',
'errors' => $validator->errors()
], 422);
}
// Get the jadwal
$jadwal = JadwalVitamin::findOrFail($request->jadwal_vitamin_id);
// Get anak and verify age eligibility
$anak = Anak::findOrFail($request->anak_id);
$tanggalLahir = Carbon::parse($anak->tanggal_lahir);
$umurBulan = $tanggalLahir->diffInMonths(Carbon::parse($jadwal->tanggal));
// Get jenis vitamin
$jenisVitamin = JenisVitamin::findOrFail($jadwal->jenis_vitamin_id);
// Check if child's age is within the eligible range (using months for vitamin)
if ($umurBulan < $jenisVitamin->min_umur_bulan || $umurBulan > $jenisVitamin->max_umur_bulan) {
return response()->json([
'status' => 'error',
'message' => 'Anak tidak memenuhi syarat umur untuk vitamin ini',
'data' => [
'umur_anak_bulan' => $umurBulan,
'min_umur_bulan' => $jenisVitamin->min_umur_bulan,
'max_umur_bulan' => $jenisVitamin->max_umur_bulan
]
], 422);
}
// Check if vitamin already exists for this child and jadwal
$existingVitamin = Vitamin::where('anak_id', $request->anak_id)
->where('jenis_id', $jadwal->jenis_vitamin_id)
->first();
if ($existingVitamin) {
return response()->json([
'status' => 'error',
'message' => 'Data vitamin untuk anak dan jadwal ini sudah ada',
'data' => $existingVitamin
], 422);
}
// Create new vitamin record with jadwal_vitamin_id
$vitamin = Vitamin::create([
'anak_id' => $request->anak_id,
'jenis_id' => $jadwal->jenis_vitamin_id,
'jadwal_vitamin_id' => $jadwal->id,
'tanggal' => $jadwal->tanggal,
'status' => Vitamin::STATUS_BELUM
]);
return response()->json([
'status' => 'success',
'message' => 'Data vitamin berhasil dibuat dari jadwal',
'data' => $vitamin->load(['anak', 'jenisVitamin'])
], 201);
}
/**
* Mark a jadwal as complete and register all eligible children
*/
public function completeJadwal($id)
{
try {
$jadwal = JadwalVitamin::with('jenisVitamin')->findOrFail($id);
// Get all children
$allChildren = Anak::all();
$eligibleChildren = [];
$debug_info = [];
foreach ($allChildren as $anak) {
// Calculate age in months
$birthDate = Carbon::parse($anak->tanggal_lahir);
$ageInMonths = $birthDate->diffInMonths(Carbon::now());
// Log info for debugging
$debug_info[] = [
'anak_id' => $anak->id,
'nama' => $anak->nama_anak,
'tanggal_lahir' => $anak->tanggal_lahir,
'umur_bulan' => $ageInMonths,
'min_umur_bulan' => $jadwal->jenisVitamin->min_umur_bulan,
'max_umur_bulan' => $jadwal->jenisVitamin->max_umur_bulan,
'eligible' => ($ageInMonths >= $jadwal->jenisVitamin->min_umur_bulan && $ageInMonths <= $jadwal->jenisVitamin->max_umur_bulan)
];
// Check age eligibility
if ($ageInMonths >= $jadwal->jenisVitamin->min_umur_bulan && $ageInMonths <= $jadwal->jenisVitamin->max_umur_bulan) {
$eligibleChildren[] = $anak;
}
}
// Register each eligible child for this vitamin if not already registered
$registered = 0;
foreach ($eligibleChildren as $anak) {
// Check if already registered
$existing = Vitamin::where('anak_id', $anak->id)
->where('jenis_id', $jadwal->jenis_vitamin_id)
->first();
if (!$existing) {
// Create new vitamin record dengan status awal Belum
Vitamin::create([
'anak_id' => $anak->id,
'jenis_id' => $jadwal->jenis_vitamin_id,
'jadwal_vitamin_id' => $jadwal->id,
'tanggal' => $jadwal->tanggal,
'status' => 'Belum'
]);
$registered++;
}
}
// Status jadwal independent dari status vitamin
// Tombol "Selesai" di jadwal.blade.php akan mengubah status jadwal secara langsung
// Jika tidak ada anak yang eligible, tampilkan pesan yang jelas
$message = $registered > 0
? "Jadwal vitamin berhasil diselesaikan dan $registered anak ditambahkan ke daftar vitamin."
: "Jadwal vitamin berhasil diselesaikan tetapi tidak ada anak yang memenuhi syarat umur (min: {$jadwal->jenisVitamin->min_umur_bulan} bulan, max: {$jadwal->jenisVitamin->max_umur_bulan} bulan).";
return response()->json([
'success' => true,
'message' => $message,
'data' => [
'jadwal' => $jadwal->fresh(),
'eligible_children_count' => count($eligibleChildren),
'registered_children' => $registered,
'debug_info' => $debug_info
]
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Gagal menandai jadwal sebagai selesai: ' . $e->getMessage(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
], 500);
}
}
/**
* Update implementation status of jadwal - now independent of vitamin status
*/
private function updateJadwalStatus($jadwalId)
{
// Status jadwal sekarang independent dari status vitamin
// Akan diubah langsung menggunakan endpoint khusus
return JadwalVitamin::findOrFail($jadwalId);
}
}