expense_apply_model.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import '../../shared/models/approval_status.dart';
  2. /// 费用申请主表,对应 [ExpenseApply] 表。
  3. class ExpenseApplyModel {
  4. final String id;
  5. final String expenseApplyNo;
  6. final DateTime? expenseApplyDate;
  7. final String applicantId;
  8. final String applicantName;
  9. final String deptId;
  10. final String deptName;
  11. final double estimatedAmount;
  12. final String urgency;
  13. final String purpose;
  14. final String remark;
  15. final DateTime? effectiveDate;
  16. final String auditorId;
  17. final String status;
  18. final String usageStatus;
  19. final DateTime? validUntil;
  20. final String referenceNo;
  21. final String approvalInstanceId;
  22. final String previousInstanceIds;
  23. final int version;
  24. final DateTime createTime;
  25. final DateTime updateTime;
  26. final bool isDeleted;
  27. // ── 瞬态字段(API 从 ERP 实时查询,非存储) ──
  28. final String currentApproverId;
  29. final List<String> approvalChain;
  30. final List<ApprovalRecord> approvalRecords;
  31. // ── 子表 ──
  32. final List<ExpenseApplyDetailModel> details;
  33. final List<String> attachments;
  34. const ExpenseApplyModel({
  35. required this.id,
  36. required this.expenseApplyNo,
  37. this.expenseApplyDate,
  38. this.applicantId = '',
  39. this.applicantName = '',
  40. this.deptId = '',
  41. this.deptName = '',
  42. this.estimatedAmount = 0.0,
  43. this.urgency = 'normal',
  44. this.purpose = '',
  45. this.remark = '',
  46. this.effectiveDate,
  47. this.auditorId = '',
  48. this.status = 'draft',
  49. this.usageStatus = 'unused',
  50. this.validUntil,
  51. this.referenceNo = '',
  52. this.approvalInstanceId = '',
  53. this.previousInstanceIds = '',
  54. this.version = 1,
  55. required this.createTime,
  56. required this.updateTime,
  57. this.isDeleted = false,
  58. this.currentApproverId = '',
  59. this.approvalChain = const [],
  60. this.approvalRecords = const [],
  61. this.details = const [],
  62. this.attachments = const [],
  63. });
  64. factory ExpenseApplyModel.fromJson(Map<String, dynamic> json) {
  65. return ExpenseApplyModel(
  66. id: json['id'] as String,
  67. expenseApplyNo: json['expenseApplyNo'] as String? ?? '',
  68. expenseApplyDate: json['expenseApplyDate'] != null
  69. ? DateTime.parse(json['expenseApplyDate'] as String)
  70. : null,
  71. applicantId: json['applicantId'] as String? ?? '',
  72. applicantName: json['applicantName'] as String? ?? '',
  73. deptId: json['deptId'] as String? ?? '',
  74. deptName: json['deptName'] as String? ?? '',
  75. estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
  76. urgency: json['urgency'] as String? ?? 'normal',
  77. purpose: json['purpose'] as String? ?? '',
  78. remark: json['remark'] as String? ?? '',
  79. effectiveDate: json['effectiveDate'] != null
  80. ? DateTime.parse(json['effectiveDate'] as String)
  81. : null,
  82. auditorId: json['auditorId'] as String? ?? '',
  83. status: json['status'] as String? ?? 'draft',
  84. usageStatus: json['usageStatus'] as String? ?? 'unused',
  85. validUntil: json['validUntil'] != null
  86. ? DateTime.parse(json['validUntil'] as String)
  87. : null,
  88. referenceNo: json['referenceNo'] as String? ?? '',
  89. approvalInstanceId: json['approvalInstanceId'] as String? ?? '',
  90. previousInstanceIds: json['previousInstanceIds'] as String? ?? '',
  91. version: json['version'] as int? ?? 1,
  92. createTime: DateTime.parse(json['createTime'] as String),
  93. updateTime: DateTime.parse(json['updateTime'] as String),
  94. isDeleted: json['isDeleted'] as bool? ?? false,
  95. currentApproverId: json['currentApproverId'] as String? ?? '',
  96. approvalChain:
  97. (json['approvalChain'] as List<dynamic>?)
  98. ?.map((e) => e as String)
  99. .toList() ??
  100. [],
  101. approvalRecords:
  102. (json['approvalRecords'] as List<dynamic>?)
  103. ?.map((e) => ApprovalRecord.fromJson(e as Map<String, dynamic>))
  104. .toList() ??
  105. [],
  106. details:
  107. (json['details'] as List<dynamic>?)
  108. ?.map(
  109. (e) =>
  110. ExpenseApplyDetailModel.fromJson(e as Map<String, dynamic>),
  111. )
  112. .toList() ??
  113. [],
  114. attachments:
  115. (json['attachments'] as List<dynamic>?)
  116. ?.map((e) => e as String)
  117. .toList() ??
  118. [],
  119. );
  120. }
  121. Map<String, dynamic> toJson() => {
  122. 'id': id,
  123. 'expenseApplyNo': expenseApplyNo,
  124. 'expenseApplyDate': expenseApplyDate?.toIso8601String(),
  125. 'applicantId': applicantId,
  126. 'applicantName': applicantName,
  127. 'deptId': deptId,
  128. 'deptName': deptName,
  129. 'estimatedAmount': estimatedAmount,
  130. 'urgency': urgency,
  131. 'purpose': purpose,
  132. 'remark': remark,
  133. 'effectiveDate': effectiveDate?.toIso8601String(),
  134. 'auditorId': auditorId,
  135. 'status': status,
  136. 'usageStatus': usageStatus,
  137. 'validUntil': validUntil?.toIso8601String(),
  138. 'referenceNo': referenceNo,
  139. 'approvalInstanceId': approvalInstanceId,
  140. 'previousInstanceIds': previousInstanceIds,
  141. 'version': version,
  142. 'createTime': createTime.toIso8601String(),
  143. 'updateTime': updateTime.toIso8601String(),
  144. 'isDeleted': isDeleted,
  145. 'currentApproverId': currentApproverId,
  146. 'approvalChain': approvalChain,
  147. 'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(),
  148. 'details': details.map((d) => d.toJson()).toList(),
  149. 'attachments': attachments,
  150. };
  151. ExpenseApplyModel copyWith({
  152. String? id,
  153. String? expenseApplyNo,
  154. DateTime? expenseApplyDate,
  155. String? applicantId,
  156. String? applicantName,
  157. String? deptId,
  158. String? deptName,
  159. double? estimatedAmount,
  160. String? urgency,
  161. String? purpose,
  162. String? remark,
  163. DateTime? effectiveDate,
  164. String? auditorId,
  165. String? status,
  166. String? usageStatus,
  167. DateTime? validUntil,
  168. String? referenceNo,
  169. String? approvalInstanceId,
  170. String? previousInstanceIds,
  171. int? version,
  172. DateTime? createTime,
  173. DateTime? updateTime,
  174. bool? isDeleted,
  175. String? currentApproverId,
  176. List<String>? approvalChain,
  177. List<ApprovalRecord>? approvalRecords,
  178. List<ExpenseApplyDetailModel>? details,
  179. List<String>? attachments,
  180. }) {
  181. return ExpenseApplyModel(
  182. id: id ?? this.id,
  183. expenseApplyNo: expenseApplyNo ?? this.expenseApplyNo,
  184. expenseApplyDate: expenseApplyDate ?? this.expenseApplyDate,
  185. applicantId: applicantId ?? this.applicantId,
  186. applicantName: applicantName ?? this.applicantName,
  187. deptId: deptId ?? this.deptId,
  188. deptName: deptName ?? this.deptName,
  189. estimatedAmount: estimatedAmount ?? this.estimatedAmount,
  190. urgency: urgency ?? this.urgency,
  191. purpose: purpose ?? this.purpose,
  192. remark: remark ?? this.remark,
  193. effectiveDate: effectiveDate ?? this.effectiveDate,
  194. auditorId: auditorId ?? this.auditorId,
  195. status: status ?? this.status,
  196. usageStatus: usageStatus ?? this.usageStatus,
  197. validUntil: validUntil ?? this.validUntil,
  198. referenceNo: referenceNo ?? this.referenceNo,
  199. approvalInstanceId: approvalInstanceId ?? this.approvalInstanceId,
  200. previousInstanceIds: previousInstanceIds ?? this.previousInstanceIds,
  201. version: version ?? this.version,
  202. createTime: createTime ?? this.createTime,
  203. updateTime: updateTime ?? this.updateTime,
  204. isDeleted: isDeleted ?? this.isDeleted,
  205. currentApproverId: currentApproverId ?? this.currentApproverId,
  206. approvalChain: approvalChain ?? this.approvalChain,
  207. approvalRecords: approvalRecords ?? this.approvalRecords,
  208. details: details ?? this.details,
  209. attachments: attachments ?? this.attachments,
  210. );
  211. }
  212. }
  213. /// 费用申请预估明细,对应 [ExpenseApplyDetail] 表。
  214. class ExpenseApplyDetailModel {
  215. final String id;
  216. final String expenseApplyId;
  217. final String expenseCategory;
  218. final String purpose;
  219. final String projectId;
  220. final String projectName;
  221. final String costDeptId;
  222. final String costDeptName;
  223. final String acctSubjectId;
  224. final String acctSubjectName;
  225. final DateTime? estimatedStartDate;
  226. final DateTime? estimatedEndDate;
  227. final double estimatedAmount;
  228. final String remark;
  229. final int sortOrder;
  230. final DateTime createTime;
  231. final DateTime updateTime;
  232. final bool isDeleted;
  233. const ExpenseApplyDetailModel({
  234. required this.id,
  235. this.expenseApplyId = '',
  236. this.expenseCategory = '',
  237. this.purpose = '',
  238. this.projectId = '',
  239. this.projectName = '',
  240. this.costDeptId = '',
  241. this.costDeptName = '',
  242. this.acctSubjectId = '',
  243. this.acctSubjectName = '',
  244. this.estimatedStartDate,
  245. this.estimatedEndDate,
  246. this.estimatedAmount = 0.0,
  247. this.remark = '',
  248. this.sortOrder = 1,
  249. required this.createTime,
  250. required this.updateTime,
  251. this.isDeleted = false,
  252. });
  253. factory ExpenseApplyDetailModel.fromJson(Map<String, dynamic> json) {
  254. return ExpenseApplyDetailModel(
  255. id: json['id'] as String,
  256. expenseApplyId: json['expenseApplyId'] as String? ?? '',
  257. expenseCategory: json['expenseCategory'] as String? ?? '',
  258. purpose: json['purpose'] as String? ?? '',
  259. projectId: json['projectId'] as String? ?? '',
  260. projectName: json['projectName'] as String? ?? '',
  261. costDeptId: json['costDeptId'] as String? ?? '',
  262. costDeptName: json['costDeptName'] as String? ?? '',
  263. acctSubjectId: json['acctSubjectId'] as String? ?? '',
  264. acctSubjectName: json['acctSubjectName'] as String? ?? '',
  265. estimatedStartDate: json['estimatedStartDate'] != null
  266. ? DateTime.parse(json['estimatedStartDate'] as String)
  267. : null,
  268. estimatedEndDate: json['estimatedEndDate'] != null
  269. ? DateTime.parse(json['estimatedEndDate'] as String)
  270. : null,
  271. estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
  272. remark: json['remark'] as String? ?? '',
  273. sortOrder: json['sortOrder'] as int? ?? 1,
  274. createTime: DateTime.parse(json['createTime'] as String),
  275. updateTime: DateTime.parse(json['updateTime'] as String),
  276. isDeleted: json['isDeleted'] as bool? ?? false,
  277. );
  278. }
  279. Map<String, dynamic> toJson() => {
  280. 'id': id,
  281. 'expenseApplyId': expenseApplyId,
  282. 'expenseCategory': expenseCategory,
  283. 'purpose': purpose,
  284. 'projectId': projectId,
  285. 'projectName': projectName,
  286. 'costDeptId': costDeptId,
  287. 'costDeptName': costDeptName,
  288. 'acctSubjectId': acctSubjectId,
  289. 'acctSubjectName': acctSubjectName,
  290. 'estimatedStartDate': estimatedStartDate?.toIso8601String(),
  291. 'estimatedEndDate': estimatedEndDate?.toIso8601String(),
  292. 'estimatedAmount': estimatedAmount,
  293. 'remark': remark,
  294. 'sortOrder': sortOrder,
  295. 'createTime': createTime.toIso8601String(),
  296. 'updateTime': updateTime.toIso8601String(),
  297. 'isDeleted': isDeleted,
  298. };
  299. }