129 lines
4.3 KiB
Dart
129 lines
4.3 KiB
Dart
import 'package:get/get.dart';
|
|
import 'package:marco/helpers/services/api_service.dart';
|
|
import 'package:marco/model/finance/payment_request_list_model.dart';
|
|
import 'package:marco/model/finance/payment_request_filter.dart';
|
|
import 'package:marco/helpers/services/app_logger.dart';
|
|
|
|
class PaymentRequestController extends GetxController {
|
|
// ---------------- Observables ----------------
|
|
final RxList<PaymentRequest> paymentRequests = <PaymentRequest>[].obs;
|
|
final RxBool isLoading = false.obs;
|
|
final RxString errorMessage = ''.obs;
|
|
final RxBool isFilterApplied = false.obs;
|
|
|
|
// ---------------- Pagination ----------------
|
|
int _pageSize = 20;
|
|
int _pageNumber = 1;
|
|
bool _hasMoreData = true;
|
|
|
|
// ---------------- Filters ----------------
|
|
RxMap<String, dynamic> appliedFilter = <String, dynamic>{}.obs;
|
|
RxString searchString = ''.obs;
|
|
|
|
// ---------------- Filter Options ----------------
|
|
RxList<IdNameModel> projects = <IdNameModel>[].obs;
|
|
RxList<IdNameModel> payees = <IdNameModel>[].obs;
|
|
RxList<IdNameModel> categories = <IdNameModel>[].obs;
|
|
RxList<IdNameModel> currencies = <IdNameModel>[].obs;
|
|
RxList<IdNameModel> statuses = <IdNameModel>[].obs;
|
|
RxList<IdNameModel> createdBy = <IdNameModel>[].obs;
|
|
|
|
// ---------------- Fetch Filter Options ----------------
|
|
Future<void> fetchPaymentRequestFilterOptions() async {
|
|
try {
|
|
final response = await ApiService.getExpensePaymentRequestFilterApi();
|
|
if (response != null) {
|
|
projects.assignAll(response.data.projects);
|
|
payees.assignAll(response.data.payees);
|
|
categories.assignAll(response.data.expenseCategory);
|
|
currencies.assignAll(response.data.currency);
|
|
statuses.assignAll(response.data.status);
|
|
createdBy.assignAll(response.data.createdBy);
|
|
} else {
|
|
logSafe("Payment request filter API returned null",
|
|
level: LogLevel.warning);
|
|
}
|
|
} catch (e, stack) {
|
|
logSafe("Exception in fetchPaymentRequestFilterOptions: $e",
|
|
level: LogLevel.error);
|
|
logSafe("StackTrace: $stack", level: LogLevel.debug);
|
|
}
|
|
}
|
|
|
|
// ---------------- Fetch Payment Requests ----------------
|
|
Future<void> fetchPaymentRequests({int pageSize = 20}) async {
|
|
isLoading.value = true;
|
|
errorMessage.value = '';
|
|
_pageNumber = 1;
|
|
_pageSize = pageSize;
|
|
_hasMoreData = true;
|
|
paymentRequests.clear();
|
|
|
|
await _fetchPaymentRequestsFromApi();
|
|
isLoading.value = false;
|
|
}
|
|
|
|
// ---------------- Load More ----------------
|
|
Future<void> loadMorePaymentRequests() async {
|
|
if (isLoading.value || !_hasMoreData) return;
|
|
|
|
_pageNumber += 1;
|
|
isLoading.value = true;
|
|
|
|
await _fetchPaymentRequestsFromApi();
|
|
isLoading.value = false;
|
|
}
|
|
|
|
// ---------------- Internal API Call ----------------
|
|
Future<void> _fetchPaymentRequestsFromApi() async {
|
|
try {
|
|
final response = await ApiService.getExpensePaymentRequestListApi(
|
|
pageSize: _pageSize,
|
|
pageNumber: _pageNumber,
|
|
filter: appliedFilter,
|
|
searchString: searchString.value,
|
|
);
|
|
|
|
if (response != null && response.data.data.isNotEmpty) {
|
|
if (_pageNumber == 1) {
|
|
// First page, replace the list
|
|
paymentRequests.assignAll(response.data.data);
|
|
} else {
|
|
// Insert new data at the top for latest first
|
|
paymentRequests.insertAll(0, response.data.data);
|
|
}
|
|
} else {
|
|
if (_pageNumber == 1) {
|
|
errorMessage.value = 'No payment requests found.';
|
|
} else {
|
|
_hasMoreData = false;
|
|
}
|
|
}
|
|
} catch (e, stack) {
|
|
errorMessage.value = 'Failed to fetch payment requests.';
|
|
logSafe("Exception in _fetchPaymentRequestsFromApi: $e",
|
|
level: LogLevel.error);
|
|
logSafe("StackTrace: $stack", level: LogLevel.debug);
|
|
}
|
|
}
|
|
|
|
// ---------------- Filter Management ----------------
|
|
void setFilterApplied(bool applied) {
|
|
isFilterApplied.value = applied;
|
|
}
|
|
|
|
void applyFilter(Map<String, dynamic> filter, {String search = ''}) {
|
|
appliedFilter.assignAll(filter);
|
|
searchString.value = search;
|
|
isFilterApplied.value = filter.isNotEmpty || search.isNotEmpty;
|
|
fetchPaymentRequests();
|
|
}
|
|
|
|
void clearFilter() {
|
|
appliedFilter.clear();
|
|
searchString.value = '';
|
|
isFilterApplied.value = false;
|
|
fetchPaymentRequests();
|
|
}
|
|
}
|