overtime_apply_model.dart 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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:
  57. json['IsAuditApproved'] == true ||
  58. (json['isAuditApproved'] as int?) == 1,
  59. totalJbHours:
  60. (json['TotalJbHours'] as num?)?.toDouble() ??
  61. (json['totalJbHours'] as num?)?.toDouble() ??
  62. 0,
  63. details: _parseDetails(json['Details'] ?? json['details']),
  64. );
  65. }
  66. Map<String, dynamic> toJson() => {
  67. 'JB_NO': jbNo,
  68. 'JB_DD': jbDd?.toIso8601String(),
  69. 'SAL_NO': salNo,
  70. 'SAL_NAME': salName,
  71. 'DEP': dep,
  72. 'DEP_NAME': depName,
  73. 'REASON': reason,
  74. 'REM': rem,
  75. 'USR': usr,
  76. 'RECORD_DD': recordDd?.toIso8601String(),
  77. 'CHK_MAN': chkMan,
  78. 'CLS_DATE': clsDate?.toIso8601String(),
  79. 'isAuditApproved': isAuditApproved ? 1 : 0,
  80. 'details': details.map((d) => d.toJson()).toList(),
  81. };
  82. static List<OvertimeApplyDetailModel> _parseDetails(dynamic data) {
  83. if (data == null) return [];
  84. if (data is List) {
  85. return data
  86. .map(
  87. (e) => OvertimeApplyDetailModel.fromJson(e as Map<String, dynamic>),
  88. )
  89. .toList();
  90. }
  91. return [];
  92. }
  93. OvertimeApplyModel copyWith({
  94. String? jbNo,
  95. DateTime? jbDd,
  96. String? salNo,
  97. String? salName,
  98. String? dep,
  99. String? depName,
  100. String? reason,
  101. String? rem,
  102. String? usr,
  103. DateTime? recordDd,
  104. String? chkMan,
  105. DateTime? clsDate,
  106. bool? isAuditApproved,
  107. List<OvertimeApplyDetailModel>? details,
  108. }) {
  109. return OvertimeApplyModel(
  110. jbNo: jbNo ?? this.jbNo,
  111. jbDd: jbDd ?? this.jbDd,
  112. salNo: salNo ?? this.salNo,
  113. salName: salName ?? this.salName,
  114. dep: dep ?? this.dep,
  115. depName: depName ?? this.depName,
  116. reason: reason ?? this.reason,
  117. rem: rem ?? this.rem,
  118. usr: usr ?? this.usr,
  119. recordDd: recordDd ?? this.recordDd,
  120. chkMan: chkMan ?? this.chkMan,
  121. clsDate: clsDate ?? this.clsDate,
  122. isAuditApproved: isAuditApproved ?? this.isAuditApproved,
  123. details: details ?? this.details,
  124. );
  125. }
  126. }
  127. /// 加班明细,对应 OA_OVERTIME_DETAIL 表。
  128. class OvertimeApplyDetailModel {
  129. final int itm; // ITM 项次
  130. final String? jbNo; // JB_NO 加班单号
  131. final String salNo; // SAL_NO 员工代号
  132. final String salName; // 员工姓名(瞬态)
  133. final String dep; // DEP 部门
  134. final String depName; // DEP_NAME 部门名称(瞬态)
  135. final String
  136. jbType; // JB_TYPE: WORKING_DAY/REST_DAY/PUBLIC_HOLIDAY/SPECIAL_HOLIDAY/OTHER
  137. final DateTime? jbDate; // JB_DATE 加班日期
  138. final DateTime? startTime; // START_TIME 开始时间
  139. final DateTime? endTime; // END_TIME 结束时间
  140. final double jbHours; // JB_HOURS 加班时长
  141. final double jbDays; // JB_DAYS 加班天数
  142. final String attPeriod; // ATT_PERIOD 考勤周期 yyyy-MM
  143. final String reason; // REASON 事由
  144. final String
  145. compensationType; // COMPENSATION_TYPE: OVERTIME_PAY/COMPENSATORY_LEAVE/NO_COMPENSATION/OTHER
  146. final double compensationCount; // COMPENSATION_COUNT 折算补偿次数
  147. final String adr; // ADR 地点
  148. final String rem; // REM 备注
  149. final int dayOfWeek; // DAY_OF_WEEK 星期几标记位(0=无, 1=日~7=六)
  150. const OvertimeApplyDetailModel({
  151. this.itm = 0,
  152. this.jbNo = '',
  153. this.salNo = '',
  154. this.salName = '',
  155. this.dep = '',
  156. this.depName = '',
  157. this.jbType = 'WORKING_DAY',
  158. this.jbDate,
  159. this.startTime,
  160. this.endTime,
  161. this.jbHours = 0.0,
  162. this.jbDays = 0.0,
  163. this.attPeriod = '',
  164. this.reason = '',
  165. this.compensationType = 'OVERTIME_PAY',
  166. this.compensationCount = 0.0,
  167. this.adr = '',
  168. this.rem = '',
  169. this.dayOfWeek = 0,
  170. });
  171. factory OvertimeApplyDetailModel.fromJson(Map<String, dynamic> json) {
  172. return OvertimeApplyDetailModel(
  173. jbNo: json['JB_NO'] as String?,
  174. itm: json['ITM'] as int? ?? 0,
  175. salNo: json['SAL_NO'] as String? ?? '',
  176. salName: json['SAL_NAME'] as String? ?? '',
  177. dep: json['DEP'] as String? ?? '',
  178. depName: json['DEP_NAME'] as String? ?? '',
  179. jbType: json['JB_TYPE'] as String? ?? 'WORKING_DAY',
  180. jbDate: json['JB_DATE'] != null
  181. ? DateTime.tryParse(json['JB_DATE'] as String)
  182. : null,
  183. startTime: json['START_TIME'] != null
  184. ? DateTime.tryParse(json['START_TIME'] as String)
  185. : null,
  186. endTime: json['END_TIME'] != null
  187. ? DateTime.tryParse(json['END_TIME'] as String)
  188. : null,
  189. jbHours: (json['JB_HOURS'] as num?)?.toDouble() ?? 0.0,
  190. jbDays: (json['JB_DAYS'] as num?)?.toDouble() ?? 0.0,
  191. attPeriod: json['ATT_PERIOD'] as String? ?? '',
  192. reason: json['REASON'] as String? ?? '',
  193. compensationType: json['COMPENSATION_TYPE'] as String? ?? 'OVERTIME_PAY',
  194. compensationCount:
  195. (json['COMPENSATION_COUNT'] as num?)?.toDouble() ?? 0.0,
  196. adr: json['ADR'] as String? ?? '',
  197. rem: json['REM'] as String? ?? '',
  198. dayOfWeek: json['DAY_OF_WEEK'] is int
  199. ? json['DAY_OF_WEEK'] as int
  200. : int.tryParse(
  201. (json['DAY_OF_WEEK'] ?? json['dayOfWeek'])?.toString() ?? '',
  202. ) ??
  203. 0,
  204. );
  205. }
  206. Map<String, dynamic> toJson() => {
  207. 'JB_NO': jbNo,
  208. 'ITM': itm,
  209. 'SAL_NO': salNo,
  210. 'SAL_NAME': salName,
  211. 'DEP': dep,
  212. 'DEP_NAME': depName,
  213. 'JB_TYPE': jbType,
  214. 'JB_DATE': jbDate?.toIso8601String(),
  215. 'START_TIME': startTime?.toIso8601String(),
  216. 'END_TIME': endTime?.toIso8601String(),
  217. 'JB_HOURS': jbHours,
  218. 'JB_DAYS': jbDays,
  219. 'ATT_PERIOD': attPeriod,
  220. 'REASON': reason,
  221. 'COMPENSATION_TYPE': compensationType,
  222. 'COMPENSATION_COUNT': compensationCount,
  223. 'ADR': adr,
  224. 'REM': rem,
  225. 'DAY_OF_WEEK': dayOfWeek.toString(),
  226. };
  227. OvertimeApplyDetailModel copyWith({
  228. int? itm,
  229. String? jbNo,
  230. String? salNo,
  231. String? salName,
  232. String? dep,
  233. String? depName,
  234. String? jbType,
  235. DateTime? jbDate,
  236. DateTime? startTime,
  237. DateTime? endTime,
  238. double? jbHours,
  239. double? jbDays,
  240. String? attPeriod,
  241. String? reason,
  242. String? compensationType,
  243. double? compensationCount,
  244. String? adr,
  245. String? rem,
  246. int? dayOfWeek,
  247. }) {
  248. return OvertimeApplyDetailModel(
  249. itm: itm ?? this.itm,
  250. jbNo: jbNo ?? this.jbNo,
  251. salNo: salNo ?? this.salNo,
  252. salName: salName ?? this.salName,
  253. dep: dep ?? this.dep,
  254. depName: depName ?? this.depName,
  255. jbType: jbType ?? this.jbType,
  256. jbDate: jbDate ?? this.jbDate,
  257. startTime: startTime ?? this.startTime,
  258. endTime: endTime ?? this.endTime,
  259. jbHours: jbHours ?? this.jbHours,
  260. jbDays: jbDays ?? this.jbDays,
  261. attPeriod: attPeriod ?? this.attPeriod,
  262. reason: reason ?? this.reason,
  263. compensationType: compensationType ?? this.compensationType,
  264. compensationCount: compensationCount ?? this.compensationCount,
  265. adr: adr ?? this.adr,
  266. rem: rem ?? this.rem,
  267. dayOfWeek: dayOfWeek ?? this.dayOfWeek,
  268. );
  269. }
  270. }