overtime_apply_model.dart 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /// 加班申请主表,对应 OA_OVERTIME 表。
  2. class OvertimeApplyModel {
  3. final String jbNo; // JB_NO 加班单号(主键)
  4. final DateTime? jbDd; // JB_DD 申请日期
  5. final String salNo; // SAL_NO 申请人
  6. final String salName; // SAL_NAME 申请人姓名(瞬态)
  7. final String dep; // DEP 所属部门
  8. final String depName; // DEP_NAME 部门名称(瞬态)
  9. final String reason; // REASON 加班原因
  10. final String rem; // REM 备注
  11. final String usr; // USR 录入人
  12. final DateTime? recordDd; // RECORD_DD 录入日期
  13. final String chkMan; // CHK_MAN 审核人
  14. final DateTime? clsDate; // CLS_DATE 终审日期
  15. final bool isAuditApproved; // 瞬态:审批状态
  16. final double totalJbHours; // 明细加班时长合计(列表API返回)
  17. // ── 子表 ──
  18. final List<OvertimeApplyDetailModel> details;
  19. const OvertimeApplyModel({
  20. required this.jbNo,
  21. this.jbDd,
  22. this.salNo = '',
  23. this.salName = '',
  24. this.dep = '',
  25. this.depName = '',
  26. this.reason = '',
  27. this.rem = '',
  28. this.usr = '',
  29. this.recordDd,
  30. this.chkMan = '',
  31. this.clsDate,
  32. this.isAuditApproved = false,
  33. this.totalJbHours = 0,
  34. this.details = const [],
  35. });
  36. factory OvertimeApplyModel.fromJson(Map<String, dynamic> json) {
  37. return OvertimeApplyModel(
  38. jbNo: json['JB_NO'] as String? ?? '',
  39. jbDd: json['JB_DD'] != null
  40. ? DateTime.tryParse(json['JB_DD'] as String)
  41. : null,
  42. salNo: json['SAL_NO'] as String? ?? '',
  43. salName: json['SAL_NAME'] as String? ?? json['NAME'] as String? ?? '',
  44. dep: json['DEP'] as String? ?? '',
  45. depName: json['DEP_NAME'] as String? ?? '',
  46. reason: json['REASON'] as String? ?? '',
  47. rem: json['REM'] as String? ?? '',
  48. usr: json['USR'] as String? ?? '',
  49. recordDd: json['RECORD_DD'] != null
  50. ? DateTime.tryParse(json['RECORD_DD'] as String)
  51. : null,
  52. chkMan: json['CHK_MAN'] as String? ?? '',
  53. clsDate: json['CLS_DATE'] != null
  54. ? DateTime.tryParse(json['CLS_DATE'] as String)
  55. : null,
  56. isAuditApproved: (json['isAuditApproved'] as int?) == 1,
  57. totalJbHours: (json['TotalJbHours'] as num?)?.toDouble() ??
  58. (json['totalJbHours'] as num?)?.toDouble() ??
  59. 0,
  60. details: _parseDetails(json['Details'] ?? json['details']),
  61. );
  62. }
  63. Map<String, dynamic> toJson() => {
  64. 'JB_NO': jbNo,
  65. 'JB_DD': jbDd?.toIso8601String(),
  66. 'SAL_NO': salNo,
  67. 'SAL_NAME': salName,
  68. 'DEP': dep,
  69. 'DEP_NAME': depName,
  70. 'REASON': reason,
  71. 'REM': rem,
  72. 'USR': usr,
  73. 'RECORD_DD': recordDd?.toIso8601String(),
  74. 'CHK_MAN': chkMan,
  75. 'CLS_DATE': clsDate?.toIso8601String(),
  76. 'isAuditApproved': isAuditApproved ? 1 : 0,
  77. 'details': details.map((d) => d.toJson()).toList(),
  78. };
  79. static List<OvertimeApplyDetailModel> _parseDetails(dynamic data) {
  80. if (data == null) return [];
  81. if (data is List) {
  82. return data
  83. .map((e) =>
  84. OvertimeApplyDetailModel.fromJson(e as Map<String, dynamic>))
  85. .toList();
  86. }
  87. return [];
  88. }
  89. OvertimeApplyModel copyWith({
  90. String? jbNo,
  91. DateTime? jbDd,
  92. String? salNo,
  93. String? salName,
  94. String? dep,
  95. String? depName,
  96. String? reason,
  97. String? rem,
  98. String? usr,
  99. DateTime? recordDd,
  100. String? chkMan,
  101. DateTime? clsDate,
  102. bool? isAuditApproved,
  103. List<OvertimeApplyDetailModel>? details,
  104. }) {
  105. return OvertimeApplyModel(
  106. jbNo: jbNo ?? this.jbNo,
  107. jbDd: jbDd ?? this.jbDd,
  108. salNo: salNo ?? this.salNo,
  109. salName: salName ?? this.salName,
  110. dep: dep ?? this.dep,
  111. depName: depName ?? this.depName,
  112. reason: reason ?? this.reason,
  113. rem: rem ?? this.rem,
  114. usr: usr ?? this.usr,
  115. recordDd: recordDd ?? this.recordDd,
  116. chkMan: chkMan ?? this.chkMan,
  117. clsDate: clsDate ?? this.clsDate,
  118. isAuditApproved: isAuditApproved ?? this.isAuditApproved,
  119. details: details ?? this.details,
  120. );
  121. }
  122. }
  123. /// 加班明细,对应 OA_OVERTIME_DETAIL 表。
  124. class OvertimeApplyDetailModel {
  125. final int itm; // ITM 项次
  126. final String? jbNo; // JB_NO 加班单号
  127. final String salNo; // SAL_NO 员工代号
  128. final String salName; // 员工姓名(瞬态)
  129. final String dep; // DEP 部门
  130. final String
  131. jbType; // JB_TYPE: WORKING_DAY/REST_DAY/PUBLIC_HOLIDAY/SPECIAL_HOLIDAY/OTHER
  132. final DateTime? jbDate; // JB_DATE 加班日期
  133. final DateTime? startTime; // START_TIME 开始时间
  134. final DateTime? endTime; // END_TIME 结束时间
  135. final double jbHours; // JB_HOURS 加班时长
  136. final double jbDays; // JB_DAYS 加班天数
  137. final String attPeriod; // ATT_PERIOD 考勤周期 yyyy-MM
  138. final String reason; // REASON 事由
  139. final String
  140. compensationType; // COMPENSATION_TYPE: OVERTIME_PAY/COMPENSATORY_LEAVE/NO_COMPENSATION/OTHER
  141. final double compensationCount; // COMPENSATION_COUNT 折算补偿次数
  142. final String adr; // ADR 地点
  143. final String rem; // REM 备注
  144. final int dayOfWeek; // DAY_OF_WEEK 星期几标记位(0=无, 1=日~7=六)
  145. const OvertimeApplyDetailModel({
  146. this.itm = 0,
  147. this.jbNo = '',
  148. this.salNo = '',
  149. this.salName = '',
  150. this.dep = '',
  151. this.jbType = 'WORKING_DAY',
  152. this.jbDate,
  153. this.startTime,
  154. this.endTime,
  155. this.jbHours = 0.0,
  156. this.jbDays = 0.0,
  157. this.attPeriod = '',
  158. this.reason = '',
  159. this.compensationType = 'OVERTIME_PAY',
  160. this.compensationCount = 0.0,
  161. this.adr = '',
  162. this.rem = '',
  163. this.dayOfWeek = 0,
  164. });
  165. factory OvertimeApplyDetailModel.fromJson(Map<String, dynamic> json) {
  166. return OvertimeApplyDetailModel(
  167. jbNo: json['JB_NO'] as String?,
  168. itm: json['ITM'] as int? ?? 0,
  169. salNo: json['SAL_NO'] as String? ?? '',
  170. salName: json['SAL_NAME'] as String? ?? '',
  171. dep: json['DEP'] as String? ?? '',
  172. jbType: json['JB_TYPE'] as String? ?? 'WORKING_DAY',
  173. jbDate: json['JB_DATE'] != null
  174. ? DateTime.tryParse(json['JB_DATE'] as String)
  175. : null,
  176. startTime: json['START_TIME'] != null
  177. ? DateTime.tryParse(json['START_TIME'] as String)
  178. : null,
  179. endTime: json['END_TIME'] != null
  180. ? DateTime.tryParse(json['END_TIME'] as String)
  181. : null,
  182. jbHours: (json['JB_HOURS'] as num?)?.toDouble() ?? 0.0,
  183. jbDays: (json['JB_DAYS'] as num?)?.toDouble() ?? 0.0,
  184. attPeriod: json['ATT_PERIOD'] as String? ?? '',
  185. reason: json['REASON'] as String? ?? '',
  186. compensationType: json['COMPENSATION_TYPE'] as String? ?? 'OVERTIME_PAY',
  187. compensationCount:
  188. (json['COMPENSATION_COUNT'] as num?)?.toDouble() ?? 0.0,
  189. adr: json['ADR'] as String? ?? '',
  190. rem: json['REM'] as String? ?? '',
  191. dayOfWeek: json['DAY_OF_WEEK'] is int
  192. ? json['DAY_OF_WEEK'] as int
  193. : int.tryParse(
  194. (json['DAY_OF_WEEK'] ?? json['dayOfWeek'])?.toString() ??
  195. '') ??
  196. 0,
  197. );
  198. }
  199. Map<String, dynamic> toJson() => {
  200. 'JB_NO': jbNo,
  201. 'ITM': itm,
  202. 'SAL_NO': salNo,
  203. 'SAL_NAME': salName,
  204. 'DEP': dep,
  205. 'JB_TYPE': jbType,
  206. 'JB_DATE': jbDate?.toIso8601String(),
  207. 'START_TIME': startTime?.toIso8601String(),
  208. 'END_TIME': endTime?.toIso8601String(),
  209. 'JB_HOURS': jbHours,
  210. 'JB_DAYS': jbDays,
  211. 'ATT_PERIOD': attPeriod,
  212. 'REASON': reason,
  213. 'COMPENSATION_TYPE': compensationType,
  214. 'COMPENSATION_COUNT': compensationCount,
  215. 'ADR': adr,
  216. 'REM': rem,
  217. 'DAY_OF_WEEK': dayOfWeek.toString(),
  218. };
  219. OvertimeApplyDetailModel copyWith({
  220. int? itm,
  221. String? jbNo,
  222. String? salNo,
  223. String? salName,
  224. String? dep,
  225. String? jbType,
  226. DateTime? jbDate,
  227. DateTime? startTime,
  228. DateTime? endTime,
  229. double? jbHours,
  230. double? jbDays,
  231. String? attPeriod,
  232. String? reason,
  233. String? compensationType,
  234. double? compensationCount,
  235. String? adr,
  236. String? rem,
  237. int? dayOfWeek,
  238. }) {
  239. return OvertimeApplyDetailModel(
  240. itm: itm ?? this.itm,
  241. jbNo: jbNo ?? this.jbNo,
  242. salNo: salNo ?? this.salNo,
  243. salName: salName ?? this.salName,
  244. dep: dep ?? this.dep,
  245. jbType: jbType ?? this.jbType,
  246. jbDate: jbDate ?? this.jbDate,
  247. startTime: startTime ?? this.startTime,
  248. endTime: endTime ?? this.endTime,
  249. jbHours: jbHours ?? this.jbHours,
  250. jbDays: jbDays ?? this.jbDays,
  251. attPeriod: attPeriod ?? this.attPeriod,
  252. reason: reason ?? this.reason,
  253. compensationType: compensationType ?? this.compensationType,
  254. compensationCount: compensationCount ?? this.compensationCount,
  255. adr: adr ?? this.adr,
  256. rem: rem ?? this.rem,
  257. dayOfWeek: dayOfWeek ?? this.dayOfWeek,
  258. );
  259. }
  260. }