Commit 23e3d84e by Ren Ping

feat:移除不满足工程师时间窗强约束的订单

1 parent 1181ddaf
......@@ -30,7 +30,7 @@ public interface DispatchOrderRepository extends CrudRepository<DispatchOrder, L
List<DispatchOrder> findAllWithoutConfirm(String groupId, String batchNo);
// 查看算法指派成功(也有抹掉技术员、时间情况),非confirm状态的
@Query("from DispatchOrder where teamId=?1 and batchNo=?2 and status !='CONFIRM' ")
@Query("from DispatchOrder where teamId=?1 and batchNo=?2 ")
List<DispatchOrder> findAllWithoutConfirm2(String teamId, String batchNo);
Optional<DispatchOrder> findByGroupIdAndBatchNoAndOrderIdAndDt(String groupId, String batchNo, String orderId, String dt);
......
......@@ -20,8 +20,11 @@ import lombok.Setter;
public class Customer {
private long id;
private String code;
private String status;
// 已分配
private String dispatchedTechnicianCode;
// 已排除
......@@ -56,7 +59,7 @@ public class Customer {
}
public Customer(long id, String code, String dt, Location location, int startTime, int endTime, String requiredSkill,
int serviceDuration) {
int serviceDuration, String status) {
this.id = id;
this.code = code;
this.dt = dt;
......@@ -65,6 +68,7 @@ public class Customer {
this.endTime = endTime;
this.requiredSkill = requiredSkill;
this.serviceDuration = serviceDuration;
this.status = status;
}
@InverseRelationShadowVariable(sourceVariableName = "customerList")
......
......@@ -26,7 +26,7 @@ public interface ExtractService {
/*
* 按小队将dispath_order 中的计算结果,回写到 order_info
* */
void extractDispatchToOrder2(String TeamId, String batchNo, boolean isConfirm) ;
void extractDispatchToOrder2(String TeamId, String batchNo, boolean cutOff) ;
}
......@@ -186,7 +186,7 @@ public class ExtractServiceImpl implements ExtractService {
*/
@Transactional(isolation = READ_COMMITTED, propagation = Propagation.REQUIRED)
@Override
public void extractDispatchToOrder2(String teamId, String batchNo, boolean isConfirm) {
public void extractDispatchToOrder2(String teamId, String batchNo, boolean cutOff) {
log.info("算法结果更新到工单, teamId:{}, batchNo:{}", teamId, batchNo);
entityManager.clear();
......@@ -230,10 +230,11 @@ public class ExtractServiceImpl implements ExtractService {
OrderInfo orderInfo = orderOpt.get();
if (!("OPEN".equals(orderInfo.getBeanStatus()) &&
Set.of("AUTO_NOW", "AUTO_BATCH").contains(orderInfo.getAppointmentMethod()) &&
Set.of("INIT", "PRE").contains(orderInfo.getAppointmentStatus()) &&
"NORMAL".equals(orderInfo.getOrderStatus()) && "INIT".equals(orderInfo.getServiceStatus()))) {
if (!("OPEN".equals(orderInfo.getBeanStatus())
&& Set.of("AUTO_NOW", "AUTO_BATCH", "MANUAL").contains(orderInfo.getAppointmentMethod())
&& Set.of("INIT", "PRE", "CONFIRM").contains(orderInfo.getAppointmentStatus())
&& "NORMAL".equals(orderInfo.getOrderStatus())
&& "INIT".equals(orderInfo.getServiceStatus()))) {
log.warn("算法结果更新到工单, step1.1-loop, 工单状态异常, teamId:{}, batchNo:{}, orderId:{}, bean-status:{}, appointment-status:{}, order-status:{}, service-status:{}",
teamId, batchNo, orderId, orderInfo.getBeanStatus(), orderInfo.getAppointmentStatus(), orderInfo.getOrderStatus(), orderInfo.getServiceStatus());
......@@ -263,12 +264,14 @@ public class ExtractServiceImpl implements ExtractService {
orderInfo.setPlanEndTime(dispatchOrder.getTimeEnd());
orderInfo.setArriveElapsed(dispatchOrder.getPathTime());
orderInfo.setArriveDistance(dispatchOrder.getPathDistance());
orderInfo.setAppointmentStatus(isConfirm ? "CONFIRM" : "PRE");
if (!"CONFIRM".equals(dispatchOrder.getStatus())) {
orderInfo.setAppointmentStatus(cutOff ? "CONFIRM" : "PRE");
}
orderInfo.setDispatcher("AUTO_BATCH");
orderInfo.setUpdateTime(LocalDateTime.now());
orderInfoRepo.save(orderInfo);
if (isConfirm) {
if (cutOff) {
OrderEvent orderEvent = new OrderEvent().setOrderId(orderId).setSuborderId(orderInfo.getSubId()).setHappen(LocalDateTime.now())
.setEvent("批量自动指派").setOperator("DISPATCH").setOperatorName("算法批量指派").setSource("PEA-DISPATCH")
.setDescription(String.format("批量自动指派:<%s,%s>", engCode, engName)).setMemo("")
......
......@@ -259,7 +259,7 @@ public class SolveServiceImpl implements SolveService {
order.setPriority(0);
}
Customer customer = new Customer(order.getId(), order.getOrderId(), order.getDt(), location, start, end, order.getSkills(), order.getTakeTime());
Customer customer = new Customer(order.getId(), order.getOrderId(), order.getDt(), location, start, end, order.getSkills(), order.getTakeTime(), order.getStatus());
OrderInfo orderInfo = orderInfoRepository.findByOrderId(order.getOrderId()).get(0);
if ((StrUtil.equals("MANUAL", orderInfo.getAppointmentMethod())
&& StrUtil.equals("CONFIRM", orderInfo.getAppointmentStatus()))
......@@ -535,7 +535,8 @@ public class SolveServiceImpl implements SolveService {
log.info("算法结果回写dispatch, step1-清除历史, groupId:{}, batchNo:{}", teamId, batchNo);
Object[] paramClear = {teamId, batchNo};
String sqlReset = "update dispatch_order set engineer_code='', seq=0, time_begin=null, time_end=null, path_time=0, path_distance=0 " + "where team_id=? and batch_no=? and status!='CONFIRM' ";
// confirm 状态工单不清除
String sqlReset = "update dispatch_order set engineer_code=null, seq=0, time_begin=null, time_end=null, path_time=0, path_distance=0 " + "where team_id=? and batch_no=? and status!='CONFIRM' ";
jdbcTemplate.update(sqlReset, paramClear);
log.info("算法结果回写dispatch, step2-开始回写, teamId:{}, batchNo:{}", teamId, batchNo);
......@@ -561,7 +562,7 @@ public class SolveServiceImpl implements SolveService {
int pathTime = customer.getPathTimeFromPreviousStandstill();
long pathDistance = customer.getDistanceFromPreviousStandstill();
String sql = "update dispatch_order set engineer_code=?, seq=?, time_begin=? ,time_end=?, path_time=?, path_distance=? " + " where team_id=? and batch_no=? and order_id=? and dt=? and status!='CONFIRM' ";
String sql = "update dispatch_order set engineer_code=?, seq=?, time_begin=? ,time_end=?, path_time=?, path_distance=? " + " where team_id=? and batch_no=? and order_id=? and dt=?";
Object[] param = {technician.getCode(), idx, arriveTime, leaveTime, pathTime, pathDistance, teamId, batchNo, customer.getCode(), customer.getDt()};
int rowUpdated = jdbcTemplate.update(sql, param);
log.info("算法结果回写dispatch, step3-逐个客户处理, order_id:{}, engineer_code:{}, seq: {}, begin:{}, end:{} ,rowUpdated:{}", customer.getCode(), technician.getCode(), seq, arriveTime, leaveTime, rowUpdated);
......
......@@ -51,6 +51,7 @@ public class DataUtils {
/**
* 获取初始化测试数据
* fullDay 是否全天派工
*
* @return
* @throws UncheckedIOException
* @throws FileNotFoundException
......@@ -68,7 +69,7 @@ public class DataUtils {
Map<String, Integer> customerCodeServiceTimeMap = loadCustomerCodeServiceTimeMap();
DispatchSolution problem = createVehicleRoutingSolution(customerIndexMap, customerIndexXyMap,
technicianIndexMap, technicianCodeSkillsMap, customerCodeSkillMap, technicianCodePreferredLocationMap,
preferredlocationDistanceMap, customerCodeServiceTimeMap,fullDay);
preferredlocationDistanceMap, customerCodeServiceTimeMap, fullDay);
return problem;
}
......@@ -252,7 +253,7 @@ public class DataUtils {
String[] temps = line.split(",");
for (int j = 0; j < temps.length; j++) {
// 秒转分钟
pathTimeMatrix[i][j] = (long) (Math.round(Float.parseFloat(temps[j]) ));
pathTimeMatrix[i][j] = (long) (Math.round(Float.parseFloat(temps[j])));
}
}
for (int i = 0; i < pathTimeMatrix.length; i++) {
......@@ -293,7 +294,8 @@ public class DataUtils {
customerList.add(new Customer(i + 1, customerIndexMap.get(i + 1), "2000-01-01", locationIndex.get(i + 2),
customerStartMap.get(i + 1), customerEndMap.get(i + 1), customerSkillMap.get(i + 1),
// 初始化技能服务时间
customerCodeServiceTimeMap.get(customerIndexMap.get(i + 1))));
customerCodeServiceTimeMap.get(customerIndexMap.get(i + 1)),
null));
}
// 初始化Depot
......@@ -314,7 +316,7 @@ public class DataUtils {
String[] temps = xyString.split(",");
Location preferredlocation = new Location(i + 1, Float.parseFloat(RegExUtils.removeAll(temps[0], "\"")),
Float.parseFloat(RegExUtils.removeAll(temps[1], "\"")));
technicianList.add(new Technician(i + 1, technicianIndexMap.get(i + 1), depot, 480, fullDay ? 1440 : 1080 , skills,
technicianList.add(new Technician(i + 1, technicianIndexMap.get(i + 1), depot, 480, fullDay ? 1440 : 1080, skills,
preferredlocationDistanceMap.get(technicianIndexMap.get(i + 1)), preferredlocation));
}
......@@ -325,7 +327,7 @@ public class DataUtils {
orderCodeTechnichanCodesMap.put("106863823", "6200040858");
for (Customer customer : customerList) {
if (null != orderCodeTechnichanCodesMap.get(customer.getCode())) {
System.out.println("set code"+customer.getCode()+" : "+orderCodeTechnichanCodesMap.get(customer.getCode()));
System.out.println("set code" + customer.getCode() + " : " + orderCodeTechnichanCodesMap.get(customer.getCode()));
customer.setDispatchedTechnicianCode(orderCodeTechnichanCodesMap.get(customer.getCode()));
}
}
......
......@@ -11,6 +11,7 @@ import java.util.stream.Collectors;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.optaplanner.constraint.streams.drools.DroolsConstraintStreamScoreDirector;
......@@ -400,7 +401,8 @@ public class DispatchSolutionUtils {
List<Customer> customerList = new ArrayList<>();
customerList.addAll(((Technician) indictedObject).getCustomerList());
for (Customer customer : customerList) {
if (!customer.isInTechnicianTimeWindows()) {
if (!customer.isInTechnicianTimeWindows()
&& !StrUtil.equals("CONFIRM", customer.getStatus())) {
// 更新shadow变量
updateShadowVariable(customer);
// 移除技术员
......@@ -411,6 +413,19 @@ public class DispatchSolutionUtils {
}
}
break;
case dispatchedMatch:
for (Object indictedObject : constraintMatch.getIndictedObjectList()) {
// 违反硬约束对象,根据具体约束返回不同类型对象
if (indictedObject instanceof Customer) {
Customer customer = (Customer) indictedObject;
// 更新shadow变量
updateShadowVariable(customer);
// 移除技术员
customer.getTechnician().getCustomerList().remove(customer);
solution.getUnDispatchedCustomers().add(customer);
}
}
break;
default:
break;
}
......
......@@ -3,7 +3,7 @@ server:
dispatch:
cron:
expr: 0 10 8-23 * * ?
expr: 0 9 8-23 * * ?
next-day-limit: 2
scheduler:
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!