first commit
This commit is contained in:
2364
lib/app/modules/warga/controllers/order_sewa_aset_controller.dart
Normal file
2364
lib/app/modules/warga/controllers/order_sewa_aset_controller.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,443 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:flutter_logs/flutter_logs.dart';
|
||||
import '../../../data/models/paket_model.dart';
|
||||
import '../../../data/providers/aset_provider.dart';
|
||||
import '../../../data/providers/sewa_provider.dart';
|
||||
import '../../../services/service_manager.dart';
|
||||
import '../../../services/navigation_service.dart';
|
||||
|
||||
class OrderSewaPaketController extends GetxController {
|
||||
// Dependencies
|
||||
final AsetProvider asetProvider = Get.find<AsetProvider>();
|
||||
final SewaProvider sewaProvider = Get.find<SewaProvider>();
|
||||
final NavigationService navigationService = ServiceManager().navigationService;
|
||||
|
||||
// State variables
|
||||
final paket = Rx<PaketModel?>(null);
|
||||
final paketImages = RxList<String>([]);
|
||||
final isLoading = RxBool(true);
|
||||
final isPhotosLoading = RxBool(true);
|
||||
final selectedSatuanWaktu = Rx<Map<String, dynamic>?>(null);
|
||||
final selectedDate = RxString('');
|
||||
final selectedStartDate = Rx<DateTime?>(null);
|
||||
final selectedEndDate = Rx<DateTime?>(null);
|
||||
final selectedStartTime = RxInt(-1);
|
||||
final selectedEndTime = RxInt(-1);
|
||||
final formattedDateRange = RxString('');
|
||||
final formattedTimeRange = RxString('');
|
||||
final totalPrice = RxDouble(0.0);
|
||||
final kuantitas = RxInt(1);
|
||||
final isSubmitting = RxBool(false);
|
||||
|
||||
// Format currency
|
||||
final currencyFormat = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
FlutterLogs.logInfo("OrderSewaPaketController", "onInit", "Initializing OrderSewaPaketController");
|
||||
|
||||
// Get the paket ID from arguments
|
||||
final Map<String, dynamic> args = Get.arguments ?? {};
|
||||
final String? paketId = args['id'];
|
||||
|
||||
if (paketId != null) {
|
||||
loadPaketData(paketId);
|
||||
} else {
|
||||
debugPrint('❌ No paket ID provided in arguments');
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle hot reload - restore state if needed
|
||||
void handleHotReload() {
|
||||
if (paket.value == null) {
|
||||
final Map<String, dynamic> args = Get.arguments ?? {};
|
||||
final String? paketId = args['id'];
|
||||
|
||||
if (paketId != null) {
|
||||
// Try to get from cache first
|
||||
final cachedPaket = GetStorage().read('cached_paket_$paketId');
|
||||
if (cachedPaket != null) {
|
||||
debugPrint('🔄 Hot reload: Restoring paket from cache');
|
||||
paket.value = cachedPaket;
|
||||
loadPaketPhotos(paketId);
|
||||
initializePriceOptions();
|
||||
} else {
|
||||
loadPaketData(paketId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load paket data from API
|
||||
Future<void> loadPaketData(String id) async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
debugPrint('🔍 Loading paket data for ID: $id');
|
||||
|
||||
// First check if we have it in cache
|
||||
final cachedPaket = GetStorage().read('cached_paket_$id');
|
||||
if (cachedPaket != null) {
|
||||
debugPrint('✅ Found cached paket data');
|
||||
paket.value = cachedPaket;
|
||||
await loadPaketPhotos(id);
|
||||
initializePriceOptions();
|
||||
} else {
|
||||
// Get all pakets and filter for the one we need
|
||||
final List<dynamic> allPakets = await asetProvider.getPakets();
|
||||
final rawPaket = allPakets.firstWhere(
|
||||
(paket) => paket['id'] == id,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
// Declare loadedPaket outside the if block for wider scope
|
||||
PaketModel? loadedPaket;
|
||||
|
||||
if (rawPaket != null) {
|
||||
// Convert to PaketModel
|
||||
try {
|
||||
// Handle Map directly - pakets from getPakets() are always maps
|
||||
loadedPaket = PaketModel.fromMap(rawPaket);
|
||||
debugPrint('✅ Successfully converted paket to PaketModel');
|
||||
} catch (e) {
|
||||
debugPrint('❌ Error converting paket map to PaketModel: $e');
|
||||
// Fallback using our helper methods
|
||||
loadedPaket = PaketModel(
|
||||
id: getPaketId(rawPaket),
|
||||
nama: getPaketNama(rawPaket),
|
||||
deskripsi: getPaketDeskripsi(rawPaket),
|
||||
harga: getPaketHarga(rawPaket),
|
||||
kuantitas: getPaketKuantitas(rawPaket),
|
||||
foto_paket: getPaketMainPhoto(rawPaket),
|
||||
satuanWaktuSewa: getPaketSatuanWaktuSewa(rawPaket),
|
||||
);
|
||||
debugPrint('✅ Created PaketModel using helper methods');
|
||||
}
|
||||
|
||||
// Update the state with the loaded paket
|
||||
if (loadedPaket != null) {
|
||||
debugPrint('✅ Loaded paket: ${loadedPaket.nama}');
|
||||
paket.value = loadedPaket;
|
||||
|
||||
// Cache for future use
|
||||
GetStorage().write('cached_paket_$id', loadedPaket);
|
||||
|
||||
// Load photos for this paket
|
||||
await loadPaketPhotos(id);
|
||||
|
||||
// Set initial pricing option
|
||||
initializePriceOptions();
|
||||
|
||||
// Ensure we have at least one photo if available
|
||||
if (paketImages.isEmpty) {
|
||||
String? mainPhoto = getPaketMainPhoto(paket.value);
|
||||
if (mainPhoto != null && mainPhoto.isNotEmpty) {
|
||||
paketImages.add(mainPhoto);
|
||||
debugPrint('✅ Added main paket photo: $mainPhoto');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debugPrint('❌ No paket found with id: $id');
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the total price if we have a paket loaded
|
||||
if (paket.value != null) {
|
||||
calculateTotalPrice();
|
||||
debugPrint('💰 Total price calculated: ${totalPrice.value}');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('❌ Error loading paket data: $e');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper methods to safely access paket properties
|
||||
String? getPaketId(dynamic paket) {
|
||||
if (paket == null) return null;
|
||||
try {
|
||||
return paket.id ?? paket['id'];
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String? getPaketNama(dynamic paket) {
|
||||
if (paket == null) return null;
|
||||
try {
|
||||
return paket.nama ?? paket['nama'];
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String? getPaketDeskripsi(dynamic paket) {
|
||||
if (paket == null) return null;
|
||||
try {
|
||||
return paket.deskripsi ?? paket['deskripsi'];
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
double getPaketHarga(dynamic paket) {
|
||||
if (paket == null) return 0.0;
|
||||
try {
|
||||
var harga = paket.harga ?? paket['harga'] ?? 0;
|
||||
return double.tryParse(harga.toString()) ?? 0.0;
|
||||
} catch (_) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
int getPaketKuantitas(dynamic paket) {
|
||||
if (paket == null) return 1;
|
||||
try {
|
||||
var qty = paket.kuantitas ?? paket['kuantitas'] ?? 1;
|
||||
return int.tryParse(qty.toString()) ?? 1;
|
||||
} catch (_) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
String? getPaketMainPhoto(dynamic paket) {
|
||||
if (paket == null) return null;
|
||||
try {
|
||||
return paket.foto_paket ?? paket['foto_paket'];
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> getPaketSatuanWaktuSewa(dynamic paket) {
|
||||
if (paket == null) return [];
|
||||
try {
|
||||
return paket.satuanWaktuSewa ?? paket['satuanWaktuSewa'] ?? [];
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Load photos for the paket
|
||||
Future<void> loadPaketPhotos(String paketId) async {
|
||||
try {
|
||||
isPhotosLoading.value = true;
|
||||
final photos = await asetProvider.getFotoPaket(paketId);
|
||||
if (photos != null && photos.isNotEmpty) {
|
||||
paketImages.clear();
|
||||
for (var photo in photos) {
|
||||
try {
|
||||
if (photo.fotoPaket != null && photo.fotoPaket.isNotEmpty) {
|
||||
paketImages.add(photo.fotoPaket);
|
||||
} else if (photo.fotoAset != null && photo.fotoAset.isNotEmpty) {
|
||||
paketImages.add(photo.fotoAset);
|
||||
}
|
||||
} catch (e) {
|
||||
var fotoUrl = photo['foto_paket'] ?? photo['foto_aset'];
|
||||
if (fotoUrl != null && fotoUrl.isNotEmpty) {
|
||||
paketImages.add(fotoUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
isPhotosLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize price options
|
||||
void initializePriceOptions() {
|
||||
if (paket.value == null) return;
|
||||
|
||||
final satuanWaktuSewa = getPaketSatuanWaktuSewa(paket.value);
|
||||
if (satuanWaktuSewa.isNotEmpty) {
|
||||
// Default to the first option
|
||||
selectSatuanWaktu(satuanWaktuSewa.first);
|
||||
}
|
||||
}
|
||||
|
||||
// Select satuan waktu
|
||||
void selectSatuanWaktu(Map<String, dynamic> satuanWaktu) {
|
||||
selectedSatuanWaktu.value = satuanWaktu;
|
||||
|
||||
// Reset date and time selections
|
||||
selectedStartDate.value = null;
|
||||
selectedEndDate.value = null;
|
||||
selectedStartTime.value = -1;
|
||||
selectedEndTime.value = -1;
|
||||
selectedDate.value = '';
|
||||
formattedDateRange.value = '';
|
||||
formattedTimeRange.value = '';
|
||||
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
// Check if the rental is daily
|
||||
bool isDailyRental() {
|
||||
final namaSatuan = selectedSatuanWaktu.value?['nama_satuan_waktu'] ?? '';
|
||||
return namaSatuan.toString().toLowerCase().contains('hari');
|
||||
}
|
||||
|
||||
// Select date range for daily rental
|
||||
void selectDateRange(DateTime start, DateTime end) {
|
||||
selectedStartDate.value = start;
|
||||
selectedEndDate.value = end;
|
||||
|
||||
// Format the date range
|
||||
final formatter = DateFormat('d MMM yyyy', 'id');
|
||||
if (start.year == end.year && start.month == end.month && start.day == end.day) {
|
||||
formattedDateRange.value = formatter.format(start);
|
||||
} else {
|
||||
formattedDateRange.value = '${formatter.format(start)} - ${formatter.format(end)}';
|
||||
}
|
||||
|
||||
selectedDate.value = formatter.format(start);
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
// Select date for hourly rental
|
||||
void selectDate(DateTime date) {
|
||||
selectedStartDate.value = date;
|
||||
selectedDate.value = DateFormat('d MMM yyyy', 'id').format(date);
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
// Select time range for hourly rental
|
||||
void selectTimeRange(int start, int end) {
|
||||
selectedStartTime.value = start;
|
||||
selectedEndTime.value = end;
|
||||
|
||||
// Format the time range
|
||||
final startTime = '$start:00';
|
||||
final endTime = '$end:00';
|
||||
formattedTimeRange.value = '$startTime - $endTime';
|
||||
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
// Calculate total price
|
||||
void calculateTotalPrice() {
|
||||
if (selectedSatuanWaktu.value == null) {
|
||||
totalPrice.value = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
final basePrice = double.tryParse(selectedSatuanWaktu.value!['harga'].toString()) ?? 0.0;
|
||||
|
||||
if (isDailyRental()) {
|
||||
if (selectedStartDate.value != null && selectedEndDate.value != null) {
|
||||
final days = selectedEndDate.value!.difference(selectedStartDate.value!).inDays + 1;
|
||||
totalPrice.value = basePrice * days;
|
||||
} else {
|
||||
totalPrice.value = basePrice;
|
||||
}
|
||||
} else {
|
||||
if (selectedStartTime.value >= 0 && selectedEndTime.value >= 0) {
|
||||
final hours = selectedEndTime.value - selectedStartTime.value;
|
||||
totalPrice.value = basePrice * hours;
|
||||
} else {
|
||||
totalPrice.value = basePrice;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply by quantity
|
||||
totalPrice.value *= kuantitas.value;
|
||||
}
|
||||
|
||||
// Format price as currency
|
||||
String formatPrice(double price) {
|
||||
return currencyFormat.format(price);
|
||||
}
|
||||
|
||||
// Submit order
|
||||
Future<void> submitOrder() async {
|
||||
try {
|
||||
if (paket.value == null || selectedSatuanWaktu.value == null) {
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Data paket tidak lengkap',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((isDailyRental() && (selectedStartDate.value == null || selectedEndDate.value == null)) ||
|
||||
(!isDailyRental() && (selectedStartDate.value == null || selectedStartTime.value < 0 || selectedEndTime.value < 0))) {
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Silakan pilih waktu sewa',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
isSubmitting.value = true;
|
||||
|
||||
// Prepare order data
|
||||
final Map<String, dynamic> orderData = {
|
||||
'id_paket': paket.value!.id,
|
||||
'id_satuan_waktu_sewa': selectedSatuanWaktu.value!['id'],
|
||||
'tanggal_mulai': selectedStartDate.value!.toIso8601String(),
|
||||
'tanggal_selesai': selectedEndDate.value?.toIso8601String() ?? selectedStartDate.value!.toIso8601String(),
|
||||
'jam_mulai': isDailyRental() ? null : selectedStartTime.value,
|
||||
'jam_selesai': isDailyRental() ? null : selectedEndTime.value,
|
||||
'total_harga': totalPrice.value,
|
||||
'kuantitas': kuantitas.value,
|
||||
};
|
||||
|
||||
// Submit the order
|
||||
final result = await sewaProvider.createPaketOrder(orderData);
|
||||
|
||||
if (result != null) {
|
||||
Get.snackbar(
|
||||
'Sukses',
|
||||
'Pesanan berhasil dibuat',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
|
||||
// Navigate to payment page
|
||||
navigationService.navigateToPembayaranSewa(result['id']);
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Gagal membuat pesanan',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('❌ Error submitting order: $e');
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Terjadi kesalahan: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
} finally {
|
||||
isSubmitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle back button press
|
||||
void onBackPressed() {
|
||||
navigationService.navigateToSewaAset();
|
||||
}
|
||||
}
|
1115
lib/app/modules/warga/controllers/pembayaran_sewa_controller.bak
Normal file
1115
lib/app/modules/warga/controllers/pembayaran_sewa_controller.bak
Normal file
File diff suppressed because it is too large
Load Diff
1202
lib/app/modules/warga/controllers/pembayaran_sewa_controller.dart
Normal file
1202
lib/app/modules/warga/controllers/pembayaran_sewa_controller.dart
Normal file
File diff suppressed because it is too large
Load Diff
471
lib/app/modules/warga/controllers/sewa_aset_controller.dart
Normal file
471
lib/app/modules/warga/controllers/sewa_aset_controller.dart
Normal file
@ -0,0 +1,471 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../../../data/providers/aset_provider.dart';
|
||||
import '../../../data/models/aset_model.dart';
|
||||
import '../../../routes/app_routes.dart';
|
||||
import '../../../data/models/pesanan_model.dart';
|
||||
import '../../../data/models/satuan_waktu_model.dart';
|
||||
import '../../../data/models/satuan_waktu_sewa_model.dart';
|
||||
import '../../../data/providers/auth_provider.dart';
|
||||
import '../../../data/providers/pesanan_provider.dart';
|
||||
import '../../../services/navigation_service.dart';
|
||||
import '../../../services/service_manager.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
|
||||
class SewaAsetController extends GetxController
|
||||
with GetSingleTickerProviderStateMixin {
|
||||
final AsetProvider _asetProvider = Get.find<AsetProvider>();
|
||||
final AuthProvider authProvider = Get.find<AuthProvider>();
|
||||
final PesananProvider pesananProvider = Get.put(PesananProvider());
|
||||
final NavigationService navigationService = Get.find<NavigationService>();
|
||||
final box = GetStorage();
|
||||
|
||||
// Tab controller
|
||||
late TabController tabController;
|
||||
// Reactive tab index
|
||||
final currentTabIndex = 0.obs;
|
||||
|
||||
// State variables
|
||||
final asets = <AsetModel>[].obs;
|
||||
final filteredAsets = <AsetModel>[].obs;
|
||||
|
||||
// Paket-related variables
|
||||
final pakets = RxList<dynamic>([]);
|
||||
final filteredPakets = RxList<dynamic>([]);
|
||||
final isLoadingPakets = false.obs;
|
||||
|
||||
final isLoading = true.obs;
|
||||
|
||||
// Search controller
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
||||
// Reactive variables
|
||||
final isOrdering = false.obs;
|
||||
final selectedAset = Rx<AsetModel?>(null);
|
||||
final selectedSatuanWaktuSewa = Rx<SatuanWaktuSewaModel?>(null);
|
||||
final selectedDurasi = 1.obs;
|
||||
final totalHarga = 0.obs;
|
||||
final selectedDate = DateTime.now().obs;
|
||||
final selectedTime = '08:00'.obs;
|
||||
final satuanWaktuDropdownItems =
|
||||
<DropdownMenuItem<SatuanWaktuSewaModel>>[].obs;
|
||||
|
||||
// Flag untuk menangani hot reload
|
||||
final hasInitialized = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
debugPrint('🚀 SewaAsetController: onInit called');
|
||||
|
||||
// Initialize tab controller
|
||||
tabController = TabController(length: 2, vsync: this);
|
||||
// Listen for tab changes
|
||||
tabController.addListener(() {
|
||||
currentTabIndex.value = tabController.index;
|
||||
|
||||
// Load packages data when switching to package tab for the first time
|
||||
if (currentTabIndex.value == 1 && pakets.isEmpty) {
|
||||
loadPakets();
|
||||
}
|
||||
});
|
||||
|
||||
loadAsets();
|
||||
|
||||
searchController.addListener(() {
|
||||
if (currentTabIndex.value == 0) {
|
||||
filterAsets(searchController.text);
|
||||
} else {
|
||||
filterPakets(searchController.text);
|
||||
}
|
||||
});
|
||||
|
||||
hasInitialized.value = true;
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
debugPrint('🚀 SewaAsetController: onReady called');
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
debugPrint('🧹 SewaAsetController: onClose called');
|
||||
searchController.dispose();
|
||||
tabController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
// Method untuk menangani hot reload
|
||||
void handleHotReload() {
|
||||
debugPrint('🔥 Hot reload detected in SewaAsetController');
|
||||
if (!hasInitialized.value) {
|
||||
debugPrint('🔄 Reinitializing SewaAsetController after hot reload');
|
||||
loadAsets();
|
||||
if (currentTabIndex.value == 1) {
|
||||
loadPakets();
|
||||
}
|
||||
hasInitialized.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Method untuk menangani tombol back
|
||||
void onBackPressed() {
|
||||
debugPrint('🔙 Back button pressed in SewaAsetView');
|
||||
navigationService.backFromSewaAset();
|
||||
}
|
||||
|
||||
Future<void> loadAsets() async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
final sewaAsets = await _asetProvider.getSewaAsets();
|
||||
|
||||
// Debug data satuan waktu sewa yang diterima
|
||||
debugPrint('===== DEBUG ASET & SATUAN WAKTU SEWA =====');
|
||||
for (var aset in sewaAsets) {
|
||||
debugPrint('Aset: ${aset.nama} (ID: ${aset.id})');
|
||||
|
||||
if (aset.satuanWaktuSewa.isEmpty) {
|
||||
debugPrint(' - Tidak ada satuan waktu sewa yang terkait');
|
||||
} else {
|
||||
debugPrint(
|
||||
' - Memiliki ${aset.satuanWaktuSewa.length} satuan waktu sewa:',
|
||||
);
|
||||
for (var sws in aset.satuanWaktuSewa) {
|
||||
debugPrint(' * ID: ${sws['id']}');
|
||||
debugPrint(' Aset ID: ${sws['aset_id']}');
|
||||
debugPrint(' Satuan Waktu ID: ${sws['satuan_waktu_id']}');
|
||||
debugPrint(' Harga: ${sws['harga']}');
|
||||
debugPrint(' Nama Satuan Waktu: ${sws['nama_satuan_waktu']}');
|
||||
debugPrint(' -----');
|
||||
}
|
||||
}
|
||||
debugPrint('=====================================');
|
||||
}
|
||||
|
||||
asets.assignAll(sewaAsets);
|
||||
filteredAsets.assignAll(sewaAsets);
|
||||
|
||||
// Tambahkan log info tentang jumlah aset yang berhasil dimuat
|
||||
debugPrint('Loaded ${sewaAsets.length} aset sewa successfully');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading asets: $e');
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Terjadi kesalahan saat memuat data aset',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
void filterAsets(String query) {
|
||||
if (query.isEmpty) {
|
||||
filteredAsets.assignAll(asets);
|
||||
} else {
|
||||
filteredAsets.assignAll(
|
||||
asets
|
||||
.where(
|
||||
(aset) => aset.nama.toLowerCase().contains(query.toLowerCase()),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void refreshAsets() {
|
||||
loadAsets();
|
||||
}
|
||||
|
||||
String formatPrice(dynamic price) {
|
||||
if (price == null) return 'Rp 0';
|
||||
|
||||
// Handle different types
|
||||
num numericPrice;
|
||||
if (price is int || price is double) {
|
||||
numericPrice = price;
|
||||
} else if (price is String) {
|
||||
numericPrice = double.tryParse(price) ?? 0;
|
||||
} else {
|
||||
return 'Rp 0';
|
||||
}
|
||||
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
return formatter.format(numericPrice);
|
||||
}
|
||||
|
||||
void selectAset(AsetModel aset) {
|
||||
selectedAset.value = aset;
|
||||
// Reset related values
|
||||
selectedSatuanWaktuSewa.value = null;
|
||||
selectedDurasi.value = 1;
|
||||
totalHarga.value = 0;
|
||||
|
||||
// Prepare dropdown items for satuan waktu sewa
|
||||
updateSatuanWaktuDropdown();
|
||||
}
|
||||
|
||||
void updateSatuanWaktuDropdown() {
|
||||
satuanWaktuDropdownItems.clear();
|
||||
|
||||
if (selectedAset.value != null &&
|
||||
selectedAset.value!.satuanWaktuSewa.isNotEmpty) {
|
||||
for (var item in selectedAset.value!.satuanWaktuSewa) {
|
||||
final satuanWaktuSewa = SatuanWaktuSewaModel.fromJson(item);
|
||||
satuanWaktuDropdownItems.add(
|
||||
DropdownMenuItem<SatuanWaktuSewaModel>(
|
||||
value: satuanWaktuSewa,
|
||||
child: Text(
|
||||
'${satuanWaktuSewa.namaSatuanWaktu ?? "Unknown"} - Rp${NumberFormat.decimalPattern('id').format(satuanWaktuSewa.harga)}',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void selectSatuanWaktu(SatuanWaktuSewaModel? satuanWaktuSewa) {
|
||||
selectedSatuanWaktuSewa.value = satuanWaktuSewa;
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
void updateDurasi(int durasi) {
|
||||
if (durasi < 1) durasi = 1;
|
||||
selectedDurasi.value = durasi;
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
void calculateTotalPrice() {
|
||||
if (selectedSatuanWaktuSewa.value != null) {
|
||||
totalHarga.value =
|
||||
selectedSatuanWaktuSewa.value!.harga * selectedDurasi.value;
|
||||
} else {
|
||||
totalHarga.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pickDate(DateTime date) {
|
||||
selectedDate.value = date;
|
||||
}
|
||||
|
||||
void pickTime(String time) {
|
||||
selectedTime.value = time;
|
||||
}
|
||||
|
||||
// Helper method to show error snackbar
|
||||
void _showError(String message) {
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
message,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
}
|
||||
|
||||
// Method untuk melakukan pemesanan
|
||||
Future<void> placeOrderAset() async {
|
||||
if (selectedAset.value == null) {
|
||||
_showError('Silakan pilih aset terlebih dahulu');
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedSatuanWaktuSewa.value == null) {
|
||||
_showError('Silakan pilih satuan waktu sewa');
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedDurasi.value <= 0) {
|
||||
_showError('Durasi sewa harus lebih dari 0');
|
||||
return;
|
||||
}
|
||||
|
||||
final userId = authProvider.getCurrentUserId();
|
||||
if (userId == null) {
|
||||
_showError('Anda belum login, silakan login terlebih dahulu');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final result = await _asetProvider.orderAset(
|
||||
userId: userId,
|
||||
asetId: selectedAset.value!.id,
|
||||
satuanWaktuSewaId: selectedSatuanWaktuSewa.value!.id,
|
||||
durasi: selectedDurasi.value,
|
||||
totalHarga: totalHarga.value,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
Get.snackbar(
|
||||
'Sukses',
|
||||
'Pesanan berhasil dibuat',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
resetSelections();
|
||||
} else {
|
||||
_showError('Gagal membuat pesanan');
|
||||
}
|
||||
} catch (e) {
|
||||
_showError('Terjadi kesalahan: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Method untuk reset pilihan setelah pemesanan berhasil
|
||||
void resetSelections() {
|
||||
selectedAset.value = null;
|
||||
selectedSatuanWaktuSewa.value = null;
|
||||
selectedDurasi.value = 1;
|
||||
totalHarga.value = 0;
|
||||
}
|
||||
|
||||
// Load packages data from paket table
|
||||
Future<void> loadPakets() async {
|
||||
try {
|
||||
isLoadingPakets.value = true;
|
||||
|
||||
// Call the provider method to get paket data
|
||||
final paketData = await _asetProvider.getPakets();
|
||||
|
||||
// Debug paket data
|
||||
debugPrint('===== DEBUG PAKET & SATUAN WAKTU SEWA =====');
|
||||
for (var paket in paketData) {
|
||||
debugPrint('Paket: ${paket['nama']} (ID: ${paket['id']})');
|
||||
|
||||
if (paket['satuanWaktuSewa'] == null ||
|
||||
paket['satuanWaktuSewa'].isEmpty) {
|
||||
debugPrint(' - Tidak ada satuan waktu sewa yang terkait');
|
||||
} else {
|
||||
debugPrint(
|
||||
' - Memiliki ${paket['satuanWaktuSewa'].length} satuan waktu sewa:',
|
||||
);
|
||||
for (var sws in paket['satuanWaktuSewa']) {
|
||||
debugPrint(' * ID: ${sws['id']}');
|
||||
debugPrint(' Paket ID: ${sws['paket_id']}');
|
||||
debugPrint(' Satuan Waktu ID: ${sws['satuan_waktu_id']}');
|
||||
debugPrint(' Harga: ${sws['harga']}');
|
||||
debugPrint(' Nama Satuan Waktu: ${sws['nama_satuan_waktu']}');
|
||||
debugPrint(' -----');
|
||||
}
|
||||
}
|
||||
debugPrint('=====================================');
|
||||
}
|
||||
|
||||
pakets.assignAll(paketData);
|
||||
filteredPakets.assignAll(paketData);
|
||||
|
||||
debugPrint('Loaded ${paketData.length} paket successfully');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading pakets: $e');
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Terjadi kesalahan saat memuat data paket',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
} finally {
|
||||
isLoadingPakets.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to filter pakets based on search query
|
||||
void filterPakets(String query) {
|
||||
if (query.isEmpty) {
|
||||
filteredPakets.assignAll(pakets);
|
||||
} else {
|
||||
filteredPakets.assignAll(
|
||||
pakets
|
||||
.where(
|
||||
(paket) => paket['nama'].toString().toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void refreshPakets() {
|
||||
loadPakets();
|
||||
}
|
||||
|
||||
// Method to load paket data
|
||||
Future<void> loadPaketData() async {
|
||||
try {
|
||||
isLoadingPakets.value = true;
|
||||
final result = await _asetProvider.getPakets();
|
||||
if (result != null) {
|
||||
pakets.clear();
|
||||
filteredPakets.clear();
|
||||
pakets.addAll(result);
|
||||
filteredPakets.addAll(result);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error loading pakets: $e');
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'Gagal memuat data paket. Silakan coba lagi nanti.',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
} finally {
|
||||
isLoadingPakets.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Method for placing an order for a paket
|
||||
Future<void> placeOrderPaket({
|
||||
required String paketId,
|
||||
required String satuanWaktuSewaId,
|
||||
required int durasi,
|
||||
required int totalHarga,
|
||||
}) async {
|
||||
debugPrint('===== PLACE ORDER PAKET =====');
|
||||
debugPrint('paketId: $paketId');
|
||||
debugPrint('satuanWaktuSewaId: $satuanWaktuSewaId');
|
||||
debugPrint('durasi: $durasi');
|
||||
debugPrint('totalHarga: $totalHarga');
|
||||
|
||||
final userId = authProvider.getCurrentUserId();
|
||||
if (userId == null) {
|
||||
_showError('Anda belum login, silakan login terlebih dahulu');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final result = await _asetProvider.orderPaket(
|
||||
userId: userId,
|
||||
paketId: paketId,
|
||||
satuanWaktuSewaId: satuanWaktuSewaId,
|
||||
durasi: durasi,
|
||||
totalHarga: totalHarga,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
Get.snackbar(
|
||||
'Sukses',
|
||||
'Pesanan paket berhasil dibuat',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white,
|
||||
);
|
||||
} else {
|
||||
_showError('Gagal membuat pesanan paket');
|
||||
}
|
||||
} catch (e) {
|
||||
_showError('Terjadi kesalahan: $e');
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
import 'package:get/get.dart';
|
||||
import '../../../data/providers/auth_provider.dart';
|
||||
import '../../../routes/app_routes.dart';
|
||||
import '../../../services/navigation_service.dart';
|
||||
|
||||
class WargaDashboardController extends GetxController {
|
||||
// Dependency injection
|
||||
final AuthProvider _authProvider = Get.find<AuthProvider>();
|
||||
final NavigationService navigationService = Get.find<NavigationService>();
|
||||
|
||||
// User data
|
||||
final userName = 'Pengguna Warga'.obs;
|
||||
final userRole = 'Warga'.obs;
|
||||
final userAvatar = Rx<String?>(null);
|
||||
final userEmail = ''.obs;
|
||||
final userNik = ''.obs;
|
||||
final userPhone = ''.obs;
|
||||
final userAddress = ''.obs;
|
||||
|
||||
// Navigation state is now managed by NavigationService
|
||||
|
||||
// Sample data (would be loaded from API)
|
||||
final activeRentals = <Map<String, dynamic>>[].obs;
|
||||
|
||||
// Active bills
|
||||
final activeBills = <Map<String, dynamic>>[].obs;
|
||||
|
||||
// Active penalties
|
||||
final activePenalties = <Map<String, dynamic>>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
// Set navigation index to Home (0)
|
||||
navigationService.setNavIndex(0);
|
||||
|
||||
// Load user data
|
||||
_loadUserData();
|
||||
|
||||
// Load sample data
|
||||
_loadSampleData();
|
||||
|
||||
// Load dummy data for bills and penalties
|
||||
loadDummyData();
|
||||
|
||||
// Load unpaid rentals
|
||||
loadUnpaidRentals();
|
||||
}
|
||||
|
||||
Future<void> _loadUserData() async {
|
||||
try {
|
||||
// Get the full name from warga_desa table
|
||||
final fullName = await _authProvider.getUserFullName();
|
||||
if (fullName != null && fullName.isNotEmpty) {
|
||||
userName.value = fullName;
|
||||
}
|
||||
|
||||
// Get the avatar URL
|
||||
final avatar = await _authProvider.getUserAvatar();
|
||||
userAvatar.value = avatar;
|
||||
|
||||
// Get the role name
|
||||
final roleId = await _authProvider.getUserRoleId();
|
||||
if (roleId != null) {
|
||||
final roleName = await _authProvider.getRoleName(roleId);
|
||||
if (roleName != null) {
|
||||
userRole.value = roleName;
|
||||
}
|
||||
}
|
||||
|
||||
// Load additional user data
|
||||
// In a real app, these would come from the API/database
|
||||
userEmail.value = await _authProvider.getUserEmail() ?? '';
|
||||
userNik.value = await _authProvider.getUserNIK() ?? '';
|
||||
userPhone.value = await _authProvider.getUserPhone() ?? '';
|
||||
userAddress.value = await _authProvider.getUserAddress() ?? '';
|
||||
} catch (e) {
|
||||
print('Error loading user data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void _loadSampleData() {
|
||||
// Clear any existing data
|
||||
activeRentals.clear();
|
||||
|
||||
// Load active rentals from API
|
||||
// For now, using sample data
|
||||
activeRentals.add({
|
||||
'id': '1',
|
||||
'name': 'Kursi',
|
||||
'time': '24 April 2023, 10:00 - 12:00',
|
||||
'duration': '2 jam',
|
||||
'price': 'Rp50.000',
|
||||
'can_extend': true,
|
||||
});
|
||||
}
|
||||
|
||||
void extendRental(String rentalId) {
|
||||
// Implementasi untuk memperpanjang sewa
|
||||
// Seharusnya melakukan API call ke backend
|
||||
}
|
||||
|
||||
void endRental(String rentalId) {
|
||||
// Implementasi untuk mengakhiri sewa
|
||||
// Seharusnya melakukan API call ke backend
|
||||
}
|
||||
|
||||
void navigateToRentals() {
|
||||
// Navigate to SewaAset using the navigation service
|
||||
navigationService.toSewaAset();
|
||||
}
|
||||
|
||||
void refreshData() {
|
||||
// Refresh data from repository
|
||||
_loadSampleData();
|
||||
loadDummyData();
|
||||
}
|
||||
|
||||
void onNavItemTapped(int index) {
|
||||
if (navigationService.currentNavIndex.value == index) {
|
||||
return; // Don't do anything if same tab
|
||||
}
|
||||
|
||||
navigationService.setNavIndex(index);
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
// Already on Home tab
|
||||
break;
|
||||
case 1:
|
||||
// Navigate to Sewa page
|
||||
navigationService.toWargaSewa();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void logout() async {
|
||||
await _authProvider.signOut();
|
||||
navigationService.toLogin();
|
||||
}
|
||||
|
||||
void loadDummyData() {
|
||||
// Dummy active bills
|
||||
activeBills.clear();
|
||||
activeBills.add({
|
||||
'id': '1',
|
||||
'title': 'Tagihan Air',
|
||||
'due_date': '30 Apr 2023',
|
||||
'amount': 'Rp 125.000',
|
||||
});
|
||||
activeBills.add({
|
||||
'id': '2',
|
||||
'title': 'Sewa Aula Desa',
|
||||
'due_date': '15 Apr 2023',
|
||||
'amount': 'Rp 350.000',
|
||||
});
|
||||
|
||||
// Dummy active penalties
|
||||
activePenalties.clear();
|
||||
activePenalties.add({
|
||||
'id': '1',
|
||||
'title': 'Keterlambatan Sewa Traktor',
|
||||
'days_late': '7',
|
||||
'amount': 'Rp 75.000',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> loadUnpaidRentals() async {
|
||||
try {
|
||||
final results = await _authProvider.getSewaAsetByStatus([
|
||||
'MENUNGGU PEMBAYARAN',
|
||||
'PEMBAYARANAN DENDA',
|
||||
]);
|
||||
activeBills.value = results;
|
||||
} catch (e) {
|
||||
print('Error loading unpaid rentals: $e');
|
||||
}
|
||||
}
|
||||
}
|
710
lib/app/modules/warga/controllers/warga_sewa_controller.dart
Normal file
710
lib/app/modules/warga/controllers/warga_sewa_controller.dart
Normal file
@ -0,0 +1,710 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../../../routes/app_routes.dart';
|
||||
import '../../../services/navigation_service.dart';
|
||||
import '../../../data/providers/auth_provider.dart';
|
||||
import '../../../data/providers/aset_provider.dart';
|
||||
|
||||
class WargaSewaController extends GetxController
|
||||
with GetSingleTickerProviderStateMixin {
|
||||
late TabController tabController;
|
||||
|
||||
// Get navigation service
|
||||
final NavigationService navigationService = Get.find<NavigationService>();
|
||||
|
||||
// Get auth provider for user data and sewa_aset queries
|
||||
final AuthProvider authProvider = Get.find<AuthProvider>();
|
||||
|
||||
// Get aset provider for asset data
|
||||
final AsetProvider asetProvider = Get.find<AsetProvider>();
|
||||
|
||||
// Observable lists for different rental statuses
|
||||
final rentals = <Map<String, dynamic>>[].obs;
|
||||
final pendingRentals = <Map<String, dynamic>>[].obs;
|
||||
final acceptedRentals = <Map<String, dynamic>>[].obs;
|
||||
final completedRentals = <Map<String, dynamic>>[].obs;
|
||||
final cancelledRentals = <Map<String, dynamic>>[].obs;
|
||||
|
||||
// Loading states
|
||||
final isLoading = false.obs;
|
||||
final isLoadingPending = false.obs;
|
||||
final isLoadingAccepted = false.obs;
|
||||
final isLoadingCompleted = false.obs;
|
||||
final isLoadingCancelled = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
// Ensure tab index is set to Sewa (1)
|
||||
navigationService.setNavIndex(1);
|
||||
|
||||
// Initialize tab controller with 6 tabs
|
||||
tabController = TabController(length: 6, vsync: this);
|
||||
|
||||
// Set initial tab and ensure tab view is updated
|
||||
tabController.index = 0;
|
||||
|
||||
// Load real rental data for all tabs
|
||||
loadRentalsData();
|
||||
loadPendingRentals();
|
||||
loadAcceptedRentals();
|
||||
loadCompletedRentals();
|
||||
loadCancelledRentals();
|
||||
|
||||
// Listen to tab changes to update state if needed
|
||||
tabController.addListener(() {
|
||||
// Update selected tab index when changed via swipe
|
||||
final int currentIndex = tabController.index;
|
||||
debugPrint('Tab changed to index: $currentIndex');
|
||||
|
||||
// Load data for the selected tab if not already loaded
|
||||
switch (currentIndex) {
|
||||
case 0: // Belum Bayar
|
||||
if (rentals.isEmpty && !isLoading.value) {
|
||||
loadRentalsData();
|
||||
}
|
||||
break;
|
||||
case 1: // Pending
|
||||
if (pendingRentals.isEmpty && !isLoadingPending.value) {
|
||||
loadPendingRentals();
|
||||
}
|
||||
break;
|
||||
case 2: // Diterima
|
||||
if (acceptedRentals.isEmpty && !isLoadingAccepted.value) {
|
||||
loadAcceptedRentals();
|
||||
}
|
||||
break;
|
||||
case 3: // Aktif
|
||||
// Add Aktif tab logic when needed
|
||||
break;
|
||||
case 4: // Selesai
|
||||
if (completedRentals.isEmpty && !isLoadingCompleted.value) {
|
||||
loadCompletedRentals();
|
||||
}
|
||||
break;
|
||||
case 5: // Dibatalkan
|
||||
if (cancelledRentals.isEmpty && !isLoadingCancelled.value) {
|
||||
loadCancelledRentals();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
// Ensure nav index is set to Sewa (1) when the controller is ready
|
||||
// This helps maintain correct state during hot reload
|
||||
navigationService.setNavIndex(1);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
tabController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
// Load real data from sewa_aset table
|
||||
Future<void> loadRentalsData() async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
// Clear existing data
|
||||
rentals.clear();
|
||||
|
||||
// Get sewa_aset data with status "MENUNGGU PEMBAYARAN" or "PEMBAYARAN DENDA"
|
||||
final sewaAsetList = await authProvider.getSewaAsetByStatus([
|
||||
'MENUNGGU PEMBAYARAN',
|
||||
'PEMBAYARAN DENDA'
|
||||
]);
|
||||
|
||||
debugPrint('Fetched ${sewaAsetList.length} sewa_aset records');
|
||||
|
||||
// Process each sewa_aset record
|
||||
for (var sewaAset in sewaAsetList) {
|
||||
// Get asset details if aset_id is available
|
||||
String assetName = 'Aset';
|
||||
String? imageUrl;
|
||||
String namaSatuanWaktu = sewaAset['nama_satuan_waktu'] ?? 'jam';
|
||||
|
||||
if (sewaAset['aset_id'] != null) {
|
||||
final asetData = await asetProvider.getAsetById(sewaAset['aset_id']);
|
||||
if (asetData != null) {
|
||||
assetName = asetData.nama;
|
||||
imageUrl = asetData.imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse waktu mulai and waktu selesai
|
||||
DateTime? waktuMulai;
|
||||
DateTime? waktuSelesai;
|
||||
String waktuSewa = '';
|
||||
String tanggalSewa = '';
|
||||
String jamMulai = '';
|
||||
String jamSelesai = '';
|
||||
String rentangWaktu = '';
|
||||
|
||||
if (sewaAset['waktu_mulai'] != null && sewaAset['waktu_selesai'] != null) {
|
||||
waktuMulai = DateTime.parse(sewaAset['waktu_mulai']);
|
||||
waktuSelesai = DateTime.parse(sewaAset['waktu_selesai']);
|
||||
|
||||
// Format for display
|
||||
final formatTanggal = DateFormat('dd-MM-yyyy');
|
||||
final formatWaktu = DateFormat('HH:mm');
|
||||
final formatTanggalLengkap = DateFormat('dd MMMM yyyy', 'id_ID');
|
||||
|
||||
tanggalSewa = formatTanggalLengkap.format(waktuMulai);
|
||||
jamMulai = formatWaktu.format(waktuMulai);
|
||||
jamSelesai = formatWaktu.format(waktuSelesai);
|
||||
|
||||
// Format based on satuan waktu
|
||||
if (namaSatuanWaktu.toLowerCase() == 'jam') {
|
||||
// For hours, show time range on same day
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
} else if (namaSatuanWaktu.toLowerCase() == 'hari') {
|
||||
// For days, show date range
|
||||
final tanggalMulai = formatTanggalLengkap.format(waktuMulai);
|
||||
final tanggalSelesai = formatTanggalLengkap.format(waktuSelesai);
|
||||
rentangWaktu = '$tanggalMulai - $tanggalSelesai';
|
||||
} else {
|
||||
// Default format
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
}
|
||||
|
||||
// Full time format for waktuSewa
|
||||
waktuSewa = '${formatTanggal.format(waktuMulai)} | ${formatWaktu.format(waktuMulai)} - '
|
||||
'${formatTanggal.format(waktuSelesai)} | ${formatWaktu.format(waktuSelesai)}';
|
||||
}
|
||||
|
||||
// Format price
|
||||
String totalPrice = 'Rp 0';
|
||||
if (sewaAset['total'] != null) {
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
totalPrice = formatter.format(sewaAset['total']);
|
||||
}
|
||||
|
||||
// Add to rentals list
|
||||
rentals.add({
|
||||
'id': sewaAset['id'] ?? '',
|
||||
'name': assetName,
|
||||
'imageUrl': imageUrl ?? 'assets/images/gambar_pendukung.jpg',
|
||||
'jumlahUnit': sewaAset['kuantitas'] ?? 0,
|
||||
'waktuSewa': waktuSewa,
|
||||
'duration': '${sewaAset['durasi'] ?? 0} ${namaSatuanWaktu}',
|
||||
'status': sewaAset['status'] ?? 'MENUNGGU PEMBAYARAN',
|
||||
'totalPrice': totalPrice,
|
||||
'countdown': '00:59:59', // Default countdown
|
||||
'tanggalSewa': tanggalSewa,
|
||||
'jamMulai': jamMulai,
|
||||
'jamSelesai': jamSelesai,
|
||||
'rentangWaktu': rentangWaktu,
|
||||
'namaSatuanWaktu': namaSatuanWaktu,
|
||||
'waktuMulai': sewaAset['waktu_mulai'],
|
||||
'waktuSelesai': sewaAset['waktu_selesai'],
|
||||
});
|
||||
}
|
||||
|
||||
debugPrint('Processed ${rentals.length} rental records');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading rentals data: $e');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
void navigateToRentals() {
|
||||
navigationService.toSewaAset();
|
||||
}
|
||||
|
||||
void onNavItemTapped(int index) {
|
||||
if (navigationService.currentNavIndex.value == index) return;
|
||||
|
||||
navigationService.setNavIndex(index);
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
// Navigate to Home
|
||||
Get.offNamed(Routes.WARGA_DASHBOARD);
|
||||
break;
|
||||
case 1:
|
||||
// Already on Sewa tab
|
||||
break;
|
||||
case 2:
|
||||
// Navigate to Langganan
|
||||
Get.offNamed(Routes.LANGGANAN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
void cancelRental(String id) {
|
||||
Get.snackbar(
|
||||
'Info',
|
||||
'Pembatalan berhasil',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
|
||||
// Navigate to payment page with the selected rental data
|
||||
void viewRentalDetail(Map<String, dynamic> rental) {
|
||||
debugPrint('Navigating to payment page with rental ID: ${rental['id']}');
|
||||
|
||||
// Navigate to payment page with rental data
|
||||
Get.toNamed(
|
||||
Routes.PEMBAYARAN_SEWA,
|
||||
arguments: {
|
||||
'orderId': rental['id'],
|
||||
'rentalData': rental,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void payRental(String id) {
|
||||
Get.snackbar(
|
||||
'Info',
|
||||
'Navigasi ke halaman pembayaran',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
|
||||
// Load data for the Selesai tab (status: SELESAI)
|
||||
Future<void> loadCompletedRentals() async {
|
||||
try {
|
||||
isLoadingCompleted.value = true;
|
||||
|
||||
// Clear existing data
|
||||
completedRentals.clear();
|
||||
|
||||
// Get sewa_aset data with status "SELESAI"
|
||||
final sewaAsetList = await authProvider.getSewaAsetByStatus(['SELESAI']);
|
||||
|
||||
debugPrint('Fetched ${sewaAsetList.length} completed sewa_aset records');
|
||||
|
||||
// Process each sewa_aset record
|
||||
for (var sewaAset in sewaAsetList) {
|
||||
// Get asset details if aset_id is available
|
||||
String assetName = 'Aset';
|
||||
String? imageUrl;
|
||||
String namaSatuanWaktu = sewaAset['nama_satuan_waktu'] ?? 'jam';
|
||||
|
||||
if (sewaAset['aset_id'] != null) {
|
||||
final asetData = await asetProvider.getAsetById(sewaAset['aset_id']);
|
||||
if (asetData != null) {
|
||||
assetName = asetData.nama;
|
||||
imageUrl = asetData.imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse waktu mulai and waktu selesai
|
||||
DateTime? waktuMulai;
|
||||
DateTime? waktuSelesai;
|
||||
String waktuSewa = '';
|
||||
String tanggalSewa = '';
|
||||
String jamMulai = '';
|
||||
String jamSelesai = '';
|
||||
String rentangWaktu = '';
|
||||
|
||||
if (sewaAset['waktu_mulai'] != null && sewaAset['waktu_selesai'] != null) {
|
||||
waktuMulai = DateTime.parse(sewaAset['waktu_mulai']);
|
||||
waktuSelesai = DateTime.parse(sewaAset['waktu_selesai']);
|
||||
|
||||
// Format for display
|
||||
final formatTanggal = DateFormat('dd-MM-yyyy');
|
||||
final formatWaktu = DateFormat('HH:mm');
|
||||
final formatTanggalLengkap = DateFormat('dd MMMM yyyy', 'id_ID');
|
||||
|
||||
tanggalSewa = formatTanggalLengkap.format(waktuMulai);
|
||||
jamMulai = formatWaktu.format(waktuMulai);
|
||||
jamSelesai = formatWaktu.format(waktuSelesai);
|
||||
|
||||
// Format based on satuan waktu
|
||||
if (namaSatuanWaktu.toLowerCase() == 'jam') {
|
||||
// For hours, show time range on same day
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
} else if (namaSatuanWaktu.toLowerCase() == 'hari') {
|
||||
// For days, show date range
|
||||
final tanggalMulai = formatTanggalLengkap.format(waktuMulai);
|
||||
final tanggalSelesai = formatTanggalLengkap.format(waktuSelesai);
|
||||
rentangWaktu = '$tanggalMulai - $tanggalSelesai';
|
||||
} else {
|
||||
// Default format
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
}
|
||||
|
||||
// Full time format for waktuSewa
|
||||
waktuSewa = '${formatTanggal.format(waktuMulai)} | ${formatWaktu.format(waktuMulai)} - '
|
||||
'${formatTanggal.format(waktuSelesai)} | ${formatWaktu.format(waktuSelesai)}';
|
||||
}
|
||||
|
||||
// Format price
|
||||
String totalPrice = 'Rp 0';
|
||||
if (sewaAset['total'] != null) {
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
totalPrice = formatter.format(sewaAset['total']);
|
||||
}
|
||||
|
||||
// Add to completed rentals list
|
||||
completedRentals.add({
|
||||
'id': sewaAset['id'] ?? '',
|
||||
'name': assetName,
|
||||
'imageUrl': imageUrl ?? 'assets/images/gambar_pendukung.jpg',
|
||||
'jumlahUnit': sewaAset['kuantitas'] ?? 0,
|
||||
'waktuSewa': waktuSewa,
|
||||
'duration': '${sewaAset['durasi'] ?? 0} ${namaSatuanWaktu}',
|
||||
'status': sewaAset['status'] ?? 'SELESAI',
|
||||
'totalPrice': totalPrice,
|
||||
'tanggalSewa': tanggalSewa,
|
||||
'jamMulai': jamMulai,
|
||||
'jamSelesai': jamSelesai,
|
||||
'rentangWaktu': rentangWaktu,
|
||||
'namaSatuanWaktu': namaSatuanWaktu,
|
||||
'waktuMulai': sewaAset['waktu_mulai'],
|
||||
'waktuSelesai': sewaAset['waktu_selesai'],
|
||||
});
|
||||
}
|
||||
|
||||
debugPrint('Processed ${completedRentals.length} completed rental records');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading completed rentals data: $e');
|
||||
} finally {
|
||||
isLoadingCompleted.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Load data for the Dibatalkan tab (status: DIBATALKAN)
|
||||
Future<void> loadCancelledRentals() async {
|
||||
try {
|
||||
isLoadingCancelled.value = true;
|
||||
|
||||
// Clear existing data
|
||||
cancelledRentals.clear();
|
||||
|
||||
// Get sewa_aset data with status "DIBATALKAN"
|
||||
final sewaAsetList = await authProvider.getSewaAsetByStatus(['DIBATALKAN']);
|
||||
|
||||
debugPrint('Fetched ${sewaAsetList.length} cancelled sewa_aset records');
|
||||
|
||||
// Process each sewa_aset record
|
||||
for (var sewaAset in sewaAsetList) {
|
||||
// Get asset details if aset_id is available
|
||||
String assetName = 'Aset';
|
||||
String? imageUrl;
|
||||
String namaSatuanWaktu = sewaAset['nama_satuan_waktu'] ?? 'jam';
|
||||
|
||||
if (sewaAset['aset_id'] != null) {
|
||||
final asetData = await asetProvider.getAsetById(sewaAset['aset_id']);
|
||||
if (asetData != null) {
|
||||
assetName = asetData.nama;
|
||||
imageUrl = asetData.imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse waktu mulai and waktu selesai
|
||||
DateTime? waktuMulai;
|
||||
DateTime? waktuSelesai;
|
||||
String waktuSewa = '';
|
||||
String tanggalSewa = '';
|
||||
String jamMulai = '';
|
||||
String jamSelesai = '';
|
||||
String rentangWaktu = '';
|
||||
|
||||
if (sewaAset['waktu_mulai'] != null && sewaAset['waktu_selesai'] != null) {
|
||||
waktuMulai = DateTime.parse(sewaAset['waktu_mulai']);
|
||||
waktuSelesai = DateTime.parse(sewaAset['waktu_selesai']);
|
||||
|
||||
// Format for display
|
||||
final formatTanggal = DateFormat('dd-MM-yyyy');
|
||||
final formatWaktu = DateFormat('HH:mm');
|
||||
final formatTanggalLengkap = DateFormat('dd MMMM yyyy', 'id_ID');
|
||||
|
||||
tanggalSewa = formatTanggalLengkap.format(waktuMulai);
|
||||
jamMulai = formatWaktu.format(waktuMulai);
|
||||
jamSelesai = formatWaktu.format(waktuSelesai);
|
||||
|
||||
// Format based on satuan waktu
|
||||
if (namaSatuanWaktu.toLowerCase() == 'jam') {
|
||||
// For hours, show time range on same day
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
} else if (namaSatuanWaktu.toLowerCase() == 'hari') {
|
||||
// For days, show date range
|
||||
final tanggalMulai = formatTanggalLengkap.format(waktuMulai);
|
||||
final tanggalSelesai = formatTanggalLengkap.format(waktuSelesai);
|
||||
rentangWaktu = '$tanggalMulai - $tanggalSelesai';
|
||||
} else {
|
||||
// Default format
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
}
|
||||
|
||||
// Full time format for waktuSewa
|
||||
waktuSewa = '${formatTanggal.format(waktuMulai)} | ${formatWaktu.format(waktuMulai)} - '
|
||||
'${formatTanggal.format(waktuSelesai)} | ${formatWaktu.format(waktuSelesai)}';
|
||||
}
|
||||
|
||||
// Format price
|
||||
String totalPrice = 'Rp 0';
|
||||
if (sewaAset['total'] != null) {
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
totalPrice = formatter.format(sewaAset['total']);
|
||||
}
|
||||
|
||||
// Add to cancelled rentals list
|
||||
cancelledRentals.add({
|
||||
'id': sewaAset['id'] ?? '',
|
||||
'name': assetName,
|
||||
'imageUrl': imageUrl ?? 'assets/images/gambar_pendukung.jpg',
|
||||
'jumlahUnit': sewaAset['kuantitas'] ?? 0,
|
||||
'waktuSewa': waktuSewa,
|
||||
'duration': '${sewaAset['durasi'] ?? 0} ${namaSatuanWaktu}',
|
||||
'status': sewaAset['status'] ?? 'DIBATALKAN',
|
||||
'totalPrice': totalPrice,
|
||||
'tanggalSewa': tanggalSewa,
|
||||
'jamMulai': jamMulai,
|
||||
'jamSelesai': jamSelesai,
|
||||
'rentangWaktu': rentangWaktu,
|
||||
'namaSatuanWaktu': namaSatuanWaktu,
|
||||
'waktuMulai': sewaAset['waktu_mulai'],
|
||||
'waktuSelesai': sewaAset['waktu_selesai'],
|
||||
'alasanPembatalan': sewaAset['alasan_pembatalan'] ?? '-',
|
||||
});
|
||||
}
|
||||
|
||||
debugPrint('Processed ${cancelledRentals.length} cancelled rental records');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading cancelled rentals data: $e');
|
||||
} finally {
|
||||
isLoadingCancelled.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Load data for the Pending tab (status: PERIKSA PEMBAYARAN)
|
||||
Future<void> loadPendingRentals() async {
|
||||
try {
|
||||
isLoadingPending.value = true;
|
||||
|
||||
// Clear existing data
|
||||
pendingRentals.clear();
|
||||
|
||||
// Get sewa_aset data with status "PERIKSA PEMBAYARAN"
|
||||
final sewaAsetList = await authProvider.getSewaAsetByStatus(['PERIKSA PEMBAYARAN']);
|
||||
|
||||
debugPrint('Fetched ${sewaAsetList.length} pending sewa_aset records');
|
||||
|
||||
// Process each sewa_aset record
|
||||
for (var sewaAset in sewaAsetList) {
|
||||
// Get asset details if aset_id is available
|
||||
String assetName = 'Aset';
|
||||
String? imageUrl;
|
||||
String namaSatuanWaktu = sewaAset['nama_satuan_waktu'] ?? 'jam';
|
||||
|
||||
if (sewaAset['aset_id'] != null) {
|
||||
final asetData = await asetProvider.getAsetById(sewaAset['aset_id']);
|
||||
if (asetData != null) {
|
||||
assetName = asetData.nama;
|
||||
imageUrl = asetData.imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse waktu mulai and waktu selesai
|
||||
DateTime? waktuMulai;
|
||||
DateTime? waktuSelesai;
|
||||
String waktuSewa = '';
|
||||
String tanggalSewa = '';
|
||||
String jamMulai = '';
|
||||
String jamSelesai = '';
|
||||
String rentangWaktu = '';
|
||||
|
||||
if (sewaAset['waktu_mulai'] != null && sewaAset['waktu_selesai'] != null) {
|
||||
waktuMulai = DateTime.parse(sewaAset['waktu_mulai']);
|
||||
waktuSelesai = DateTime.parse(sewaAset['waktu_selesai']);
|
||||
|
||||
// Format for display
|
||||
final formatTanggal = DateFormat('dd-MM-yyyy');
|
||||
final formatWaktu = DateFormat('HH:mm');
|
||||
final formatTanggalLengkap = DateFormat('dd MMMM yyyy', 'id_ID');
|
||||
|
||||
tanggalSewa = formatTanggalLengkap.format(waktuMulai);
|
||||
jamMulai = formatWaktu.format(waktuMulai);
|
||||
jamSelesai = formatWaktu.format(waktuSelesai);
|
||||
|
||||
// Format based on satuan waktu
|
||||
if (namaSatuanWaktu.toLowerCase() == 'jam') {
|
||||
// For hours, show time range on same day
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
} else if (namaSatuanWaktu.toLowerCase() == 'hari') {
|
||||
// For days, show date range
|
||||
final tanggalMulai = formatTanggalLengkap.format(waktuMulai);
|
||||
final tanggalSelesai = formatTanggalLengkap.format(waktuSelesai);
|
||||
rentangWaktu = '$tanggalMulai - $tanggalSelesai';
|
||||
} else {
|
||||
// Default format
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
}
|
||||
|
||||
// Full time format for waktuSewa
|
||||
waktuSewa = '${formatTanggal.format(waktuMulai)} | ${formatWaktu.format(waktuMulai)} - '
|
||||
'${formatTanggal.format(waktuSelesai)} | ${formatWaktu.format(waktuSelesai)}';
|
||||
}
|
||||
|
||||
// Format price
|
||||
String totalPrice = 'Rp 0';
|
||||
if (sewaAset['total'] != null) {
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
totalPrice = formatter.format(sewaAset['total']);
|
||||
}
|
||||
|
||||
// Add to pending rentals list
|
||||
pendingRentals.add({
|
||||
'id': sewaAset['id'] ?? '',
|
||||
'name': assetName,
|
||||
'imageUrl': imageUrl ?? 'assets/images/gambar_pendukung.jpg',
|
||||
'jumlahUnit': sewaAset['kuantitas'] ?? 0,
|
||||
'waktuSewa': waktuSewa,
|
||||
'duration': '${sewaAset['durasi'] ?? 0} ${namaSatuanWaktu}',
|
||||
'status': sewaAset['status'] ?? 'PERIKSA PEMBAYARAN',
|
||||
'totalPrice': totalPrice,
|
||||
'tanggalSewa': tanggalSewa,
|
||||
'jamMulai': jamMulai,
|
||||
'jamSelesai': jamSelesai,
|
||||
'rentangWaktu': rentangWaktu,
|
||||
'namaSatuanWaktu': namaSatuanWaktu,
|
||||
'waktuMulai': sewaAset['waktu_mulai'],
|
||||
'waktuSelesai': sewaAset['waktu_selesai'],
|
||||
});
|
||||
}
|
||||
|
||||
debugPrint('Processed ${pendingRentals.length} pending rental records');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading pending rentals data: $e');
|
||||
} finally {
|
||||
isLoadingPending.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Load data for the Diterima tab (status: DITERIMA)
|
||||
Future<void> loadAcceptedRentals() async {
|
||||
try {
|
||||
isLoadingAccepted.value = true;
|
||||
|
||||
// Clear existing data
|
||||
acceptedRentals.clear();
|
||||
|
||||
// Get sewa_aset data with status "DITERIMA"
|
||||
final sewaAsetList = await authProvider.getSewaAsetByStatus(['DITERIMA']);
|
||||
|
||||
debugPrint('Fetched ${sewaAsetList.length} accepted sewa_aset records');
|
||||
|
||||
// Process each sewa_aset record
|
||||
for (var sewaAset in sewaAsetList) {
|
||||
// Get asset details if aset_id is available
|
||||
String assetName = 'Aset';
|
||||
String? imageUrl;
|
||||
String namaSatuanWaktu = sewaAset['nama_satuan_waktu'] ?? 'jam';
|
||||
|
||||
if (sewaAset['aset_id'] != null) {
|
||||
final asetData = await asetProvider.getAsetById(sewaAset['aset_id']);
|
||||
if (asetData != null) {
|
||||
assetName = asetData.nama;
|
||||
imageUrl = asetData.imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse waktu mulai and waktu selesai
|
||||
DateTime? waktuMulai;
|
||||
DateTime? waktuSelesai;
|
||||
String waktuSewa = '';
|
||||
String tanggalSewa = '';
|
||||
String jamMulai = '';
|
||||
String jamSelesai = '';
|
||||
String rentangWaktu = '';
|
||||
|
||||
if (sewaAset['waktu_mulai'] != null && sewaAset['waktu_selesai'] != null) {
|
||||
waktuMulai = DateTime.parse(sewaAset['waktu_mulai']);
|
||||
waktuSelesai = DateTime.parse(sewaAset['waktu_selesai']);
|
||||
|
||||
// Format for display
|
||||
final formatTanggal = DateFormat('dd-MM-yyyy');
|
||||
final formatWaktu = DateFormat('HH:mm');
|
||||
final formatTanggalLengkap = DateFormat('dd MMMM yyyy', 'id_ID');
|
||||
|
||||
tanggalSewa = formatTanggalLengkap.format(waktuMulai);
|
||||
jamMulai = formatWaktu.format(waktuMulai);
|
||||
jamSelesai = formatWaktu.format(waktuSelesai);
|
||||
|
||||
// Format based on satuan waktu
|
||||
if (namaSatuanWaktu.toLowerCase() == 'jam') {
|
||||
// For hours, show time range on same day
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
} else if (namaSatuanWaktu.toLowerCase() == 'hari') {
|
||||
// For days, show date range
|
||||
final tanggalMulai = formatTanggalLengkap.format(waktuMulai);
|
||||
final tanggalSelesai = formatTanggalLengkap.format(waktuSelesai);
|
||||
rentangWaktu = '$tanggalMulai - $tanggalSelesai';
|
||||
} else {
|
||||
// Default format
|
||||
rentangWaktu = '$jamMulai - $jamSelesai';
|
||||
}
|
||||
|
||||
// Full time format for waktuSewa
|
||||
waktuSewa = '${formatTanggal.format(waktuMulai)} | ${formatWaktu.format(waktuMulai)} - '
|
||||
'${formatTanggal.format(waktuSelesai)} | ${formatWaktu.format(waktuSelesai)}';
|
||||
}
|
||||
|
||||
// Format price
|
||||
String totalPrice = 'Rp 0';
|
||||
if (sewaAset['total'] != null) {
|
||||
final formatter = NumberFormat.currency(
|
||||
locale: 'id',
|
||||
symbol: 'Rp ',
|
||||
decimalDigits: 0,
|
||||
);
|
||||
totalPrice = formatter.format(sewaAset['total']);
|
||||
}
|
||||
|
||||
// Add to accepted rentals list
|
||||
acceptedRentals.add({
|
||||
'id': sewaAset['id'] ?? '',
|
||||
'name': assetName,
|
||||
'imageUrl': imageUrl ?? 'assets/images/gambar_pendukung.jpg',
|
||||
'jumlahUnit': sewaAset['kuantitas'] ?? 0,
|
||||
'waktuSewa': waktuSewa,
|
||||
'duration': '${sewaAset['durasi'] ?? 0} ${namaSatuanWaktu}',
|
||||
'status': sewaAset['status'] ?? 'DITERIMA',
|
||||
'totalPrice': totalPrice,
|
||||
'tanggalSewa': tanggalSewa,
|
||||
'jamMulai': jamMulai,
|
||||
'jamSelesai': jamSelesai,
|
||||
'rentangWaktu': rentangWaktu,
|
||||
'namaSatuanWaktu': namaSatuanWaktu,
|
||||
'waktuMulai': sewaAset['waktu_mulai'],
|
||||
'waktuSelesai': sewaAset['waktu_selesai'],
|
||||
});
|
||||
}
|
||||
|
||||
debugPrint('Processed ${acceptedRentals.length} accepted rental records');
|
||||
} catch (e) {
|
||||
debugPrint('Error loading accepted rentals data: $e');
|
||||
} finally {
|
||||
isLoadingAccepted.value = false;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user