expense_apply_model.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. final int isTransferred;
  28. final bool isAuditApproved;
  29. // ── 瞬态字段(API 从 ERP 实时查询,非存储) ──
  30. final String currentApproverId;
  31. final List<String> approvalChain;
  32. final List<ApprovalRecord> approvalRecords;
  33. // ── 子表 ──
  34. final List<ExpenseApplyDetailModel> details;
  35. final List<String> attachments;
  36. const ExpenseApplyModel({
  37. required this.id,
  38. required this.expenseApplyNo,
  39. this.expenseApplyDate,
  40. this.applicantId = '',
  41. this.applicantName = '',
  42. this.deptId = '',
  43. this.deptName = '',
  44. this.estimatedAmount = 0.0,
  45. this.urgency = 'normal',
  46. this.purpose = '',
  47. this.remark = '',
  48. this.effectiveDate,
  49. this.auditorId = '',
  50. this.status = 'draft',
  51. this.usageStatus = 'unused',
  52. this.validUntil,
  53. this.referenceNo = '',
  54. this.approvalInstanceId = '',
  55. this.previousInstanceIds = '',
  56. this.version = 1,
  57. required this.createTime,
  58. required this.updateTime,
  59. this.isDeleted = false,
  60. this.isTransferred = 0,
  61. this.isAuditApproved = false,
  62. this.currentApproverId = '',
  63. this.approvalChain = const [],
  64. this.approvalRecords = const [],
  65. this.details = const [],
  66. this.attachments = const [],
  67. });
  68. factory ExpenseApplyModel.fromJson(Map<String, dynamic> json) {
  69. return ExpenseApplyModel(
  70. id: json['id'] as String? ?? '',
  71. expenseApplyNo: json['applyNo'] as String? ?? '',
  72. expenseApplyDate: json['applyDate'] != null
  73. ? DateTime.parse(json['applyDate'] as String)
  74. : null,
  75. applicantId: json['usr'] as String? ?? '',
  76. applicantName: json['applicantName'] as String? ?? json['usr'] as String? ?? '',
  77. deptId: json['dept'] as String? ?? '',
  78. deptName: json['deptName'] as String? ?? json['dep'] as String? ?? '',
  79. estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
  80. urgency: json['urgency'] as String? ?? json['priority'] as String? ?? 'normal',
  81. purpose: json['reason'] as String? ?? json['purpose'] as String? ?? '',
  82. remark: json['rem'] as String? ?? '',
  83. effectiveDate: json['effDd'] != null
  84. ? DateTime.parse(json['effDd'] as String)
  85. : null,
  86. auditorId: json['chkMan'] as String? ?? '',
  87. status: json['clsDate'] != null ? 'closed' : (json['status'] as String? ?? 'draft'),
  88. usageStatus: json['usageStatus'] as String? ?? 'unused',
  89. validUntil: json['validUntil'] != null
  90. ? DateTime.parse(json['validUntil'] as String)
  91. : null,
  92. referenceNo: json['referenceNo'] as String? ?? '',
  93. approvalInstanceId: json['approvalInstanceId'] as String? ?? '',
  94. previousInstanceIds: json['previousInstanceIds'] as String? ?? '',
  95. version: json['version'] as int? ?? 1,
  96. createTime: json['createTime'] != null
  97. ? DateTime.parse(json['createTime'] as String)
  98. : DateTime.now(),
  99. updateTime: json['updateTime'] != null
  100. ? DateTime.parse(json['updateTime'] as String)
  101. : DateTime.now(),
  102. isDeleted: json['isDeleted'] as bool? ?? false,
  103. isTransferred: json['isTransferred'] as int? ?? 0,
  104. isAuditApproved: (json['isAuditApproved'] as int?) == 1,
  105. currentApproverId: json['currentApproverId'] as String? ?? '',
  106. approvalChain:
  107. (json['approvalChain'] as List<dynamic>?)
  108. ?.map((e) => e as String)
  109. .toList() ??
  110. [],
  111. approvalRecords:
  112. (json['approvalRecords'] as List<dynamic>?)
  113. ?.map((e) => ApprovalRecord.fromJson(e as Map<String, dynamic>))
  114. .toList() ??
  115. [],
  116. details:
  117. (json['details'] as List<dynamic>?)
  118. ?.map(
  119. (e) =>
  120. ExpenseApplyDetailModel.fromJson(e as Map<String, dynamic>),
  121. )
  122. .toList() ??
  123. [],
  124. attachments:
  125. (json['attachments'] as List<dynamic>?)
  126. ?.map((e) => e as String)
  127. .toList() ??
  128. [],
  129. );
  130. }
  131. Map<String, dynamic> toJson() => {
  132. 'id': id,
  133. 'expenseApplyNo': expenseApplyNo,
  134. 'expenseApplyDate': expenseApplyDate?.toIso8601String(),
  135. 'applicantId': applicantId,
  136. 'applicantName': applicantName,
  137. 'deptId': deptId,
  138. 'deptName': deptName,
  139. 'estimatedAmount': estimatedAmount,
  140. 'urgency': urgency,
  141. 'purpose': purpose,
  142. 'remark': remark,
  143. 'effectiveDate': effectiveDate?.toIso8601String(),
  144. 'auditorId': auditorId,
  145. 'status': status,
  146. 'usageStatus': usageStatus,
  147. 'validUntil': validUntil?.toIso8601String(),
  148. 'referenceNo': referenceNo,
  149. 'approvalInstanceId': approvalInstanceId,
  150. 'previousInstanceIds': previousInstanceIds,
  151. 'version': version,
  152. 'createTime': createTime.toIso8601String(),
  153. 'updateTime': updateTime.toIso8601String(),
  154. 'isDeleted': isDeleted,
  155. 'isTransferred': isTransferred,
  156. 'isAuditApproved': isAuditApproved ? 1 : 0,
  157. 'currentApproverId': currentApproverId,
  158. 'approvalChain': approvalChain,
  159. 'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(),
  160. 'details': details.map((d) => d.toJson()).toList(),
  161. 'attachments': attachments,
  162. };
  163. ExpenseApplyModel copyWith({
  164. String? id,
  165. String? expenseApplyNo,
  166. DateTime? expenseApplyDate,
  167. String? applicantId,
  168. String? applicantName,
  169. String? deptId,
  170. String? deptName,
  171. double? estimatedAmount,
  172. String? urgency,
  173. String? purpose,
  174. String? remark,
  175. DateTime? effectiveDate,
  176. String? auditorId,
  177. String? status,
  178. String? usageStatus,
  179. DateTime? validUntil,
  180. String? referenceNo,
  181. String? approvalInstanceId,
  182. String? previousInstanceIds,
  183. int? version,
  184. DateTime? createTime,
  185. DateTime? updateTime,
  186. bool? isDeleted,
  187. int? isTransferred,
  188. bool? isAuditApproved,
  189. String? currentApproverId,
  190. List<String>? approvalChain,
  191. List<ApprovalRecord>? approvalRecords,
  192. List<ExpenseApplyDetailModel>? details,
  193. List<String>? attachments,
  194. }) {
  195. return ExpenseApplyModel(
  196. id: id ?? this.id,
  197. expenseApplyNo: expenseApplyNo ?? this.expenseApplyNo,
  198. expenseApplyDate: expenseApplyDate ?? this.expenseApplyDate,
  199. applicantId: applicantId ?? this.applicantId,
  200. applicantName: applicantName ?? this.applicantName,
  201. deptId: deptId ?? this.deptId,
  202. deptName: deptName ?? this.deptName,
  203. estimatedAmount: estimatedAmount ?? this.estimatedAmount,
  204. urgency: urgency ?? this.urgency,
  205. purpose: purpose ?? this.purpose,
  206. remark: remark ?? this.remark,
  207. effectiveDate: effectiveDate ?? this.effectiveDate,
  208. auditorId: auditorId ?? this.auditorId,
  209. status: status ?? this.status,
  210. usageStatus: usageStatus ?? this.usageStatus,
  211. validUntil: validUntil ?? this.validUntil,
  212. referenceNo: referenceNo ?? this.referenceNo,
  213. approvalInstanceId: approvalInstanceId ?? this.approvalInstanceId,
  214. previousInstanceIds: previousInstanceIds ?? this.previousInstanceIds,
  215. version: version ?? this.version,
  216. createTime: createTime ?? this.createTime,
  217. updateTime: updateTime ?? this.updateTime,
  218. isDeleted: isDeleted ?? this.isDeleted,
  219. isTransferred: isTransferred ?? this.isTransferred,
  220. isAuditApproved: isAuditApproved ?? this.isAuditApproved,
  221. currentApproverId: currentApproverId ?? this.currentApproverId,
  222. approvalChain: approvalChain ?? this.approvalChain,
  223. approvalRecords: approvalRecords ?? this.approvalRecords,
  224. details: details ?? this.details,
  225. attachments: attachments ?? this.attachments,
  226. );
  227. }
  228. }
  229. /// 费用申请预估明细,对应 [ExpenseApplyDetail] 表。
  230. class ExpenseApplyDetailModel {
  231. final String id;
  232. final String expenseApplyId;
  233. final String expenseCategory;
  234. final String categoryName;
  235. final String purpose;
  236. final String projectId;
  237. final String projectName;
  238. final String costDeptId;
  239. final String costDeptName;
  240. final String acctSubjectId;
  241. final String acctSubjectName;
  242. final String sqMan;
  243. final String sqName;
  244. final DateTime? estimatedStartDate;
  245. final DateTime? estimatedEndDate;
  246. final double estimatedAmount;
  247. final String bxNo;
  248. final String remark;
  249. final int? preItm;
  250. final int sortOrder;
  251. final DateTime createTime;
  252. final DateTime updateTime;
  253. final bool isDeleted;
  254. const ExpenseApplyDetailModel({
  255. required this.id,
  256. this.expenseApplyId = '',
  257. this.expenseCategory = '',
  258. this.categoryName = '',
  259. this.purpose = '',
  260. this.projectId = '',
  261. this.projectName = '',
  262. this.costDeptId = '',
  263. this.costDeptName = '',
  264. this.acctSubjectId = '',
  265. this.acctSubjectName = '',
  266. this.sqMan = '',
  267. this.sqName = '',
  268. this.estimatedStartDate,
  269. this.estimatedEndDate,
  270. this.estimatedAmount = 0.0,
  271. this.bxNo = '',
  272. this.remark = '',
  273. this.preItm,
  274. this.sortOrder = 1,
  275. required this.createTime,
  276. required this.updateTime,
  277. this.isDeleted = false,
  278. });
  279. factory ExpenseApplyDetailModel.fromJson(Map<String, dynamic> json) {
  280. return ExpenseApplyDetailModel(
  281. id: json['id'] as String? ?? '',
  282. expenseApplyId: json['aeNo'] as String? ?? '',
  283. expenseCategory: json['typeNo'] as String? ?? '',
  284. categoryName: json['typeName'] as String? ?? '',
  285. purpose: json['purpose'] as String? ?? '',
  286. projectId: json['objNo'] as String? ?? '',
  287. projectName: json['objName'] as String? ?? json['projectName'] as String? ?? '',
  288. costDeptId: json['dep'] as String? ?? '',
  289. costDeptName: json['depName'] as String? ?? json['dep'] as String? ?? '',
  290. acctSubjectId: json['accNo'] as String? ?? '',
  291. acctSubjectName: json['accName'] as String? ?? '',
  292. estimatedStartDate: json['startDd'] != null
  293. ? DateTime.parse(json['startDd'] as String)
  294. : null,
  295. estimatedEndDate: json['endDd'] != null
  296. ? DateTime.parse(json['endDd'] as String)
  297. : null,
  298. estimatedAmount: (json['amtnYj'] as num?)?.toDouble() ?? 0.0,
  299. bxNo: json['bxNo'] as String? ?? '',
  300. remark: json['rem'] as String? ?? '',
  301. preItm: json['preItm'] as int?,
  302. sqMan: json['sqMan'] as String? ?? '',
  303. sqName: json['sqName'] as String? ?? '',
  304. sortOrder: json['itm'] as int? ?? 1,
  305. createTime: json['createTime'] != null
  306. ? DateTime.parse(json['createTime'] as String)
  307. : DateTime.now(),
  308. updateTime: json['updateTime'] != null
  309. ? DateTime.parse(json['updateTime'] as String)
  310. : DateTime.now(),
  311. isDeleted: json['isDeleted'] as bool? ?? false,
  312. );
  313. }
  314. Map<String, dynamic> toJson() => {
  315. 'id': id,
  316. 'expenseApplyId': expenseApplyId,
  317. 'expenseCategory': expenseCategory,
  318. 'categoryName': categoryName,
  319. 'purpose': purpose,
  320. 'projectId': projectId,
  321. 'projectName': projectName,
  322. 'costDeptId': costDeptId,
  323. 'costDeptName': costDeptName,
  324. 'acctSubjectId': acctSubjectId,
  325. 'acctSubjectName': acctSubjectName,
  326. 'sqMan': sqMan,
  327. 'sqName': sqName,
  328. 'estimatedStartDate': estimatedStartDate?.toIso8601String(),
  329. 'estimatedEndDate': estimatedEndDate?.toIso8601String(),
  330. 'estimatedAmount': estimatedAmount,
  331. 'bxNo': bxNo,
  332. 'remark': remark,
  333. 'preItm': preItm,
  334. 'sortOrder': sortOrder,
  335. 'createTime': createTime.toIso8601String(),
  336. 'updateTime': updateTime.toIso8601String(),
  337. 'isDeleted': isDeleted,
  338. };
  339. }