marco.pms.mobileapp/lib/controller/expense/expense_detail_controller.dart
Vaibhav Surve e5b3616245 Refactor expense models and detail screen for improved error handling and data validation
- Enhanced `ExpenseResponse` and `ExpenseData` models to handle null values and provide default values.
- Introduced a new `Filter` class to encapsulate filtering logic for expenses.
- Updated `ExpenseDetailScreen` to utilize a controller for fetching expense details and managing loading states.
- Improved UI responsiveness with loading skeletons and error messages.
- Refactored filter bottom sheet to streamline filter selection and reset functionality.
- Added visual indicators for filter application in the main expense screen.
- Enhanced expense detail display with better formatting and status color handling.
2025-07-28 12:09:13 +05:30

71 lines
2.5 KiB
Dart

import 'package:get/get.dart';
import 'package:marco/helpers/services/api_service.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/model/expense/expense_list_model.dart';
class ExpenseDetailController extends GetxController {
final Rx<ExpenseModel?> expense = Rx<ExpenseModel?>(null);
final RxBool isLoading = false.obs;
final RxString errorMessage = ''.obs;
/// Fetch expense details by ID
Future<void> fetchExpenseDetails(String expenseId) async {
isLoading.value = true;
errorMessage.value = '';
try {
logSafe("Fetching expense details for ID: $expenseId");
final result = await ApiService.getExpenseDetailsApi(expenseId: expenseId);
if (result != null) {
try {
expense.value = ExpenseModel.fromJson(result);
logSafe("Expense details loaded successfully: ${expense.value?.id}");
} catch (e) {
errorMessage.value = 'Failed to parse expense details: $e';
logSafe("Parse error in fetchExpenseDetails: $e",
level: LogLevel.error);
}
} else {
errorMessage.value = 'Failed to fetch expense details from server.';
logSafe("fetchExpenseDetails failed: null response",
level: LogLevel.error);
}
} catch (e, stack) {
errorMessage.value = 'An unexpected error occurred.';
logSafe("Exception in fetchExpenseDetails: $e", level: LogLevel.error);
logSafe("StackTrace: $stack", level: LogLevel.debug);
} finally {
isLoading.value = false;
}
}
/// Update status for this specific expense
Future<bool> updateExpenseStatus(String expenseId, String statusId) async {
isLoading.value = true;
errorMessage.value = '';
try {
logSafe("Updating status for expense: $expenseId -> $statusId");
final success = await ApiService.updateExpenseStatusApi(
expenseId: expenseId,
statusId: statusId,
);
if (success) {
logSafe("Expense status updated successfully.");
await fetchExpenseDetails(expenseId); // Refresh details
return true;
} else {
errorMessage.value = "Failed to update expense status.";
return false;
}
} catch (e, stack) {
errorMessage.value = 'An unexpected error occurred.';
logSafe("Exception in updateExpenseStatus: $e", level: LogLevel.error);
logSafe("StackTrace: $stack", level: LogLevel.debug);
return false;
} finally {
isLoading.value = false;
}
}
}