Commit 810f3686 by Ren Ping

Merge remote-tracking branch 'origin/develop' into develop

2 parents f7354cae a9e76e49
Showing with 455 additions and 142 deletions
......@@ -5,6 +5,7 @@ import com.dituhui.pea.common.Result;
import com.dituhui.pea.dispatch.IPath;
import com.dituhui.pea.enums.StatusCodeEnum;
import com.dituhui.pea.order.common.jackson.DateUtil;
import com.dituhui.pea.order.common.jackson.JsonUtil;
import com.dituhui.pea.order.dao.TableCodeCheckDao;
import com.dituhui.pea.order.dto.param.BaseDistance;
import com.dituhui.pea.order.dto.param.BaseDistanceParam;
......@@ -31,6 +32,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
......@@ -58,6 +60,7 @@ import java.util.stream.Collectors;
@RequestMapping("/pea-order/pea")
@RequiredArgsConstructor
@Validated
@Slf4j
public class PeaApiController {
private final EngineerCalendarService engineerCalendarService;
......@@ -71,8 +74,6 @@ public class PeaApiController {
private final IPath path;
private static final String stage = "{\"orderId\": \"X10001\", \"engineerCode\": \"E12005\", \"engineerName\": \"祝枝山\", \"engineerCodeAssist\": \"E12446\", \"engineerNameAssist\": \"李晓阳\", \"planVisitTime\": \"2023-07-27 12:00:00\", \"realtimeInfo\": {\"engineerLocation\": {\"latitude\": 31.349701, \"longitude\": 120.675945, \"address\": \"江苏省苏州市苏州工业园区和顺路\", \"name\": \"和顺大酒店\"}, \"estimate\": {\"distance\": 2300, \"arriveTime\": \"2023-07-27 12:12:00\"}}}";
/**
* 3.1GET 查询技术员日历
*
......@@ -345,10 +346,11 @@ public class PeaApiController {
DistanceParam distanceParam = new DistanceParam();
distanceParam.setOrigin(new Location(origin.getLongitude(), origin.getLatitude()));
distanceParam.setOrigin(new Location(destination.getLongitude(), destination.getLatitude()));
distanceParam.setOrigin(new Location(origin.getLatitude(),origin.getLongitude()));
distanceParam.setDestination(new Location(destination.getLatitude(),destination.getLongitude()));
distanceParam.setVehicle(param.getVehicle());
DistanceDTO locationDistance = path.getLocationDistance(distanceParam);
log.info("[baseDistance], 两点间距离返回结果:{}", JsonUtil.toJson(locationDistance));
result.setDistance((int) locationDistance.getDis());
result.setDuration((long) locationDistance.getTime());
......
......@@ -24,6 +24,10 @@ public class CalendarDetailDTO {
private String phone;
private String planId;
private String remark;
/**
* 是否全天
*/
private Boolean wholeDay;
private String type;
private String typeName;
......
package com.dituhui.pea.order.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
public class CalendarUpdateDTO {
@lombok.Data
public static class Request {
@NotBlank
/**
* 日程是否是全天
*/
@NotNull(message = "请指定日程是否是全天")
private Boolean wholeDay;
/**
* 日程所属日期, 格式: yyyy-MM-dd
*/
@NotNull(message = "请指定日程所属日期, 格式:yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date itineraryDate;
/**
* 开始时间:HH:mm:ss, wholeDay为true时可不传
*/
private String startTime;
@NotBlank
/**
* 结束时间:HH:mm:ss, wholeDay为true时可不传
*/
private String endTime;
/**
* 日程所属工程师编号
*/
@NotBlank
private String engineerCode;
/**
* 日程计划ID
*/
@NotBlank
private String planId;
/**
* 备注
*/
private String remark;
}
......
......@@ -93,5 +93,12 @@ public class DispatchEngineerOrderListResp {
* 是否是特殊时间段,0否 1是 默认0
*/
private Integer isSpecialTime;
/**
* 是否是cutoff,0否 1是 默认0
*/
private Integer isCutoff = 0;
private String beanTags;
}
}
......@@ -107,4 +107,24 @@ public class OrderServiceList {
private String planStartTime;
private String planEndTime;
/**
* 交通工具:1汽车;2电动车;3自行车;4步行 默认是汽车
*/
private String vehicle;
/**
* 常规出发地,1配件仓,2家庭住址,3工作地址 默认工作地址
*/
private Integer departure;
/**
* 出发地点x
*/
private String departureX;
/**
* 出发地点y
*/
private String departureY;
}
......@@ -18,6 +18,12 @@ public class CapacityEngineerCalendarEntity {
@Column(nullable = false)
private String workday;
/**
* 事件日程是否是全天类型
*/
@Column(name = "whole_day", nullable = false)
private Boolean wholeDay;
@Column(name = "engineer_code", nullable = false, columnDefinition = "varchar(50) default '0'")
private String engineerCode;
......
package com.dituhui.pea.order.scheduler;
import com.dituhui.pea.order.common.DateUtils;
import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.common.jackson.DateTimeUtil;
import com.dituhui.pea.order.common.jackson.DateUtil;
import com.dituhui.pea.order.dao.CapacityOrgStatDao;
import com.dituhui.pea.order.dao.CapacityStatisticDao;
import com.dituhui.pea.order.dao.CapacityTeamStatDao;
import com.dituhui.pea.order.dao.OrgBranchDao;
import com.dituhui.pea.order.dao.OrgClusterDao;
import com.dituhui.pea.order.dao.OrgGroupDao;
import com.dituhui.pea.order.dao.OrgTeamDao;
import com.dituhui.pea.order.dto.CapacityOrgStatDTO;
import com.dituhui.pea.order.entity.*;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.entity.CapacityOrgStatEntity;
import com.dituhui.pea.order.entity.CapacityTeamStatEntity;
import com.dituhui.pea.order.entity.OrgBranchEntity;
import com.dituhui.pea.order.entity.OrgClusterEntity;
import com.dituhui.pea.order.entity.OrgGroupEntity;
import com.dituhui.pea.order.entity.OrgTeamEntity;
import com.dituhui.pea.order.service.MsgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
......@@ -12,6 +28,7 @@ import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
......@@ -35,6 +52,10 @@ public class CalcOrgCapacityScheduler {
private CapacityOrgStatDao capacityOrgStatDao;
@Autowired
private CapacityTeamStatDao capacityTeamStatDao;
@Autowired
private MsgService msgService;
@Autowired
private OrgClusterDao orgClusterDao;
@Value("${scheduler.calc-org-capacity.day-offset-begin}")
private int dayOffsetBegin;
......@@ -127,6 +148,12 @@ public class CalcOrgCapacityScheduler {
entity.setUpdateTime(LocalDateTime.now());
// todo entity.setOrderCount();
capacityOrgStatDao.save(entity);
double usedPercentage = (double) dto.getCapUsed() / dto.getCapTotal();
log.info("[calcOneBranch] {}小组容量已使用占比{}", groupId, usedPercentage);
if (BigDecimal.valueOf(usedPercentage).compareTo(new BigDecimal("0.8")) >= 0) {
addCapacityMsg("", "", groupId, LocalDate.parse(date, DateUtil.DATE_FORMATTER), dto.getLayer());
}
}
}
......@@ -165,7 +192,43 @@ public class CalcOrgCapacityScheduler {
entity.setUpdateTime(LocalDateTime.now());
// todo entity.setOrderCount();
capacityOrgStatDao.save(entity);
double usedPercentage = (double) dto.getCapUsed() / dto.getCapTotal();
log.info("[calcOneBranch] {}分部容量已使用占比{}", branchId, usedPercentage);
if (BigDecimal.valueOf(usedPercentage).compareTo(new BigDecimal("0.8")) >= 0) {
addCapacityMsg("", branchId, "", LocalDate.parse(date, DateUtil.DATE_FORMATTER), dto.getLayer());
}
}
}
private void addCapacityMsg(String clusterId, String branchId, String groupId,
LocalDate targetDate, String layer) {
MsgDTO msgDTO = new MsgDTO();
msgDTO.setType(2);
String msg = "{0}{1}的容量在{2}已预约达80%";
String msgBrand = "";
if (StringUtils.isNotBlank(clusterId)) {
OrgClusterEntity cluster = orgClusterDao.getByClusterId(clusterId);
msgBrand = cluster.getName();
msgDTO.setClusterId(clusterId);
}
if (StringUtils.isNotBlank(branchId)) {
OrgBranchEntity branch = orgBranchDao.getByBranchId(branchId);
msgBrand = branch.getBranchName();
msgDTO.setBranchId(branchId);
}
if (StringUtils.isNotBlank(groupId)) {
OrgGroupEntity group = orgGroupDao.getByGroupId(groupId);
msgBrand = group.getGroupName();
msgDTO.setGroupId(groupId);
}
msg = MessageFormat.format(msg, msgBrand, layer, DateTimeUtil.formatDate(targetDate));
msgDTO.setContent(msg);
msgDTO.setTag(1);
msgService.add(msgDTO);
}
private void calcAllTeamByDays(String bdate, String edate) {
......
......@@ -52,20 +52,23 @@ public interface EngineerCalendarService {
List<OccupyInfoDetail> getEngineerWorkDayCalendar(String engineerCode, LocalDate targetDate);
/**
* 判定工程师指定日期是否在工作队的工作日期
* 判定工程师指定日期是否在指定工作队的工作日期
*
* @param teamId 工作队
* @param engineerCode 工程师编号
* @param targetDate 目标日期
* @return 是否是工作队内日期工作时间
* @return 是否是指定工作队内日期工作时间
* @apiNote 仅考虑工作队工作日期, 不考虑事件日程
*/
boolean engineerTeamDateWorkTime(String teamId, String engineerCode, LocalDate targetDate);
/**
* 判定工程师只顶你日期是否休息日
* 判定工程师指定日期是否休息日
*
* @param engineerCode 工程师编号
* @param targetDate 目标日期
* @param targetDate 目标日期
* @return 是否是工作日
* @apiNote 仅考虑工作队工作日期, 不考虑事件日程
*/
boolean engineerWorkDay(String engineerCode, LocalDate targetDate);
......@@ -89,4 +92,14 @@ public interface EngineerCalendarService {
* @return 时间窗格式
*/
List<OccupyInfoDetail> timeWindowsSlice(String engineerCode, String teamId, LocalDate targetDate);
/**
* 判定工程师是否全天请假(非派工时间)或者全天休息
*
* @param engineerCode 工程师编号
* @param targetDate 目标日期
* @return 全天休息(含请假)返回true, 否则false
*/
boolean engineerTargetLeave(String engineerCode, LocalDate targetDate);
}
......@@ -17,6 +17,7 @@ import com.dituhui.pea.order.entity.*;
import com.dituhui.pea.order.enums.*;
import com.dituhui.pea.order.service.CommonService;
import com.dituhui.pea.order.service.DispatchService;
import com.dituhui.pea.order.service.EngineerCalendarService;
import com.dituhui.pea.order.service.OrderInfoService;
import com.dituhui.pea.order.utils.CommonUtil;
import com.google.common.collect.Sets;
......@@ -76,6 +77,9 @@ public class DispatchServiceImpl implements DispatchService {
@Autowired
private OrderInfoService orderInfoService;
@Autowired
private EngineerCalendarService engineerCalendarService;
@Transactional
@Override
public Result<?> getDispatchOrderList(DispatchOrderListReq reqDTO) {
......@@ -243,22 +247,8 @@ public class DispatchServiceImpl implements DispatchService {
List engineerCodes2 = new ArrayList();
for (String engineerCode : engineerCodes) {
//获取工作队休息时间, 判定目标时间是否在工作队休息日中
Set<OrgTeamEntity> teams = orgTeamDao.selectTeamByEngineerCode(engineerCode);
if (!org.springframework.util.CollectionUtils.isEmpty(teams)) {
List<String> teamCommonWorkdaysOfWeek = teams.stream()
.map(team -> Arrays.asList(team.getWorkdays().split(",")))
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
// 求多个工作队的公共空闲时间
final int dayOfWeek = targetDate.getDayOfWeek().getValue();
List<String> commonLeisureDayOfWeek = EngineerCalendarServiceImpl.ALL_WORK_DAY_OF_WEEK.stream().filter(day -> teamCommonWorkdaysOfWeek.stream().noneMatch(tDay -> Objects.equals(day, tDay)))
.collect(Collectors.toList());
if (!commonLeisureDayOfWeek.contains(String.valueOf(dayOfWeek))) {
engineerCodes2.add(engineerCode);
}
//求所有事程时间与工作队休息时间的并集
if (!engineerCalendarService.engineerTargetLeave(engineerCode, targetDate)) {
engineerCodes2.add(engineerCode);
}
}
return engineerCodes2;
......@@ -314,6 +304,8 @@ public class DispatchServiceImpl implements DispatchService {
item.setTranscend(o.getTranscend());
item.setBeanPriority(o.getBeanPriority());
item.setIsSpecialTime(o.getIsSpecialTime());
item.setIsCutoff(o.getIsCutoff());
item.setBeanTags(o.getBeanTags());
if (isContinue && StringUtils.isNotEmpty(o.getMultipleOrders())) {
List<OrderInfoEntity> byMultipleOrders = orderInfoDao.findByMultipleOrdersAndOrderIdNot(o.getMultipleOrders(), o.getOrderId());
List<DispatchEngineerOrderListResp.OrderInfo> multipleItems = new ArrayList<>();
......
......@@ -40,6 +40,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
......@@ -156,6 +157,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
rs.setStartTime(DateUtils.formatDateTime(entity.getStartTime()));
rs.setEndTime(DateUtils.formatDateTime(entity.getEndTime()));
rs.setRemark(entity.getMemo());
rs.setWholeDay(entity.getWholeDay());
// todo 操作员
rs.setOperator(entity.getOperatorName());
return Result.success(rs);
......@@ -169,15 +171,39 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
if (entity == null) {
return Result.failed("日历配置信息不存在");
}
// todo 业务检查,暂时只需要检查日期时间必须为将来; 后面还需要检查配置项是否与其他配置项在时间上有交叉
LocalDateTime time1 = DateUtils.localDateTimeFromStr(reqDTO.getStartTime());
LocalDateTime time2 = DateUtils.localDateTimeFromStr(reqDTO.getEndTime());
final Date itineraryDate = reqDTO.getItineraryDate();
final LocalDate itineraryLocalDate = itineraryDate.toInstant().atZone(ZoneId.systemDefault())
.toLocalDate();
// 日程所属工程师
final String engineerCode = entity.getEngineerCode();
// 业务检查,暂时只需要检查日期时间必须为将来; 后面还需要检查配置项是否与其他配置项在时间上有交叉
LocalDateTime time1, time2;
if (Objects.equals(Boolean.TRUE, reqDTO.getWholeDay())) {
//获取工程师上下班时间
EngineerBusinessEntity config = engineerBusinessDao.getByEngineerCode(engineerCode);
LocalTime startTime = LocalTime.parse(String.format("%s:00", config.getWorkOn()), DateUtil.TIME_FORMATTER);
LocalTime endTime = LocalTime.parse(String.format("%s:00", config.getWorkOff()), DateUtil.TIME_FORMATTER);
time1 = LocalDateTime.of(itineraryLocalDate, startTime);
time2 = LocalDateTime.of(itineraryLocalDate, endTime);
} else {
time1 = LocalDateTime.of(itineraryLocalDate, LocalTime.parse(reqDTO.getStartTime(), DateUtil.TIME_FORMATTER));
time2 = LocalDateTime.of(itineraryLocalDate, LocalTime.parse(reqDTO.getEndTime(), DateUtil.TIME_FORMATTER));
}
if (time1.isAfter(time2)) {
return Result.failed("开始/结束时间输入错误");
}
if (time1.isBefore(LocalDateTime.now()) || time2.isBefore(LocalDateTime.now())) {
return Result.failed("只能更新未来时间");
}
Optional<CheckTime> checkTimeOptional = checkTimesHasOverlap(time1.toLocalDate(), engineerCode, time1, time2, reqDTO.getPlanId());
if (checkTimeOptional.isPresent()) {
CheckTime checkTime = checkTimeOptional.get();
throw new BusinessException("工号为" + engineerCode + "的工程师在"
+ checkTime.getStartTime() + "到"
+ checkTime.getEndTime() + "区间已有日程安排");
}
entity.setWholeDay(reqDTO.getWholeDay());
entity.setStartTime(time1);
entity.setEndTime(time2);
entity.setMemo(reqDTO.getRemark());
......@@ -229,7 +255,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
endTime = String.format("%s %s:00", endTime, config.getWorkOff());
}
if ("none".equals(repeatType)) {
addOneEngineerPlan(userId, engineerCode, type, beginTime, endTime, remark);
addOneEngineerPlan(userId, engineerCode, type, beginTime, endTime, remark, isAllday);
} else {
LocalDate beginDate = DateUtils.localDateFromStr(beginTime);
LocalDate endDate = DateUtils.localDateFromStr(repeatEndDate);
......@@ -242,7 +268,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
long days = beginDate.until(current, ChronoUnit.DAYS);
beginTime = DateUtils.formatDateTime(DateUtils.localDateTimeFromStr(finalBeginTime).plusDays(days));
endTime = DateUtils.formatDateTime(DateUtils.localDateTimeFromStr(finalEndTime).plusDays(days));
addOneEngineerPlan(userId, engineerCode, type, beginTime, endTime, remark);
addOneEngineerPlan(userId, engineerCode, type, beginTime, endTime, remark, isAllday);
current = getNextDate(current, repeatType);
}
}
......@@ -276,7 +302,8 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
return current;
}
private void addOneEngineerPlan(String userId, String engineerCode, String type, String beginTime, String endTime, String remark) {
private void addOneEngineerPlan(String userId, String engineerCode, String type, String beginTime, String endTime, String remark,
Boolean allDay) {
// 一个工程师、一条配置处理;可能一条会跨多天,需要分别补充处理
log.info("addOneEngineerPlan ==> [engineerCode:{}][beginTime:{}]", engineerCode, beginTime);
String userName = user.getUserInfo(userId).getResult().getAccount();
......@@ -287,7 +314,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
if (beginDate.isEqual(endDate)) {
LocalDateTime startTime = DateUtils.localDateTimeFromStr(beginTime);
LocalDateTime endTime1 = DateUtils.localDateTimeFromStr(endTime);
Optional<CheckTime> checkTimeOptional = checkTimesHasOverlap(endDate, engineerCode, startTime, endTime1);
Optional<CheckTime> checkTimeOptional = checkTimesHasOverlap(endDate, engineerCode, startTime, endTime1, "");
if (checkTimeOptional.isPresent()) {
CheckTime checkTime = checkTimeOptional.get();
throw new BusinessException("工号为" + engineerCode + "的工程师在"
......@@ -305,6 +332,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
e.setStartTime(startTime);
e.setEndTime(endTime1);
e.setWorkday(DateUtils.formatDate(beginDate));
e.setWholeDay(allDay);
e.setMemo(remark);
//
e.setOperatorId(userId);
......@@ -342,7 +370,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
e.setEndTime(DateUtils.localDateTimeFromStr(etime));
}
//校验是否有当天时间段的记录
Optional<CheckTime> checkTimeOptional = checkTimesHasOverlap(current, engineerCode, e.getStartTime(), e.getEndTime());
Optional<CheckTime> checkTimeOptional = checkTimesHasOverlap(current, engineerCode, e.getStartTime(), e.getEndTime(), "");
if (checkTimeOptional.isPresent()) {
CheckTime checkTime = checkTimeOptional.get();
throw new BusinessException("工号为" + engineerCode + "的工程师在"
......@@ -355,6 +383,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
e.setOperatorId(userId);
e.setOperatorName(userName);
all.add(e);
e.setWholeDay(allDay);
// 按日迭代
current = current.plusDays(1);
}
......@@ -362,12 +391,18 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
}
private Optional<CheckTime> checkTimesHasOverlap(LocalDate date,
String engineerCode, LocalDateTime dynaStartTime, LocalDateTime dynaEndTime) {
String engineerCode, LocalDateTime dynaStartTime, LocalDateTime dynaEndTime,
String excludePlanId) {
//获取指定日期的工作人员日历
List<CapacityEngineerCalendarEntity> calendar = capacityEngineerCalendarDao.findCalendarByWorkdayAndEngineerCode(DateTimeUtil.formatDate(date), engineerCode);
if (CollectionUtils.isEmpty(calendar)) {
return Optional.empty();
}
if (StringUtils.isNotBlank(excludePlanId)) {
calendar = calendar.stream()
.filter(t -> !Objects.equals(t.getPlanId(), excludePlanId))
.collect(Collectors.toList());
}
//进行时间交集检查, 如果有交集返回 true 无则返回
return calendar.stream()
.filter(t -> {
......@@ -628,7 +663,7 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
.distinct()
.collect(Collectors.toList());
final int dayOfWeek = targetDate.getDayOfWeek().getValue();
return ALL_WORK_DAY_OF_WEEK.contains(String.valueOf(dayOfWeek));
return teamCommonWorkdaysOfWeek.contains(String.valueOf(dayOfWeek));
}
@Override
......@@ -688,6 +723,31 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
return CapacityUtils.intervalTime(workStartTime, workEndTime, usedTimeInfo);
}
@Override
public boolean engineerTargetLeave(String engineerCode, LocalDate targetDate) {
Set<OrgTeamEntity> teams = orgTeamDao.selectTeamByEngineerCode(engineerCode);
List<String> teamCommonWorkdaysOfWeek = Optional.ofNullable(teams).orElse(Collections.emptySet()).stream()
.map(team -> Arrays.asList(team.getWorkdays().split(",")))
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
// 求多个工作队的公共空闲时间
final int dayOfWeek = targetDate.getDayOfWeek().getValue();
List<String> commonLeisureDayOfWeek = ALL_WORK_DAY_OF_WEEK.stream()
.filter(day -> teamCommonWorkdaysOfWeek.stream().noneMatch(tDay -> Objects.equals(day, tDay)))
.collect(Collectors.toList());
if (!commonLeisureDayOfWeek.contains(String.valueOf(dayOfWeek))) {
//日程表事件记录时间
List<CapacityEngineerCalendarEntity> configs = capacityEngineerCalendarDao.findCalendarByWorkdayAndEngineerCode(DateTimeUtil.formatDate(targetDate), engineerCode);
return Optional.ofNullable(configs).orElse(Collections.emptyList())
.stream()
.anyMatch(t -> Objects.equals(Boolean.TRUE, t.getWholeDay()));
}
return true;
}
private EngineerCalendarDTO.Calendar getEmptyCalendar(String teamId, String date) {
// 初始化一天的日历
EngineerCalendarDTO.Calendar calendar = new EngineerCalendarDTO.Calendar();
......
......@@ -13,6 +13,7 @@ import com.dituhui.pea.order.enums.OrderFlowEnum;
import com.dituhui.pea.order.enums.OrderPeaTagsEnum;
import com.dituhui.pea.order.enums.ServiceStatusEnum;
import com.dituhui.pea.order.service.EngineerGanttService;
import com.dituhui.pea.order.utils.OrderUtil;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
......@@ -228,7 +229,7 @@ public class EngineerGanttServiceImpl implements EngineerGanttService {
tips.add(new LabelValueDTO().setLabel("工单号码").setValue(order.getOrderId()));
tips.add(new LabelValueDTO().setLabel("品牌/类型/技能").setValue(String.format("%s/%s/%s", order.getBrand(), order.getType(), order.getSkill())));
tips.add(new LabelValueDTO().setLabel("电话/地址").setValue(String.format("%s %s\n %s", order.getName(), order.getPhone(), order.getAddress())));
tips.add(new LabelValueDTO().setLabel("标签").setValue(getTags(order)));
tips.add(new LabelValueDTO().setLabel("标签").setValue(String.join(",", OrderUtil.handleTags(order))));
tips.add(new LabelValueDTO().setLabel("耗时").setValue(String.format("%s分钟", order.getTakeTime())));
tips.add(new LabelValueDTO().setLabel("期望时间").setValue(String.format("%s-%s",
DateUtils.formatDateTime(order.getExpectTimeBegin(), "HH:mm"), DateUtils.formatDateTime(order.getExpectTimeEnd(), "HH:mm"))));
......@@ -243,29 +244,6 @@ public class EngineerGanttServiceImpl implements EngineerGanttService {
return tips;
}
private String getTags(OrderInfoEntity order) {
List<String> tagList = new ArrayList();
if (StringUtils.isNotBlank(order.getBeanTags())) {
tagList = Arrays.stream(order.getBeanTags().split(",")).collect(Collectors.toList());
}
if (order.getIsCutoff() == 1) {
tagList.add(OrderPeaTagsEnum.cutoff.getTag());
}
if (order.getIsSpecialTime() == 1) {
tagList.add(OrderPeaTagsEnum.special.getTag());
}
if (order.getTranscend() == 1) {
tagList.add(OrderPeaTagsEnum.transcend.getTag());
}
if (order.getBeanPriority().equals("1")) {
tagList.add(OrderPeaTagsEnum.urgent.getTag());
}
if (StringUtils.isNotBlank(order.getMultipleOrders())) {
tagList.add(OrderPeaTagsEnum.multipleOrders.getTag());
}
return String.join(",", tagList);
}
private boolean checkOrderIsFinish(String serviceStatus) {
String[] array = {"FINISHED", "UNFINISHED"};
......
......@@ -9,12 +9,11 @@ import com.dituhui.pea.order.common.DateUtils;
import com.dituhui.pea.order.common.OrderAssignCheck;
import com.dituhui.pea.order.common.Stapial4jUtil;
import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.common.jackson.DateUtil;
import com.dituhui.pea.order.dao.EngineerBusinessDao;
import com.dituhui.pea.order.dao.EngineerInfoDao;
import com.dituhui.pea.order.dao.EngineerSkillGroupDao;
import com.dituhui.pea.order.dao.OrderInfoDao;
import com.dituhui.pea.order.dao.OrgBranchDao;
import com.dituhui.pea.order.dao.OrgGroupDao;
import com.dituhui.pea.order.dao.OrgTeamDao;
import com.dituhui.pea.order.dao.OrgTeamEngineerDao;
import com.dituhui.pea.order.dao.SkillInfoDao;
......@@ -39,9 +38,8 @@ import com.dituhui.pea.order.enums.OrderFlowEnum;
import com.dituhui.pea.order.enums.OrderStatusEnum;
import com.dituhui.pea.order.enums.ServiceStatusEnum;
import com.dituhui.pea.order.enums.TestimonialsEngineerTag;
import com.dituhui.pea.order.service.CapacityQueryService;
import com.dituhui.pea.order.service.CommonService;
import com.dituhui.pea.order.service.FendanService;
import com.dituhui.pea.order.service.EngineerCalendarService;
import com.dituhui.pea.order.service.MsgService;
import com.dituhui.pea.order.service.OrderAssign;
import com.dituhui.pea.order.service.OrderInfoService;
......@@ -114,25 +112,16 @@ public class OrderAssignImpl implements OrderAssign {
private OrderInfoService orderInfoService;
@Autowired
private OrgGroupDao orgGroupDao;
@Autowired
private FendanService fendanService;
@Autowired
private OrgBranchDao orgBranchDao;
@Autowired
private MsgService msgService;
@Autowired
private CapacityQueryService capacityQueryService;
@Autowired
private IUser userService;
@Autowired
private EngineerBusinessDao engineerBusinessDao;
@Autowired
private EngineerCalendarService engineerCalendarService;
@Transactional
@Override
......@@ -144,9 +133,12 @@ public class OrderAssignImpl implements OrderAssign {
}
String date = TimeUtils.IsoLocalDate2String(order.getDt());
LocalDate targetDate = LocalDate.parse(date, DateUtil.DATE_FORMATTER);
// 获取符合筛选条件的技术员
// 改造本方法 让其支持标签返回
List<TempEngineer> engineerLocationList = this.searchEngineerCodes(order, req.getDistance(), req.getKey(), req.getRecommend(), req.getUserId());
List<TempEngineer> engineerLocationList = this.searchEngineerCodes(order, req.getDistance(), req.getKey(),
req.getRecommend(), req.getUserId(), targetDate);
List<String> engineerCodes = engineerLocationList.stream().map(TempEngineer::getEngineerCode).collect(Collectors.toList());
Map<String, TempEngineer> engineerDistanceMap = engineerLocationList.stream().collect(Collectors.toMap(
TempEngineer::getEngineerCode,
......@@ -191,7 +183,7 @@ public class OrderAssignImpl implements OrderAssign {
engineerTag = TestimonialsEngineerTag.TEAM;
} else if (tempEngineer.getDistance().compareTo(judgeDistance) <= 0) {
engineerTag = TestimonialsEngineerTag.PERIPHERAL;
} else if (req.isSearch()){
} else if (req.isSearch()) {
engineerTag = TestimonialsEngineerTag.SEARCH;
} else {
engineerTag = TestimonialsEngineerTag.NONE;
......@@ -222,7 +214,8 @@ public class OrderAssignImpl implements OrderAssign {
@Override
public Result<?> orderAssign(OrderAssignReq req) throws BusinessException {
// 服务单指派-指派提交
OrderInfoEntity entity = orderInfoDao.getByOrderId(req.getOrderId());
String orderId = req.getOrderId();
OrderInfoEntity entity = orderInfoDao.getByOrderId(orderId);
if (entity == null) {
return Result.failed("订单不存在");
}
......@@ -242,7 +235,9 @@ public class OrderAssignImpl implements OrderAssign {
List<OrderInfoEntity> engineerOrders = orderInfoDao.findByDtAndEngineerCode(entity.getDt(), engineer.getEngineerCode());
Result<OrderInfoEntity> entityResult = orderInfoService.insterEngineerOrders(engineerOrders, entity, skill, byTeamId, engineer);
if (!entityResult.getCode().equals(ResultEnum.SUCCESS.getCode())) {
return Result.failed("当前工程师工单已满");
String desc = StatusCodeEnum.ENGINEER_IS_LEAVE_TIME.getDesc();
desc = String.format(desc, orderId, engineer.getName());
return new Result(StatusCodeEnum.ENGINEER_IS_LEAVE_TIME.getCode(), desc, null);
}
entity = entityResult.getResult();
......@@ -287,6 +282,10 @@ public class OrderAssignImpl implements OrderAssign {
// 更新order_request表为未指派
order = OrderUtil.handleErrorOrder2(order);
}
if (order.getIsAppointEngineer() == 1) {
order.setIsAppointEngineer(0);
order.setAppointEngineerCodes(null);
}
orderInfoDao.save(order);
commonService.addOrderEvent(orderId, "", "PEA", "PEA", OrderEventEnum.backOrderPool.getEvent(), OrderEventEnum.backOrderPool.getMsg(), "");
......@@ -323,7 +322,8 @@ public class OrderAssignImpl implements OrderAssign {
return order;
}
private List<TempEngineer> searchEngineerCodes(OrderInfoEntity order, Double distance, String key, String recommend, String userId) {
private List<TempEngineer> searchEngineerCodes(OrderInfoEntity order, Double distance, String key, String recommend,
String userId, LocalDate targetDate) {
Set<String> engineerCodes1 = this.searchEngineerByRecommend(order, recommend, userId);
if (engineerCodes1.isEmpty()) {
log.info("recommend:{}筛选条件未找到技术员", recommend);
......@@ -364,6 +364,11 @@ public class OrderAssignImpl implements OrderAssign {
double orderLongitude = Double.parseDouble(order.getX());
double orderLatitude = Double.parseDouble(order.getY());
//排除当天已经请假或者休息的人员
engineerCodes1 = engineerCodes1.stream()
.filter(engineerCode -> !engineerCalendarService.engineerTargetLeave(engineerCode, targetDate))
.collect(Collectors.toSet());
//均计算距离
List<TempEngineer> result = engineerCodes1.stream()
.map(engineerCode -> {
......
......@@ -61,6 +61,7 @@ import com.dituhui.pea.order.service.MsgService;
import com.dituhui.pea.order.service.OrderCreateService;
import com.dituhui.pea.order.service.OrderInfoService;
import com.dituhui.pea.order.utils.CommonUtil;
import com.dituhui.pea.order.utils.OrderUtil;
import com.dituhui.pea.pojo.saas.req.AdministrativeDistrictReq;
import com.dituhui.pea.pojo.saas.resp.AdministrativeDistrictResp;
import com.dituhui.pea.util.DateUtil;
......@@ -289,6 +290,8 @@ public class OrderCreateServiceImpl implements OrderCreateService {
entity.setExpectTimeEnd(DateUtil.fromDate(req.getExpectEnd()));
entity.setAppointmentStatus(OrderFlowEnum.INIT.name());
entity.setAppointmentMethod(AppointmentMethodEnum.AUTO_BATCH.name());
entity.setDt(entity.getExpectTimeBegin().toLocalDate());
entity.setOrderId(orderId);
//获取省市区
AdministrativeDistrictReq administrativeDistrictReq = new AdministrativeDistrictReq();
administrativeDistrictReq.setPoints(location.getLongitude() + "," + location.getLatitude());
......@@ -298,7 +301,6 @@ public class OrderCreateServiceImpl implements OrderCreateService {
entity.setCity(adminDistrict.getResult().getSubNames().getCity());
entity.setCounty(adminDistrict.getResult().getSubNames().getCounty());
}
List<String> tags = req.getOrderTags();
// 处理技能和标签
entity.setTakeTime(skillInfoEntity.getTakeTime());
String joinTags = CollectionUtils.isEmpty(req.getOrderTags()) ? "" : String.join(",", req.getOrderTags());
......@@ -309,10 +311,10 @@ public class OrderCreateServiceImpl implements OrderCreateService {
if (!DateUtil.judgeTimeIsToday(entity.getExpectTimeBegin())) {
entity.setAppointmentMethod(AppointmentMethodEnum.AUTO_NOW.name());
}
tags.add(OrderPeaTagsEnum.urgent.getTag());
//发送通知分部消息
// sendMsg(entity.getOrgBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate());
}
//一家多单
Result<String> addMultipleOrders = orderInfoService.addMultipleOrders(entity.getDt(), location.getAddressId(), orderId);
entity.setMultipleOrders(addMultipleOrders.getResult());
// 处理指派工程师
entity.setIsAppointEngineer(req.getIsAppointEngineer());
......@@ -355,12 +357,10 @@ public class OrderCreateServiceImpl implements OrderCreateService {
// 处理超派
entity.setTranscend(1);
}
Integer special = 0;
if (fendanResult.getCode().equals(StatusCodeEnum.FENDAN_IS_TRANSCEND_AND_SPECIAL.getCode())) {
// 处理超派和特殊时间
entity.setTranscend(1);
entity.setIsSpecialTime(1);
special = 1;
}
OrgBranchEntity branchEntity = orgBranchDao.findByCitycodeListLike("%" + adminDistrict.getResult().getSubNames().getCity() + "%");
entity.setOrgClusterId(branchEntity.getClusterId());
......@@ -370,7 +370,7 @@ public class OrderCreateServiceImpl implements OrderCreateService {
Integer cutoff = CommonUtil.isCutoff(entity.getExpectTimeBegin(), null);
entity.setIsCutoff(cutoff);
//发送通知分部消息
sendMsg(branchEntity.getBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate(), tags, cutoff, special);
sendMsg(branchEntity.getBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate(), entity);
} else {
// 根据分单工作队,填写clusterId/branchId/groupId/teamId等
OrgTeamInfo teamInfo = fendanResult.getResult();
......@@ -395,14 +395,13 @@ public class OrderCreateServiceImpl implements OrderCreateService {
entity.setIsSpecialTime(special);
entity.setAppointmentMethod(AppointmentMethodEnum.MANUAL.name());
//发送通知分部消息
sendMsg(teamInfo.getBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate(), tags, cutoff, special);
sendMsg(teamInfo.getBranchId(), orderId, entity.getExpectTimeBegin().toLocalDate(), entity);
}
}
}
// 字段转换
entity.setSource(req.getSource());
entity.setOrderId(orderId);
entity.setName(req.getName());
entity.setPhone(req.getPhone());
entity.setBeanBrand(req.getBrand());
......@@ -416,7 +415,6 @@ public class OrderCreateServiceImpl implements OrderCreateService {
entity.setPlanEndTime(entity.getExpectTimeEnd());
// order_request的description字段,仅仅用于内部备注,不对外
entity.setApplyNote(req.getDescription());
entity.setDt(entity.getExpectTimeBegin().toLocalDate());
entity.setSubId(newSubId(entity.getOrderId(), entity.getDt()));
entity.setX(req.getLocation().getLongitude().toString());
entity.setY(req.getLocation().getLatitude().toString());
......@@ -428,10 +426,6 @@ public class OrderCreateServiceImpl implements OrderCreateService {
entity.setBeanSubStatus("");
entity.setWorkshop(false);
//一家多单
Result<String> addMultipleOrders = orderInfoService.addMultipleOrders(entity.getDt(), location.getAddressId(), orderId);
entity.setMultipleOrders(addMultipleOrders.getResult());
// 记录订单和节点
orderInfoDao.save(entity);
commonService.addOrderEvent(orderId, "", req.getSource(), "API", OrderEventEnum.createOrder.getEvent(), String.format(OrderEventEnum.createOrder.getMsg(), req.getSource(), "BEAN", req.getOrderId()), "");
......@@ -442,21 +436,12 @@ public class OrderCreateServiceImpl implements OrderCreateService {
return Result.success(null);
}
private void sendMsg(String branchId, String orderId, LocalDate toLocalDate, List<String> tags, Integer cutoff, Integer special) {
if (cutoff == 1) {
tags.add(OrderPeaTagsEnum.cutoff.getTag());
}
if (special == 1) {
tags.add(OrderPeaTagsEnum.special.getTag());
}
if (CollectionUtils.isNotEmpty(tags)) {
tags = tags.stream().filter(e -> StringUtils.isNotBlank(e)).collect(Collectors.toList());
}
private void sendMsg(String branchId, String orderId, LocalDate toLocalDate, OrderInfoEntity orderInfo) {
MsgDTO msgDTO = new MsgDTO();
msgDTO.setBranchId(branchId);
msgDTO.setType(0);
msgDTO.setOrderIds(orderId);
msgDTO.setContent(String.format("有1条预约日期在%s的工单需人工外理,标签是(%s),单号:%S", toLocalDate, String.join(",", tags), orderId));
msgDTO.setContent(String.format("有1条预约日期在%s的工单需人工外理,标签是(%s),单号:%S", toLocalDate, String.join(",", OrderUtil.handleTags(orderInfo)), orderId));
msgService.add(msgDTO);
}
......
......@@ -80,6 +80,9 @@ public class OrderInfoServiceImpl implements OrderInfoService {
@Autowired
private EngineerCalendarService engineerCalendarService;
@Autowired
private EngineerSkillGroupDao engineerSkillGroupDao;
/**
* 新增订单处理一家多单逻辑
......@@ -324,13 +327,33 @@ public class OrderInfoServiceImpl implements OrderInfoService {
// 是否网点
//网点都需要重新指派
boolean isNetwork = ObjectUtil.isNull(groupEntity) ? false : groupEntity.getCategory() == 2;
// 是否需要从新指派
boolean isAssign = false;
String branchId = order.getOrgBranchId();
String clusterId = order.getOrgClusterId();
String teamId = order.getOrgTeamId();
// 修改技能时处理工单耗时
if (skillUpdate) {
isAssign = true;
SkillInfoEntity skillInfoEntity = skillInfoDao.getByBrandAndTypeAndSkill(order.getBrand(), order.getType(), order.getSkill());
if (ObjectUtil.isNull(skillInfoEntity)) {
return Result.failed(StatusCodeEnum.ORDER_SKILL_NOT_EXISTS);
}
order.setTakeTime(skillInfoEntity.getTakeTime());
// 处理指定工程师技能是否符合
if (order.getIsAppointEngineer() == 1) {
EngineerSkillGroupEntity skillGroupCode = engineerSkillGroupDao.findByEngineerCodeAndSkillGroupCode(order.getAppointEngineerCodes().split(",")[0], skillInfoEntity.getSkillGroupCode());
if (ObjectUtil.isNotEmpty(skillGroupCode)) {
isAssign = false;
}
}
}
// 当天单变更技能直接人工指派
if (isToday && skillUpdate) {
if (order.getIsAppointEngineer() != 1) {
if (isAssign) {
order = OrderUtil.handleErrorOrder(order);
teamId = null;
order.setAppointmentMethod(AppointmentMethodEnum.MANUAL.name());
......@@ -342,12 +365,12 @@ public class OrderInfoServiceImpl implements OrderInfoService {
// i.自有:优先改约指派给当前工程师
// ii.网点:优先改约指派给当前网点
// (不给当前工程师)
if (!isToday && isBelong && skillUpdate && order.getIsAppointEngineer() != 1) {
if (!isToday && isBelong && skillUpdate && isAssign) {
//地址变更需要从新分单
order = orderFendan(order, req, location);
clusterId = order.getOrgClusterId();
branchId = order.getOrgBranchId();
} else if (isToday && isBelong && order.getIsAppointEngineer() != 1) {
} else if (isToday && isBelong && isAssign) {
// b.已派人-改约到当天
// i.自有:优先改约指派给当前工程师
// (会影响该工程师当天后续工单的时
......@@ -394,15 +417,6 @@ public class OrderInfoServiceImpl implements OrderInfoService {
}
}
// 修改技能时处理工单耗时
if (skillUpdate) {
SkillInfoEntity skillInfoEntity = skillInfoDao.getByBrandAndTypeAndSkill(order.getBrand(), order.getType(), order.getSkill());
if (ObjectUtil.isNull(skillInfoEntity)) {
return Result.failed(StatusCodeEnum.ORDER_SKILL_NOT_EXISTS);
}
order.setTakeTime(skillInfoEntity.getTakeTime());
}
//处理一家多单
// order = handleMultipleOrders(order);
if (!orderDt.isEqual(expectBegin.toLocalDate())) {
......@@ -708,6 +722,8 @@ public class OrderInfoServiceImpl implements OrderInfoService {
* @return
*/
private OrderInfoEntity orderFendan(OrderInfoEntity order, OrderReschedule req, Location location) {
//清除指派信息
order = OrderUtil.handleErrorOrder(order);
order.setServiceStatus(ServiceStatusEnum.INIT.getCode());
if (StringUtils.isNotBlank(req.getDescription())) {
order.setDescription(order.getDescription());
......
......@@ -8,6 +8,7 @@ import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.common.ListUtils;
import com.dituhui.pea.order.common.TimeUtils;
import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.EngineerBusinessListResp;
import com.dituhui.pea.order.dto.OrderServiceList;
import com.dituhui.pea.order.dto.OrderServiceListReq;
import com.dituhui.pea.order.dto.OrderServiceListResp;
......@@ -37,6 +38,12 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
@Autowired
private OrderInfoDao orderInfoDao;
@Autowired
private EngineerBusinessDao engineerBusinessDao;
@Autowired
private OrgWarehouseInfoDao orgWarehouseInfoDao;
@Transactional
@Override
public Result<OrderServiceListResp> getOrderServiceList(OrderServiceListReq reqDTO) throws BusinessException {
......@@ -61,17 +68,8 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
lqw.in(ListUtils.isNotEmpty(reqDTO.getTeamIds()), OrderInfo::getOrgTeamId, reqDTO.getTeamIds());
lqw.in(ListUtils.isNotEmpty(reqDTO.getAppointmentType()), OrderInfo::getAppointmentMethod, reqDTO.getAppointmentType());
lqw.in(ListUtils.isNotEmpty(reqDTO.getAppointmentStatus()), OrderInfo::getAppointmentStatus, reqDTO.getAppointmentStatus());
lqw.in(ListUtils.isNotEmpty(reqDTO.getPriorities()), OrderInfo::getBeanPriority, reqDTO.getPriorities());
lqw.orderByDesc(OrderInfo::getCreateTime);
if (ListUtils.isNotEmpty(reqDTO.getPriorities())) {
List<Integer> p = reqDTO.getPriorities();
if (p.contains(0) && p.contains(1)) {
lqw.ge(OrderInfo::getPriority, 1);
} else if (p.contains(0) && !p.contains(1)) {
lqw.le(OrderInfo::getPriority, 1);
} else if (p.contains(1) && !p.contains(0)) {
lqw.ge(OrderInfo::getPriority, 5);
}
}
if (ListUtils.isNotEmpty(reqDTO.getEngineerCodes())) {
lqw.and(w ->
......@@ -105,7 +103,9 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
List<OrderInfo> orders = pg.getRecords();
// 获取技术员姓名
Map<String, String> engineerNames = this.getEngineerNames(orders);
Map<String, EngineerInfoEntity> engineerNames = this.getEngineerNames(orders);
// 获取技术员业务信息
Map<String, EngineerBusinessEntity> engineerBusiness = this.getEngineerBusiness(engineerNames);
// 获取branch
Map<String, String> branchNames = this.getBranchNames(orders);
......@@ -134,6 +134,13 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
List<String> names = this.getOrderEngineerNames(o.getEngineerCode(), o.getEngineerCodeSub(), engineerNames);
record.setEngineerNum(names.size()); //工程师数量
record.setEngineerNames(String.join("、", names)); //工程师姓名列表
if (engineerBusiness.containsKey(o.getEngineerCode())) {
EngineerBusinessEntity businessEntity = engineerBusiness.get(o.getEngineerCode());
record.setDepartureX(businessEntity.getX());
record.setDepartureY(businessEntity.getY());
record.setDeparture(businessEntity.getDeparture());
record.setVehicle(businessEntity.getVehicle());
}
}
record.setExpectTimeBegin(TimeUtils.IsoTimestamp2DateTime(o.getExpectTimeBegin()));
......@@ -169,7 +176,7 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
List<OrderInfoEntity> byMultipleOrders = orderInfoDao.findByMultipleOrdersAndOrderIdNot(o.getMultipleOrders(), o.getOrderId());
List<OrderServiceList> multipleItems = new ArrayList<>();
for (OrderInfoEntity info : byMultipleOrders) {
multipleItems.add(toMultipleOrders(info, branchNames, engineerNames));
multipleItems.add(toMultipleOrders(info, branchNames, engineerNames, engineerBusiness));
}
record.setMultipleOrderList(multipleItems);
}
......@@ -187,7 +194,47 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
return Result.success(res);
}
private OrderServiceList toMultipleOrders(OrderInfoEntity o, Map<String, String> branchNames, Map<String, String> engineerNames) {
/**
* 获取团队配件仓地址
*
* @param orders
* @return
*/
private Map<String, OrgWarehouseInfoEntity> getTeamWarehouseInfo(List<OrderInfo> orders) {
Map<String, OrgWarehouseInfoEntity> orgWarehouseInfoEntityMap = new HashMap<>();
for (OrderInfo r : orders) {
if (StringUtils.isEmpty(r.getOrgTeamId())) {
continue;
}
if (orgWarehouseInfoEntityMap.containsKey(r.getOrgTeamId())) {
continue;
}
OrgWarehouseInfoEntity byTeamAssigned = orgWarehouseInfoDao.getByTeamAssigned(r.getOrgTeamId());
if (ObjectUtil.isNull(byTeamAssigned)) {
continue;
}
orgWarehouseInfoEntityMap.put(r.getOrgTeamId(), byTeamAssigned);
}
return orgWarehouseInfoEntityMap;
}
private Map<String, EngineerBusinessEntity> getEngineerBusiness(Map<String, EngineerInfoEntity> engineerNames) {
// 获取技术员姓名
Set<String> engineerCodes = new HashSet<>();
for (String engineerCode : engineerNames.keySet()) {
if (StringUtils.isNotEmpty(engineerCode)) {
engineerCodes.add(engineerCode);
}
}
if (engineerCodes.isEmpty()) {
return new HashMap<>();
}
List<EngineerBusinessEntity> engineers = engineerBusinessDao.findByEngineerCodeIn(new ArrayList<>(engineerCodes));
return engineers.stream().collect(Collectors.toMap(EngineerBusinessEntity::getEngineerCode, e -> e));
}
private OrderServiceList toMultipleOrders(OrderInfoEntity o, Map<String, String> branchNames, Map<String, EngineerInfoEntity> engineerNames, Map<String, EngineerBusinessEntity> engineerBusiness) {
OrderServiceList record = new OrderServiceList();
record.setOrderId(o.getOrderId());
record.setType(o.getType());
......@@ -210,6 +257,12 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
List<String> names = this.getOrderEngineerNames(o.getEngineerCode(), o.getEngineerCodeSub(), engineerNames);
record.setEngineerNum(names.size()); //工程师数量
record.setEngineerNames(String.join("、", names)); //工程师姓名列表
if (engineerBusiness.containsKey(o.getEngineerCode())) {
EngineerBusinessEntity businessEntity = engineerBusiness.get(o.getEngineerCode());
record.setDepartureX(businessEntity.getX());
record.setDepartureY(businessEntity.getY());
record.setDeparture(businessEntity.getDeparture());
}
}
record.setExpectTimeBegin(TimeUtils.IsoLocalDateTime2String(o.getExpectTimeBegin()));
......@@ -232,7 +285,7 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
return record;
}
private Map<String, String> getEngineerNames(List<OrderInfo> orders) {
private Map<String, EngineerInfoEntity> getEngineerNames(List<OrderInfo> orders) {
// 获取技术员姓名
Set<String> engineerCodes = new HashSet<>();
for (OrderInfo r : orders) {
......@@ -247,7 +300,7 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
return new HashMap<>();
}
List<EngineerInfoEntity> engineers = engineerInfoDao.findByEngineerCodeIn(new ArrayList<>(engineerCodes));
return engineers.stream().collect(Collectors.toMap(EngineerInfoEntity::getEngineerCode, EngineerInfoEntity::getName));
return engineers.stream().collect(Collectors.toMap(EngineerInfoEntity::getEngineerCode, e -> e));
}
private Map<String, String> getBranchNames(List<OrderInfo> orders) {
......@@ -265,7 +318,7 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
return records.stream().collect(Collectors.toMap(OrgBranchEntity::getBranchId, OrgBranchEntity::getBranchName));
}
private List<String> getOrderEngineerNames(String engineerCode, String engineerCodeSub, Map<String, String> engineerNames) {
private List<String> getOrderEngineerNames(String engineerCode, String engineerCodeSub, Map<String, EngineerInfoEntity> engineerNames) {
// 获取订单技术员姓名信息
List<String> names = new ArrayList<>();
List<String> codes = new ArrayList<>() {
......@@ -275,9 +328,9 @@ public class OrderServiceListServiceImpl implements OrderServiceListService {
}
};
for (String code : codes) {
String name = engineerNames.getOrDefault(code, "");
if (StringUtils.isNotEmpty(name)) {
names.add(name);
EngineerInfoEntity engineerInfo = engineerNames.getOrDefault(code, null);
if (ObjectUtil.isNotNull(engineerInfo)) {
names.add(engineerInfo.getName());
}
}
return names;
......
......@@ -11,6 +11,7 @@ import com.dituhui.pea.order.dao.EngineerSkillGroupDao;
import com.dituhui.pea.order.dao.MapBlockInfoDao;
import com.dituhui.pea.order.dao.OrderInfoDao;
import com.dituhui.pea.order.dao.OrgGroupDao;
import com.dituhui.pea.order.dao.OrgTeamDao;
import com.dituhui.pea.order.dto.param.EstimateDTO;
import com.dituhui.pea.order.dto.param.Location;
import com.dituhui.pea.order.dto.param.Order;
......@@ -22,6 +23,7 @@ import com.dituhui.pea.order.entity.EngineerSkillGroupEntity;
import com.dituhui.pea.order.entity.MapBlockInfoEntity;
import com.dituhui.pea.order.entity.OrderInfoEntity;
import com.dituhui.pea.order.entity.OrgGroupEntity;
import com.dituhui.pea.order.entity.OrgTeamEntity;
import com.dituhui.pea.order.enums.AppointmentMethodEnum;
import com.dituhui.pea.order.enums.OrderEventEnum;
import com.dituhui.pea.order.enums.OrderFlowEnum;
......@@ -29,6 +31,7 @@ import com.dituhui.pea.order.enums.OrderStatusEnum;
import com.dituhui.pea.order.enums.ServiceStatusEnum;
import com.dituhui.pea.order.service.CommonService;
import com.dituhui.pea.order.service.PeaOuterAPIService;
import com.dituhui.pea.order.utils.CommonUtil;
import com.dituhui.pea.pojo.fendan.FendanDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
......@@ -62,6 +65,7 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
* 分部数据访问层
*/
private final OrgGroupDao orgGroupDao;
private final OrgTeamDao orgTeamDao;
private final OrderInfoDao orderInfoDao;
private final EngineerSkillGroupDao engineerSkillGroupDao;
private final SaasUtils saasUtils;
......@@ -174,6 +178,9 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
final String orderId = request.getOrderId();
OrderInfoEntity orderInfo = orderInfoDao.getByOrderId(orderId);
EngineerInfoEntity engineerInfo = engineerInfoDao.getByEngineerCode(request.getEngineerCode());
Set<OrgTeamEntity> teamEntitySet = orgTeamDao.selectTeamByEngineerCode(request.getEngineerCode());
OrgTeamEntity team = new ArrayList<>(teamEntitySet).get(0);
//confirmed预约成功;other预约失败
if (Objects.equals(request.getAppointmentResult(), "CONFIRMED")) {
orderInfo.setAppointmentStatus(String.valueOf(OrderFlowEnum.CONFIRM));
......@@ -196,6 +203,15 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
orderInfo.setExpectTimeEnd(LocalDateTime.of(date, exceptEndHour));
orderInfo.setExpectTimeDesc(MessageFormat.format("{0}月{1}日{2}-{3}点", date.getMonthValue(), date.getDayOfMonth(), exceptStartHour.getHour(), exceptEndHour.getHour()));
orderInfo.setApplyNote(MessageFormat.format("{0}-{1}", DateTimeUtil.formatTime(exceptStartHour), DateTimeUtil.formatTime(exceptEndHour)));
//是否特殊时间段
Integer special = CommonUtil.isSpecial(orderInfo.getExpectTimeBegin().toLocalTime(), orderInfo.getExpectTimeEnd().toLocalTime(),
team.getWorkOn(), team.getWorkOff());
orderInfo.setIsSpecialTime(special);
//是否当日单
Integer cutoff = CommonUtil.isCutoff(orderInfo.getExpectTimeBegin(), team.getCuteOff());
orderInfo.setIsCutoff(cutoff);
}
orderInfo.setReasonForFailure(request.getReasonForFailure());
......
......@@ -11,6 +11,7 @@ import com.dituhui.pea.order.dto.OrderChangeListDTO;
import com.dituhui.pea.order.dto.WorkbenchSummaryResp;
import com.dituhui.pea.order.entity.OrderEventEntity;
import com.dituhui.pea.order.entity.OrderInfoEntity;
import com.dituhui.pea.order.enums.AppointmentMethodEnum;
import com.dituhui.pea.order.enums.OrderFlowEnum;
import com.dituhui.pea.order.service.WorkbenchService;
import lombok.extern.slf4j.Slf4j;
......@@ -79,16 +80,26 @@ public class WorkbenchServiceImpl implements WorkbenchService {
return Result.success(rs);
}
/**
* 工作台工单状态统计
*
* @param levelType
* @param levelValue
* @param dt
* @return
*/
@Override
public Result<?> getWorkbenchSummary(String levelType, String levelValue, LocalDate dt) {
List<WorkbenchSummaryResp.ItemDTO> items = new ArrayList<>();
//处理工单分配状态 待人工处理 待自动处理 全部订单
HashMap<String, Long> methodSummary = this.transAppointmentMethod(this.queryCountByAppointmentMethod(levelType, levelValue, dt));
WorkbenchSummaryResp.ItemDTO methodItem = new WorkbenchSummaryResp.ItemDTO();
methodItem.setType("order");
methodItem.setRows(this.packValueAppointmentMethod(methodSummary));
items.add(methodItem);
// 处理改约。取消。超时等状态
HashMap<String, Long> statusSummary = this.transOrderStatus(this.queryCountByOrderStatus(levelType, levelValue, dt));
WorkbenchSummaryResp.ItemDTO statusItem = new WorkbenchSummaryResp.ItemDTO();
statusItem.setType("order");
......@@ -99,7 +110,7 @@ public class WorkbenchServiceImpl implements WorkbenchService {
// - 已延误:已到开始时间,TARO没有反馈开始的工单.
valueDTOS.add(new WorkbenchSummaryResp.ValueDTO("已延误", queryDelayNum(levelType, levelValue, dt), null, "#FF3D44", "", new HashMap<>()));
statusItem.setRows(valueDTOS);
// - 已超时:已到开始时间,TARO没有反馈开始的工单.
// - 已超时:已过预计结束时间,TARO没有反馈开始的工单.
valueDTOS.add(new WorkbenchSummaryResp.ValueDTO("已超时", queryOvertimeNum(levelType, levelValue, dt), null, "#FF3D44", "", new HashMap<>()));
statusItem.setRows(valueDTOS);
items.add(statusItem);
......@@ -186,6 +197,14 @@ public class WorkbenchServiceImpl implements WorkbenchService {
return rescheduledNum;
}
/**
* 分组统计订单分配状态
*
* @param levelType
* @param levelValue
* @param dt
* @return
*/
private List<Map<String, Object>> queryCountByAppointmentMethod(String levelType, String levelValue, LocalDate dt) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> criteriaQuery = criteriaBuilder.createQuery(Object[].class);
......@@ -278,6 +297,12 @@ public class WorkbenchServiceImpl implements WorkbenchService {
return mappedResults;
}
/**
* 组装分组数据
*
* @param results
* @return
*/
private HashMap<String, Long> transAppointmentMethod(List<Map<String, Object>> results) {
HashMap<String, Long> map = new HashMap<>();
......@@ -291,15 +316,15 @@ public class WorkbenchServiceImpl implements WorkbenchService {
total += count;
if (method.equals("MANUAL")) {
if (method.equals(AppointmentMethodEnum.MANUAL.name())) {
manualTotal += count;
} else if (method.startsWith("AUTO_")) {
autoTotal += count;
}
if (method.equals("MANUAL") && status.equals("INIT")) {
if (method.equals(AppointmentMethodEnum.MANUAL.name()) && status.equals(OrderFlowEnum.INIT.name())) {
map.put("manualDealing", count);
} else if (method.equals("AUTO_") && status.equals("INIT")) {
} else if (method.startsWith("AUTO_") && status.equals(OrderFlowEnum.INIT.name())) {
map.put("autoDealing", count);
}
}
......
package com.dituhui.pea.order.utils;
import com.dituhui.pea.order.entity.OrderInfoEntity;
import com.dituhui.pea.order.enums.OrderPeaTagsEnum;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class OrderUtil {
/**
......@@ -31,4 +38,34 @@ public class OrderUtil {
return order;
}
/**
* 分单,超派,特殊时间等处理工单指派工程师,网点等数据
*
* @param order
* @return
*/
public static List<String> handleTags(OrderInfoEntity order) {
List<String> tagList = new ArrayList();
if (StringUtils.isNotBlank(order.getBeanTags())) {
tagList = Arrays.stream(order.getBeanTags().split(",")).collect(Collectors.toList());
}
if (order.getIsCutoff() == 1) {
tagList.add(OrderPeaTagsEnum.cutoff.getTag());
}
if (order.getIsSpecialTime() == 1) {
tagList.add(OrderPeaTagsEnum.special.getTag());
}
if (order.getTranscend() == 1) {
tagList.add(OrderPeaTagsEnum.transcend.getTag());
}
if (order.getBeanPriority().equals("1")) {
tagList.add(OrderPeaTagsEnum.urgent.getTag());
}
if (StringUtils.isNotBlank(order.getMultipleOrders())) {
tagList.add(OrderPeaTagsEnum.multipleOrders.getTag());
}
return tagList;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!