E41220983_MuhamadSugengCahy.../praresi/lib/presentation/controllers/home_controller.dart

132 lines
3.8 KiB
Dart

import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:get/get.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:intl/intl.dart';
import 'package:fl_chart/fl_chart.dart';
class DashboardController extends GetxController {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
var totalPendapatan = 0.0.obs;
var totalPendapatanCOD = 0.0.obs;
var totalPendapatanNonCOD = 0.0.obs;
var totalPaket = 0.obs;
var totalPaketCOD = 0.obs;
var totalPaketNonCOD = 0.obs;
var isLoading = false.obs;
var grafikPengiriman = <FlSpot>[].obs;
StreamSubscription? _listenerRealtime;
@override
void onInit() {
super.onInit();
_listenRealtimeData();
}
@override
void onClose() {
_listenerRealtime?.cancel();
super.onClose();
}
/// 🔁 Listener realtime dashboard & grafik
void _listenRealtimeData() {
final user = _auth.currentUser;
if (user == null) return;
final userId = user.uid;
// Pastikan urut berdasarkan waktu dibuat
_listenerRealtime = _firestore
.collection('resis')
.where('store_id', isEqualTo: userId)
.orderBy('created_at', descending: false)
.snapshots()
.listen((snapshot) {
_updateDashboard(snapshot.docs);
}, onError: (e) {
print("🔥 Error listen data: $e");
});
}
/// 🔹 Hitung ulang total dan grafik setiap ada perubahan data
void _updateDashboard(List<QueryDocumentSnapshot<Map<String, dynamic>>> docs) {
final now = DateTime.now();
final cutoff = now.subtract(const Duration(days: 6));
double total = 0;
double totalCod = 0;
double totalNonCod = 0;
int paket = 0;
int paketCod = 0;
int paketNonCod = 0;
Map<String, int> pengirimanPerTanggal = {};
for (var doc in docs) {
final data = doc.data();
if (data['created_at'] == null) continue;
final createdAt = (data['created_at'] as Timestamp).toDate().toLocal();
final tanggalKey = DateFormat('yyyy-MM-dd').format(createdAt);
// Total untuk hari ini
if (createdAt.year == now.year &&
createdAt.month == now.month &&
createdAt.day == now.day) {
final totalTransaksi = double.tryParse(data['total'].toString()) ?? 0;
final pembayaran = data['pembayaran']?.toString().toUpperCase() ?? '';
total += totalTransaksi;
paket++;
if (pembayaran == 'COD') {
paketCod++;
totalCod += totalTransaksi;
} else {
paketNonCod++;
totalNonCod += totalTransaksi;
}
}
// Total pengiriman 7 hari terakhir
if (!(createdAt.isBefore(cutoff) || createdAt.isAfter(now))) {
pengirimanPerTanggal.update(tanggalKey, (v) => v + 1,
ifAbsent: () => 1);
}
}
// 🔸 Update data observabel
totalPendapatan.value = total;
totalPendapatanCOD.value = totalCod;
totalPendapatanNonCOD.value = totalNonCod;
totalPaket.value = paket;
totalPaketCOD.value = paketCod;
totalPaketNonCOD.value = paketNonCod;
// 🔹 Buat data untuk 7 hari grafik
final List<FlSpot> newSpots = [];
for (int i = 0; i < 7; i++) {
final date = cutoff.add(Duration(days: i));
final key = DateFormat('yyyy-MM-dd').format(date);
final jumlah = pengirimanPerTanggal[key] ?? 0;
newSpots.add(FlSpot(i.toDouble(), jumlah.toDouble()));
}
// 🔸 Assign dan refresh supaya UI update langsung
grafikPengiriman.assignAll(newSpots);
grafikPengiriman.refresh();
print("📊 Dashboard & grafik diperbarui realtime (${DateTime.now()})");
}
String formatRupiah(double value) {
final format =
NumberFormat.currency(locale: 'id_ID', symbol: 'Rp ', decimalDigits: 0);
return format.format(value);
}
}