diff --git a/lib/helpers/widgets/expense/expense_main_components.dart b/lib/helpers/widgets/expense/expense_main_components.dart index 9e96931..31ffe4d 100644 --- a/lib/helpers/widgets/expense/expense_main_components.dart +++ b/lib/helpers/widgets/expense/expense_main_components.dart @@ -319,7 +319,7 @@ class ExpenseList extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - MyText.bodyMedium(expense.expensesType.name, + MyText.bodyMedium(expense.expenseCategory.name, fontWeight: 600), Row( children: [ diff --git a/lib/model/expense/expense_list_model.dart b/lib/model/expense/expense_list_model.dart index b37f83b..2058fe3 100644 --- a/lib/model/expense/expense_list_model.dart +++ b/lib/model/expense/expense_list_model.dart @@ -8,21 +8,22 @@ ExpenseResponse expenseResponseFromJson(String str) => String expenseResponseToJson(ExpenseResponse data) => json.encode(data.toJson()); +/// --- Top-level Response --- class ExpenseResponse { final bool success; final String message; final ExpenseData data; final dynamic errors; - final int statusCode; - final DateTime timestamp; + 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, + this.errors, + this.statusCode, + this.timestamp, }); factory ExpenseResponse.fromJson(Map json) { @@ -34,8 +35,10 @@ class ExpenseResponse { ? ExpenseData.fromJson(dataField) : ExpenseData.empty(), errors: json["errors"], - statusCode: json["statusCode"] ?? 0, - timestamp: DateTime.tryParse(json["timestamp"] ?? '') ?? DateTime.now(), + statusCode: json["statusCode"], + timestamp: json["timestamp"] != null + ? DateTime.tryParse(json["timestamp"]) + : null, ); } @@ -45,19 +48,20 @@ class ExpenseResponse { "data": data.toJson(), "errors": errors, "statusCode": statusCode, - "timestamp": timestamp.toIso8601String(), + "timestamp": timestamp?.toIso8601String(), }; } +/// --- Expense Data --- class ExpenseData { - final Filter? filter; + final Filter? currentFilter; final int currentPage; final int totalPages; final int totalEntites; final List data; ExpenseData({ - required this.filter, + required this.currentFilter, required this.currentPage, required this.totalPages, required this.totalEntites, @@ -65,7 +69,9 @@ class ExpenseData { }); factory ExpenseData.fromJson(Map json) => ExpenseData( - filter: json["filter"] != null ? Filter.fromJson(json["filter"]) : null, + currentFilter: json["currentFilter"] != null + ? Filter.fromJson(json["currentFilter"]) + : null, currentPage: json["currentPage"] ?? 0, totalPages: json["totalPages"] ?? 0, totalEntites: json["totalEntites"] ?? 0, @@ -75,7 +81,7 @@ class ExpenseData { ); factory ExpenseData.empty() => ExpenseData( - filter: null, + currentFilter: null, currentPage: 0, totalPages: 0, totalEntites: 0, @@ -83,7 +89,7 @@ class ExpenseData { ); Map toJson() => { - "filter": filter?.toJson(), + "currentFilter": currentFilter?.toJson(), "currentPage": currentPage, "totalPages": totalPages, "totalEntites": totalEntites, @@ -91,33 +97,51 @@ class ExpenseData { }; } +/// --- Filter --- class Filter { - final List projectIds; - final List statusIds; - final List createdByIds; - final List paidById; + final List? projectIds; + final List? statusIds; + final List? createdByIds; + final List? paidById; + final List? expenseCategoryIds; + final bool? isTransactionDate; final DateTime? startDate; final DateTime? endDate; Filter({ - required this.projectIds, - required this.statusIds, - required this.createdByIds, - required this.paidById, - required this.startDate, - required this.endDate, + this.projectIds, + this.statusIds, + this.createdByIds, + this.paidById, + this.expenseCategoryIds, + this.isTransactionDate, + this.startDate, + this.endDate, }); factory Filter.fromJson(Map json) => Filter( - projectIds: List.from(json["projectIds"] ?? []), - statusIds: List.from(json["statusIds"] ?? []), - createdByIds: List.from(json["createdByIds"] ?? []), - paidById: List.from(json["paidById"] ?? []), + projectIds: json["projectIds"] != null + ? List.from(json["projectIds"]) + : null, + statusIds: json["statusIds"] != null + ? List.from(json["statusIds"]) + : null, + createdByIds: json["createdByIds"] != null + ? List.from(json["createdByIds"]) + : null, + paidById: json["paidById"] != null + ? List.from(json["paidById"]) + : null, + expenseCategoryIds: json["expenseCategoryIds"] != null + ? List.from(json["expenseCategoryIds"]) + : null, + isTransactionDate: json["isTransactionDate"], startDate: json["startDate"] != null ? DateTime.tryParse(json["startDate"]) : null, - endDate: - json["endDate"] != null ? DateTime.tryParse(json["endDate"]) : null, + endDate: json["endDate"] != null + ? DateTime.tryParse(json["endDate"]) + : null, ); Map toJson() => { @@ -125,25 +149,32 @@ class Filter { "statusIds": statusIds, "createdByIds": createdByIds, "paidById": paidById, + "expenseCategoryIds": expenseCategoryIds, + "isTransactionDate": isTransactionDate, "startDate": startDate?.toIso8601String(), "endDate": endDate?.toIso8601String(), }; } -// --- ExpenseModel and other classes remain same as you wrote --- -// I will include them here for completeness. - +/// --- Expense Model --- class ExpenseModel { final String id; final Project project; - final ExpenseType expensesType; + final ExpenseType expenseCategory; final PaymentMode paymentMode; final PaidBy paidBy; final CreatedBy createdBy; final DateTime transactionDate; final DateTime createdAt; final String supplerName; + final String expenseUId; + final String? paymentRequestUID; + final String transactionId; final double amount; + final Currency currency; + final String description; + final double? baseAmount; + final double? taxAmount; final Status status; final List nextStatus; final bool preApproved; @@ -151,24 +182,30 @@ class ExpenseModel { ExpenseModel({ required this.id, required this.project, - required this.expensesType, + required this.expenseCategory, required this.paymentMode, required this.paidBy, required this.createdBy, required this.transactionDate, required this.createdAt, required this.supplerName, + required this.expenseUId, + this.paymentRequestUID, + required this.transactionId, required this.amount, + required this.currency, + required this.description, + this.baseAmount, + this.taxAmount, required this.status, required this.nextStatus, required this.preApproved, }); - /// ✅ Comma-separated amount getter with currency symbol String get formattedAmount { final formatter = NumberFormat.currency( locale: 'en_IN', - symbol: '₹ ', + symbol: '${currency.symbol} ', decimalDigits: 2, ); return formatter.format(amount); @@ -177,15 +214,27 @@ class ExpenseModel { factory ExpenseModel.fromJson(Map json) => ExpenseModel( id: json["id"] ?? '', project: Project.fromJson(json["project"] ?? {}), - expensesType: ExpenseType.fromJson(json["expensesType"] ?? {}), + expenseCategory: ExpenseType.fromJson(json["expenseCategory"] ?? {}), paymentMode: PaymentMode.fromJson(json["paymentMode"] ?? {}), paidBy: PaidBy.fromJson(json["paidBy"] ?? {}), createdBy: CreatedBy.fromJson(json["createdBy"] ?? {}), transactionDate: DateTime.tryParse(json["transactionDate"] ?? '') ?? DateTime.now(), - createdAt: DateTime.tryParse(json["createdAt"] ?? '') ?? DateTime.now(), + createdAt: + DateTime.tryParse(json["createdAt"] ?? '') ?? DateTime.now(), supplerName: json["supplerName"] ?? '', + expenseUId: json["expenseUId"] ?? '', + paymentRequestUID: json["paymentRequestUID"], + transactionId: json["transactionId"] ?? '', amount: (json["amount"] ?? 0).toDouble(), + currency: Currency.fromJson(json["currency"] ?? {}), + description: json["description"] ?? '', + baseAmount: json["baseAmount"] != null + ? (json["baseAmount"] as num).toDouble() + : null, + taxAmount: json["taxAmount"] != null + ? (json["taxAmount"] as num).toDouble() + : null, status: Status.fromJson(json["status"] ?? {}), nextStatus: (json["nextStatus"] as List? ?? []) .map((x) => Status.fromJson(x)) @@ -196,20 +245,28 @@ class ExpenseModel { Map toJson() => { "id": id, "project": project.toJson(), - "expensesType": expensesType.toJson(), + "expenseCategory": expenseCategory.toJson(), "paymentMode": paymentMode.toJson(), "paidBy": paidBy.toJson(), "createdBy": createdBy.toJson(), "transactionDate": transactionDate.toIso8601String(), "createdAt": createdAt.toIso8601String(), "supplerName": supplerName, + "expenseUId": expenseUId, + "paymentRequestUID": paymentRequestUID, + "transactionId": transactionId, "amount": amount, + "currency": currency.toJson(), + "description": description, + "baseAmount": baseAmount, + "taxAmount": taxAmount, "status": status.toJson(), "nextStatus": List.from(nextStatus.map((x) => x.toJson())), "preApproved": preApproved, }; } +/// --- Project --- class Project { final String id; final String name; @@ -237,7 +294,8 @@ class Project { shortName: json["shortName"] ?? '', projectAddress: json["projectAddress"] ?? '', contactPerson: json["contactPerson"] ?? '', - startDate: DateTime.tryParse(json["startDate"] ?? '') ?? DateTime.now(), + startDate: + DateTime.tryParse(json["startDate"] ?? '') ?? DateTime.now(), endDate: DateTime.tryParse(json["endDate"] ?? '') ?? DateTime.now(), projectStatusId: json["projectStatusId"] ?? '', ); @@ -254,6 +312,7 @@ class Project { }; } +/// --- Expense Type --- class ExpenseType { final String id; final String name; @@ -282,6 +341,7 @@ class ExpenseType { }; } +/// --- Payment Mode --- class PaymentMode { final String id; final String name; @@ -306,6 +366,7 @@ class PaymentMode { }; } +/// --- PaidBy & CreatedBy --- class PaidBy { final String id; final String firstName; @@ -342,24 +403,18 @@ class PaidBy { }; } -class CreatedBy { - final String id; - final String firstName; - final String lastName; - final String photo; - final String jobRoleId; - final String? jobRoleName; - +class CreatedBy extends PaidBy { CreatedBy({ - required this.id, - required this.firstName, - required this.lastName, - required this.photo, - required this.jobRoleId, - this.jobRoleName, + required super.id, + required super.firstName, + required super.lastName, + required super.photo, + required super.jobRoleId, + super.jobRoleName, }); - factory CreatedBy.fromJson(Map json) => CreatedBy( + factory CreatedBy.fromJson(Map json) => + CreatedBy( id: json["id"] ?? '', firstName: json["firstName"] ?? '', lastName: json["lastName"] ?? '', @@ -367,17 +422,9 @@ class CreatedBy { jobRoleId: json["jobRoleId"] ?? '', jobRoleName: json["jobRoleName"], ); - - Map toJson() => { - "id": id, - "firstName": firstName, - "lastName": lastName, - "photo": photo, - "jobRoleId": jobRoleId, - "jobRoleName": jobRoleName, - }; } +/// --- Status --- class Status { final String id; final String name; @@ -413,3 +460,36 @@ class Status { "isSystem": isSystem, }; } + +/// --- Currency --- +class Currency { + final String id; + final String currencyCode; + final String currencyName; + final String symbol; + final bool isActive; + + Currency({ + required this.id, + required this.currencyCode, + required this.currencyName, + required this.symbol, + required this.isActive, + }); + + factory Currency.fromJson(Map json) => Currency( + id: json["id"] ?? '', + currencyCode: json["currencyCode"] ?? '', + currencyName: json["currencyName"] ?? '', + symbol: json["symbol"] ?? '', + isActive: json["isActive"] ?? false, + ); + + Map toJson() => { + "id": id, + "currencyCode": currencyCode, + "currencyName": currencyName, + "symbol": symbol, + "isActive": isActive, + }; +} diff --git a/lib/view/expense/expense_screen.dart b/lib/view/expense/expense_screen.dart index d826b1c..453ae00 100644 --- a/lib/view/expense/expense_screen.dart +++ b/lib/view/expense/expense_screen.dart @@ -67,7 +67,7 @@ class _ExpenseMainScreenState extends State final filtered = expenseController.expenses.where((e) { return query.isEmpty || - e.expensesType.name.toLowerCase().contains(query) || + e.expenseCategory.name.toLowerCase().contains(query) || e.supplerName.toLowerCase().contains(query) || e.paymentMode.name.toLowerCase().contains(query); }).toList()