overtime_model.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /// 加班申请主表,对应 OA_OT_APPLY 表。
  2. class OvertimeModel {
  3. final int applyId;
  4. final String billNo;
  5. final DateTime? applyDate;
  6. final String origBillNo;
  7. final String salesman;
  8. final String dept;
  9. final String customer;
  10. final String billType;
  11. final bool isClosed;
  12. final String feedback;
  13. final String remark;
  14. final int status;
  15. final String createUser;
  16. final DateTime createTime;
  17. final DateTime updateTime;
  18. // ── 瞬态字段(API 实时查询,非存储) ──
  19. final bool isAuditApproved;
  20. // ── 子表 ──
  21. final List<OvertimeDetailModel> details;
  22. const OvertimeModel({
  23. required this.applyId,
  24. this.billNo = '',
  25. this.applyDate,
  26. this.origBillNo = '',
  27. this.salesman = '',
  28. this.dept = '',
  29. this.customer = '',
  30. this.billType = '',
  31. this.isClosed = false,
  32. this.feedback = '',
  33. this.remark = '',
  34. this.status = 0,
  35. this.createUser = '',
  36. required this.createTime,
  37. required this.updateTime,
  38. this.isAuditApproved = false,
  39. this.details = const [],
  40. });
  41. factory OvertimeModel.fromJson(Map<String, dynamic> json) {
  42. return OvertimeModel(
  43. applyId: json['applyId'] as int? ?? 0,
  44. billNo: json['billNo'] as String? ?? '',
  45. applyDate: json['applyDate'] != null
  46. ? DateTime.tryParse(json['applyDate'] as String)
  47. : null,
  48. origBillNo: json['origBillNo'] as String? ?? '',
  49. salesman: json['salesman'] as String? ?? '',
  50. dept: json['dept'] as String? ?? '',
  51. customer: json['customer'] as String? ?? '',
  52. billType: json['billType'] as String? ?? '',
  53. isClosed: (json['isClosed'] as int?) == 1,
  54. feedback: json['feedback'] as String? ?? '',
  55. remark: json['remark'] as String? ?? '',
  56. status: json['status'] as int? ?? 0,
  57. createUser: json['createUser'] as String? ?? '',
  58. createTime: json['createTime'] != null
  59. ? DateTime.parse(json['createTime'] as String)
  60. : DateTime.now(),
  61. updateTime: json['updateTime'] != null
  62. ? DateTime.parse(json['updateTime'] as String)
  63. : DateTime.now(),
  64. isAuditApproved: (json['isAuditApproved'] as int?) == 1,
  65. details:
  66. (json['details'] as List<dynamic>?)
  67. ?.map(
  68. (e) => OvertimeDetailModel.fromJson(e as Map<String, dynamic>),
  69. )
  70. .toList() ??
  71. [],
  72. );
  73. }
  74. Map<String, dynamic> toJson() => {
  75. 'applyId': applyId,
  76. 'billNo': billNo,
  77. 'applyDate': applyDate?.toIso8601String(),
  78. 'origBillNo': origBillNo,
  79. 'salesman': salesman,
  80. 'dept': dept,
  81. 'customer': customer,
  82. 'billType': billType,
  83. 'isClosed': isClosed ? 1 : 0,
  84. 'feedback': feedback,
  85. 'remark': remark,
  86. 'status': status,
  87. 'createUser': createUser,
  88. 'createTime': createTime.toIso8601String(),
  89. 'updateTime': updateTime.toIso8601String(),
  90. 'isAuditApproved': isAuditApproved ? 1 : 0,
  91. 'details': details.map((d) => d.toJson()).toList(),
  92. };
  93. OvertimeModel copyWith({
  94. int? applyId,
  95. String? billNo,
  96. DateTime? applyDate,
  97. String? origBillNo,
  98. String? salesman,
  99. String? dept,
  100. String? customer,
  101. String? billType,
  102. bool? isClosed,
  103. String? feedback,
  104. String? remark,
  105. int? status,
  106. String? createUser,
  107. DateTime? createTime,
  108. DateTime? updateTime,
  109. bool? isAuditApproved,
  110. List<OvertimeDetailModel>? details,
  111. }) {
  112. return OvertimeModel(
  113. applyId: applyId ?? this.applyId,
  114. billNo: billNo ?? this.billNo,
  115. applyDate: applyDate ?? this.applyDate,
  116. origBillNo: origBillNo ?? this.origBillNo,
  117. salesman: salesman ?? this.salesman,
  118. dept: dept ?? this.dept,
  119. customer: customer ?? this.customer,
  120. billType: billType ?? this.billType,
  121. isClosed: isClosed ?? this.isClosed,
  122. feedback: feedback ?? this.feedback,
  123. remark: remark ?? this.remark,
  124. status: status ?? this.status,
  125. createUser: createUser ?? this.createUser,
  126. createTime: createTime ?? this.createTime,
  127. updateTime: updateTime ?? this.updateTime,
  128. isAuditApproved: isAuditApproved ?? this.isAuditApproved,
  129. details: details ?? this.details,
  130. );
  131. }
  132. }
  133. /// 加班明细,对应 OA_OT_DETAIL 表。
  134. class OvertimeDetailModel {
  135. final int detailId;
  136. final int applyId;
  137. final int seqNo;
  138. final String empCode;
  139. final String shiftType;
  140. final DateTime? startDate;
  141. final DateTime? endDate;
  142. final double approvedHours;
  143. final String isApproved;
  144. final String directOt;
  145. final double otQuantity;
  146. final String reason;
  147. final String handleMethod;
  148. final String chargeMethod;
  149. final String remark;
  150. final String isClosed;
  151. final String outBillNo;
  152. const OvertimeDetailModel({
  153. required this.detailId,
  154. this.applyId = 0,
  155. this.seqNo = 0,
  156. this.empCode = '',
  157. this.shiftType = '',
  158. this.startDate,
  159. this.endDate,
  160. this.approvedHours = 0.0,
  161. this.isApproved = 'N',
  162. this.directOt = 'N',
  163. this.otQuantity = 0.0,
  164. this.reason = '',
  165. this.handleMethod = '',
  166. this.chargeMethod = '',
  167. this.remark = '',
  168. this.isClosed = 'N',
  169. this.outBillNo = '',
  170. });
  171. factory OvertimeDetailModel.fromJson(Map<String, dynamic> json) {
  172. return OvertimeDetailModel(
  173. detailId: json['detailId'] as int? ?? 0,
  174. applyId: json['applyId'] as int? ?? 0,
  175. seqNo: json['seqNo'] as int? ?? 0,
  176. empCode: json['empCode'] as String? ?? '',
  177. shiftType: json['shiftType'] as String? ?? '',
  178. startDate: json['startDate'] != null
  179. ? DateTime.tryParse(json['startDate'] as String)
  180. : null,
  181. endDate: json['endDate'] != null
  182. ? DateTime.tryParse(json['endDate'] as String)
  183. : null,
  184. approvedHours: (json['approvedHours'] as num?)?.toDouble() ?? 0.0,
  185. isApproved: json['isApproved'] as String? ?? 'N',
  186. directOt: json['directOt'] as String? ?? 'N',
  187. otQuantity: (json['otQuantity'] as num?)?.toDouble() ?? 0.0,
  188. reason: json['reason'] as String? ?? '',
  189. handleMethod: json['handleMethod'] as String? ?? '',
  190. chargeMethod: json['chargeMethod'] as String? ?? '',
  191. remark: json['remark'] as String? ?? '',
  192. isClosed: json['isClosed'] as String? ?? 'N',
  193. outBillNo: json['outBillNo'] as String? ?? '',
  194. );
  195. }
  196. Map<String, dynamic> toJson() => {
  197. 'detailId': detailId,
  198. 'applyId': applyId,
  199. 'seqNo': seqNo,
  200. 'empCode': empCode,
  201. 'shiftType': shiftType,
  202. 'startDate': startDate?.toIso8601String(),
  203. 'endDate': endDate?.toIso8601String(),
  204. 'approvedHours': approvedHours,
  205. 'isApproved': isApproved,
  206. 'directOt': directOt,
  207. 'otQuantity': otQuantity,
  208. 'reason': reason,
  209. 'handleMethod': handleMethod,
  210. 'chargeMethod': chargeMethod,
  211. 'remark': remark,
  212. 'isClosed': isClosed,
  213. 'outBillNo': outBillNo,
  214. };
  215. }