fix:出库、取货

This commit is contained in:
2026-01-14 20:37:40 +08:00
parent f585da58d1
commit d39f071c38
5 changed files with 74 additions and 168 deletions

View File

@@ -172,6 +172,7 @@ public class PdaCommonServiceImpl implements PdaCommonService {
if (ObjectUtil.isEmpty(bagNo)) {
throw new BadRequestException("袋号不能为空!");
}
param.put("bag_code", bagNo);
List<JSONObject> bagAssembly = mdPbGroupplateMapper.getBagAssembly(param);
if (bagAssembly.size() != 1) {
throw new BadRequestException(bagAssembly.size() == 0 ? "组袋记录不存在,请先组袋!" : "组袋记录信息有误,请查询并清理后重试!");

View File

@@ -137,64 +137,67 @@ public class PdaProductionServiceImpl implements PdaProductionService {
* @param param
* @return
*/
@SneakyThrows
@Override
@Transactional(rollbackFor = Exception.class)
public PdaResponse confirmCallMaterial(JSONObject param) {
// hint: 没有创建出库单
// point_code, row
log.info("手持托盘叫料:{}", param);
if (ObjectUtil.isEmpty(param.get("point_code"))) {
throw new BadRequestException("请输入要料点!");
}
if (ObjectUtil.isEmpty(param.get("row"))) {
throw new BadRequestException("请选择呼叫的物料!");
}
String pointCode = param.getString("point_code");
SchBasePoint endPoint = pointService.getByPointCode(pointCode, true);
if (ObjectUtil.isEmpty(endPoint)) {
throw new BadRequestException("输入的点位不存在或者点位已被禁用, 请检查输入点位是否正确或是否被禁用!");
}
if (!"1".equals(endPoint.getPoint_status())) {
throw new BadRequestException("该点位不是空位,请检查后呼叫!");
}
// 判断任务是否创建
List<SchBaseTask> tasks = taskService.getTaskByQuery(new LambdaQueryWrapper<SchBaseTask>()
.eq(SchBaseTask::getPoint_code2, pointCode));
if (tasks.size() > 0) {
throw new BadRequestException("该点位已创建过任务!");
}
RLock lock = redissonClient.getLock("lock:confirmCallMaterial");
boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
try {
if (tryLock) {
if (ObjectUtil.isEmpty(param.get("point_code"))) {
throw new BadRequestException("请输入要料点!");
}
if (ObjectUtil.isEmpty(param.get("row"))) {
throw new BadRequestException("请选择呼叫的物料!");
}
String pointCode = param.getString("point_code");
SchBasePoint endPoint = pointService.getByPointCode(pointCode, true);
if (ObjectUtil.isEmpty(endPoint)) {
throw new BadRequestException("输入的点位不存在或者点位已被禁用, 请检查输入点位是否正确或是否被禁用!");
}
if (!"1".equals(endPoint.getPoint_status())) {
throw new BadRequestException("该点位不是空位,请检查后呼叫!");
}
// 判断任务是否创建
List<SchBaseTask> tasks = taskService.getTaskByQuery(new LambdaQueryWrapper<SchBaseTask>()
.eq(SchBaseTask::getPoint_code2, pointCode));
if (tasks.size() > 0) {
throw new BadRequestException("该点位已创建过任务!");
}
JSONObject row = param.getJSONObject("row");
// 如果是制粒,需要走正规出入库流程
if ("ZLQ".equals(endPoint.getRegion_code())) {
Structattr structattr = structattrService.getByCode(row.getString("struct_code"));
param.put("bill_type", IOSEnum.OUT_BILL_TYPE.code("批料出库"));
// 1 创建出库单、明细、分配明细
List<JSONObject> res = groupplateService.getPalletViewByVehicleCode(row.getString("vehicle_code"), Arrays.asList("1", "2"));
param.put("rows", res);
JSONObject invObj = defaultPdaBuildParam.doBuildOutInvObj(param, structattr.getStor_id(), true);
String invId = outBillService.insertDtl(invObj);
// 2 循环根据插入的dtl 去寻找袋的组盘信息调用手动分配
List<IOStorInvDtlDto> billDtl = outBillService.getOutBillDtl(MapUtil.of("iostorinv_id", invId));
for (IOStorInvDtlDto ioStorInvDtlDto : billDtl) {
JSONObject divObj = defaultPdaBuildParam.buildManuaOutDivData(param, ioStorInvDtlDto);
outBillService.manualDiv(divObj);
JSONObject row = param.getJSONObject("row");
Structattr structattr = structattrService.getByCode(row.getString("struct_code"));
param.put("bill_type", IOSEnum.OUT_BILL_TYPE.code("批料出库"));
// 1 创建出库单、明细、分配明细
List<JSONObject> res = groupplateService.getPalletViewByVehicleCode(row.getString("vehicle_code"), Arrays.asList("1", "2"));
param.put("rows", res);
JSONObject invObj = defaultPdaBuildParam.doBuildOutInvObj(param, structattr.getStor_id(), true);
String invId = outBillService.insertDtl(invObj);
// 2 循环根据插入的dtl 去寻找袋的组盘信息调用手动分配
List<IOStorInvDtlDto> billDtl = outBillService.getOutBillDtl(MapUtil.of("iostorinv_id", invId));
for (IOStorInvDtlDto ioStorInvDtlDto : billDtl) {
JSONObject divObj = defaultPdaBuildParam.buildManuaOutDivData(param, ioStorInvDtlDto);
outBillService.manualDiv(divObj);
}
// 3 创建任务
JSONObject jsonMst = defaultPdaBuildParam.buildOutAllSetData(endPoint, invId);
// 如果是制粒/配液,需要走正规出入库流程
if ("ZLQ".equals(endPoint.getRegion_code()) || "PYQ".equals(endPoint.getRegion_code())) {
jsonMst.put("flag", "1");
}
outBillService.allSetPoint(jsonMst);
} else {
throw new BadRequestException("速度太快啦,稍后再试...");
}
} finally {
if (tryLock) {
lock.unlock();
}
// 3 创建任务
JSONObject jsonMst = defaultPdaBuildParam.buildOutAllSetData(endPoint, invId);
outBillService.allSetPoint(jsonMst);
return PdaResponse.requestOk("呼叫成功!");
}
// 创建任务
JSONObject taskParam = new JSONObject();
taskParam.put("point_code1", row.getString("struct_code"));
taskParam.put("point_code2", param.getString("point_code"));
taskParam.put("vehicle_code", row.getString("vehicle_code"));
// 代表任务完成的时候不需要调用库存完成
taskParam.put("flag", "1");
palletOutTask.create(taskParam);
return PdaResponse.requestOk("呼叫成功!");
}
@@ -204,7 +207,7 @@ public class PdaProductionServiceImpl implements PdaProductionService {
if (ObjectUtil.isEmpty(search)) {
throw new BadRequestException("请输入袋号编码!");
}
List<JSONObject> groups = groupplateService.getPalletView(search, Arrays.asList("1", "2"));
List<JSONObject> groups = groupplateService.getPalletView(search, Arrays.asList("1", "2", "4"));
if (groups.size() != 1) {
throw new BadRequestException(groups.size() == 0 ? "组袋记录不存在,请先组袋!" : "组袋记录信息有误,请查询并清理后重试!");
}
@@ -219,9 +222,6 @@ public class PdaProductionServiceImpl implements PdaProductionService {
@Transactional(rollbackFor = Exception.class)
public PdaResponse takePalletMaterial(JSONObject param) {
log.info("手持取物料: {}", param);
String currentUserId = SecurityUtils.getCurrentUserId();
String nickName = SecurityUtils.getCurrentNickName();
String now = DateUtil.now();
// search、rows、total_qty
String search = param.getString("search");
// SchBasePoint point = pointService.getByPointCode(search, false);
@@ -233,51 +233,15 @@ public class PdaProductionServiceImpl implements PdaProductionService {
}
storagevehicleinfoService.getByCode(search);
JSONArray rows = param.getJSONArray("rows");
// 找到托盘的仓位
List<Structattr> startPoints = structattrService
.getByVehicleCode(rows.getJSONObject(0).getString("vehicle_code")
, IOSEnum.LOCK_TYPE.code("其他锁"), false);
if (startPoints.size() == 0) {
throw new BadRequestException("未找到当前托盘的原始库位信息!");
}
Structattr structattr = startPoints.get(0);
// 手动更新库存信息
// 1、创建出库单、明细、分配明细
// 1.1 单据表
String invId = IdUtil.getStringId();
IOStorInv ioStorInv = new IOStorInv();
ioStorInv.setIostorinv_id(invId);
ioStorInv.setBill_code(CodeUtil.getNewCode("OUT_STORE_CODE"));
ioStorInv.setBiz_date(DateUtil.format(new Date(), "yyyy-MM-dd"));
ioStorInv.setIo_type(IOSEnum.IO_TYPE.code("出库"));
ioStorInv.setDetail_count(1);
ioStorInv.setCreate_mode(IOSEnum.CREATE_MODE.code("终端产生"));
ioStorInv.setStor_id(structattr.getStor_id());
ioStorInv.setStor_code(structattr.getStor_code());
ioStorInv.setStor_name(structattr.getStor_name());
ioStorInv.setBill_status(IOSEnum.BILL_STATUS.code("完成"));
ioStorInv.setBill_type(IOSEnum.OUT_BILL_TYPE.code("原辅料出库"));
ioStorInv.setBuss_type(IOSEnum.OUT_BILL_TYPE.code("原辅料出库").substring(0, 4));
ioStorInv.setIs_delete(BaseDataEnum.IS_YES_NOT.code(""));
ioStorInv.setIs_upload(BaseDataEnum.IS_YES_NOT.code(""));
ioStorInv.setInput_optid(currentUserId);
ioStorInv.setInput_optname(nickName);
ioStorInv.setInput_time(now);
ioStorInv.setUpdate_optid(currentUserId);
ioStorInv.setUpdate_optname(nickName);
ioStorInv.setUpdate_time(now);
ioStorInv.setTotal_qty(param.getBigDecimal("total_qty"));
ioStorInv.setDetail_count(rows.size());
outBillService.save(ioStorInv);
// 扣除组盘数据
List<GroupPlate> needAddOrUpdGroups = new ArrayList<>();
List<String> needDelGroups = new ArrayList<>();
List<MdPbStoragevehicleext> vehicleObjs = storagevehicleextService.list(new LambdaQueryWrapper<MdPbStoragevehicleext>()
.eq(MdPbStoragevehicleext::getStoragevehicle_code, rows.getJSONObject(0).getString("vehicle_code")));
BigDecimal whileSub = new BigDecimal("0");
for (int i = 0; i < rows.size(); i++) {
JSONObject row = rows.getJSONObject(i);
GroupPlate delGroup = groupplateService.getById(row.getString("group_id"));
if (ObjectUtil.isEmpty(delGroup)) {
continue;
}
GroupPlate groupPlate = JSON.parseObject(row.toJSONString(), GroupPlate.class);
// 其他需要删除
delGroup.setQty(delGroup.getQty().subtract(groupPlate.getQty()));
@@ -286,77 +250,9 @@ public class PdaProductionServiceImpl implements PdaProductionService {
} else {
needAddOrUpdGroups.add(delGroup);
}
whileSub.add(groupPlate.getQty());
// 1.2 单据明细
IOStorInvDtl dtl = new IOStorInvDtl();
dtl.setIostorinvdtl_id(IdUtil.getStringId());
dtl.setIostorinv_id(invId);
dtl.setSeq_no("1");
dtl.setMaterial_id(row.getString("material_id"));
dtl.setPcsn(groupPlate.getPcsn());
dtl.setBill_status(IOSEnum.BILL_STATUS.code("完成"));
dtl.setQty_unit_id(groupPlate.getQty_unit_id());
dtl.setQty_unit_name(groupPlate.getQty_unit_name());
dtl.setPlan_qty(groupPlate.getQty());
dtl.setAssign_qty(groupPlate.getQty());
dtl.setUnassign_qty(BigDecimal.ZERO);
ioStorInvDtlMapper.insert(dtl);
// 1.3 分配明细
IOStorInvDis ioStorInvDis = new IOStorInvDis();
ioStorInvDis.setIostorinvdis_id(IdUtil.getStringId());
ioStorInvDis.setIostorinv_id(dtl.getIostorinv_id());
ioStorInvDis.setIostorinvdtl_id(dtl.getIostorinvdtl_id());
ioStorInvDis.setSeq_no("1");
ioStorInvDis.setSect_id(structattr.getSect_id());
ioStorInvDis.setPcsn(groupPlate.getPcsn());
ioStorInvDis.setMaterial_id(row.getString("material_id"));
ioStorInvDis.setSect_name(structattr.getSect_name());
ioStorInvDis.setSect_code(structattr.getSect_code());
ioStorInvDis.setStruct_id(structattr.getStruct_id());
ioStorInvDis.setStruct_name(structattr.getStruct_name());
ioStorInvDis.setStruct_code(structattr.getStruct_code());
ioStorInvDis.setStoragevehicle_code(row.getString("vehicle_code"));
ioStorInvDis.setIs_issued(BaseDataEnum.IS_YES_NOT.code(""));
ioStorInvDis.setQty_unit_id(groupPlate.getQty_unit_id());
ioStorInvDis.setQty_unit_name(groupPlate.getQty_unit_name());
ioStorInvDis.setWork_status(IOSEnum.INBILL_DIS_STATUS.code("完成"));
ioStorInvDis.setPlan_qty(groupPlate.getQty());
ioStorInvDisMapper.insert(ioStorInvDis);
vehicleObjs.stream()
.filter(vehicle ->
vehicle.getStoragevehicle_code().equals(row.getString("vehicle_code")) &&
vehicle.getMaterial_id().equals(row.getString("material_id")) &&
vehicle.getPcsn().equals(row.getString("pcsn")))
.findFirst()
.ifPresent(vehicle -> {
BigDecimal newQty = vehicle.getCanuse_qty().subtract(row.getBigDecimal("qty"));
vehicle.setCanuse_qty(newQty.max(BigDecimal.ZERO));
});
}
List<MdPbStoragevehicleext> zeroQtyVehicles = vehicleObjs.stream()
.filter(vehicle -> vehicle.getCanuse_qty().compareTo(BigDecimal.ZERO) == 0)
.collect(Collectors.toList());
List<MdPbStoragevehicleext> nonZeroQtyVehicles = vehicleObjs.stream()
.filter(vehicle -> vehicle.getCanuse_qty().compareTo(BigDecimal.ZERO) != 0)
.collect(Collectors.toList());
groupplateService.saveOrUpdateBatch(needAddOrUpdGroups);
groupplateService.removeByIds(needDelGroups);
// 托盘数量修改
if (nonZeroQtyVehicles.size() > 0) {
storagevehicleextService.updateBatchById(nonZeroQtyVehicles);
}
if (zeroQtyVehicles.size() > 0) {
storagevehicleextService.removeByIds(zeroQtyVehicles.stream().map(MdPbStoragevehicleext::getStoragevehicleext_id).collect(Collectors.toList()));
}
if (nonZeroQtyVehicles.size() == 0) {
// 说明托盘没东西了,点位释放
structattr.setLock_type(IOSEnum.LOCK_TYPE.code("未锁定"));
structattr.setStoragevehicle_code(null);
structattr.setIs_emptyvehicle("0");
structattrService.updateById(structattr);
}
return PdaResponse.requestOk("取料成功!");
}

View File

@@ -25,6 +25,7 @@ import org.nl.wms.sch_manage.service.util.AcsTaskDto;
import org.nl.wms.sch_manage.service.util.TaskType;
import org.nl.wms.warehouse_management.enums.IOSConstant;
import org.nl.wms.warehouse_management.enums.IOSEnum;
import org.nl.wms.warehouse_management.service.IMdPbGroupplateService;
import org.nl.wms.warehouse_management.service.IOutBillService;
import org.nl.wms.warehouse_management.service.dao.GroupPlate;
import org.nl.wms.warehouse_management.service.dao.IOStorInvDis;
@@ -72,7 +73,7 @@ public class PalletOutTask extends AbstractTask {
* 组盘记录服务
*/
@Resource
private GroupPlateMapper groupPlateMapper;
private IMdPbGroupplateService pbGroupplateService;
@Resource
private IStructattrService structattrService;
@@ -195,10 +196,16 @@ public class PalletOutTask extends AbstractTask {
.set(SchBasePoint::getIng_task_code, taskObj.getTask_id())
);
JSONObject jsonObject = JSONObject.parseObject(taskObj.getRequest_param());
if (ObjectUtil.isEmpty(jsonObject.get("flag"))) {
// 解锁、库存清空
outBillService.taskFinish(taskObj);
// 解锁、库存清空
outBillService.taskFinish(taskObj);
if (ObjectUtil.isNotEmpty(jsonObject.get("flag"))) {
this.taskConfirm(taskObj.getTask_code());
} else {
// 修改组盘信息
pbGroupplateService.update(new LambdaUpdateWrapper<GroupPlate>()
.set(GroupPlate::getRemark, taskObj.getPoint_code1())
.set(GroupPlate::getStatus, "4")
.eq(GroupPlate::getVehicle_code, taskObj.getVehicle_code()));
}
// 任务完成
taskObj.setTask_status(TaskStatus.FINISHED.getCode());
@@ -233,7 +240,7 @@ public class PalletOutTask extends AbstractTask {
SchBaseTask taskObj = taskService.getByCode(task_code);
// 删除组盘信息
groupPlateMapper.delete(
pbGroupplateService.remove(
new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getVehicle_code, taskObj.getVehicle_code())
);

View File

@@ -162,11 +162,14 @@
m.material_spec,
m.material_model,
m.material_type_id,
c.class_code,
c.class_name,
s.supp_name
FROM
`md_pb_groupplate` g
LEFT JOIN md_me_materialbase m ON m.material_id = g.material_id
LEFT JOIN md_cs_supplierbase s ON s.supp_code = g.supp_code
LEFT JOIN md_pb_classstandard c ON c.class_id = m.material_type_id
WHERE g.vehicle_code = #{search} AND g.`status` IN
<foreach collection="status" item="code" separator="," open="(" close=")">
#{code}

View File

@@ -56,10 +56,9 @@
<rrOperation />
</el-form>
</div>
<rrOperation />
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission">
<!-- <el-button
<!-- <el-button
slot="right"
class="filter-item"
type="success"
@@ -186,7 +185,7 @@ export default {
this.crud.toQuery()
},
printTable() {
let row = this.$refs.table.selection[0]
const row = this.$refs.table.selection[0]
var bake_num = row.bake_num
if (row.out_type === '1004') {
bake_num += 1