diff --git a/lib/controller/expense/expense_screen_controller.dart b/lib/controller/expense/expense_screen_controller.dart index 39dd724..1acdec9 100644 --- a/lib/controller/expense/expense_screen_controller.dart +++ b/lib/controller/expense/expense_screen_controller.dart @@ -72,15 +72,12 @@ class ExpenseController extends GetxController { if (result != null) { try { - final List rawList = result['expenses'] ?? []; - final parsed = rawList - .map((e) => ExpenseModel.fromJson(e as Map)) - .toList(); + final expenseResponse = ExpenseResponse.fromJson(result); + expenses.assignAll(expenseResponse.data.data); - expenses.assignAll(parsed); - logSafe("Expenses loaded: ${parsed.length}"); + logSafe("Expenses loaded: ${expenses.length}"); logSafe( - "Pagination Info: Page ${result['currentPage']} of ${result['totalPages']} | Total: ${result['totalEntites']}"); + "Pagination Info: Page ${expenseResponse.data.currentPage} of ${expenseResponse.data.totalPages} | Total: ${expenseResponse.data.totalEntites}"); } catch (e) { errorMessage.value = 'Failed to parse expenses: $e'; logSafe("Parse error in fetchExpenses: $e", level: LogLevel.error); diff --git a/lib/helpers/services/api_service.dart b/lib/helpers/services/api_service.dart index cf3c28d..4520a68 100644 --- a/lib/helpers/services/api_service.dart +++ b/lib/helpers/services/api_service.dart @@ -308,27 +308,25 @@ class ApiService { try { final response = await _getRequest(uri.toString()); - if (response == null) return null; + if (response == null) { + logSafe("Expense list request failed: null response", + level: LogLevel.error); + return null; + } - final parsed = _parseResponseForAllData(response, label: 'Expense List'); + // Directly parse and return the entire JSON response + final body = response.body.trim(); + if (body.isEmpty) { + logSafe("Expense list response body is empty", level: LogLevel.error); + return null; + } - if (parsed != null && parsed['data'] is Map) { - final dataObj = parsed['data'] as Map; - - if (dataObj['data'] is List) { - return { - 'currentPage': dataObj['currentPage'] ?? 1, - 'totalPages': dataObj['totalPages'] ?? 1, - 'totalEntites': dataObj['totalEntites'] ?? 0, - 'expenses': List.from(dataObj['data']), - }; - } else { - logSafe("Expense list 'data' is not a list: $dataObj", - level: LogLevel.error); - return null; - } + final jsonResponse = jsonDecode(body); + if (jsonResponse is Map) { + logSafe("Expense list response parsed successfully"); + return jsonResponse; // Return the entire API response } else { - logSafe("Unexpected response structure: $parsed", + logSafe("Unexpected response structure: $jsonResponse", level: LogLevel.error); return null; } diff --git a/lib/model/expense/expense_list_model.dart b/lib/model/expense/expense_list_model.dart index b23468c..410c0be 100644 --- a/lib/model/expense/expense_list_model.dart +++ b/lib/model/expense/expense_list_model.dart @@ -1,14 +1,77 @@ import 'dart:convert'; -List expenseModelFromJson(String str) { - final jsonData = json.decode(str); - return List.from( - jsonData["data"]["data"].map((x) => ExpenseModel.fromJson(x)) - ); +/// Parse the entire response +ExpenseResponse expenseResponseFromJson(String str) => + ExpenseResponse.fromJson(json.decode(str)); + +String expenseResponseToJson(ExpenseResponse data) => + json.encode(data.toJson()); + +class ExpenseResponse { + final bool success; + final String message; + final ExpenseData data; + final dynamic errors; + final int statusCode; + final DateTime timestamp; + + ExpenseResponse({ + required this.success, + required this.message, + required this.data, + required this.errors, + required this.statusCode, + required this.timestamp, + }); + + factory ExpenseResponse.fromJson(Map json) => + ExpenseResponse( + success: json["success"], + message: json["message"], + data: ExpenseData.fromJson(json["data"]), + errors: json["errors"], + statusCode: json["statusCode"], + timestamp: DateTime.parse(json["timestamp"]), + ); + + Map toJson() => { + "success": success, + "message": message, + "data": data.toJson(), + "errors": errors, + "statusCode": statusCode, + "timestamp": timestamp.toIso8601String(), + }; } -String expenseModelToJson(List data) => - json.encode(List.from(data.map((x) => x.toJson()))); +class ExpenseData { + final int currentPage; + final int totalPages; + final int totalEntites; + final List data; + + ExpenseData({ + required this.currentPage, + required this.totalPages, + required this.totalEntites, + required this.data, + }); + + factory ExpenseData.fromJson(Map json) => ExpenseData( + currentPage: json["currentPage"], + totalPages: json["totalPages"], + totalEntites: json["totalEntites"], + data: List.from( + json["data"].map((x) => ExpenseModel.fromJson(x))), + ); + + Map toJson() => { + "currentPage": currentPage, + "totalPages": totalPages, + "totalEntites": totalEntites, + "data": List.from(data.map((x) => x.toJson())), + }; +} class ExpenseModel { final String id; @@ -53,9 +116,12 @@ class ExpenseModel { supplerName: json["supplerName"], amount: (json["amount"] as num).toDouble(), status: Status.fromJson(json["status"]), - nextStatus: List.from( - json["nextStatus"].map((x) => Status.fromJson(x))), - preApproved: json["preApproved"], + nextStatus: json["nextStatus"] != null + ? List.from( + json["nextStatus"].map((x) => Status.fromJson(x)), + ) + : [], + preApproved: json["preApproved"] ?? false, ); Map toJson() => {