add:二期新增空木箱出库功能

This commit is contained in:
2025-02-26 18:35:13 +08:00
parent 8743d3c71c
commit f71e2aeb64
6 changed files with 363 additions and 0 deletions

View File

@@ -83,4 +83,11 @@ public class ProductOutTwoController {
return new ResponseEntity<>(TableDataInfo.build(productOutTwoService.woodenBoxPoint(whereJson)), HttpStatus.OK);
}
@PostMapping("/boxOut")
@Log("木箱出库")
@SaIgnore
public ResponseEntity<Object> boxOut(@RequestBody JSONObject whereJson) {
return new ResponseEntity<>(productOutTwoService.boxOut(whereJson),HttpStatus.OK);
}
}

View File

@@ -84,4 +84,10 @@ public interface ProductOutTwoService {
*/
List<JSONObject> woodenBoxPoint(JSONObject whereJson);
/**
* 要出库的木箱明细
* @param whereJson 、
* @return 、
*/
JSONObject boxOut(JSONObject whereJson);
}

View File

@@ -13,6 +13,7 @@ import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService;
import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxlashboundService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxlashbound;
import org.nl.b_lms.storage_manage.database.service.dao.mapper.BstIvtBoxinfoMapper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service.OutBoxManageService;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.modules.wql.util.SpringContextHolder;
@@ -46,6 +47,9 @@ public class ProductOutTwoServiceImpl implements ProductOutTwoService {
@Autowired
private IPdmBiOrderbominfoService iPdmBiOrderbominfoService;
@Autowired
private OutBoxManageService outBoxManageService;
@Override
public JSONObject ivtQuery(JSONObject whereJson) {
@@ -190,4 +194,15 @@ public class ProductOutTwoServiceImpl implements ProductOutTwoService {
}
return null;
}
@Override
@Transactional(rollbackFor = Exception.class)
public JSONObject boxOut(JSONObject whereJson) {
List<JSONObject> data = whereJson.getJSONArray("data").toJavaList(JSONObject.class);
outBoxManageService.publicBoxOut(data);
JSONObject result = new JSONObject();
result.put("message", "下发出库成功!");
return result;
}
}

View File

@@ -0,0 +1,198 @@
package org.nl.b_lms.sch.tasks;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import static org.nl.wms.util.TaskUtil.getRoutePlanCode;
/**
* 二期空木箱出库任务类(异常口)
* Created by Lxy on 2024/1/19.
*/
@Service
public class TwoOutBoxExcepTask extends AbstractAcsTask {
/**
* 处理类
*/
private final String THIS_CLASS = TwoOutBoxExcepTask.class.getName();
@Override
public List<AcsTaskDto> addTask() {
/*
* 下发给ACS时需要特殊处理
*/
// 任务表
WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task");
JSONArray arr = taskTab.query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0' AND point_code2 = 'CK2001' order by create_time").getResultJSONArray(0);
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
for (int i = 0; i < arr.size(); i++) {
JSONObject json = arr.getJSONObject(i);
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(json.getString("task_id"))
.task_code(json.getString("task_code"))
.route_plan_code(getRoutePlanCode(json.getString("point_code1")))
.task_type(json.getString("acs_task_type"))
.start_device_code(json.getString("point_code1"))
.next_device_code(json.getString("point_code2"))
.vehicle_code(json.getString("vehicle_code2"))
.vehicle_code2(json.getString("vehicle_code"))
.interaction_json(json.getJSONObject("request_param"))
.priority(json.getString("priority"))
.class_type(json.getString("task_type"))
.dtl_type(String.valueOf(dtl_type))
.product_area(IOSEnum.PRODUCT_AREA.code("BLK"))
.remark(json.getString("remark"))
.build();
resultList.add(dto);
// 更新任务为下发
JSONObject paramMap = new JSONObject();
paramMap.put("task_status", TaskStatusEnum.ISSUE.getCode());
taskTab.update(paramMap, "task_id ='" + json.getString("task_id") + "'");
}
return resultList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateTaskStatus(JSONObject taskObj, String status) {
// 仓位表
WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr");
// 任务表
WQLObject taskTab = WQLObject.getWQLObject("sch_base_task");
// 载具信息表
WQLObject extTab = WQLObject.getWQLObject("md_pb_storagevehicleext");
JSONObject jsonTask = taskTab.query("task_id = '" + taskObj.getString("task_id") + "'").uniqueResult(0);
// 更新任务的参数
JSONObject map = new JSONObject();
/*
* 1-执行中, 2-完成 ,0-acs取消
*/
// 执行中
if (status.equals(TaskStatusEnum.EXECUTING.getCode())) {
map.put("task_status", TaskStatusEnum.EXECUTING.getCode());
}
// 完成
if (status.equals(TaskStatusEnum.FINISHED.getCode())) {
map.put("task_status", TaskStatusEnum.FINISHED.getCode());
// 更新仓位
JSONObject jsonAttr = attrTab.query("struct_code = '" + jsonTask.getString("point_code1") + "'").uniqueResult(0);
jsonAttr.put("lock_type", IOSEnum.LOCK_TYPE.code("未锁定"));
jsonAttr.put("storagevehicle_code", "");
attrTab.update(jsonAttr);
// 更新载具信息表
JSONObject param = new JSONObject();
param.put("pcsn", "");
extTab.update(param,"pcsn = '"+jsonTask.getString("vehicle_code") +"'");
}
// 取消
if (status.equals(IOSEnum.IS_NOTANDYES.code(""))) {
if (taskObj.getIntValue("task_status") > Integer.valueOf(TaskStatusEnum.ISSUE.getCode())) {
throw new BadRequestException("任务已执行不能取消");
}
// 更新任务表删除字段
map.put("is_delete", IOSEnum.IS_NOTANDYES.code(""));
// 解锁仓位
JSONObject jsonAttr = attrTab.query("struct_code = '" + jsonTask.getString("point_code1") + "'").uniqueResult(0);
jsonAttr.put("lock_type", IOSEnum.LOCK_TYPE.code("未锁定"));
attrTab.update(jsonAttr);
}
map.put("update_optid", SecurityUtils.getCurrentUserId());
map.put("update_optname", SecurityUtils.getCurrentNickName());
map.put("update_time", DateUtil.now());
WQLObject.getWQLObject("SCH_BASE_Task").update(map, "task_id = '" + taskObj.getString("task_id") + "'");
}
@Override
public void findStartPoint() {
}
@Override
public void findNextPoint() {
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createTask(JSONObject form) {
if (StrUtil.isBlank(form.getString("task_type"))) {
throw new BadRequestException("业务类型不能为空!");
}
if (StrUtil.isBlank(form.getString("start_device_code"))) {
throw new BadRequestException("起点不能为空!");
}
if (StrUtil.isBlank(form.getString("next_device_code"))) {
throw new BadRequestException("终点不能为空!");
}
if (StrUtil.isBlank(form.getString("vehicle_code"))) {
throw new BadRequestException("木箱号不能为空!");
}
JSONObject json = new JSONObject();
json.put("task_id", IdUtil.getSnowflake(1, 1).nextId());
json.put("task_code", IdUtil.getSnowflake(1, 1).nextId());
json.put("task_type", form.getString("task_type"));
json.put("vehicle_code", form.getString("vehicle_code"));
json.put("vehicle_code2", form.getString("vehicle_code2"));
json.put("vehicle_type", form.getString("vehicle_type"));
json.put("task_status", TaskStatusEnum.START_AND_POINT.getCode());
json.put("task_group_id", form.getLongValue("task_group_id"));
json.put("point_code1", form.getString("start_device_code"));
json.put("point_code2", form.getString("next_device_code"));
json.put("request_param", form.getString("request_param"));
json.put("handle_class", this.getClass().getName());
json.put("create_id", SecurityUtils.getCurrentUserId());
json.put("create_name", SecurityUtils.getCurrentUsername());
json.put("create_time", DateUtil.now());
json.put("priority", form.getString("priority"));
json.put("acs_task_type", "7");
WQLObject.getWQLObject("SCH_BASE_Task").insert(json);
return json.getString("task_id");
}
@Override
@Transactional(rollbackFor = Exception.class)
public void forceFinish(String task_id) {
JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0);
this.updateTaskStatus(taskObj, TaskStatusEnum.FINISHED.getCode());
}
@Override
public void cancel(String task_id) {
JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0);
this.updateTaskStatus(taskObj, IOSEnum.ACS_RESULT.code("取消"));
}
}

View File

@@ -8,6 +8,7 @@ import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.sch.tasks.TwoExcepionalMoveTask;
import org.nl.b_lms.sch.tasks.TwoMoveBoxTask;
import org.nl.b_lms.sch.tasks.TwoOutBoxExcepTask;
import org.nl.b_lms.sch.tasks.TwoOutBoxTask;
import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
@@ -737,4 +738,132 @@ public class OutBoxManageServiceImpl implements OutBoxManageService {
return jsonTaskParam.getString("task_group_id");
}
@Override
@Transactional(rollbackFor = Exception.class)
public void publicBoxOut(List<JSONObject> list) {
WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr");
WQLObject extTab = WQLObject.getWQLObject("md_pb_storagevehicleext");
// 查询需要出库的仓位信息
String struct_code_in = list.stream()
.map(row -> row.getString("struct_code"))
.collect(Collectors.joining("','"));
List<JSONObject> attrList = attrTab.query("struct_code in ('" + struct_code_in + "') AND sect_code = 'BZC01'")
.getResultJSONArray(0).toJavaList(JSONObject.class);
// 获取这些仓位的每排仓位
String row_num_in = attrList.stream()
.map(row -> row.getString("row_num"))
.distinct()
.collect(Collectors.joining("','"));
List<JSONObject> allList = attrTab.query("row_num IN ('" + row_num_in + "') AND sect_code = 'BZC01' AND is_delete = '0'")
.getResultJSONArray(0).toJavaList(JSONObject.class);
// 查询木箱对应的托盘号
String box_no_in = list.stream()
.map(row -> row.getString("box_no"))
.collect(Collectors.joining("','"));
List<JSONObject> extList = extTab.query("pcsn IN ('" + box_no_in + "')")
.getResultJSONArray(0).toJavaList(JSONObject.class);
// 需要移库的木箱仓位
ArrayList<JSONObject> moveList = new ArrayList<>();
// 创建任务
for (JSONObject json : attrList) {
// 判断是否是深货位
if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
// 查询对应的浅货位
JSONObject jsonShallow = allList.stream()
.filter(row -> row.getString("row_num").equals(json.getString("row_num")) &&
row.getString("col_num").equals(json.getString("col_num")) &&
row.getString("layer_num").equals(json.getString("layer_num")) &&
row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code(""))
)
.findFirst().orElse(null);
if (ObjectUtil.isEmpty(jsonShallow)) {
throw new BadRequestException("仓位【"+json.getString("struct_code")+"】对应的浅货位信息错误!");
}
// 判断浅货位是否有空木箱
if (ObjectUtil.isNotEmpty(jsonShallow.getString("storagevehicle_code"))) {
// 判断是否是当前需要出库的集合当中
int size = (int) attrList.stream()
.filter(row -> row.getString("struct_code").equals(jsonShallow.getString("struct_code"))).count();
// 不在要出库的集合当中
if (size == 0) {
// 判断是否被锁定
if (jsonShallow.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
// 加入要移库的集合当中
moveList.add(jsonShallow);
} else if (!jsonShallow.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("木箱出库锁"))
&& (!jsonShallow.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("移出锁")))
) {
throw new BadRequestException("仓位【"+jsonShallow.getString("struct_code")+"】被锁定,无法生成移库任务!");
}
}
}
}
// 校验木箱是否绑定了托盘
JSONObject jsonExt = extList.stream()
.filter(row -> row.getString("pcsn").equals(json.getString("storagevehicle_code")))
.findFirst().orElse(null);
if (ObjectUtil.isEmpty(jsonExt)) {
throw new BadRequestException("此木箱【"+json.getString("storagevehicle_code")+"】没有绑定托盘,请核查");
}
// 创建任务
JSONObject jsonTaskParam = new JSONObject();
jsonTaskParam.put("task_type", "010704");
jsonTaskParam.put("start_device_code", json.getString("struct_code"));
jsonTaskParam.put("next_device_code", IOSEnum.EXCEP_OUT.code("异常出库口"));
jsonTaskParam.put("vehicle_code", json.getString("storagevehicle_code"));
jsonTaskParam.put("vehicle_code2", jsonExt.getString("storagevehicle_code"));
jsonTaskParam.put("task_group_id", IdUtil.getStringId());
jsonTaskParam.put("priority", json.getString("zdepth"));
JSONObject request_param = new JSONObject();
request_param.put("containerType", json.getString("storagevehicle_type"));
jsonTaskParam.put("request_param", request_param.toString());
TwoOutBoxExcepTask twoOutBoxExcepTask = new TwoOutBoxExcepTask();
twoOutBoxExcepTask.createTask(jsonTaskParam);
// 更新仓位锁定状态
json.put("lock_type", IOSEnum.LOCK_TYPE.code("木箱出库锁"));
attrTab.update(json);
}
// 查询移库木箱对应的托盘
String storagevehicle_code_in = moveList.stream()
.map(row -> row.getString("storagevehicle_code"))
.collect(Collectors.joining("','"));
List<JSONObject> extMoveList = extTab.query("pcsn IN ('" + storagevehicle_code_in + "')")
.getResultJSONArray(0).toJavaList(JSONObject.class);
// 此循环为防止下发一部分后报错无法回滚
moveList.forEach(item -> {
// 校验木箱和托盘是否绑定
JSONObject jsonExtMove = extMoveList.stream()
.filter(row -> row.getString("pcsn").equals(item.getString("storagevehicle_code")))
.findFirst().orElse(null);
if (ObjectUtil.isEmpty(jsonExtMove)) {
throw new BadRequestException("此移库木箱【"+jsonExtMove.getString("storagevehicle_code")+"】没有绑定托盘,请核查");
}
});
// 生成移库任务
for (JSONObject jsonMove : moveList) {
// 调用接口生成木箱移库任务
this.createBoxMove(jsonMove);
}
// 下发木箱出库任务
new TwoOutBoxExcepTask().immediateNotifyAcs(null);
}
}

View File

@@ -2,6 +2,8 @@ package org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
* <p>
* 空木箱业务处理 服务类
@@ -52,4 +54,10 @@ public interface OutBoxManageService {
*/
public String createBoxMove(JSONObject jsonObject);
/**
* 根据木箱号出库公共方法(多条数据)
* @param list 需要出库的木箱集合
*/
void publicBoxOut(List<JSONObject> list);
}