import '../../shared/models/approval_status.dart'; class ExpenseModel { final String id; final String reportNo; final String applicantId; final String applicantName; final String deptId; final String deptName; final String expenseType; final double totalAmount; final int invoiceCount; final String costCenterId; final String costCenterName; final String projectId; final String projectName; final String budgetSubjectId; final String budgetSubjectName; final String paymentMethod; final String accountName; final String remark; final String purpose; final String status; final String currentApproverId; final List approvalChain; final DateTime createTime; final DateTime updateTime; final List attachments; final String paymentStatus; final String voucherNo; final List details; final List approvalRecords; // 财务查验 final bool isInvoiceVerified; final bool isTaxIdMatched; final bool isCategoryCompliant; // 数据库字段 final String bankName; final String bankAccount; final String bankTransferNo; final String approvalInstanceId; final DateTime? applicationDate; final String currencyCode; final double approvedAmount; const ExpenseModel({ required this.id, required this.reportNo, required this.applicantId, required this.applicantName, required this.deptId, required this.deptName, required this.expenseType, required this.totalAmount, this.invoiceCount = 0, this.costCenterId = '', this.costCenterName = '', this.projectId = '', this.projectName = '', this.budgetSubjectId = '', this.budgetSubjectName = '', this.attachments = const [], this.paymentStatus = 'unpaid', this.voucherNo = '', this.paymentMethod = '', this.accountName = '', this.remark = '', this.purpose = '', this.status = 'draft', this.currentApproverId = '', this.approvalChain = const [], required this.createTime, required this.updateTime, this.details = const [], this.approvalRecords = const [], this.isInvoiceVerified = false, this.isTaxIdMatched = false, this.isCategoryCompliant = false, this.bankName = '', this.bankAccount = '', this.bankTransferNo = '', this.approvalInstanceId = '', this.applicationDate, this.currencyCode = 'CNY', this.approvedAmount = 0.0, }); factory ExpenseModel.fromJson(Map json) { return ExpenseModel( id: json['id'] as String, reportNo: json['reportNo'] 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? ?? '', totalAmount: (json['totalAmount'] as num?)?.toDouble() ?? 0.0, invoiceCount: json['invoiceCount'] as int? ?? 0, costCenterId: json['costCenterId'] as String? ?? '', costCenterName: json['costCenterName'] as String? ?? '', projectId: json['projectId'] as String? ?? '', projectName: json['projectName'] as String? ?? '', budgetSubjectId: json['budgetSubjectId'] as String? ?? '', budgetSubjectName: json['budgetSubjectName'] as String? ?? '', attachments: (json['attachments'] as List?) ?.map((e) => e as String) .toList() ?? [], paymentStatus: json['paymentStatus'] as String? ?? 'unpaid', voucherNo: json['voucherNo'] as String? ?? '', paymentMethod: json['paymentMethod'] as String? ?? '', accountName: json['accountName'] as String? ?? '', remark: json['remark'] as String? ?? '', purpose: json['purpose'] 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), details: (json['details'] as List?) ?.map( (e) => ExpenseDetailModel.fromJson(e as Map), ) .toList() ?? [], approvalRecords: (json['approvalRecords'] as List?) ?.map((e) => ApprovalRecord.fromJson(e as Map)) .toList() ?? [], isInvoiceVerified: json['isInvoiceVerified'] as bool? ?? false, isTaxIdMatched: json['isTaxIdMatched'] as bool? ?? false, isCategoryCompliant: json['isCategoryCompliant'] as bool? ?? false, bankName: json['bankName'] as String? ?? '', bankAccount: json['bankAccount'] as String? ?? '', bankTransferNo: json['bankTransferNo'] as String? ?? '', approvalInstanceId: json['approvalInstanceId'] as String? ?? '', applicationDate: json['applicationDate'] != null ? DateTime.parse(json['applicationDate'] as String) : null, currencyCode: json['currencyCode'] as String? ?? 'CNY', approvedAmount: (json['approvedAmount'] as num?)?.toDouble() ?? 0.0, ); } Map toJson() => { 'id': id, 'reportNo': reportNo, 'applicantId': applicantId, 'applicantName': applicantName, 'deptId': deptId, 'deptName': deptName, 'expenseType': expenseType, 'totalAmount': totalAmount, 'invoiceCount': invoiceCount, 'costCenterId': costCenterId, 'costCenterName': costCenterName, 'projectId': projectId, 'projectName': projectName, 'budgetSubjectId': budgetSubjectId, 'budgetSubjectName': budgetSubjectName, 'attachments': attachments, 'paymentStatus': paymentStatus, 'voucherNo': voucherNo, 'paymentMethod': paymentMethod, 'accountName': accountName, 'remark': remark, 'purpose': purpose, 'status': status, 'currentApproverId': currentApproverId, 'approvalChain': approvalChain, 'createTime': createTime.toIso8601String(), 'updateTime': updateTime.toIso8601String(), 'details': details.map((d) => d.toJson()).toList(), 'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(), 'isInvoiceVerified': isInvoiceVerified, 'isTaxIdMatched': isTaxIdMatched, 'isCategoryCompliant': isCategoryCompliant, 'bankName': bankName, 'bankAccount': bankAccount, 'bankTransferNo': bankTransferNo, 'approvalInstanceId': approvalInstanceId, 'applicationDate': applicationDate?.toIso8601String(), 'currencyCode': currencyCode, 'approvedAmount': approvedAmount, }; ExpenseModel copyWith({ String? id, String? reportNo, String? applicantId, String? applicantName, String? deptId, String? deptName, String? expenseType, double? totalAmount, int? invoiceCount, String? costCenterId, String? costCenterName, String? projectId, String? projectName, String? budgetSubjectId, String? budgetSubjectName, List? attachments, String? paymentStatus, String? voucherNo, String? paymentMethod, String? accountName, String? remark, String? purpose, String? status, String? currentApproverId, List? approvalChain, DateTime? createTime, DateTime? updateTime, List? details, List? approvalRecords, bool? isInvoiceVerified, bool? isTaxIdMatched, bool? isCategoryCompliant, String? bankName, String? bankAccount, String? bankTransferNo, String? approvalInstanceId, DateTime? applicationDate, String? currencyCode, double? approvedAmount, }) { return ExpenseModel( id: id ?? this.id, reportNo: reportNo ?? this.reportNo, applicantId: applicantId ?? this.applicantId, applicantName: applicantName ?? this.applicantName, deptId: deptId ?? this.deptId, deptName: deptName ?? this.deptName, expenseType: expenseType ?? this.expenseType, totalAmount: totalAmount ?? this.totalAmount, invoiceCount: invoiceCount ?? this.invoiceCount, costCenterId: costCenterId ?? this.costCenterId, costCenterName: costCenterName ?? this.costCenterName, projectId: projectId ?? this.projectId, projectName: projectName ?? this.projectName, budgetSubjectId: budgetSubjectId ?? this.budgetSubjectId, budgetSubjectName: budgetSubjectName ?? this.budgetSubjectName, attachments: attachments ?? this.attachments, paymentStatus: paymentStatus ?? this.paymentStatus, voucherNo: voucherNo ?? this.voucherNo, paymentMethod: paymentMethod ?? this.paymentMethod, accountName: accountName ?? this.accountName, remark: remark ?? this.remark, purpose: purpose ?? this.purpose, status: status ?? this.status, currentApproverId: currentApproverId ?? this.currentApproverId, approvalChain: approvalChain ?? this.approvalChain, createTime: createTime ?? this.createTime, updateTime: updateTime ?? this.updateTime, details: details ?? this.details, approvalRecords: approvalRecords ?? this.approvalRecords, isInvoiceVerified: isInvoiceVerified ?? this.isInvoiceVerified, isTaxIdMatched: isTaxIdMatched ?? this.isTaxIdMatched, isCategoryCompliant: isCategoryCompliant ?? this.isCategoryCompliant, bankName: bankName ?? this.bankName, bankAccount: bankAccount ?? this.bankAccount, bankTransferNo: bankTransferNo ?? this.bankTransferNo, approvalInstanceId: approvalInstanceId ?? this.approvalInstanceId, applicationDate: applicationDate ?? this.applicationDate, currencyCode: currencyCode ?? this.currencyCode, approvedAmount: approvedAmount ?? this.approvedAmount, ); } } class ExpenseDetailModel { final String id; final String expenseId; final DateTime expenseDate; final String expenseType; final String expenseDesc; final double amount; final double taxAmount; final double totalAmount; final double baseAmount; final String currency; final double exchangeRate; final String invoiceNo; final String invoiceCode; final String invoiceType; final bool isDeductible; final double taxRate; final String remark; final List attachments; final double approvedAmount; final String customerVendorName; final String projectCode; final String subjectCode; final String projectCategory; final double offsetAmount; final int sortOrder; const ExpenseDetailModel({ required this.id, required this.expenseId, required this.expenseDate, required this.expenseType, required this.expenseDesc, required this.amount, this.taxAmount = 0.0, required this.totalAmount, this.baseAmount = 0.0, this.currency = 'CNY', this.exchangeRate = 1.0, this.invoiceNo = '', this.invoiceCode = '', this.invoiceType = '', this.isDeductible = false, this.taxRate = 0.0, this.remark = '', this.attachments = const [], this.approvedAmount = 0.0, this.customerVendorName = '', this.projectCode = '', this.subjectCode = '', this.projectCategory = '', this.offsetAmount = 0.0, this.sortOrder = 1, }); factory ExpenseDetailModel.fromJson(Map json) { return ExpenseDetailModel( id: json['id'] as String, expenseId: json['expenseId'] as String? ?? '', expenseDate: DateTime.parse(json['expenseDate'] as String), expenseType: json['expenseType'] as String? ?? '', expenseDesc: json['expenseDesc'] as String? ?? '', amount: (json['amount'] as num?)?.toDouble() ?? 0.0, taxAmount: (json['taxAmount'] as num?)?.toDouble() ?? 0.0, totalAmount: (json['totalAmount'] as num?)?.toDouble() ?? 0.0, baseAmount: (json['baseAmount'] as num?)?.toDouble() ?? 0.0, currency: json['currency'] as String? ?? 'CNY', exchangeRate: (json['exchangeRate'] as num?)?.toDouble() ?? 1.0, invoiceNo: json['invoiceNo'] as String? ?? '', invoiceCode: json['invoiceCode'] as String? ?? '', invoiceType: json['invoiceType'] as String? ?? '', isDeductible: json['isDeductible'] as bool? ?? false, taxRate: (json['taxRate'] as num?)?.toDouble() ?? 0.0, remark: json['remark'] as String? ?? '', attachments: (json['attachments'] as List?) ?.map((e) => e as String) .toList() ?? [], approvedAmount: (json['approvedAmount'] as num?)?.toDouble() ?? 0.0, customerVendorName: json['customerVendorName'] as String? ?? '', projectCode: json['projectCode'] as String? ?? '', subjectCode: json['subjectCode'] as String? ?? '', projectCategory: json['projectCategory'] as String? ?? '', offsetAmount: (json['offsetAmount'] as num?)?.toDouble() ?? 0.0, sortOrder: json['sortOrder'] as int? ?? 1, ); } Map toJson() => { 'id': id, 'expenseId': expenseId, 'expenseDate': expenseDate.toIso8601String(), 'expenseType': expenseType, 'expenseDesc': expenseDesc, 'amount': amount, 'taxAmount': taxAmount, 'totalAmount': totalAmount, 'baseAmount': baseAmount, 'currency': currency, 'exchangeRate': exchangeRate, 'invoiceNo': invoiceNo, 'invoiceCode': invoiceCode, 'invoiceType': invoiceType, 'isDeductible': isDeductible, 'taxRate': taxRate, 'remark': remark, 'attachments': attachments, 'approvedAmount': approvedAmount, 'customerVendorName': customerVendorName, 'projectCode': projectCode, 'subjectCode': subjectCode, 'projectCategory': projectCategory, 'offsetAmount': offsetAmount, 'sortOrder': sortOrder, }; ExpenseDetailModel copyWith({ String? id, String? expenseId, DateTime? expenseDate, String? expenseType, String? expenseDesc, double? amount, double? taxAmount, double? totalAmount, double? baseAmount, String? currency, double? exchangeRate, String? invoiceNo, String? invoiceCode, String? invoiceType, bool? isDeductible, double? taxRate, String? remark, List? attachments, double? approvedAmount, String? customerVendorName, String? projectCode, String? subjectCode, String? projectCategory, double? offsetAmount, int? sortOrder, }) { return ExpenseDetailModel( id: id ?? this.id, expenseId: expenseId ?? this.expenseId, expenseDate: expenseDate ?? this.expenseDate, expenseType: expenseType ?? this.expenseType, expenseDesc: expenseDesc ?? this.expenseDesc, amount: amount ?? this.amount, taxAmount: taxAmount ?? this.taxAmount, totalAmount: totalAmount ?? this.totalAmount, baseAmount: baseAmount ?? this.baseAmount, currency: currency ?? this.currency, exchangeRate: exchangeRate ?? this.exchangeRate, invoiceNo: invoiceNo ?? this.invoiceNo, invoiceCode: invoiceCode ?? this.invoiceCode, invoiceType: invoiceType ?? this.invoiceType, isDeductible: isDeductible ?? this.isDeductible, taxRate: taxRate ?? this.taxRate, remark: remark ?? this.remark, attachments: attachments ?? this.attachments, approvedAmount: approvedAmount ?? this.approvedAmount, customerVendorName: customerVendorName ?? this.customerVendorName, projectCode: projectCode ?? this.projectCode, subjectCode: subjectCode ?? this.subjectCode, projectCategory: projectCategory ?? this.projectCategory, offsetAmount: offsetAmount ?? this.offsetAmount, sortOrder: sortOrder ?? this.sortOrder, ); } }