| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- import '../../shared/models/approval_status.dart';
- /// 费用报销主表,对应 [Expense] 表。
- class ExpenseModel {
- final String id;
- final String expenseNo;
- final DateTime? expenseDate;
- final String applicantId;
- final String applicantName;
- final String deptId;
- final String deptName;
- final String currencyCode;
- final bool isGenerateVoucher;
- final String voucherNo;
- final double approvedAmount;
- final double totalAmount;
- final String purpose;
- final String remark;
- final String paymentMethod;
- final bool isInvoiceVerified;
- final bool isTaxIdMatched;
- final bool isCategoryCompliant;
- final String bankTransferNo;
- final String paymentStatus;
- final String status;
- final String approvalInstanceId;
- final String previousInstanceIds;
- final DateTime? effectiveDate;
- final String auditorId;
- final int version;
- final DateTime createTime;
- final DateTime updateTime;
- final bool isDeleted;
- // ── 瞬态字段(API 从 ERP 实时查询,非存储) ──
- final String currentApproverId;
- final List<String> approvalChain;
- final List<ApprovalRecord> approvalRecords;
- // ── 子表 ──
- final List<ExpenseDetailModel> details;
- final List<String> attachments;
- const ExpenseModel({
- required this.id,
- required this.expenseNo,
- this.expenseDate,
- this.applicantId = '',
- this.applicantName = '',
- this.deptId = '',
- this.deptName = '',
- this.currencyCode = 'CNY',
- this.isGenerateVoucher = false,
- this.voucherNo = '',
- this.approvedAmount = 0.0,
- this.totalAmount = 0.0,
- this.purpose = '',
- this.remark = '',
- this.paymentMethod = '',
- this.isInvoiceVerified = false,
- this.isTaxIdMatched = false,
- this.isCategoryCompliant = false,
- this.bankTransferNo = '',
- this.paymentStatus = 'unpaid',
- this.status = 'draft',
- this.approvalInstanceId = '',
- this.previousInstanceIds = '',
- this.effectiveDate,
- this.auditorId = '',
- this.version = 1,
- required this.createTime,
- required this.updateTime,
- this.isDeleted = false,
- this.currentApproverId = '',
- this.approvalChain = const [],
- this.approvalRecords = const [],
- this.details = const [],
- this.attachments = const [],
- });
- factory ExpenseModel.fromJson(Map<String, dynamic> json) {
- return ExpenseModel(
- id: json['id'] as String,
- expenseNo: json['expenseNo'] as String? ?? '',
- expenseDate: json['expenseDate'] != null
- ? DateTime.parse(json['expenseDate'] as String)
- : null,
- applicantId: json['applicantId'] as String? ?? '',
- applicantName: json['applicantName'] as String? ?? '',
- deptId: json['deptId'] as String? ?? '',
- deptName: json['deptName'] as String? ?? '',
- currencyCode: json['currencyCode'] as String? ?? 'CNY',
- isGenerateVoucher: json['isGenerateVoucher'] as bool? ?? false,
- voucherNo: json['voucherNo'] as String? ?? '',
- approvedAmount: (json['approvedAmount'] as num?)?.toDouble() ?? 0.0,
- totalAmount: (json['totalAmount'] as num?)?.toDouble() ?? 0.0,
- purpose: json['purpose'] as String? ?? '',
- remark: json['remark'] as String? ?? '',
- paymentMethod: json['paymentMethod'] as String? ?? '',
- isInvoiceVerified: json['isInvoiceVerified'] as bool? ?? false,
- isTaxIdMatched: json['isTaxIdMatched'] as bool? ?? false,
- isCategoryCompliant: json['isCategoryCompliant'] as bool? ?? false,
- bankTransferNo: json['bankTransferNo'] as String? ?? '',
- paymentStatus: json['paymentStatus'] as String? ?? 'unpaid',
- status: json['status'] as String? ?? 'draft',
- approvalInstanceId: json['approvalInstanceId'] as String? ?? '',
- previousInstanceIds: json['previousInstanceIds'] as String? ?? '',
- effectiveDate: json['effectiveDate'] != null
- ? DateTime.parse(json['effectiveDate'] as String)
- : null,
- auditorId: json['auditorId'] as String? ?? '',
- version: json['version'] as int? ?? 1,
- createTime: DateTime.parse(json['createTime'] as String),
- updateTime: DateTime.parse(json['updateTime'] as String),
- isDeleted: json['isDeleted'] as bool? ?? false,
- currentApproverId: json['currentApproverId'] as String? ?? '',
- approvalChain:
- (json['approvalChain'] as List<dynamic>?)
- ?.map((e) => e as String)
- .toList() ??
- [],
- approvalRecords:
- (json['approvalRecords'] as List<dynamic>?)
- ?.map((e) => ApprovalRecord.fromJson(e as Map<String, dynamic>))
- .toList() ??
- [],
- details:
- (json['details'] as List<dynamic>?)
- ?.map(
- (e) => ExpenseDetailModel.fromJson(e as Map<String, dynamic>),
- )
- .toList() ??
- [],
- attachments:
- (json['attachments'] as List<dynamic>?)
- ?.map((e) => e as String)
- .toList() ??
- [],
- );
- }
- Map<String, dynamic> toJson() => {
- 'id': id,
- 'expenseNo': expenseNo,
- 'expenseDate': expenseDate?.toIso8601String(),
- 'applicantId': applicantId,
- 'applicantName': applicantName,
- 'deptId': deptId,
- 'deptName': deptName,
- 'currencyCode': currencyCode,
- 'isGenerateVoucher': isGenerateVoucher,
- 'voucherNo': voucherNo,
- 'approvedAmount': approvedAmount,
- 'totalAmount': totalAmount,
- 'purpose': purpose,
- 'remark': remark,
- 'paymentMethod': paymentMethod,
- 'isInvoiceVerified': isInvoiceVerified,
- 'isTaxIdMatched': isTaxIdMatched,
- 'isCategoryCompliant': isCategoryCompliant,
- 'bankTransferNo': bankTransferNo,
- 'paymentStatus': paymentStatus,
- 'status': status,
- 'approvalInstanceId': approvalInstanceId,
- 'previousInstanceIds': previousInstanceIds,
- 'effectiveDate': effectiveDate?.toIso8601String(),
- 'auditorId': auditorId,
- 'version': version,
- 'createTime': createTime.toIso8601String(),
- 'updateTime': updateTime.toIso8601String(),
- 'isDeleted': isDeleted,
- 'currentApproverId': currentApproverId,
- 'approvalChain': approvalChain,
- 'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(),
- 'details': details.map((d) => d.toJson()).toList(),
- 'attachments': attachments,
- };
- ExpenseModel copyWith({
- String? id,
- String? expenseNo,
- DateTime? expenseDate,
- String? applicantId,
- String? applicantName,
- String? deptId,
- String? deptName,
- String? currencyCode,
- bool? isGenerateVoucher,
- String? voucherNo,
- double? approvedAmount,
- double? totalAmount,
- String? purpose,
- String? remark,
- String? paymentMethod,
- bool? isInvoiceVerified,
- bool? isTaxIdMatched,
- bool? isCategoryCompliant,
- String? bankTransferNo,
- String? paymentStatus,
- String? status,
- String? approvalInstanceId,
- String? previousInstanceIds,
- DateTime? effectiveDate,
- String? auditorId,
- int? version,
- DateTime? createTime,
- DateTime? updateTime,
- bool? isDeleted,
- String? currentApproverId,
- List<String>? approvalChain,
- List<ApprovalRecord>? approvalRecords,
- List<ExpenseDetailModel>? details,
- List<String>? attachments,
- }) {
- return ExpenseModel(
- id: id ?? this.id,
- expenseNo: expenseNo ?? this.expenseNo,
- expenseDate: expenseDate ?? this.expenseDate,
- applicantId: applicantId ?? this.applicantId,
- applicantName: applicantName ?? this.applicantName,
- deptId: deptId ?? this.deptId,
- deptName: deptName ?? this.deptName,
- currencyCode: currencyCode ?? this.currencyCode,
- isGenerateVoucher: isGenerateVoucher ?? this.isGenerateVoucher,
- voucherNo: voucherNo ?? this.voucherNo,
- approvedAmount: approvedAmount ?? this.approvedAmount,
- totalAmount: totalAmount ?? this.totalAmount,
- purpose: purpose ?? this.purpose,
- paymentMethod: paymentMethod ?? this.paymentMethod,
- isInvoiceVerified: isInvoiceVerified ?? this.isInvoiceVerified,
- isTaxIdMatched: isTaxIdMatched ?? this.isTaxIdMatched,
- isCategoryCompliant: isCategoryCompliant ?? this.isCategoryCompliant,
- bankTransferNo: bankTransferNo ?? this.bankTransferNo,
- paymentStatus: paymentStatus ?? this.paymentStatus,
- status: status ?? this.status,
- approvalInstanceId: approvalInstanceId ?? this.approvalInstanceId,
- previousInstanceIds: previousInstanceIds ?? this.previousInstanceIds,
- effectiveDate: effectiveDate ?? this.effectiveDate,
- auditorId: auditorId ?? this.auditorId,
- version: version ?? this.version,
- createTime: createTime ?? this.createTime,
- updateTime: updateTime ?? this.updateTime,
- isDeleted: isDeleted ?? this.isDeleted,
- currentApproverId: currentApproverId ?? this.currentApproverId,
- approvalChain: approvalChain ?? this.approvalChain,
- approvalRecords: approvalRecords ?? this.approvalRecords,
- details: details ?? this.details,
- attachments: attachments ?? this.attachments,
- );
- }
- }
- /// 费用报销明细,对应 [ExpenseDetail] 表。
- class ExpenseDetailModel {
- final String id;
- final String expenseId;
- final String expenseApplyId;
- final String expenseApplyNo;
- final DateTime? expenseApplyDate;
- final String expenseCategory;
- final String purpose;
- final String projectId;
- final String projectName;
- final String costDeptId;
- final String costDeptName;
- final String acctSubjectId;
- final String acctSubjectName;
- final double amount;
- final double taxRate;
- final double taxAmount;
- final double totalAmount;
- final String currencyCode;
- final double exchangeRate;
- final double baseAmount;
- final double approvedAmount;
- final String customerVendorId;
- final String customerVendorName;
- final double offsetAmount;
- final String bankName;
- final String bankAccountName;
- final String bankAccount;
- final String remark;
- final int sortOrder;
- final List<String> attachments;
- final DateTime createTime;
- final DateTime updateTime;
- final bool isDeleted;
- const ExpenseDetailModel({
- required this.id,
- required this.expenseId,
- this.expenseApplyId = '',
- this.expenseApplyNo = '',
- this.expenseApplyDate,
- this.expenseCategory = '',
- this.purpose = '',
- this.projectId = '',
- this.projectName = '',
- this.costDeptId = '',
- this.costDeptName = '',
- this.acctSubjectId = '',
- this.acctSubjectName = '',
- required this.amount,
- this.taxRate = 0.0,
- this.taxAmount = 0.0,
- required this.totalAmount,
- this.currencyCode = 'CNY',
- this.exchangeRate = 1.0,
- this.baseAmount = 0.0,
- this.approvedAmount = 0.0,
- this.customerVendorId = '',
- this.customerVendorName = '',
- this.offsetAmount = 0.0,
- this.bankName = '',
- this.bankAccountName = '',
- this.bankAccount = '',
- this.remark = '',
- this.sortOrder = 1,
- this.attachments = const [],
- required this.createTime,
- required this.updateTime,
- this.isDeleted = false,
- });
- factory ExpenseDetailModel.fromJson(Map<String, dynamic> json) {
- return ExpenseDetailModel(
- id: json['id'] as String,
- expenseId: json['expenseId'] as String? ?? '',
- expenseApplyId: json['expenseApplyId'] as String? ?? '',
- expenseApplyNo: json['expenseApplyNo'] as String? ?? '',
- expenseApplyDate: json['expenseApplyDate'] != null
- ? DateTime.parse(json['expenseApplyDate'] as String)
- : null,
- expenseCategory: json['expenseCategory'] as String? ?? '',
- purpose: json['purpose'] as String? ?? '',
- projectId: json['projectId'] as String? ?? '',
- projectName: json['projectName'] as String? ?? '',
- costDeptId: json['costDeptId'] as String? ?? '',
- costDeptName: json['costDeptName'] as String? ?? '',
- acctSubjectId: json['acctSubjectId'] as String? ?? '',
- acctSubjectName: json['acctSubjectName'] as String? ?? '',
- amount: (json['amount'] as num?)?.toDouble() ?? 0.0,
- taxRate: (json['taxRate'] as num?)?.toDouble() ?? 0.0,
- taxAmount: (json['taxAmount'] as num?)?.toDouble() ?? 0.0,
- totalAmount: (json['totalAmount'] as num?)?.toDouble() ?? 0.0,
- currencyCode: json['currencyCode'] as String? ?? 'CNY',
- exchangeRate: (json['exchangeRate'] as num?)?.toDouble() ?? 1.0,
- baseAmount: (json['baseAmount'] as num?)?.toDouble() ?? 0.0,
- approvedAmount: (json['approvedAmount'] as num?)?.toDouble() ?? 0.0,
- customerVendorId: json['customerVendorId'] as String? ?? '',
- customerVendorName: json['customerVendorName'] as String? ?? '',
- offsetAmount: (json['offsetAmount'] as num?)?.toDouble() ?? 0.0,
- bankName: json['bankName'] as String? ?? '',
- bankAccountName: json['bankAccountName'] as String? ?? '',
- bankAccount: json['bankAccount'] as String? ?? '',
- remark: json['remark'] as String? ?? '',
- sortOrder: json['sortOrder'] as int? ?? 1,
- attachments:
- (json['attachments'] as List<dynamic>?)
- ?.map((e) => e as String)
- .toList() ??
- [],
- createTime: DateTime.parse(json['createTime'] as String),
- updateTime: DateTime.parse(json['updateTime'] as String),
- isDeleted: json['isDeleted'] as bool? ?? false,
- );
- }
- Map<String, dynamic> toJson() => {
- 'id': id,
- 'expenseId': expenseId,
- 'expenseApplyId': expenseApplyId,
- 'expenseApplyNo': expenseApplyNo,
- 'expenseApplyDate': expenseApplyDate?.toIso8601String(),
- 'expenseCategory': expenseCategory,
- 'purpose': purpose,
- 'projectId': projectId,
- 'projectName': projectName,
- 'costDeptId': costDeptId,
- 'costDeptName': costDeptName,
- 'acctSubjectId': acctSubjectId,
- 'acctSubjectName': acctSubjectName,
- 'amount': amount,
- 'taxRate': taxRate,
- 'taxAmount': taxAmount,
- 'totalAmount': totalAmount,
- 'currencyCode': currencyCode,
- 'exchangeRate': exchangeRate,
- 'baseAmount': baseAmount,
- 'approvedAmount': approvedAmount,
- 'customerVendorId': customerVendorId,
- 'customerVendorName': customerVendorName,
- 'offsetAmount': offsetAmount,
- 'bankName': bankName,
- 'bankAccountName': bankAccountName,
- 'bankAccount': bankAccount,
- 'remark': remark,
- 'sortOrder': sortOrder,
- 'attachments': attachments,
- 'createTime': createTime.toIso8601String(),
- 'updateTime': updateTime.toIso8601String(),
- 'isDeleted': isDeleted,
- };
- ExpenseDetailModel copyWith({
- String? id,
- String? expenseId,
- String? expenseApplyId,
- String? expenseApplyNo,
- DateTime? expenseApplyDate,
- String? expenseCategory,
- String? purpose,
- String? projectId,
- String? projectName,
- String? costDeptId,
- String? costDeptName,
- String? acctSubjectId,
- String? acctSubjectName,
- double? amount,
- double? taxRate,
- double? taxAmount,
- double? totalAmount,
- String? currencyCode,
- double? exchangeRate,
- double? baseAmount,
- double? approvedAmount,
- String? customerVendorId,
- String? customerVendorName,
- double? offsetAmount,
- String? bankName,
- String? bankAccountName,
- String? bankAccount,
- String? remark,
- int? sortOrder,
- List<String>? attachments,
- DateTime? createTime,
- DateTime? updateTime,
- bool? isDeleted,
- }) {
- return ExpenseDetailModel(
- id: id ?? this.id,
- expenseId: expenseId ?? this.expenseId,
- expenseApplyId: expenseApplyId ?? this.expenseApplyId,
- expenseApplyNo: expenseApplyNo ?? this.expenseApplyNo,
- expenseApplyDate: expenseApplyDate ?? this.expenseApplyDate,
- expenseCategory: expenseCategory ?? this.expenseCategory,
- purpose: purpose ?? this.purpose,
- projectId: projectId ?? this.projectId,
- projectName: projectName ?? this.projectName,
- costDeptId: costDeptId ?? this.costDeptId,
- costDeptName: costDeptName ?? this.costDeptName,
- acctSubjectId: acctSubjectId ?? this.acctSubjectId,
- acctSubjectName: acctSubjectName ?? this.acctSubjectName,
- amount: amount ?? this.amount,
- taxRate: taxRate ?? this.taxRate,
- taxAmount: taxAmount ?? this.taxAmount,
- totalAmount: totalAmount ?? this.totalAmount,
- currencyCode: currencyCode ?? this.currencyCode,
- exchangeRate: exchangeRate ?? this.exchangeRate,
- baseAmount: baseAmount ?? this.baseAmount,
- approvedAmount: approvedAmount ?? this.approvedAmount,
- customerVendorId: customerVendorId ?? this.customerVendorId,
- customerVendorName: customerVendorName ?? this.customerVendorName,
- offsetAmount: offsetAmount ?? this.offsetAmount,
- bankName: bankName ?? this.bankName,
- bankAccountName: bankAccountName ?? this.bankAccountName,
- bankAccount: bankAccount ?? this.bankAccount,
- remark: remark ?? this.remark,
- sortOrder: sortOrder ?? this.sortOrder,
- attachments: attachments ?? this.attachments,
- createTime: createTime ?? this.createTime,
- updateTime: updateTime ?? this.updateTime,
- isDeleted: isDeleted ?? this.isDeleted,
- );
- }
- }
|