import 'dart:convert'; import 'package:intl/intl.dart'; /// Parse the entire response ExpenseResponse expenseResponseFromJson(String str) => ExpenseResponse.fromJson(json.decode(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; ExpenseResponse({ required this.success, required this.message, required this.data, this.errors, this.statusCode, this.timestamp, }); factory ExpenseResponse.fromJson(Map json) { final dataField = json["data"]; return ExpenseResponse( success: json["success"] ?? false, message: json["message"] ?? '', data: (dataField is Map) ? ExpenseData.fromJson(dataField) : ExpenseData.empty(), errors: json["errors"], statusCode: json["statusCode"], timestamp: json["timestamp"] != null ? DateTime.tryParse(json["timestamp"]) : null, ); } Map toJson() => { "success": success, "message": message, "data": data.toJson(), "errors": errors, "statusCode": statusCode, "timestamp": timestamp?.toIso8601String(), }; } /// --- Expense Data --- class ExpenseData { final Filter? currentFilter; final int currentPage; final int totalPages; final int totalEntites; final List data; ExpenseData({ required this.currentFilter, required this.currentPage, required this.totalPages, required this.totalEntites, required this.data, }); factory ExpenseData.fromJson(Map json) => ExpenseData( currentFilter: json["currentFilter"] != null ? Filter.fromJson(json["currentFilter"]) : null, currentPage: json["currentPage"] ?? 0, totalPages: json["totalPages"] ?? 0, totalEntites: json["totalEntites"] ?? 0, data: (json["data"] as List? ?? []) .map((x) => ExpenseModel.fromJson(x)) .toList(), ); factory ExpenseData.empty() => ExpenseData( currentFilter: null, currentPage: 0, totalPages: 0, totalEntites: 0, data: [], ); Map toJson() => { "currentFilter": currentFilter?.toJson(), "currentPage": currentPage, "totalPages": totalPages, "totalEntites": totalEntites, "data": List.from(data.map((x) => x.toJson())), }; } /// --- Filter --- class Filter { 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({ this.projectIds, this.statusIds, this.createdByIds, this.paidById, this.expenseCategoryIds, this.isTransactionDate, this.startDate, this.endDate, }); factory Filter.fromJson(Map json) => Filter( 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, ); Map toJson() => { "projectIds": projectIds, "statusIds": statusIds, "createdByIds": createdByIds, "paidById": paidById, "expenseCategoryIds": expenseCategoryIds, "isTransactionDate": isTransactionDate, "startDate": startDate?.toIso8601String(), "endDate": endDate?.toIso8601String(), }; } /// --- Expense Model --- class ExpenseModel { final String id; final Project project; 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; ExpenseModel({ required this.id, required this.project, 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, }); String get formattedAmount { final formatter = NumberFormat.currency( locale: 'en_IN', symbol: '${currency.symbol} ', decimalDigits: 2, ); return formatter.format(amount); } factory ExpenseModel.fromJson(Map json) => ExpenseModel( id: json["id"] ?? '', project: Project.fromJson(json["project"] ?? {}), 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(), 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)) .toList(), preApproved: json["preApproved"] ?? false, ); Map toJson() => { "id": id, "project": project.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; final String shortName; final String projectAddress; final String contactPerson; final DateTime startDate; final DateTime endDate; final String projectStatusId; Project({ required this.id, required this.name, required this.shortName, required this.projectAddress, required this.contactPerson, required this.startDate, required this.endDate, required this.projectStatusId, }); factory Project.fromJson(Map json) => Project( id: json["id"] ?? '', name: json["name"] ?? '', shortName: json["shortName"] ?? '', projectAddress: json["projectAddress"] ?? '', contactPerson: json["contactPerson"] ?? '', startDate: DateTime.tryParse(json["startDate"] ?? '') ?? DateTime.now(), endDate: DateTime.tryParse(json["endDate"] ?? '') ?? DateTime.now(), projectStatusId: json["projectStatusId"] ?? '', ); Map toJson() => { "id": id, "name": name, "shortName": shortName, "projectAddress": projectAddress, "contactPerson": contactPerson, "startDate": startDate.toIso8601String(), "endDate": endDate.toIso8601String(), "projectStatusId": projectStatusId, }; } /// --- Expense Type --- class ExpenseType { final String id; final String name; final bool noOfPersonsRequired; final String description; ExpenseType({ required this.id, required this.name, required this.noOfPersonsRequired, required this.description, }); factory ExpenseType.fromJson(Map json) => ExpenseType( id: json["id"] ?? '', name: json["name"] ?? '', noOfPersonsRequired: json["noOfPersonsRequired"] ?? false, description: json["description"] ?? '', ); Map toJson() => { "id": id, "name": name, "noOfPersonsRequired": noOfPersonsRequired, "description": description, }; } /// --- Payment Mode --- class PaymentMode { final String id; final String name; final String description; PaymentMode({ required this.id, required this.name, required this.description, }); factory PaymentMode.fromJson(Map json) => PaymentMode( id: json["id"] ?? '', name: json["name"] ?? '', description: json["description"] ?? '', ); Map toJson() => { "id": id, "name": name, "description": description, }; } /// --- PaidBy & CreatedBy --- class PaidBy { final String id; final String firstName; final String lastName; final String photo; final String jobRoleId; final String? jobRoleName; PaidBy({ required this.id, required this.firstName, required this.lastName, required this.photo, required this.jobRoleId, this.jobRoleName, }); factory PaidBy.fromJson(Map json) => PaidBy( id: json["id"] ?? '', firstName: json["firstName"] ?? '', lastName: json["lastName"] ?? '', photo: json["photo"] ?? '', jobRoleId: json["jobRoleId"] ?? '', jobRoleName: json["jobRoleName"], ); Map toJson() => { "id": id, "firstName": firstName, "lastName": lastName, "photo": photo, "jobRoleId": jobRoleId, "jobRoleName": jobRoleName, }; } class CreatedBy extends PaidBy { CreatedBy({ required super.id, required super.firstName, required super.lastName, required super.photo, required super.jobRoleId, super.jobRoleName, }); factory CreatedBy.fromJson(Map json) => CreatedBy( id: json["id"] ?? '', firstName: json["firstName"] ?? '', lastName: json["lastName"] ?? '', photo: json["photo"] ?? '', jobRoleId: json["jobRoleId"] ?? '', jobRoleName: json["jobRoleName"], ); } /// --- Status --- class Status { final String id; final String name; final String displayName; final String description; final String color; final bool isSystem; Status({ required this.id, required this.name, required this.displayName, required this.description, required this.color, required this.isSystem, }); factory Status.fromJson(Map json) => Status( id: json["id"] ?? '', name: json["name"] ?? '', displayName: json["displayName"] ?? '', description: json["description"] ?? '', color: (json["color"] ?? '').replaceAll("'", ''), isSystem: json["isSystem"] ?? false, ); Map toJson() => { "id": id, "name": name, "displayName": displayName, "description": description, "color": color, "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, }; }