1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.batch.service;
17
18 import java.text.ParseException;
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.apache.commons.exec.util.MapUtils;
26 import org.apache.commons.lang.ArrayUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.log4j.Logger;
29 import org.kuali.hr.core.document.CalendarDocumentHeaderContract;
30 import org.kuali.hr.job.Job;
31 import org.kuali.hr.lm.leaveplan.LeavePlan;
32 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
33 import org.kuali.hr.lm.workflow.service.LeaveCalendarDocumentHeaderService;
34 import org.kuali.hr.time.assignment.Assignment;
35 import org.kuali.hr.time.assignment.service.AssignmentService;
36 import org.kuali.hr.time.batch.BatchJobUtil;
37 import org.kuali.hr.time.batch.CarryOverJob;
38 import org.kuali.hr.time.batch.EmployeeApprovalJob;
39 import org.kuali.hr.time.batch.EndPayPeriodJob;
40 import org.kuali.hr.time.batch.EndReportingPeriodJob;
41 import org.kuali.hr.time.batch.InitiateJob;
42 import org.kuali.hr.time.batch.MissedPunchApprovalJob;
43 import org.kuali.hr.time.batch.SupervisorApprovalJob;
44 import org.kuali.hr.time.calendar.Calendar;
45 import org.kuali.hr.time.calendar.CalendarEntries;
46 import org.kuali.hr.time.calendar.service.CalendarService;
47 import org.kuali.hr.time.clocklog.ClockLog;
48 import org.kuali.hr.time.clocklog.service.ClockLogService;
49 import org.kuali.hr.time.missedpunch.MissedPunchDocument;
50 import org.kuali.hr.time.missedpunch.service.MissedPunchService;
51 import org.kuali.hr.time.principal.PrincipalHRAttributes;
52 import org.kuali.hr.time.principal.service.PrincipalHRAttributesService;
53 import org.kuali.hr.time.util.TkConstants;
54 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
55 import org.kuali.hr.time.workflow.service.TimesheetDocumentHeaderService;
56 import org.kuali.rice.kew.api.document.DocumentStatus;
57 import org.quartz.JobDataMap;
58 import org.quartz.JobDetail;
59 import org.quartz.Scheduler;
60 import org.quartz.SchedulerException;
61 import org.quartz.SimpleTrigger;
62 import org.quartz.Trigger;
63
64 public class BatchJobServiceImpl implements BatchJobService {
65
66 private static final Logger LOG = Logger.getLogger(BatchJobServiceImpl.class);
67
68 private Scheduler scheduler;
69
70 private AssignmentService assignmentService;
71 private CalendarService calendarService;
72 private ClockLogService clockLogService;
73 private LeaveCalendarDocumentHeaderService leaveCalendarDocumentHeaderService;
74 private MissedPunchService missedPunchService;
75 private PrincipalHRAttributesService principalHRAttributesService;
76 private TimesheetDocumentHeaderService timesheetDocumentHeaderService;
77
78 @Override
79 public void scheduleInitiateJobs(CalendarEntries calendarEntry) throws SchedulerException {
80 scheduleInitiateJobs(calendarEntry, calendarEntry.getBatchInitiateDateTime());
81 }
82
83 @Override
84 public void scheduleInitiateJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
85 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
86 String calendarTypes = calendar.getCalendarTypes();
87 String calendarName = calendar.getCalendarName();
88 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime();
89 java.util.Date endDate = calendarEntry.getEndPeriodDateTime();
90
91 if (StringUtils.equals(calendarTypes, "Pay")) {
92 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate);
93
94 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) {
95 String principalId = principalHRAttribute.getPrincipalId();
96 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry);
97
98 for (Assignment assignment : assignments) {
99 Job job = assignment.getJob();
100
101 if (StringUtils.equalsIgnoreCase(job.getFlsaStatus(), TkConstants.FLSA_STATUS_EXEMPT)) {
102 TimesheetDocumentHeader timesheetDocumentHeader = getTimesheetDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate);
103 if (timesheetDocumentHeader == null || StringUtils.equals(timesheetDocumentHeader.getDocumentStatus(), TkConstants.ROUTE_STATUS.CANCEL)) {
104 scheduleInitiateJob(calendarEntry, scheduleDate, assignment.getPrincipalId());
105 }
106 }
107 }
108 }
109 } else if (StringUtils.equals(calendarTypes, "Leave")) {
110 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForLeaveCalendar(calendarName, scheduleDate);
111
112 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) {
113 String principalId = principalHRAttribute.getPrincipalId();
114 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(principalId, calendarEntry);
115
116 for (Assignment assignment : assignments) {
117 Job job = assignment.getJob();
118
119 if (job.isEligibleForLeave() && StringUtils.equalsIgnoreCase(job.getFlsaStatus(), TkConstants.FLSA_STATUS_NON_EXEMPT)) {
120 LeaveCalendarDocumentHeader leaveCalendarDocumentHeader = getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate);
121 if (leaveCalendarDocumentHeader == null || StringUtils.equals(leaveCalendarDocumentHeader.getDocumentStatus(), TkConstants.ROUTE_STATUS.CANCEL)) {
122 scheduleInitiateJob(calendarEntry, scheduleDate, assignment.getPrincipalId());
123 }
124 }
125 }
126 }
127 }
128 }
129
130 private void scheduleInitiateJob(CalendarEntries calendarEntry, Date scheduleDate, String principalId) throws SchedulerException {
131 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
132 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
133
134 Map<String, String> jobDataMap = new HashMap<String, String>();
135 jobDataMap.put("principalId", principalId);
136
137 scheduleJob(InitiateJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
138 }
139
140 @Override
141 public void scheduleEndReportingPeriodJobs(CalendarEntries calendarEntry) throws SchedulerException {
142 scheduleEndReportingPeriodJobs(calendarEntry, calendarEntry.getEndPeriodDateTime());
143 }
144
145 @Override
146 public void scheduleEndReportingPeriodJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
147 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
148 String calendarTypes = calendar.getCalendarTypes();
149 String calendarName = calendar.getCalendarName();
150 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime();
151 java.util.Date endDate = calendarEntry.getEndPeriodDateTime();
152
153 if (StringUtils.equals(calendarTypes, "Pay")) {
154 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate);
155
156 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) {
157 String principalId = principalHRAttribute.getPrincipalId();
158 TimesheetDocumentHeader timesheetDocumentHeader = getTimesheetDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate);
159
160 if (timesheetDocumentHeader != null) {
161 scheduleEndReportingPeriodJob(calendarEntry, scheduleDate, principalId);
162 }
163 }
164 } else if (StringUtils.equals(calendarTypes, "Leave")) {
165 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForLeaveCalendar(calendarName, scheduleDate);
166
167 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) {
168 String principalId = principalHRAttribute.getPrincipalId();
169 LeaveCalendarDocumentHeader leaveCalendarDocumentHeader = getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate);
170
171 if (leaveCalendarDocumentHeader != null) {
172 scheduleEndReportingPeriodJob(calendarEntry, scheduleDate, principalId);
173 }
174 }
175 }
176 }
177
178 private void scheduleEndReportingPeriodJob(CalendarEntries calendarEntry, Date scheduleDate, String principalId) throws SchedulerException {
179 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
180 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
181
182 Map<String, String> jobDataMap = new HashMap<String, String>();
183 jobDataMap.put("principalId", principalId);
184
185 scheduleJob(EndReportingPeriodJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
186 }
187
188 @Override
189 public void scheduleEndPayPeriodJobs(CalendarEntries calendarEntry) throws SchedulerException {
190 scheduleEndPayPeriodJobs(calendarEntry, calendarEntry.getBatchEndPayPeriodDateTime());
191 }
192
193 @Override
194 public void scheduleEndPayPeriodJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
195 String calendarName = calendarEntry.getCalendarName();
196
197 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate);
198 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) {
199 String principalId = principalHRAttribute.getPrincipalId();
200
201 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry);
202 for (Assignment assignment : assignments) {
203 String jobNumber = String.valueOf(assignment.getJobNumber());
204 String workArea = String.valueOf(assignment.getWorkArea());
205 String task = String.valueOf(assignment.getTask());
206
207 ClockLog lastClockLog = getClockLogService().getLastClockLog(principalId, jobNumber, workArea, task, calendarEntry);
208 if (lastClockLog != null && TkConstants.ON_THE_CLOCK_CODES.contains(lastClockLog.getClockAction())) {
209 scheduleEndPayPeriodJob(calendarEntry, scheduleDate, lastClockLog);
210 }
211 }
212 }
213 }
214
215 private void scheduleEndPayPeriodJob(CalendarEntries calendarEntry, Date scheduleDate, ClockLog clockLog) throws SchedulerException {
216 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
217 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
218
219 Map<String, String> jobDataMap = new HashMap<String, String>();
220 jobDataMap.put("tkClockLogId", clockLog.getTkClockLogId());
221
222 scheduleJob(EndPayPeriodJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
223 }
224
225 @Override
226 public void scheduleEmployeeApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException {
227 scheduleEmployeeApprovalJobs(calendarEntry, calendarEntry.getBatchEmployeeApprovalDateTime());
228 }
229
230 @Override
231 public void scheduleEmployeeApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
232 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime();
233 java.util.Date endDate = calendarEntry.getEndPeriodDateTime();
234 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
235
236 if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) {
237 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
238 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) {
239 scheduleEmployeeApprovalJob(calendarEntry, scheduleDate, timesheetDocumentHeader);
240 }
241 } else if (StringUtils.equals(calendar.getCalendarTypes(), "Leave")) {
242 List<LeaveCalendarDocumentHeader> leaveCalendarDocumentHeaders = getLeaveCalendarDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
243 for (LeaveCalendarDocumentHeader leaveCalendarDocumentHeader : leaveCalendarDocumentHeaders) {
244 scheduleEmployeeApprovalJob(calendarEntry, scheduleDate, leaveCalendarDocumentHeader);
245 }
246 }
247 }
248
249 private void scheduleEmployeeApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, CalendarDocumentHeaderContract calendarDocumentHeaderContract) throws SchedulerException {
250 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
251 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
252
253 Map<String, String> jobDataMap = new HashMap<String, String>();
254 jobDataMap.put("documentId", calendarDocumentHeaderContract.getDocumentId());
255
256 scheduleJob(EmployeeApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
257 }
258
259 @Override
260 public void scheduleMissedPunchApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException {
261 scheduleMissedPunchApprovalJobs(calendarEntry, calendarEntry.getBatchSupervisorApprovalDateTime());
262 }
263
264 @Override
265 public void scheduleMissedPunchApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
266 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime();
267 java.util.Date endDate = calendarEntry.getEndPeriodDateTime();
268
269 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
270 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) {
271 List<MissedPunchDocument> missedPunchDocuments = getMissedPunchService().getMissedPunchDocsByTimesheetDocumentId(timesheetDocumentHeader.getDocumentId());
272 for (MissedPunchDocument missedPunchDocument : missedPunchDocuments) {
273 if (StringUtils.equals(missedPunchDocument.getDocumentStatus(), DocumentStatus.ENROUTE.getCode())) {
274 scheduleMissedPunchApprovalJob(calendarEntry, scheduleDate, missedPunchDocument);
275 }
276 }
277 }
278 }
279
280 private void scheduleMissedPunchApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, MissedPunchDocument missedPunchDocument) throws SchedulerException {
281 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
282 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
283
284 Map<String, String> jobDataMap = new HashMap<String, String>();
285 jobDataMap.put("principalId", missedPunchDocument.getPrincipalId());
286
287 scheduleJob(MissedPunchApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
288 }
289
290 @Override
291 public void scheduleSupervisorApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException {
292 scheduleSupervisorApprovalJobs(calendarEntry, calendarEntry.getBatchSupervisorApprovalDateTime());
293 }
294
295 @Override
296 public void scheduleSupervisorApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException {
297 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime();
298 java.util.Date endDate = calendarEntry.getEndPeriodDateTime();
299 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
300
301 if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) {
302 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
303 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) {
304 scheduleSupervisorApprovalJob(calendarEntry, scheduleDate, timesheetDocumentHeader);
305 }
306 } else if (StringUtils.equals(calendar.getCalendarTypes(), "Leave")) {
307 List<LeaveCalendarDocumentHeader> leaveCalendarDocumentHeaders = getLeaveCalendarDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
308 for (LeaveCalendarDocumentHeader leaveCalendarDocumentHeader : leaveCalendarDocumentHeaders) {
309 scheduleSupervisorApprovalJob(calendarEntry, scheduleDate, leaveCalendarDocumentHeader);
310 }
311 }
312 }
313
314 private void scheduleSupervisorApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, CalendarDocumentHeaderContract calendarDocumentHeaderContract) throws SchedulerException {
315 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
316 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId());
317
318 Map<String, String> jobDataMap = new HashMap<String, String>();
319 jobDataMap.put("documentId", calendarDocumentHeaderContract.getDocumentId());
320
321 scheduleJob(SupervisorApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
322 }
323
324
325 @Override
326 public void scheduleLeaveCarryOverJobs(LeavePlan leavePlan) throws SchedulerException {
327 String batchJobDate = leavePlan.getBatchPriorYearCarryOverStartDate();
328 java.util.Calendar batchJobTimeCal = java.util.Calendar.getInstance();
329 batchJobTimeCal.setTimeInMillis(leavePlan.getBatchPriorYearCarryOverStartTime().getTime());
330 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
331 sdf.setLenient(false);
332 java.util.Date batchJobStart = null;
333
334 try {
335 batchJobStart = sdf.parse(batchJobDate);
336 } catch (ParseException e) {
337 }
338
339 java.util.Calendar batchJobStartDateTime = java.util.Calendar.getInstance();
340 batchJobStartDateTime.setTime(batchJobStart);
341 batchJobStartDateTime.set(java.util.Calendar.YEAR,java.util.Calendar.getInstance().get(java.util.Calendar.YEAR));
342 batchJobStartDateTime.set(java.util.Calendar.HOUR_OF_DAY,batchJobTimeCal.get(java.util.Calendar.HOUR_OF_DAY));
343 batchJobStartDateTime.set(java.util.Calendar.MINUTE,batchJobTimeCal.get(java.util.Calendar.MINUTE));
344 batchJobStartDateTime.set(java.util.Calendar.SECOND, 0);
345 batchJobStartDateTime.set(java.util.Calendar.MILLISECOND, 0);
346
347 scheduleLeaveCarryOverJob(leavePlan, batchJobStartDateTime.getTime());
348 }
349
350 @Override
351 public void scheduleLeaveCarryOverJobs(LeavePlan leavePlan, Date scheduleDate) throws SchedulerException {
352 scheduleLeaveCarryOverJob(leavePlan, scheduleDate);
353 }
354
355 private void scheduleLeaveCarryOverJob(LeavePlan leavePlan, Date scheduleDate) throws SchedulerException {
356 Map<String, String> jobGroupDataMap = new HashMap<String, String>();
357 jobGroupDataMap.put("date", BatchJobUtil.FORMAT.format(scheduleDate));
358 Map<String, String> jobDataMap = new HashMap<String, String>();
359 jobDataMap.put("leavePlan", leavePlan.getLeavePlan());
360 scheduleJob(CarryOverJob.class, scheduleDate, jobGroupDataMap, jobDataMap);
361 }
362
363 @SuppressWarnings("unchecked")
364 private void scheduleJob(Class<?> jobClass, Date jobDate, Map<String, String> jobGroupDataMap, Map<String, String> jobDataMap) throws SchedulerException {
365 String jobGroupName = BatchJobUtil.getJobGroupName(jobClass, jobGroupDataMap);
366 String jobName = BatchJobUtil.getJobName(jobClass, jobDataMap);
367 String[] jobNames = getScheduler().getJobNames(jobGroupName);
368 if (!ArrayUtils.contains(jobNames, jobName)) {
369 Map<String, String> mergedDataMap = MapUtils.merge(jobGroupDataMap, jobDataMap);
370
371 JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass, false, true, false);
372 jobDetail.setJobDataMap(new JobDataMap(mergedDataMap));
373
374 String triggerGroupName = BatchJobUtil.getTriggerGroupName(jobClass, MapUtils.merge(jobGroupDataMap, jobDataMap));
375 String triggerName = BatchJobUtil.getTriggerName(jobClass, jobDate);
376 Trigger trigger = new SimpleTrigger(triggerName, triggerGroupName, jobDate);
377 trigger.setJobGroup(jobGroupName);
378 trigger.setJobName(jobName);
379
380 LOG.info("Scheduing " + jobDetail.getFullName() + " to be run on " + jobDate);
381
382 getScheduler().scheduleJob(jobDetail, trigger);
383 }
384 }
385
386 public Scheduler getScheduler() {
387 return scheduler;
388 }
389
390 public void setScheduler(Scheduler scheduler) {
391 this.scheduler = scheduler;
392 }
393
394 public AssignmentService getAssignmentService() {
395 return assignmentService;
396 }
397
398 public void setAssignmentService(AssignmentService assignmentService) {
399 this.assignmentService = assignmentService;
400 }
401
402 public CalendarService getCalendarService() {
403 return calendarService;
404 }
405
406 public void setCalendarService(CalendarService calendarService) {
407 this.calendarService = calendarService;
408 }
409
410 public ClockLogService getClockLogService() {
411 return clockLogService;
412 }
413
414 public void setClockLogService(ClockLogService clockLogService) {
415 this.clockLogService = clockLogService;
416 }
417
418 public LeaveCalendarDocumentHeaderService getLeaveCalendarDocumentHeaderService() {
419 return leaveCalendarDocumentHeaderService;
420 }
421
422 public void setLeaveCalendarDocumentHeaderService(LeaveCalendarDocumentHeaderService leaveCalendarDocumentHeaderService) {
423 this.leaveCalendarDocumentHeaderService = leaveCalendarDocumentHeaderService;
424 }
425
426 public MissedPunchService getMissedPunchService() {
427 return missedPunchService;
428 }
429
430 public void setMissedPunchService(MissedPunchService missedPunchService) {
431 this.missedPunchService = missedPunchService;
432 }
433
434 public PrincipalHRAttributesService getPrincipalHRAttributesService() {
435 return principalHRAttributesService;
436 }
437
438 public void setPrincipalHRAttributesService(PrincipalHRAttributesService principalHRAttributesService) {
439 this.principalHRAttributesService = principalHRAttributesService;
440 }
441
442 public TimesheetDocumentHeaderService getTimesheetDocumentHeaderService() {
443 return timesheetDocumentHeaderService;
444 }
445
446 public void setTimesheetDocumentHeaderService(TimesheetDocumentHeaderService timesheetDocumentHeaderService) {
447 this.timesheetDocumentHeaderService = timesheetDocumentHeaderService;
448 }
449
450 }