164 lines
5.0 KiB
Dart
164 lines
5.0 KiB
Dart
import 'package:get/get.dart';
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
class RiwayatBulananController extends GetxController {
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
final FirebaseAuth _auth = FirebaseAuth.instance;
|
|
|
|
var isLoading = false.obs;
|
|
var monthlySummary = <Map<String, dynamic>>[].obs;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
fetchMonthlySummary();
|
|
}
|
|
|
|
/// 🔹 Ambil ringkasan resi per bulan
|
|
Future<void> fetchMonthlySummary() async {
|
|
try {
|
|
isLoading.value = true;
|
|
monthlySummary.clear();
|
|
|
|
final user = _auth.currentUser;
|
|
if (user == null) return;
|
|
final userId = user.uid;
|
|
|
|
final snapshot = await _firestore
|
|
.collection('resis')
|
|
.where('store_id', isEqualTo: userId)
|
|
.get();
|
|
|
|
// 🔸 Kelompokkan data berdasarkan bulan & tahun
|
|
Map<String, Map<String, dynamic>> grouped = {};
|
|
|
|
for (var doc in snapshot.docs) {
|
|
final data = doc.data();
|
|
if (data['created_at'] == null) continue;
|
|
|
|
final createdAt = (data['created_at'] as Timestamp).toDate();
|
|
final monthKey = DateFormat('MMMM yyyy', 'id_ID').format(createdAt);
|
|
|
|
final pembayaran = (data['pembayaran'] ?? '').toString().toUpperCase();
|
|
final total = double.tryParse(data['total'].toString()) ?? 0;
|
|
|
|
if (!grouped.containsKey(monthKey)) {
|
|
grouped[monthKey] = {
|
|
'month': monthKey,
|
|
'rawDate': createdAt,
|
|
'total': 0,
|
|
'cod': 0,
|
|
'nonCod': 0,
|
|
'incomeCod': 0.0,
|
|
'incomeNonCod': 0.0,
|
|
};
|
|
}
|
|
|
|
grouped[monthKey]!['total'] += 1;
|
|
if (pembayaran == 'COD') {
|
|
grouped[monthKey]!['cod'] += 1;
|
|
grouped[monthKey]!['incomeCod'] += total;
|
|
} else {
|
|
grouped[monthKey]!['nonCod'] += 1;
|
|
grouped[monthKey]!['incomeNonCod'] += total;
|
|
}
|
|
}
|
|
|
|
// 🔸 Konversi ke List dan urutkan dari bulan terbaru
|
|
final sorted = grouped.values.toList()
|
|
..sort((a, b) => b['rawDate'].compareTo(a['rawDate']));
|
|
|
|
monthlySummary.assignAll(sorted);
|
|
} catch (e) {
|
|
print('Error fetchMonthlySummary: $e');
|
|
Get.snackbar('Error', 'Gagal mengambil data: $e');
|
|
monthlySummary.clear();
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
/// 🔹 Ambil pendapatan per bulan (COD & Non COD)
|
|
Future<Map<String, dynamic>> getPendapatanBulanan(String monthLabel) async {
|
|
try {
|
|
final user = _auth.currentUser;
|
|
if (user == null) return {};
|
|
|
|
final parsedMonth = DateFormat('MMMM yyyy', 'id_ID').parse(monthLabel);
|
|
final start = DateTime(parsedMonth.year, parsedMonth.month, 1);
|
|
final end =
|
|
DateTime(parsedMonth.year, parsedMonth.month + 1, 0, 23, 59, 59);
|
|
|
|
final snapshot = await _firestore
|
|
.collection('resis')
|
|
.where('store_id', isEqualTo: user.uid)
|
|
.where('created_at', isGreaterThanOrEqualTo: start)
|
|
.where('created_at', isLessThanOrEqualTo: end)
|
|
.get();
|
|
|
|
double codIncome = 0;
|
|
double nonCodIncome = 0;
|
|
|
|
for (var doc in snapshot.docs) {
|
|
final data = doc.data();
|
|
final pembayaran = (data['pembayaran'] ?? '').toString().toUpperCase();
|
|
final total = double.tryParse(data['total'].toString()) ?? 0;
|
|
|
|
if (pembayaran == 'COD') {
|
|
codIncome += total;
|
|
} else {
|
|
nonCodIncome += total;
|
|
}
|
|
}
|
|
|
|
return {
|
|
'cod': codIncome,
|
|
'nonCod': nonCodIncome,
|
|
};
|
|
} catch (e) {
|
|
print('Error getPendapatanBulanan: $e');
|
|
return {};
|
|
}
|
|
}
|
|
|
|
/// 🔹 Ambil semua resi di bulan tertentu
|
|
Future<List<Map<String, dynamic>>> fetchResiByMonth(String monthLabel) async {
|
|
try {
|
|
final user = _auth.currentUser;
|
|
if (user == null) return [];
|
|
|
|
final parsedMonth = DateFormat('MMMM yyyy', 'id_ID').parse(monthLabel);
|
|
final start = DateTime(parsedMonth.year, parsedMonth.month, 1);
|
|
final end =
|
|
DateTime(parsedMonth.year, parsedMonth.month + 1, 0, 23, 59, 59);
|
|
|
|
final snapshot = await _firestore
|
|
.collection('resis')
|
|
.where('store_id', isEqualTo: user.uid)
|
|
.where('created_at', isGreaterThanOrEqualTo: start)
|
|
.where('created_at', isLessThanOrEqualTo: end)
|
|
.orderBy('created_at', descending: true)
|
|
.get();
|
|
|
|
return snapshot.docs.map((doc) {
|
|
final data = doc.data();
|
|
return {
|
|
'resi_id': doc.id,
|
|
'penerima': data['penerima'] ?? '-',
|
|
'barang': data['barang'] ?? '-',
|
|
'alamat': data['alamat'] ?? '-',
|
|
'pembayaran': data['pembayaran'] ?? '-',
|
|
'no_wa': data['no_wa'] ?? '-',
|
|
'total': data['total'] ?? 0,
|
|
'created_at': data['created_at'],
|
|
};
|
|
}).toList();
|
|
} catch (e) {
|
|
print('Error fetchResiByMonth: $e');
|
|
return [];
|
|
}
|
|
}
|
|
}
|