feat(expense): refactor expense data handling and response parsing
This commit is contained in:
parent
a83954c5c4
commit
9124b815ef
@ -72,15 +72,12 @@ class ExpenseController extends GetxController {
|
||||
|
||||
if (result != null) {
|
||||
try {
|
||||
final List<dynamic> rawList = result['expenses'] ?? [];
|
||||
final parsed = rawList
|
||||
.map((e) => ExpenseModel.fromJson(e as Map<String, dynamic>))
|
||||
.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);
|
||||
|
@ -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<String, dynamic>) {
|
||||
final dataObj = parsed['data'] as Map<String, dynamic>;
|
||||
|
||||
if (dataObj['data'] is List) {
|
||||
return {
|
||||
'currentPage': dataObj['currentPage'] ?? 1,
|
||||
'totalPages': dataObj['totalPages'] ?? 1,
|
||||
'totalEntites': dataObj['totalEntites'] ?? 0,
|
||||
'expenses': List<dynamic>.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<String, dynamic>) {
|
||||
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;
|
||||
}
|
||||
|
@ -1,14 +1,77 @@
|
||||
import 'dart:convert';
|
||||
|
||||
List<ExpenseModel> expenseModelFromJson(String str) {
|
||||
final jsonData = json.decode(str);
|
||||
return List<ExpenseModel>.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<String, dynamic> 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<String, dynamic> toJson() => {
|
||||
"success": success,
|
||||
"message": message,
|
||||
"data": data.toJson(),
|
||||
"errors": errors,
|
||||
"statusCode": statusCode,
|
||||
"timestamp": timestamp.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
String expenseModelToJson(List<ExpenseModel> data) =>
|
||||
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
|
||||
class ExpenseData {
|
||||
final int currentPage;
|
||||
final int totalPages;
|
||||
final int totalEntites;
|
||||
final List<ExpenseModel> data;
|
||||
|
||||
ExpenseData({
|
||||
required this.currentPage,
|
||||
required this.totalPages,
|
||||
required this.totalEntites,
|
||||
required this.data,
|
||||
});
|
||||
|
||||
factory ExpenseData.fromJson(Map<String, dynamic> json) => ExpenseData(
|
||||
currentPage: json["currentPage"],
|
||||
totalPages: json["totalPages"],
|
||||
totalEntites: json["totalEntites"],
|
||||
data: List<ExpenseModel>.from(
|
||||
json["data"].map((x) => ExpenseModel.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"currentPage": currentPage,
|
||||
"totalPages": totalPages,
|
||||
"totalEntites": totalEntites,
|
||||
"data": List<dynamic>.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<Status>.from(
|
||||
json["nextStatus"].map((x) => Status.fromJson(x))),
|
||||
preApproved: json["preApproved"],
|
||||
nextStatus: json["nextStatus"] != null
|
||||
? List<Status>.from(
|
||||
json["nextStatus"].map((x) => Status.fromJson(x)),
|
||||
)
|
||||
: [],
|
||||
preApproved: json["preApproved"] ?? false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user