import '../../shared/models/approval_status.dart'; class ExpenseApplicationModel { final String id; final String applicationNo; final String applicantId; final String applicantName; final String deptId; final String deptName; final String expenseType; final List expenseTypes; final double estimatedAmount; final String purpose; final String remark; final String status; final String currentApproverId; final List approvalChain; final DateTime createTime; final DateTime updateTime; final DateTime? estimatedStartDate; final DateTime? estimatedEndDate; final String urgency; final String projectId; final String projectName; final String budgetSubjectId; final String budgetSubjectName; final double availableBalance; final bool isTaxIncluded; final DateTime? validUntil; final String referenceNo; final String usageStatus; // 差旅费专用 final bool isOvernight; final String transportMode; // 招待费专用 final String entertainTarget; final String entertainLevel; final int guestCount; final int hostCount; final String entertainLocation; // 会议费专用 final DateTime? meetingDate; final String meetingLocation; final List details; final List attachments; final List approvalRecords; const ExpenseApplicationModel({ required this.id, required this.applicationNo, this.applicantId = '', this.applicantName = '', this.deptId = '', this.deptName = '', this.expenseType = '', this.expenseTypes = const [], this.estimatedAmount = 0.0, this.purpose = '', this.remark = '', this.status = 'draft', this.currentApproverId = '', this.approvalChain = const [], required this.createTime, required this.updateTime, this.estimatedStartDate, this.estimatedEndDate, this.urgency = 'normal', this.projectId = '', this.projectName = '', this.budgetSubjectId = '', this.budgetSubjectName = '', this.availableBalance = 0.0, this.isTaxIncluded = false, this.validUntil, this.referenceNo = '', this.usageStatus = 'unused', this.isOvernight = false, this.transportMode = '', this.entertainTarget = '', this.entertainLevel = '', this.guestCount = 0, this.hostCount = 0, this.entertainLocation = '', this.meetingDate, this.meetingLocation = '', this.details = const [], this.attachments = const [], this.approvalRecords = const [], }); factory ExpenseApplicationModel.fromJson(Map json) { return ExpenseApplicationModel( id: json['id'] as String, applicationNo: json['applicationNo'] as String? ?? '', applicantId: json['applicantId'] as String? ?? '', applicantName: json['applicantName'] as String? ?? '', deptId: json['deptId'] as String? ?? '', deptName: json['deptName'] as String? ?? '', expenseType: json['expenseType'] as String? ?? '', expenseTypes: (json['expenseTypes'] as List?)?.map((e) => e as String).toList() ?? [], estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0, purpose: json['purpose'] as String? ?? '', remark: json['remark'] as String? ?? '', status: json['status'] as String? ?? 'draft', currentApproverId: json['currentApproverId'] as String? ?? '', approvalChain: (json['approvalChain'] as List?) ?.map((e) => e as String) .toList() ?? [], createTime: DateTime.parse(json['createTime'] as String), updateTime: DateTime.parse(json['updateTime'] as String), estimatedStartDate: json['estimatedStartDate'] != null ? DateTime.parse(json['estimatedStartDate'] as String) : null, estimatedEndDate: json['estimatedEndDate'] != null ? DateTime.parse(json['estimatedEndDate'] as String) : null, urgency: json['urgency'] as String? ?? 'normal', projectId: json['projectId'] as String? ?? '', projectName: json['projectName'] as String? ?? '', budgetSubjectId: json['budgetSubjectId'] as String? ?? '', budgetSubjectName: json['budgetSubjectName'] as String? ?? '', availableBalance: (json['availableBalance'] as num?)?.toDouble() ?? 0.0, isTaxIncluded: json['isTaxIncluded'] as bool? ?? false, validUntil: json['validUntil'] != null ? DateTime.parse(json['validUntil'] as String) : null, referenceNo: json['referenceNo'] as String? ?? '', usageStatus: json['usageStatus'] as String? ?? 'unused', isOvernight: json['isOvernight'] as bool? ?? false, transportMode: json['transportMode'] as String? ?? '', entertainTarget: json['entertainTarget'] as String? ?? '', entertainLevel: json['entertainLevel'] as String? ?? '', guestCount: json['guestCount'] as int? ?? 0, hostCount: json['hostCount'] as int? ?? 0, entertainLocation: json['entertainLocation'] as String? ?? '', meetingDate: json['meetingDate'] != null ? DateTime.parse(json['meetingDate'] as String) : null, meetingLocation: json['meetingLocation'] as String? ?? '', details: (json['details'] as List?) ?.map( (e) => ExpenseAppDetailModel.fromJson(e as Map), ) .toList() ?? [], attachments: (json['attachments'] as List?)?.map((e) => e as String).toList() ?? [], approvalRecords: (json['approvalRecords'] as List?) ?.map((e) => ApprovalRecord.fromJson(e as Map)) .toList() ?? [], ); } Map toJson() => { 'id': id, 'applicationNo': applicationNo, 'applicantId': applicantId, 'applicantName': applicantName, 'deptId': deptId, 'deptName': deptName, 'expenseType': expenseType, 'expenseTypes': expenseTypes, 'estimatedAmount': estimatedAmount, 'purpose': purpose, 'remark': remark, 'status': status, 'currentApproverId': currentApproverId, 'approvalChain': approvalChain, 'createTime': createTime.toIso8601String(), 'updateTime': updateTime.toIso8601String(), 'estimatedStartDate': estimatedStartDate?.toIso8601String(), 'estimatedEndDate': estimatedEndDate?.toIso8601String(), 'urgency': urgency, 'projectId': projectId, 'projectName': projectName, 'budgetSubjectId': budgetSubjectId, 'budgetSubjectName': budgetSubjectName, 'availableBalance': availableBalance, 'isTaxIncluded': isTaxIncluded, 'validUntil': validUntil?.toIso8601String(), 'referenceNo': referenceNo, 'usageStatus': usageStatus, 'isOvernight': isOvernight, 'transportMode': transportMode, 'entertainTarget': entertainTarget, 'entertainLevel': entertainLevel, 'guestCount': guestCount, 'hostCount': hostCount, 'entertainLocation': entertainLocation, 'meetingDate': meetingDate?.toIso8601String(), 'meetingLocation': meetingLocation, 'details': details.map((d) => d.toJson()).toList(), 'attachments': attachments, 'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(), }; ExpenseApplicationModel copyWith({ String? id, String? applicationNo, String? applicantId, String? applicantName, String? deptId, String? deptName, String? expenseType, List? expenseTypes, double? estimatedAmount, String? purpose, String? remark, String? status, String? currentApproverId, List? approvalChain, DateTime? createTime, DateTime? updateTime, DateTime? estimatedStartDate, DateTime? estimatedEndDate, String? urgency, String? projectId, String? projectName, String? budgetSubjectId, String? budgetSubjectName, double? availableBalance, bool? isTaxIncluded, DateTime? validUntil, String? referenceNo, String? usageStatus, bool? isOvernight, String? transportMode, String? entertainTarget, String? entertainLevel, int? guestCount, int? hostCount, String? entertainLocation, DateTime? meetingDate, String? meetingLocation, List? details, List? attachments, List? approvalRecords, }) { return ExpenseApplicationModel( id: id ?? this.id, applicationNo: applicationNo ?? this.applicationNo, applicantId: applicantId ?? this.applicantId, applicantName: applicantName ?? this.applicantName, deptId: deptId ?? this.deptId, deptName: deptName ?? this.deptName, expenseType: expenseType ?? this.expenseType, expenseTypes: expenseTypes ?? this.expenseTypes, estimatedAmount: estimatedAmount ?? this.estimatedAmount, purpose: purpose ?? this.purpose, remark: remark ?? this.remark, status: status ?? this.status, currentApproverId: currentApproverId ?? this.currentApproverId, approvalChain: approvalChain ?? this.approvalChain, createTime: createTime ?? this.createTime, updateTime: updateTime ?? this.updateTime, estimatedStartDate: estimatedStartDate ?? this.estimatedStartDate, estimatedEndDate: estimatedEndDate ?? this.estimatedEndDate, urgency: urgency ?? this.urgency, projectId: projectId ?? this.projectId, projectName: projectName ?? this.projectName, budgetSubjectId: budgetSubjectId ?? this.budgetSubjectId, budgetSubjectName: budgetSubjectName ?? this.budgetSubjectName, availableBalance: availableBalance ?? this.availableBalance, isTaxIncluded: isTaxIncluded ?? this.isTaxIncluded, validUntil: validUntil ?? this.validUntil, referenceNo: referenceNo ?? this.referenceNo, usageStatus: usageStatus ?? this.usageStatus, isOvernight: isOvernight ?? this.isOvernight, transportMode: transportMode ?? this.transportMode, entertainTarget: entertainTarget ?? this.entertainTarget, entertainLevel: entertainLevel ?? this.entertainLevel, guestCount: guestCount ?? this.guestCount, hostCount: hostCount ?? this.hostCount, entertainLocation: entertainLocation ?? this.entertainLocation, meetingDate: meetingDate ?? this.meetingDate, meetingLocation: meetingLocation ?? this.meetingLocation, details: details ?? this.details, attachments: attachments ?? this.attachments, approvalRecords: approvalRecords ?? this.approvalRecords, ); } } class ExpenseAppDetailModel { final String id; final String applicationId; final String itemName; final double estimatedAmount; final String remark; final int sortOrder; final double quantity; final String unit; final double unitPrice; final double lineAmount; final String category; final String description; const ExpenseAppDetailModel({ required this.id, this.applicationId = '', this.itemName = '', this.estimatedAmount = 0.0, this.remark = '', this.sortOrder = 1, this.quantity = 1, this.unit = '张', this.unitPrice = 0.0, this.lineAmount = 0.0, this.category = '', this.description = '', }); factory ExpenseAppDetailModel.fromJson(Map json) { return ExpenseAppDetailModel( id: json['id'] as String, applicationId: json['applicationId'] as String? ?? '', itemName: json['itemName'] as String? ?? '', estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0, remark: json['remark'] as String? ?? '', sortOrder: json['sortOrder'] as int? ?? 1, quantity: (json['quantity'] as num?)?.toDouble() ?? 1, unit: json['unit'] as String? ?? '张', unitPrice: (json['unitPrice'] as num?)?.toDouble() ?? 0.0, lineAmount: (json['lineAmount'] as num?)?.toDouble() ?? 0.0, category: json['category'] as String? ?? '', description: json['description'] as String? ?? '', ); } Map toJson() => { 'id': id, 'applicationId': applicationId, 'itemName': itemName, 'estimatedAmount': estimatedAmount, 'remark': remark, 'sortOrder': sortOrder, 'quantity': quantity, 'unit': unit, 'unitPrice': unitPrice, 'lineAmount': lineAmount, 'category': category, 'description': description, }; }