NIM_E31222534/Androidnya/lib/controllers/imunisasi_controller.dart

228 lines
7.0 KiB
Dart

import 'package:flutter/material.dart';
import '../models/imunisasi_model.dart';
import '../services/imunisasi_service.dart';
import '../services/anak_service.dart';
class ImunisasiController {
final ImunisasiService _imunisasiService = ImunisasiService();
List<Imunisasi> _imunisasiList = [];
final Map<String, bool> _jenisExpanded = {};
bool _isLoading = false;
String? _error;
// Getters
List<Imunisasi> get imunisasiList => _imunisasiList;
Map<String, bool> get jenisExpanded => _jenisExpanded;
bool get isLoading => _isLoading;
String? get error => _error;
// Constructor
ImunisasiController() {
// Tidak lagi perlu memanggil _initializeData() karena
// data akan diambil dari API saat loadImunisasiForAnak dipanggil
}
// Load data imunisasi untuk anak tertentu dari API
Future<void> loadImunisasiForAnak(int anakId) async {
_isLoading = true;
_error = null;
try {
// Kosongkan list terlebih dahulu untuk memastikan tidak ada data lama
_imunisasiList = [];
_jenisExpanded.clear();
// Cek dulu apakah anak ada
try {
await getAnakById(anakId);
} catch (e) {
_isLoading = false;
throw Exception('Silakan tambahkan data anak terlebih dahulu');
}
final imunisasiData = await _imunisasiService.getImunisasiByAnakId(anakId);
_imunisasiList = imunisasiData.map((data) {
return Imunisasi.fromApi(
data,
defaultColor: _getColorForImunisasi(data['jenis_imunisasi']['nama'] ?? ''),
);
}).toList();
// Reset jenisExpanded
_jenisExpanded.clear();
for (var imunisasi in _imunisasiList) {
_jenisExpanded[imunisasi.jenis] = false;
}
_isLoading = false;
} catch (e) {
print('Error loading imunisasi: $e');
_error = e.toString();
_isLoading = false;
_imunisasiList = [];
throw e;
}
}
// Tambahkan method untuk mendapatkan data anak berdasarkan ID
Future<Map<String, dynamic>> getAnakById(int anakId) async {
try {
// Gunakan AnakService jika tersedia
// final anakService = AnakService();
// return await anakService.getAnakById(anakId);
// Fallback: Gunakan ImunisasiService untuk mendapatkan data anak
return await _imunisasiService.getAnakData(anakId);
} catch (e) {
print('Error getting anak data: $e');
throw Exception('Gagal mendapatkan data anak: $e');
}
}
// Check if all immunizations for a child are complete
Future<bool> isImunisasiComplete(int anakId) async {
try {
await loadImunisasiForAnak(anakId);
// If there are no immunizations or the list is empty, return false
if (_imunisasiList.isEmpty) {
return false;
}
// Check if all immunizations have 'Sudah' status
final uncompletedImunisasi = _imunisasiList.where(
(imunisasi) => imunisasi.status != 'Sudah'
).toList();
// If there are no uncompleted immunizations, then all are complete
return uncompletedImunisasi.isEmpty;
} catch (e) {
print('Error checking complete immunization status: $e');
return false;
}
}
// Load jadwal imunisasi berdasarkan usia anak
Future<void> loadJadwalImunisasiForAnak(int anakId) async {
_isLoading = true;
_error = null;
try {
final result = await _imunisasiService.getJadwalForAnak(anakId);
final jadwalList = result['data'] as List;
if (jadwalList.isNotEmpty) {
_imunisasiList = jadwalList.map((data) {
final jadwal = data['jadwal'];
final jenisImunisasi = data['jenis_imunisasi'];
final isImplemented = data['is_implemented'] ?? false;
// Determine status based on implementation
String status = isImplemented ? 'Sudah' : 'Jadwal';
// If there's an existing imunisasi record, use its status
if (data['imunisasi'] != null) {
status = _imunisasiService.getStatusDisplay(data['imunisasi']['status']);
}
// Prepare data for Imunisasi.fromApi
Map<String, dynamic> imunisasiData = {
'id': data['imunisasi']?['id'],
'jenis_imunisasi': jenisImunisasi,
'tanggal': jadwal['tanggal'],
'status': status,
'lokasi': jadwal['lokasi'] ?? 'Posyandu',
'anak_id': anakId,
'jenis_id': jenisImunisasi['id'],
'jadwal_imunisasi_id': jadwal['id'],
};
return Imunisasi.fromApi(
imunisasiData,
defaultColor: _getColorForImunisasi(jenisImunisasi['nama'] ?? ''),
);
}).toList();
// Reset jenisExpanded
_jenisExpanded.clear();
for (var imunisasi in _imunisasiList) {
_jenisExpanded[imunisasi.jenis] = false;
}
}
_isLoading = false;
} catch (e) {
print('Error loading jadwal imunisasi: $e');
_error = 'Gagal memuat jadwal imunisasi: $e';
_isLoading = false;
}
}
// Update status imunisasi
Future<void> updateImunisasiStatus(int imunisasiId, String newStatus) async {
try {
await _imunisasiService.updateImunisasiStatus(imunisasiId, newStatus);
// Refresh data setelah update
// Note: anakId bisa disimpan sebagai property class saat loadImunisasiForAnak dipanggil
} catch (e) {
_error = 'Gagal memperbarui status imunisasi: $e';
}
}
// Mengubah status expanded untuk jenis tertentu
void toggleJenisExpanded(String jenis) {
_jenisExpanded[jenis] = !(_jenisExpanded[jenis] ?? false);
}
// Get count by status
int getCountByStatus(String status) {
if (_imunisasiList.isEmpty) return 0;
try {
if (status == 'Sudah') {
return _imunisasiList.where((v) =>
v.status == 'Sudah' ||
v.status.toLowerCase().contains('sudah') ||
v.status.toLowerCase().contains('selesai')
).length;
}
return _imunisasiList.where((v) => v.status == status).length;
} catch (e) {
print('Error in getCountByStatus: $e');
return 0;
}
}
// Mendapatkan imunisasi berdasarkan jenis
List<Imunisasi> getImunisasiByJenis(String jenis) {
if (_imunisasiList.isEmpty) return [];
return _imunisasiList.where((v) => v.jenis == jenis).toList();
}
// Helper methods
Color _getColorForImunisasi(String jenis) {
if (jenis.isEmpty) return Colors.grey;
// Map some common imunisasi types to colors
switch (jenis.toLowerCase()) {
case 'hb-0':
case 'hepatitis b':
return Colors.blue;
case 'bcg':
return Colors.purple;
case 'dpt':
case 'dpt-hb-hib':
return Colors.green;
case 'polio':
return Colors.red;
case 'campak':
case 'mr':
return Colors.orange;
default:
// Generate a color based on the hash of the name
return Colors.primaries[jenis.hashCode % Colors.primaries.length];
}
}
}