class ExpenseDetailModel { final String id; final Project project; final ExpensesType expensesType; final PaymentMode paymentMode; final Person paidBy; final Person createdBy; final Person? reviewedBy; final Person? approvedBy; final Person? processedBy; final String transactionDate; final String createdAt; final String supplerName; final double amount; final ExpenseStatus status; final List nextStatus; final bool preApproved; final String transactionId; final String description; final String location; final List documents; final List expenseLogs; final String? gstNumber; final int noOfPersons; final bool isActive; final dynamic expensesReimburse; // can be replaced with model later ExpenseDetailModel({ required this.id, required this.project, required this.expensesType, required this.paymentMode, required this.paidBy, required this.createdBy, this.reviewedBy, this.approvedBy, this.processedBy, required this.transactionDate, required this.createdAt, required this.supplerName, required this.amount, required this.status, required this.nextStatus, required this.preApproved, required this.transactionId, required this.description, required this.location, required this.documents, required this.expenseLogs, this.gstNumber, required this.noOfPersons, required this.isActive, this.expensesReimburse, }); factory ExpenseDetailModel.fromJson(Map json) { return ExpenseDetailModel( id: json['id'] ?? '', project: json['project'] != null ? Project.fromJson(json['project']) : Project.empty(), expensesType: json['expensesType'] != null ? ExpensesType.fromJson(json['expensesType']) : ExpensesType.empty(), paymentMode: json['paymentMode'] != null ? PaymentMode.fromJson(json['paymentMode']) : PaymentMode.empty(), paidBy: json['paidBy'] != null ? Person.fromJson(json['paidBy']) : Person.empty(), createdBy: json['createdBy'] != null ? Person.fromJson(json['createdBy']) : Person.empty(), reviewedBy: json['reviewedBy'] != null ? Person.fromJson(json['reviewedBy']) : null, approvedBy: json['approvedBy'] != null ? Person.fromJson(json['approvedBy']) : null, processedBy: json['processedBy'] != null ? Person.fromJson(json['processedBy']) : null, transactionDate: json['transactionDate'] ?? '', createdAt: json['createdAt'] ?? '', supplerName: json['supplerName'] ?? '', amount: (json['amount'] as num?)?.toDouble() ?? 0.0, status: json['status'] != null ? ExpenseStatus.fromJson(json['status']) : ExpenseStatus.empty(), nextStatus: (json['nextStatus'] as List?) ?.map((e) => ExpenseStatus.fromJson(e)) .toList() ?? [], preApproved: json['preApproved'] ?? false, transactionId: json['transactionId'] ?? '', description: json['description'] ?? '', location: json['location'] ?? '', documents: (json['documents'] as List?) ?.map((e) => ExpenseDocument.fromJson(e)) .toList() ?? [], expenseLogs: (json['expenseLogs'] as List?) ?.map((e) => ExpenseLog.fromJson(e)) .toList() ?? [], gstNumber: json['gstNumber']?.toString(), noOfPersons: json['noOfPersons'] ?? 0, isActive: json['isActive'] ?? true, expensesReimburse: json['expensesReimburse'], ); } } // ---------------- Project ---------------- class Project { final String id; final String name; final String shortName; final String projectAddress; final String contactPerson; final String startDate; final String 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) { return Project( id: json['id'] ?? '', name: json['name'] ?? '', shortName: json['shortName'] ?? '', projectAddress: json['projectAddress'] ?? '', contactPerson: json['contactPerson'] ?? '', startDate: json['startDate'] ?? '', endDate: json['endDate'] ?? '', projectStatusId: json['projectStatusId'] ?? '', ); } factory Project.empty() => Project( id: '', name: '', shortName: '', projectAddress: '', contactPerson: '', startDate: '', endDate: '', projectStatusId: '', ); } // ---------------- ExpensesType ---------------- class ExpensesType { final String id; final String name; final bool noOfPersonsRequired; final String description; ExpensesType({ required this.id, required this.name, required this.noOfPersonsRequired, required this.description, }); factory ExpensesType.fromJson(Map json) { return ExpensesType( id: json['id'] ?? '', name: json['name'] ?? '', noOfPersonsRequired: json['noOfPersonsRequired'] ?? false, description: json['description'] ?? '', ); } factory ExpensesType.empty() => ExpensesType( id: '', name: '', noOfPersonsRequired: false, description: '', ); } // ---------------- PaymentMode ---------------- 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) { return PaymentMode( id: json['id'] ?? '', name: json['name'] ?? '', description: json['description'] ?? '', ); } factory PaymentMode.empty() => PaymentMode( id: '', name: '', description: '', ); } // ---------------- Person ---------------- class Person { final String id; final String firstName; final String lastName; final String photo; final String jobRoleId; final String jobRoleName; Person({ required this.id, required this.firstName, required this.lastName, required this.photo, required this.jobRoleId, required this.jobRoleName, }); factory Person.fromJson(Map json) { return Person( id: json['id'] ?? '', firstName: json['firstName'] ?? '', lastName: json['lastName'] ?? '', photo: json['photo'] is String ? json['photo'] : '', jobRoleId: json['jobRoleId'] ?? '', jobRoleName: json['jobRoleName'] ?? '', ); } factory Person.empty() => Person( id: '', firstName: '', lastName: '', photo: '', jobRoleId: '', jobRoleName: '', ); } // ---------------- ExpenseStatus ---------------- class ExpenseStatus { final String id; final String name; final String displayName; final String description; final String? permissionIds; // API sends list, but can stringify final String color; final bool isSystem; ExpenseStatus({ required this.id, required this.name, required this.displayName, required this.description, required this.permissionIds, required this.color, required this.isSystem, }); factory ExpenseStatus.fromJson(Map json) { return ExpenseStatus( id: json['id'] ?? '', name: json['name'] ?? '', displayName: json['displayName'] ?? '', description: json['description'] ?? '', permissionIds: json['permissionIds']?.toString(), color: json['color'] ?? '', isSystem: json['isSystem'] ?? false, ); } factory ExpenseStatus.empty() => ExpenseStatus( id: '', name: '', displayName: '', description: '', permissionIds: null, color: '', isSystem: false, ); } // ---------------- ExpenseDocument ---------------- class ExpenseDocument { final String documentId; final String fileName; final String contentType; final String preSignedUrl; final String thumbPreSignedUrl; ExpenseDocument({ required this.documentId, required this.fileName, required this.contentType, required this.preSignedUrl, required this.thumbPreSignedUrl, }); factory ExpenseDocument.fromJson(Map json) { return ExpenseDocument( documentId: json['documentId'] ?? '', fileName: json['fileName'] ?? '', contentType: json['contentType'] ?? '', preSignedUrl: json['preSignedUrl'] ?? '', thumbPreSignedUrl: json['thumbPreSignedUrl'] ?? '', ); } } // ---------------- ExpenseLog ---------------- class ExpenseLog { final String id; final Person updatedBy; final String action; final String updateAt; final String comment; ExpenseLog({ required this.id, required this.updatedBy, required this.action, required this.updateAt, required this.comment, }); factory ExpenseLog.fromJson(Map json) { return ExpenseLog( id: json['id'] ?? '', updatedBy: json['updatedBy'] != null ? Person.fromJson(json['updatedBy']) : Person.empty(), action: json['action'] ?? '', updateAt: json['updateAt'] ?? '', comment: json['comment'] ?? '', ); } }