275 lines
7.7 KiB
Dart
275 lines
7.7 KiB
Dart
import 'package:get/get.dart';
|
|
import '../models/payment.dart';
|
|
import 'api_service.dart';
|
|
|
|
class PaymentService extends GetxController {
|
|
static PaymentService get to => Get.find();
|
|
|
|
final ApiService _apiService = ApiService();
|
|
|
|
// Observable state
|
|
final RxList<Payment> _payments = <Payment>[].obs;
|
|
final RxBool _isLoading = false.obs;
|
|
final RxString _error = ''.obs;
|
|
final RxMap<String, dynamic> _paymentSummary = <String, dynamic>{}.obs;
|
|
final RxList<Map<String, dynamic>> _pendingPayments = <Map<String, dynamic>>[].obs;
|
|
|
|
// Getters
|
|
List<Payment> get payments => _payments.toList();
|
|
bool get isLoading => _isLoading.value;
|
|
String get error => _error.value;
|
|
Map<String, dynamic> get paymentSummary => _paymentSummary;
|
|
List<Map<String, dynamic>> get pendingPayments => _pendingPayments.toList();
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_error.value = '';
|
|
}
|
|
|
|
// Record a payment
|
|
Future<bool> recordPayment({
|
|
required String groupId,
|
|
required String userId,
|
|
required int month,
|
|
required int year,
|
|
required double amount,
|
|
required String paymentMethod,
|
|
String? transactionId,
|
|
String? notes,
|
|
}) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final response = await _apiService.recordPayment({
|
|
'group_id': groupId,
|
|
'user_id': userId,
|
|
'month': month,
|
|
'year': year,
|
|
'amount': amount.toStringAsFixed(2),
|
|
'payment_method': paymentMethod,
|
|
'transaction_id': transactionId,
|
|
'notes': notes,
|
|
});
|
|
|
|
if (response['success'] == true) {
|
|
// Add the new payment to the list
|
|
final payment = Payment.fromJson(response['data']);
|
|
_payments.add(payment);
|
|
|
|
// Refresh pending payments
|
|
await loadPendingPayments(groupId);
|
|
|
|
return true;
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to record payment';
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
print('Record payment error: $e');
|
|
_error.value = 'Failed to record payment: $e';
|
|
return false;
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Load payments for a group
|
|
Future<void> loadGroupPayments(String groupId, {
|
|
String? status,
|
|
int? month,
|
|
int? year,
|
|
int page = 1,
|
|
int limit = 20,
|
|
}) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final queryParams = <String, dynamic>{
|
|
'page': page.toString(),
|
|
'limit': limit.toString(),
|
|
};
|
|
|
|
if (status != null) queryParams['status'] = status;
|
|
if (month != null) queryParams['month'] = month.toString();
|
|
if (year != null) queryParams['year'] = year.toString();
|
|
|
|
final response = await _apiService.getGroupPayments(
|
|
groupId,
|
|
status: status,
|
|
month: month,
|
|
year: year,
|
|
page: page,
|
|
limit: limit,
|
|
);
|
|
|
|
if (response['success'] == true) {
|
|
final paymentsData = response['data']['payments'] as List;
|
|
_payments.value = paymentsData.map((json) => Payment.fromJson(json)).toList();
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to load payments';
|
|
}
|
|
} catch (e) {
|
|
print('Load group payments error: $e');
|
|
_error.value = 'Failed to load payments: $e';
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Load payments for a specific member
|
|
Future<void> loadMemberPayments(String groupId, String memberId, {
|
|
String? status,
|
|
int page = 1,
|
|
int limit = 20,
|
|
}) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final queryParams = <String, dynamic>{
|
|
'page': page.toString(),
|
|
'limit': limit.toString(),
|
|
};
|
|
|
|
if (status != null) queryParams['status'] = status;
|
|
|
|
final response = await _apiService.getMemberPayments(
|
|
groupId,
|
|
memberId,
|
|
status: status,
|
|
page: page,
|
|
limit: limit,
|
|
);
|
|
|
|
if (response['success'] == true) {
|
|
final paymentsData = response['data']['payments'] as List;
|
|
_payments.value = paymentsData.map((json) => Payment.fromJson(json)).toList();
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to load member payments';
|
|
}
|
|
} catch (e) {
|
|
print('Load member payments error: $e');
|
|
_error.value = 'Failed to load member payments: $e';
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Update payment status
|
|
Future<bool> updatePaymentStatus(String paymentId, String status, {String? notes}) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final response = await _apiService.updatePaymentStatus(paymentId, status, notes: notes);
|
|
|
|
if (response['success'] == true) {
|
|
// Update the payment in the list
|
|
final updatedPayment = Payment.fromJson(response['data']);
|
|
final index = _payments.indexWhere((p) => p.id == paymentId);
|
|
if (index != -1) {
|
|
_payments[index] = updatedPayment;
|
|
}
|
|
return true;
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to update payment status';
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
print('Update payment status error: $e');
|
|
_error.value = 'Failed to update payment status: $e';
|
|
return false;
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Load payment summary for a group
|
|
Future<void> loadPaymentSummary(String groupId) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final response = await _apiService.getGroupPaymentSummary(groupId);
|
|
|
|
if (response['success'] == true) {
|
|
_paymentSummary.value = response['data'];
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to load payment summary';
|
|
}
|
|
} catch (e) {
|
|
print('Load payment summary error: $e');
|
|
_error.value = 'Failed to load payment summary: $e';
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Load pending payments for a group
|
|
Future<void> loadPendingPayments(String groupId) async {
|
|
try {
|
|
_isLoading.value = true;
|
|
_error.value = '';
|
|
|
|
final response = await _apiService.getPendingPayments(groupId);
|
|
|
|
if (response['success'] == true) {
|
|
_pendingPayments.value = List<Map<String, dynamic>>.from(response['data']['pending_payments']);
|
|
} else {
|
|
_error.value = response['message'] ?? 'Failed to load pending payments';
|
|
}
|
|
} catch (e) {
|
|
print('Load pending payments error: $e');
|
|
_error.value = 'Failed to load pending payments: $e';
|
|
} finally {
|
|
_isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// Clear error
|
|
void clearError() {
|
|
_error.value = '';
|
|
}
|
|
|
|
// Clear payments
|
|
void clearPayments() {
|
|
_payments.clear();
|
|
}
|
|
|
|
// Helper methods
|
|
List<Payment> getPaymentsByStatus(String status) {
|
|
return _payments.where((payment) => payment.status == status).toList();
|
|
}
|
|
|
|
List<Payment> getPaymentsByMonth(int month, int year) {
|
|
return _payments.where((payment) => payment.month == month && payment.year == year).toList();
|
|
}
|
|
|
|
double getTotalAmountByStatus(String status) {
|
|
return _payments
|
|
.where((payment) => payment.status == status)
|
|
.fold(0.0, (sum, payment) => sum + payment.amount);
|
|
}
|
|
|
|
// Get payment methods for dropdown
|
|
List<String> get paymentMethods => ['upi', 'bank_transfer', 'cash', 'cheque'];
|
|
|
|
String getPaymentMethodLabel(String method) {
|
|
switch (method) {
|
|
case 'upi':
|
|
return 'UPI';
|
|
case 'bank_transfer':
|
|
return 'Bank Transfer';
|
|
case 'cash':
|
|
return 'Cash';
|
|
case 'cheque':
|
|
return 'Cheque';
|
|
default:
|
|
return method.toUpperCase();
|
|
}
|
|
}
|
|
}
|