package com.mossle.workcal.service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.xml.datatype.Duration;
import com.mossle.api.tenant.TenantConnector;
import com.mossle.api.tenant.TenantDTO;
import com.mossle.api.workcal.WorkCalendarConnector;
import com.mossle.workcal.persistence.domain.WorkcalPart;
import com.mossle.workcal.persistence.domain.WorkcalRule;
import com.mossle.workcal.persistence.manager.WorkcalPartManager;
import com.mossle.workcal.persistence.manager.WorkcalRuleManager;
import com.mossle.workcal.support.DayPart;
import com.mossle.workcal.support.Holiday;
import com.mossle.workcal.support.WorkCalendar;
import com.mossle.workcal.support.WorkDay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WorkCalendarService implements WorkCalendarConnector {
private static Logger logger = LoggerFactory
.getLogger(WorkCalendarService.class);
public static final int STATUS_WEEK = 0;
public static final int STATUS_HOLIDAY = 1;
public static final int STATUS_HOLIDAY_TO_WORKDAY = 2;
public static final int STATUS_WORKDAY_TO_HOLIDAY = 3;
private WorkcalRuleManager workcalRuleManager;
private WorkcalPartManager workcalPartManager;
private String hourFormatText = "HH:mm";
private boolean enabled = true;
private Map<String, WorkCalendar> map = new HashMap<String, WorkCalendar>();
private TenantConnector tenantConnector;
public Date processDate(Date date, String tenantId) {
WorkCalendar workCalendar = map.get(tenantId);
return workCalendar.findWorkDate(date);
}
public Date add(Date date, Duration duration, String tenantId) {
WorkCalendar workCalendar = map.get(tenantId);
return workCalendar.add(date, duration);
}
public void processWeek(WorkCalendar workCalendar, String tenantId)
throws Exception {
List<WorkDay> days = new ArrayList<WorkDay>(8);
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
days.add(new Holiday(workCalendar));
// 每周的工作规则
List<WorkcalRule> workcalRules = workcalRuleManager.find(
"from WorkcalRule where status=? and tenantId=?", STATUS_WEEK,
tenantId);
for (WorkcalRule workcalRule : workcalRules) {
WorkDay day = new WorkDay(workCalendar);
int dayPartIndex = 0;
List<DayPart> dayParts = day.getDayParts();
for (WorkcalPart workcalPart : workcalPartManager.findBy(
"workcalRule", workcalRule)) {
DayPart dayPart = new DayPart();
dayPart.setWorkDay(day);
dayPart.setIndex(dayPartIndex);
Date startDate = new SimpleDateFormat(hourFormatText)
.parse(workcalPart.getStartTime());
Date endDate = new SimpleDateFormat(hourFormatText)
.parse(workcalPart.getEndTime());
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
dayPart.setFromHour(startCalendar.get(Calendar.HOUR));
dayPart.setFromMinute(startCalendar.get(Calendar.MINUTE));
dayPart.setToHour(endCalendar.get(Calendar.HOUR));
dayPart.setToMinute(endCalendar.get(Calendar.MINUTE));
dayParts.add(dayPart);
}
days.set(workcalRule.getWeek(), day);
}
}
public void processHoliday(WorkCalendar workCalendar,
WorkcalRule workcalRule) throws Exception {
Date date = workcalRule.getWorkDate();
Holiday holiday = new Holiday(workCalendar);
holiday.setDate(date);
workCalendar.addHoliday(holiday);
}
public void processWorkDay(WorkCalendar workCalendar,
WorkcalRule workcalRule) throws Exception {
Date date = workcalRule.getWorkDate();
WorkDay workDay = new WorkDay(workCalendar);
workDay.setDate(date);
int dayPartIndex = 0;
List<DayPart> dayParts = workDay.getDayParts();
for (WorkcalPart workcalPart : workcalPartManager.findBy("workcalRule",
workcalRule)) {
DayPart dayPart = new DayPart();
dayPart.setWorkDay(workDay);
dayPart.setIndex(dayPartIndex);
Date startDate = new SimpleDateFormat(hourFormatText)
.parse(workcalPart.getStartTime());
Date endDate = new SimpleDateFormat(hourFormatText)
.parse(workcalPart.getEndTime());
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
dayPart.setFromHour(startCalendar.get(Calendar.HOUR));
dayPart.setFromMinute(startCalendar.get(Calendar.MINUTE));
dayPart.setToHour(endCalendar.get(Calendar.HOUR));
dayPart.setToMinute(endCalendar.get(Calendar.MINUTE));
dayParts.add(dayPart);
}
workCalendar.addWorkDay(workDay);
}
@PostConstruct
public void init() throws Exception {
if (!enabled) {
logger.info("skip work calendar");
return;
}
for (TenantDTO tenantDto : tenantConnector.findAll()) {
String tenantId = tenantDto.getId();
WorkCalendar workCalendar = new WorkCalendar();
map.put(tenantId, workCalendar);
this.processWeek(workCalendar, tenantId);
// 特殊日期
List<WorkcalRule> extraWorkcalRules = workcalRuleManager.find(
"from WorkcalRule where status<>? and tenantId=?",
STATUS_WEEK, tenantId);
for (WorkcalRule workcalRule : extraWorkcalRules) {
if (workcalRule.getStatus() == STATUS_HOLIDAY) {
this.processHoliday(workCalendar, workcalRule);
} else if (workcalRule.getStatus() == STATUS_HOLIDAY_TO_WORKDAY) {
this.processWorkDay(workCalendar, workcalRule);
} else {
this.processHoliday(workCalendar, workcalRule);
}
}
}
}
@Resource
public void setWorkcalRuleManager(WorkcalRuleManager workcalRuleManager) {
this.workcalRuleManager = workcalRuleManager;
}
@Resource
public void setWorkcalPartManager(WorkcalPartManager workcalPartManager) {
this.workcalPartManager = workcalPartManager;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Resource
public void setTenantConnector(TenantConnector tenantConnector) {
this.tenantConnector = tenantConnector;
}
}