Perbarui model dan tampilan untuk mendukung fungsionalitas QR code dalam proses verifikasi penerima. Tambahkan properti qrCodeHash pada PenerimaPenyaluranModel dan implementasikan metode verifikasi QR code di DetailPenyaluranController. Modifikasi tampilan di WargaDetailPenerimaanView dan DetailPenyaluranPage untuk menampilkan QR code dan menambahkan fungsionalitas pemindaian QR code. Perbarui rute aplikasi untuk mendukung navigasi ke halaman pemindaian QR code dan konfirmasi penerima.

This commit is contained in:
Khafidh Fuadi
2025-03-19 13:11:24 +07:00
parent 984b8336f0
commit 0597f0aea0
19 changed files with 839 additions and 263 deletions

View File

@ -445,4 +445,57 @@ class DetailPenyaluranController extends GetxController {
isLoading.value = false;
}
}
// Metode untuk verifikasi penerima berdasarkan QR code
Future<bool> verifikasiPenerimaByQrCode(
String penyaluranId, String qrHash) async {
try {
isProcessing.value = true;
// Cari penerima dengan QR hash yang sesuai
final data = await _supabaseService.client
.from('penerima_penyaluran')
.select('*, warga:warga_id(*)')
.eq('penyaluran_bantuan_id', penyaluranId)
.eq('qr_code_hash', qrHash)
.single();
if (data != null) {
// Jika penerima ditemukan, konversi ke model
final Map<String, dynamic> sanitizedPenerimaData =
Map<String, dynamic>.from(data);
// Konversi jumlah_bantuan ke double jika bertipe String
if (sanitizedPenerimaData['jumlah_bantuan'] is String) {
sanitizedPenerimaData['jumlah_bantuan'] = double.tryParse(
sanitizedPenerimaData['jumlah_bantuan'] as String);
}
// Konversi data ke model
final penerima =
PenerimaPenyaluranModel.fromJson(sanitizedPenerimaData);
// Set isProcessing ke false sebelum navigasi untuk menghindari masalah loading
isProcessing.value = false;
// Navigasi ke halaman konfirmasi dengan data terbaru
await Get.toNamed('/petugas-desa/konfirmasi-penerima/${penerima.id}',
arguments: {
'penerima': penerima,
'tanggal_penyaluran': penyaluran.value?.tanggalPenyaluran
});
// Refresh data
await refreshData();
return true;
}
return false;
} catch (e) {
print('Error verifikasi QR code: $e');
return false;
} finally {
isProcessing.value = false;
}
}
}

View File

@ -9,6 +9,8 @@ import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart
import 'package:penyaluran_app/app/services/supabase_service.dart';
import 'package:penyaluran_app/app/utils/date_time_helper.dart';
import 'dart:async';
import 'dart:convert';
import 'package:crypto/crypto.dart';
class JadwalPenyaluranController extends GetxController {
final AuthController _authController = Get.find<AuthController>();
@ -415,38 +417,42 @@ class JadwalPenyaluranController extends GetxController {
// Buat data penerima penyaluran untuk setiap pengajuan yang disetujui
for (var pengajuan in pengajuanData) {
// Generate QR code hash unik untuk setiap penerima
final String qrCodeHash =
generateQrCodeHash(penyaluranId, pengajuan['warga_id']);
final penerimaPenyaluran = {
'penyaluran_bantuan_id': penyaluranId,
'warga_id': pengajuan['warga_id'],
'stok_bantuan_id': skemaBantuanCache[skemaId]?.stokBantuanId,
'status_penerimaan': 'MENUNGGU',
'status_penerimaan': 'BELUMMENERIMA',
'qr_code_hash': qrCodeHash,
};
// Simpan data penerima ke database
await _supabaseService.client
.from('penerima_penyaluran')
.insert(penerimaPenyaluran);
}
// Refresh data
// Setelah berhasil menambahkan, refresh data
await loadJadwalData();
await loadPermintaanPenjadwalanData();
// Kembali ke halaman sebelumnya
Get.back();
// Tampilkan notifikasi sukses
// Tampilkan pesan sukses
Get.snackbar(
'Sukses',
'Penyaluran berhasil ditambahkan',
snackPosition: SnackPosition.TOP,
'Jadwal penyaluran bantuan telah dibuat',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.green,
colorText: Colors.white,
);
} catch (e) {
print('Error menambahkan penyaluran: $e');
print('Error: $e');
Get.snackbar(
'Error',
'Gagal menambahkan penyaluran: ${e.toString()}',
snackPosition: SnackPosition.TOP,
'Gagal',
'Terjadi kesalahan saat menambahkan jadwal penyaluran',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
@ -454,4 +460,16 @@ class JadwalPenyaluranController extends GetxController {
isLoading.value = false;
}
}
// Fungsi untuk generate hash QR code berdasarkan ID penyaluran dan ID warga
String generateQrCodeHash(String penyaluranId, String wargaId) {
// Kombinasikan ID penyaluran dan ID warga dengan timestamp untuk keunikan
final String combinedData =
'$penyaluranId-$wargaId-${DateTime.now().millisecondsSinceEpoch}';
// Gunakan SHA-256 untuk menghasilkan hash yang aman
final bytes = utf8.encode(combinedData);
final hash = sha256.convert(bytes);
// Kembalikan representasi string dari hash
return hash.toString();
}
}