overtime_apply_model.dart 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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 depName; // DEP_NAME 部门名称(瞬态)
  131. final String
  132. jbType; // JB_TYPE: WORKING_DAY/REST_DAY/PUBLIC_HOLIDAY/SPECIAL_HOLIDAY/OTHER
  133. final DateTime? jbDate; // JB_DATE 加班日期
  134. final DateTime? startTime; // START_TIME 开始时间
  135. final DateTime? endTime; // END_TIME 结束时间
  136. final double jbHours; // JB_HOURS 加班时长
  137. final double jbDays; // JB_DAYS 加班天数
  138. final String attPeriod; // ATT_PERIOD 考勤周期 yyyy-MM
  139. final String reason; // REASON 事由
  140. final String
  141. compensationType; // COMPENSATION_TYPE: OVERTIME_PAY/COMPENSATORY_LEAVE/NO_COMPENSATION/OTHER
  142. final double compensationCount; // COMPENSATION_COUNT 折算补偿次数
  143. final String adr; // ADR 地点
  144. final String rem; // REM 备注
  145. final int dayOfWeek; // DAY_OF_WEEK 星期几标记位(0=无, 1=日~7=六)
  146. const OvertimeApplyDetailModel({
  147. this.itm = 0,
  148. this.jbNo = '',
  149. this.salNo = '',
  150. this.salName = '',
  151. this.dep = '',
  152. this.depName = '',
  153. this.jbType = 'WORKING_DAY',
  154. this.jbDate,
  155. this.startTime,
  156. this.endTime,
  157. this.jbHours = 0.0,
  158. this.jbDays = 0.0,
  159. this.attPeriod = '',
  160. this.reason = '',
  161. this.compensationType = 'OVERTIME_PAY',
  162. this.compensationCount = 0.0,
  163. this.adr = '',
  164. this.rem = '',
  165. this.dayOfWeek = 0,
  166. });
  167. factory OvertimeApplyDetailModel.fromJson(Map<String, dynamic> json) {
  168. return OvertimeApplyDetailModel(
  169. jbNo: json['JB_NO'] as String?,
  170. itm: json['ITM'] as int? ?? 0,
  171. salNo: json['SAL_NO'] as String? ?? '',
  172. salName: json['SAL_NAME'] as String? ?? '',
  173. dep: json['DEP'] as String? ?? '',
  174. depName: json['DEP_NAME'] as String? ?? '',
  175. jbType: json['JB_TYPE'] as String? ?? 'WORKING_DAY',
  176. jbDate: json['JB_DATE'] != null
  177. ? DateTime.tryParse(json['JB_DATE'] as String)
  178. : null,
  179. startTime: json['START_TIME'] != null
  180. ? DateTime.tryParse(json['START_TIME'] as String)
  181. : null,
  182. endTime: json['END_TIME'] != null
  183. ? DateTime.tryParse(json['END_TIME'] as String)
  184. : null,
  185. jbHours: (json['JB_HOURS'] as num?)?.toDouble() ?? 0.0,
  186. jbDays: (json['JB_DAYS'] as num?)?.toDouble() ?? 0.0,
  187. attPeriod: json['ATT_PERIOD'] as String? ?? '',
  188. reason: json['REASON'] as String? ?? '',
  189. compensationType: json['COMPENSATION_TYPE'] as String? ?? 'OVERTIME_PAY',
  190. compensationCount:
  191. (json['COMPENSATION_COUNT'] as num?)?.toDouble() ?? 0.0,
  192. adr: json['ADR'] as String? ?? '',
  193. rem: json['REM'] as String? ?? '',
  194. dayOfWeek: json['DAY_OF_WEEK'] is int
  195. ? json['DAY_OF_WEEK'] as int
  196. : int.tryParse(
  197. (json['DAY_OF_WEEK'] ?? json['dayOfWeek'])?.toString() ??
  198. '') ??
  199. 0,
  200. );
  201. }
  202. Map<String, dynamic> toJson() => {
  203. 'JB_NO': jbNo,
  204. 'ITM': itm,
  205. 'SAL_NO': salNo,
  206. 'SAL_NAME': salName,
  207. 'DEP': dep,
  208. 'DEP_NAME': depName,
  209. 'JB_TYPE': jbType,
  210. 'JB_DATE': jbDate?.toIso8601String(),
  211. 'START_TIME': startTime?.toIso8601String(),
  212. 'END_TIME': endTime?.toIso8601String(),
  213. 'JB_HOURS': jbHours,
  214. 'JB_DAYS': jbDays,
  215. 'ATT_PERIOD': attPeriod,
  216. 'REASON': reason,
  217. 'COMPENSATION_TYPE': compensationType,
  218. 'COMPENSATION_COUNT': compensationCount,
  219. 'ADR': adr,
  220. 'REM': rem,
  221. 'DAY_OF_WEEK': dayOfWeek.toString(),
  222. };
  223. OvertimeApplyDetailModel copyWith({
  224. int? itm,
  225. String? jbNo,
  226. String? salNo,
  227. String? salName,
  228. String? dep,
  229. String? depName,
  230. String? jbType,
  231. DateTime? jbDate,
  232. DateTime? startTime,
  233. DateTime? endTime,
  234. double? jbHours,
  235. double? jbDays,
  236. String? attPeriod,
  237. String? reason,
  238. String? compensationType,
  239. double? compensationCount,
  240. String? adr,
  241. String? rem,
  242. int? dayOfWeek,
  243. }) {
  244. return OvertimeApplyDetailModel(
  245. itm: itm ?? this.itm,
  246. jbNo: jbNo ?? this.jbNo,
  247. salNo: salNo ?? this.salNo,
  248. salName: salName ?? this.salName,
  249. dep: dep ?? this.dep,
  250. depName: depName ?? this.depName,
  251. jbType: jbType ?? this.jbType,
  252. jbDate: jbDate ?? this.jbDate,
  253. startTime: startTime ?? this.startTime,
  254. endTime: endTime ?? this.endTime,
  255. jbHours: jbHours ?? this.jbHours,
  256. jbDays: jbDays ?? this.jbDays,
  257. attPeriod: attPeriod ?? this.attPeriod,
  258. reason: reason ?? this.reason,
  259. compensationType: compensationType ?? this.compensationType,
  260. compensationCount: compensationCount ?? this.compensationCount,
  261. adr: adr ?? this.adr,
  262. rem: rem ?? this.rem,
  263. dayOfWeek: dayOfWeek ?? this.dayOfWeek,
  264. );
  265. }
  266. }