package com.zy.asrs.service.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.baomidou.mybatisplus.mapper.Wrapper;
|
import com.core.common.BaseRes;
|
import com.core.common.Cools;
|
import com.core.common.DateUtils;
|
import com.core.common.R;
|
import com.core.exception.CoolException;
|
import com.zy.asrs.entity.*;
|
import com.zy.asrs.entity.param.*;
|
import com.zy.asrs.service.*;
|
import com.zy.asrs.utils.VersionUtils;
|
import com.zy.common.model.LocDetlDto;
|
import com.zy.common.model.LocTypeDto;
|
import com.zy.common.model.OutLocDto;
|
import com.zy.common.model.StartupDto;
|
import com.zy.common.model.agv.AgvCommand;
|
import com.zy.common.model.agv.AgvResult;
|
import com.zy.common.service.CommonService;
|
import com.zy.common.service.erp.ErpSqlServer;
|
import com.zy.common.utils.HttpHandler;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.io.IOException;
|
import java.text.MessageFormat;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
import java.util.stream.Collectors;
|
|
/**
|
* Created by vincent on 2020/6/11
|
*/
|
@Slf4j
|
@Service
|
public class WorkServiceImpl implements WorkService {
|
|
// 工作号生成规则默认类型
|
private static final int DEFAULT_WORK_NO_TYPE = 0;
|
// 库位排号分配默认类别
|
private static final int DEFAULT_ROW_NO_TYPE = 1;
|
|
@Value("${agv.url}")
|
private String agvUrl;
|
@Autowired
|
private WrkMastService wrkMastService;
|
@Autowired
|
private BasDevpService basDevpService;
|
@Autowired
|
private CommonService commonService;
|
@Autowired
|
private WrkDetlService wrkDetlService;
|
@Autowired
|
private LocMastService locMastService;
|
@Autowired
|
private StaDescService staDescService;
|
@Autowired
|
private LocDetlService locDetlService;
|
@Autowired
|
private MatCodeService matCodeService;
|
@Autowired
|
private AdjDetlService adjDetlService;
|
@Autowired
|
private WrkMastLogService wrkMastLogService;
|
@Autowired
|
private WrkDetlLogService wrkDetlLogService;
|
@Autowired
|
private ErpSqlServer erpSqlServer;
|
@Autowired
|
private BasAgvService basAgvService;
|
|
@Override
|
@Transactional
|
public String startupFullPutStore(FullStoreParam param, Long userId) {
|
List<String> matNos = null;
|
if (Cools.isEmpty(param.getProductCode())) {
|
// 参数非空判断
|
if (Cools.isEmpty(param.getDevpNo(), param.getList())) {
|
throw new CoolException(BaseRes.PARAM);
|
}
|
matNos = param.getList().stream().map(FullStoreParam.MatCodeStore::getMatNo).distinct().collect(Collectors.toList());
|
}
|
// 源站点状态检测
|
BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getDevpNo(), true);
|
// 检索库位
|
LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
|
log.info("========>" + JSON.toJSONString(sourceStaNo));
|
log.info("-------->" + JSON.toJSONString(locTypeDto));
|
StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 1, param.getDevpNo(), false, matNos, locTypeDto, 0);
|
// 工作号
|
int workNo = dto.getWorkNo();
|
// 生成工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(new Date());
|
wrkMast.setWrkSts(1L); // 工作状态:生成入库ID
|
wrkMast.setIoType(1); // 入出库状态:1.入库
|
wrkMast.setIoPri(13D); // 优先级:10
|
wrkMast.setCrnNo(dto.getCrnNo());
|
wrkMast.setSourceStaNo(dto.getSourceStaNo());
|
wrkMast.setStaNo(dto.getStaNo());
|
wrkMast.setLocNo(dto.getLocNo());
|
wrkMast.setBarcode(param.getBarcode()); // 托盘码
|
wrkMast.setFullPlt("Y"); // 满板:Y
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setEmptyMk("N"); // 空板
|
wrkMast.setLinkMis("N");
|
wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
|
// 操作人员数据
|
wrkMast.setAppeUser(userId);
|
wrkMast.setAppeTime(new Date());
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
boolean res = wrkMastService.insert(wrkMast);
|
if (!res) {
|
throw new CoolException("保存工作档失败");
|
}
|
// 生成工作档明细
|
List<MatCodeCountDto> matDtos = new ArrayList<>();
|
if (Cools.isEmpty(param.getProductCode())) {
|
param.getList().forEach(elem -> {
|
matDtos.add(new MatCodeCountDto(elem.getMatNo(), elem.getCount(), elem.getMatStatus(), elem.getStr5(), elem.getStr6()));
|
});
|
wrkDetlService.createWorkDetail(workNo, matDtos, param.getBarcode(), userId);
|
// 成品物料
|
} else {
|
// 保持工作档明细
|
WrkDetl wrkDetl = new WrkDetl();
|
wrkDetl.setWrkNo(workNo);
|
wrkDetl.setIoTime(new Date());
|
wrkDetl.setAnfme((double) 1); // 数量
|
|
wrkDetl.setMatnr(param.getProductCode()); // 物料编号
|
wrkDetl.setMaktx(param.getProductCode()); // 物料描述
|
wrkDetl.setLgnum(param.getProductCode()); // 规格
|
wrkDetl.setType(param.getProductCode()); // 物料类别
|
wrkDetl.setMnemonic(param.getProductCode()); // 助记码
|
wrkDetl.setSupplier(param.getProductCode()); // 默认供应商
|
wrkDetl.setWarehouse(param.getProductCode()); // 默认仓库
|
wrkDetl.setBrand(param.getProductCode()); // 品牌
|
wrkDetl.setAltme(param.getProductCode()); // 单位
|
|
wrkDetl.setZpallet(param.getBarcode()); // 托盘条码
|
wrkDetl.setAppeUser(userId);
|
wrkDetl.setAppeTime(new Date());
|
wrkDetl.setModiUser(userId);
|
wrkDetl.setModiTime(new Date());
|
if (!wrkDetlService.insert(wrkDetl)) {
|
throw new CoolException("保存工作明细失败");
|
}
|
}
|
|
// 更新源站点信息
|
sourceStaNo.setWrkNo(workNo);
|
sourceStaNo.setModiUser(userId);
|
sourceStaNo.setModiTime(new Date());
|
if (!basDevpService.updateById(sourceStaNo)) {
|
throw new CoolException("更新源站失败");
|
}
|
// 更新目标库位状态
|
LocMast locMast = locMastService.selectById(dto.getLocNo());
|
if (locMast.getLocSts().equals("O")) {
|
locMast.setLocSts("S"); // S.入库预约
|
locMast.setModiUser(userId);
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("改变库位状态失败");
|
}
|
} else {
|
throw new CoolException(dto.getLocNo() + "目标库位已被占用");
|
}
|
// 判断无通知单号supplier的入库数据,CPICMO插入数据
|
List<FullStoreParam.MatCodeStore> erpMatList = param.getList();
|
for (FullStoreParam.MatCodeStore es : erpMatList) {
|
if (Cools.isEmpty(es.getStr6())) {
|
String maxKeySql = "select max(FInterID) as num from CPICMO";
|
List<ERPselectParam> maxKeyList = erpSqlServer.select(maxKeySql, ERPselectParam.class);
|
Integer maxKey = maxKeyList.get(0).getNum();
|
String ErpSql = "insert into CPICMO(FBrNo, FSourceBillNo, FBillNo, FTranType, FStatus, FMRP, FItemID, FQty, FCommitQty, FSourceEntryID, FClosed, FUnitID, FAuxCommitQty, FCancellation, FQtyFinish, FQtyScrap, FQtyLost, FAuxQtyFinish, FAuxQtyScrap, FAuxQtyLost, FMrpClosed, FBomInterID, FQtyPass, FAuxQtyPass, FQtyBack, FAuxQtyBack, FFinishTime, FReadyTIme, FPowerCutTime, FFixTime, FWaitItemTime, FWaitToolTime, FTaskID, FWorkTypeID, FCostObjID, FStockQty, FAuxStockQty, FSuspend, FReleasedQty, FReleasedAuxQty, FUnScheduledQty, FUnScheduledAuxQty, FSubEntryID, FScheduleID, FPlanOrderInterID, FProcessPrice, FProcessFee, FGMPBatchNo, FGMPCollectRate, FGMPItemBalance, FGMPBulkQty, FCustID, FMRPLockFlag, FHandworkClose, FInHighLimit, FInHighLimitQty, FInLowLimit, FInLowLimitQty, FChangeTimes, FCheckCommitQty, FAuxCheckCommitQty, FPlanConfirmed, FPlanMode, FMTONo, FPrintCount, FFinClosed, FStockFlag, FStartFlag, FVchBillNo, FVchInterID, FCardClosed, FHRReadyTime, FSourceTranType, FSourceInterId, FInterID, FAuxQty, FAuxInHighLimitQty, FAuxInLowLimitQty, Fnumber, FWorkShop) values (0, 0, '0', 85, 0, 1052, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '0', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14036, '0', 0, 0, 14215, 0, '0', 0, 1059, 0, 0, 0, 0, {0,number,#}, {1,number,#}, {2,number,#}, {3,number,#}, ''{4}'', 11378)";
|
ErpSql = MessageFormat.format(ErpSql, maxKey + 1, es.getCount(), es.getCount(), es.getCount(), es.getMatNo());
|
erpSqlServer.update(ErpSql);
|
}
|
}
|
return dto.getLocNo();
|
}
|
|
@Override
|
@Transactional
|
public void startupFullTakeStore(StockOutParam param, Long userId) {
|
// 目标站点状态检测
|
BasDevp staNo = basDevpService.checkSiteStatus(param.getOutSite());
|
int agvSite = 0;
|
if (!Cools.isEmpty(staNo.getFronting()) && staNo.getFronting().equals("Y")) {
|
agvSite = staNo.getDevNo();
|
staNo = basDevpService.checkSiteStatus(201);
|
}
|
// 获取库位明细
|
List<LocDetlDto> locDetlDtos = new ArrayList<>();
|
for (StockOutParam.LocDetl paramLocDetl : param.getLocDetls()) {
|
if (!Cools.isEmpty(paramLocDetl.getLocNo(), paramLocDetl.getMatnr(), paramLocDetl.getCount())) {
|
LocDetl sqlParam = new LocDetl();
|
sqlParam.setLocNo(paramLocDetl.getLocNo());
|
sqlParam.setMatnr(paramLocDetl.getMatnr());
|
LocDetl one = locDetlService.selectOne(new EntityWrapper<>(sqlParam));
|
if (null != one) locDetlDtos.add(new LocDetlDto(one, paramLocDetl.getCount()));
|
}
|
}
|
if (!locDetlDtos.isEmpty()) {
|
// 启动出库开始 101.出库
|
stockOut(staNo, locDetlDtos, null, userId, agvSite);
|
} else {
|
throw new CoolException("库位物料不存在");
|
}
|
}
|
|
@Override
|
@Transactional
|
public void stockOut(BasDevp staNo, List<LocDetlDto> locDetlDtos, Integer ioType, Long userId, Integer agvSite) {
|
// 合并同类项
|
Set<String> locNos = new HashSet<>();
|
locDetlDtos.forEach(dto -> locNos.add(dto.getLocDetl().getLocNo()));
|
List<OutLocDto> dtos = new ArrayList<>();
|
for (String locNo : locNos) {
|
List<LocDetlDto> list = new ArrayList<>();
|
Iterator<LocDetlDto> iterator = locDetlDtos.iterator();
|
while (iterator.hasNext()) {
|
LocDetlDto dto = iterator.next();
|
if (locNo.equals(dto.getLocDetl().getLocNo())) {
|
list.add(dto);
|
iterator.remove();
|
}
|
}
|
dtos.add(new OutLocDto(locNo, list));
|
}
|
// 生成工作档
|
for (OutLocDto dto : dtos) {
|
// 判断入出库类型:101.全板出库 or 103.拣料出库
|
if (ioType == null) {
|
ioType = dto.isAll() ? 101 : 103;
|
}
|
// 获取库位
|
LocMast locMast = locMastService.selectById(dto.getLocNo());
|
// 获取路径
|
Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
|
.eq("type_no", ioType)
|
.eq("stn_no", staNo.getDevNo())
|
.eq("crn_no", locMast.getCrnNo());
|
StaDesc staDesc = staDescService.selectOne(wrapper);
|
if (Cools.isEmpty(staDesc)) {
|
throw new CoolException("出库路径不存在");
|
}
|
// 生成工作号
|
int workNo = commonService.getWorkNo(DEFAULT_WORK_NO_TYPE);
|
// 生成工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(new Date());
|
wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
|
wrkMast.setIoType(ioType); // 入出库状态
|
wrkMast.setIoPri(13D); // 优先级:13
|
wrkMast.setCrnNo(locMast.getCrnNo());
|
wrkMast.setSourceStaNo(staDesc.getCrnStn()); // 源站
|
wrkMast.setStaNo(staDesc.getStnNo()); // 目标站
|
wrkMast.setSourceLocNo(dto.getLocNo()); // 源库位
|
wrkMast.setBarcode(locMast.getBarcode()); // 条码
|
wrkMast.setFullPlt("Y"); // 满板:Y
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setEmptyMk("N"); // 空板
|
wrkMast.setLinkMis("N");
|
wrkMast.setCtnKind(agvSite); // 出库下的小车工作区站好
|
wrkMast.setExitMk("N"); // 小车是否搬运
|
wrkMast.setAppeUser(userId); // 操作人员数据
|
wrkMast.setAppeTime(new Date());
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
if (!wrkMastService.insert(wrkMast)) {
|
throw new CoolException("保存工作档失败,出库库位号:" + dto.getLocNo());
|
}
|
// 生成工作档明细
|
for (LocDetlDto detlDto : dto.getLocDetlDtos()) {
|
// 出库时,数量为0的直接忽略
|
if (detlDto.getCount() == null || detlDto.getCount() <= 0.0D) {
|
continue;
|
}
|
WrkDetl wrkDetl = new WrkDetl();
|
wrkDetl.setWrkNo(workNo);
|
wrkDetl.setIoTime(new Date());
|
Double anfme = ioType == 101 ? detlDto.getLocDetl().getAnfme() : detlDto.getCount();
|
wrkDetl.setAnfme(anfme); // 数量
|
VersionUtils.setWrkDetl(wrkDetl, detlDto.getLocDetl()); // 版本控制
|
wrkDetl.setAppeTime(new Date());
|
wrkDetl.setAppeUser(userId);
|
wrkDetl.setModiTime(new Date());
|
wrkDetl.setModiUser(userId);
|
if (!wrkDetlService.insert(wrkDetl)) {
|
throw new CoolException("保存工作档明细失败");
|
}
|
}
|
// 修改库位状态: F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中
|
locMast = locMastService.selectById(dto.getLocNo());
|
if (locMast.getLocSts().equals("F")) {
|
locMast.setLocSts(ioType == 101 ? "R" : "P");
|
locMast.setModiUser(userId);
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("预约库位状态失败,库位号:" + dto.getLocNo());
|
}
|
} else {
|
throw new CoolException(dto.getLocNo() + "库位不是在库状态");
|
}
|
}
|
// todo:luxiaotao
|
// 同一列的同时出库,则优先出浅库位
|
}
|
|
@Override
|
@Transactional
|
public String emptyPlateIn(Integer devpNo, Long userId) {
|
// 目标站点状态检测
|
BasDevp staNo = basDevpService.checkSiteStatus(devpNo);
|
if (!Cools.isEmpty(staNo.getFronting()) && staNo.getFronting().equals("Y")) {
|
// 小车入库搬运命令 ----------------------------------------------------
|
// 判断是否有空闲小车
|
if (basAgvService.haveIdleAgv()) {
|
AgvCommand command = new AgvCommand();
|
command.setAgvId(0);
|
command.setInterCode(basAgvService.getEmptyAgvWorkNo());
|
command.setBeginLoc(String.valueOf(devpNo));
|
command.setEndLoc("1088");
|
log.info(JSON.toJSONString(command));
|
String result;
|
try {
|
result = new HttpHandler.Builder()
|
.setUri(agvUrl + "/api/interfaceTask/SendTaskByThirdParty")
|
.setJson(JSON.toJSONString(command))
|
.build()
|
.doPost();
|
} catch (IOException e) {
|
e.printStackTrace();
|
throw new CoolException("访问AGV接口失败");
|
}
|
AgvResult agvResult = JSON.parseObject(result, AgvResult.class);
|
log.info(JSON.toJSONString(agvResult));
|
if (!agvResult.getResult()) {
|
log.error("agv命令发送失败[agvId={}],错误信息={}", command.getAgvId(), agvResult.getExplain());
|
throw new CoolException("agv命令发送失败[agvId=" + command.getAgvId() + "],错误信息=" + agvResult.getExplain());
|
}
|
} else {
|
throw new CoolException("没有空闲小车");
|
}
|
|
return "待定";
|
} else {
|
// 源站点状态检测
|
BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
|
// 检索库位
|
LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
|
StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 10, devpNo, true, null, locTypeDto, 0);
|
// 工作号
|
int workNo = dto.getWorkNo();
|
// 生成工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(new Date());
|
wrkMast.setWrkSts(1L); // 工作状态:生成入库ID
|
wrkMast.setIoType(10); // 入出库状态:10.空板入库
|
wrkMast.setIoPri(13D); // 优先级:10
|
wrkMast.setCrnNo(dto.getCrnNo());
|
wrkMast.setSourceStaNo(dto.getSourceStaNo());
|
wrkMast.setStaNo(dto.getStaNo());
|
wrkMast.setLocNo(dto.getLocNo());
|
wrkMast.setFullPlt("N"); // 满板:Y
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setEmptyMk("Y"); // 空板
|
wrkMast.setLinkMis("N");
|
wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
|
// 操作人员数据
|
wrkMast.setAppeUser(userId);
|
wrkMast.setAppeTime(new Date());
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
boolean res = wrkMastService.insert(wrkMast);
|
if (!res) {
|
throw new CoolException("保存工作档失败");
|
}
|
// 更新源站点信息
|
sourceStaNo.setWrkNo(workNo);
|
sourceStaNo.setModiUser(userId);
|
sourceStaNo.setModiTime(new Date());
|
if (!basDevpService.updateById(sourceStaNo)) {
|
throw new CoolException("更新源站失败");
|
}
|
// 更新目标库位状态
|
LocMast locMast = locMastService.selectById(dto.getLocNo());
|
if (locMast.getLocSts().equals("O")) {
|
locMast.setLocSts("S"); // S.入库预约
|
locMast.setModiUser(userId);
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("改变库位状态失败");
|
}
|
} else {
|
throw new CoolException(dto.getLocNo() + "目标库位已被占用");
|
}
|
return dto.getLocNo();
|
}
|
|
}
|
|
// @Override
|
// @Transactional
|
// public String emptyPlateIn(Integer devpNo, Long userId) {
|
// // 源站点状态检测
|
// BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
|
// // 检索库位
|
// LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
|
// StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 10, devpNo, true, null, locTypeDto, 0);
|
// // 工作号
|
// int workNo = dto.getWorkNo();
|
// // 生成工作档
|
// WrkMast wrkMast = new WrkMast();
|
// wrkMast.setWrkNo(workNo);
|
// wrkMast.setIoTime(new Date());
|
// wrkMast.setWrkSts(1L); // 工作状态:生成入库ID
|
// wrkMast.setIoType(10); // 入出库状态:10.空板入库
|
// wrkMast.setIoPri(13D); // 优先级:10
|
// wrkMast.setCrnNo(dto.getCrnNo());
|
// wrkMast.setSourceStaNo(dto.getSourceStaNo());
|
// wrkMast.setStaNo(dto.getStaNo());
|
// wrkMast.setLocNo(dto.getLocNo());
|
// wrkMast.setFullPlt("N"); // 满板:Y
|
// wrkMast.setPicking("N"); // 拣料
|
// wrkMast.setExitMk("N"); // 退出
|
// wrkMast.setEmptyMk("Y"); // 空板
|
// wrkMast.setLinkMis("N");
|
// wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
|
// // 操作人员数据
|
// wrkMast.setAppeUser(userId);
|
// wrkMast.setAppeTime(new Date());
|
// wrkMast.setModiUser(userId);
|
// wrkMast.setModiTime(new Date());
|
// boolean res = wrkMastService.insert(wrkMast);
|
// if (!res) {
|
// throw new CoolException("保存工作档失败");
|
// }
|
// // 更新源站点信息
|
// sourceStaNo.setWrkNo(workNo);
|
// sourceStaNo.setModiUser(userId);
|
// sourceStaNo.setModiTime(new Date());
|
// if (!basDevpService.updateById(sourceStaNo)) {
|
// throw new CoolException("更新源站失败");
|
// }
|
// // 更新目标库位状态
|
// LocMast locMast = locMastService.selectById(dto.getLocNo());
|
// if (locMast.getLocSts().equals("O")) {
|
// locMast.setLocSts("S"); // S.入库预约
|
// locMast.setModiUser(userId);
|
// locMast.setModiTime(new Date());
|
// if (!locMastService.updateById(locMast)) {
|
// throw new CoolException("改变库位状态失败");
|
// }
|
// } else {
|
// throw new CoolException(dto.getLocNo() + "目标库位已被占用");
|
// }
|
// return dto.getLocNo();
|
// }
|
|
@Override
|
@Transactional
|
public void emptyPlateOut(EmptyPlateOutParam param, Long userId) {
|
if (Cools.isEmpty(param.getOutSite())) {
|
throw new CoolException("站点不存在");
|
}
|
// 目标站点状态检测
|
BasDevp staNo = basDevpService.checkSiteStatus(param.getOutSite());
|
int agvSite = 0;
|
if (!Cools.isEmpty(staNo.getFronting()) && staNo.getFronting().equals("Y")) {
|
agvSite = staNo.getDevNo();
|
staNo = basDevpService.checkSiteStatus(201);
|
}
|
for (String locNo : param.getLocNos()) {
|
// 获取工作号
|
int workNo = commonService.getWorkNo(DEFAULT_WORK_NO_TYPE);
|
// 获取库位
|
LocMast locMast = locMastService.selectById(locNo);
|
if (Cools.isEmpty(locMast)) {
|
throw new CoolException(locNo + "库位不存在");
|
}
|
// 获取源站
|
Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
|
.eq("type_no", 110)
|
.eq("stn_no", staNo.getDevNo())
|
.eq("crn_no", locMast.getCrnNo());
|
StaDesc staDesc = staDescService.selectOne(wrapper);
|
Integer sourceStaNo = staDesc.getCrnStn();
|
if (Cools.isEmpty(sourceStaNo)) {
|
throw new CoolException("检索源站失败");
|
}
|
// 保存工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(new Date());
|
wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
|
wrkMast.setIoType(110); // 入出库状态: 110.空板出库
|
wrkMast.setIoPri(10D);
|
wrkMast.setSourceStaNo(sourceStaNo); // 源站
|
wrkMast.setStaNo(staNo.getDevNo()); // 目标站
|
wrkMast.setCrnNo(locMast.getCrnNo());
|
wrkMast.setSourceLocNo(locNo); // 源库位
|
wrkMast.setFullPlt("N"); // 满板:Y
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setEmptyMk("Y"); // 空板
|
wrkMast.setLinkMis("N");
|
wrkMast.setCtnKind(agvSite); // 出库下的小车工作区站好
|
wrkMast.setExitMk("N"); // 小车是否搬运
|
wrkMast.setAppeUser(userId);
|
wrkMast.setAppeTime(new Date());
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
boolean res = wrkMastService.insert(wrkMast);
|
if (!res) {
|
throw new CoolException("保存工作档失败");
|
}
|
// 更新库位状态 D.空板 -> R.出库预约
|
if (locMast.getLocSts().equals("D")) {
|
locMast.setLocSts("R");
|
locMast.setModiUser(userId);
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("更新库位状态失败");
|
}
|
}
|
// todo 更新站点信息(工作号)
|
}
|
}
|
|
@Override
|
@Transactional
|
public void locCheckOut(StockOutParam param, Long userId) {
|
// 目标站点状态检测
|
BasDevp staNo = basDevpService.checkSiteStatus(param.getOutSite());
|
int agvSite = 0;
|
if (!Cools.isEmpty(staNo.getFronting()) && staNo.getFronting().equals("Y")) {
|
agvSite = staNo.getDevNo();
|
staNo = basDevpService.checkSiteStatus(201);
|
}
|
// 获取库位明细
|
List<LocDetlDto> locDetlDtos = new ArrayList<>();
|
for (StockOutParam.LocDetl paramLocDetl : param.getLocDetls()) {
|
if (!Cools.isEmpty(paramLocDetl.getLocNo(), paramLocDetl.getMatnr())) {
|
LocDetl sqlParam = new LocDetl();
|
sqlParam.setLocNo(paramLocDetl.getLocNo());
|
sqlParam.setMatnr(paramLocDetl.getMatnr());
|
LocDetl one = locDetlService.selectOne(new EntityWrapper<>(sqlParam));
|
if (null != one) locDetlDtos.add(new LocDetlDto(one, one.getAnfme()));
|
}
|
}
|
for (LocDetlDto e : locDetlDtos) {
|
if (Cools.isEmpty(e.getLocDetl().getZpallet())) {
|
throw new CoolException("托盘码为空不允许盘点,库位号" + e.getLocDetl().getLocNo());
|
}
|
}
|
if (!locDetlDtos.isEmpty()) {
|
// 启动出库开始 107.盘点出库
|
stockOut(staNo, locDetlDtos, 107, userId, agvSite);
|
} else {
|
throw new CoolException("库位物料不存在");
|
}
|
}
|
|
@Override
|
@Transactional
|
public void locMove(String sourceLocNo, String locNo, Long userId) {
|
LocMast sourceLoc = locMastService.selectById(sourceLocNo);
|
if (Cools.isEmpty(sourceLoc)) {
|
throw new CoolException("未找到库位");
|
}
|
LocMast loc = locMastService.selectById(locNo);
|
if (Cools.isEmpty(loc)) {
|
throw new CoolException("未找到库位");
|
}
|
if (!sourceLoc.getCrnNo().equals(loc.getCrnNo())) {
|
throw new CoolException("移转库位属于不同堆垛机");
|
}
|
// 库位移转时类型检测
|
VersionUtils.locMoveCheckLocType(sourceLoc, loc);
|
// 获取工作号
|
int workNo = commonService.getWorkNo(DEFAULT_WORK_NO_TYPE);
|
// 保存工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(new Date());
|
wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
|
wrkMast.setIoType(11); // 入出库状态: 11.库格移载
|
wrkMast.setIoPri(10D);
|
wrkMast.setCrnNo(sourceLoc.getCrnNo());
|
wrkMast.setSourceLocNo(sourceLocNo); // 源库位
|
wrkMast.setLocNo(locNo); // 目标库位
|
wrkMast.setFullPlt("N"); // 满板:Y
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setEmptyMk(sourceLoc.getLocSts().equals("D") ? "Y" : "N"); // 空板
|
wrkMast.setBarcode(sourceLoc.getBarcode()); // 托盘码
|
wrkMast.setLinkMis("N");
|
wrkMast.setAppeUser(userId);
|
wrkMast.setAppeTime(new Date());
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
boolean res = wrkMastService.insert(wrkMast);
|
if (!res) {
|
throw new CoolException("保存工作档失败");
|
}
|
// 工作档明细保存
|
List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", sourceLocNo));
|
for (LocDetl locDetl : locDetls) {
|
WrkDetl wrkDetl = new WrkDetl();
|
wrkDetl.setWrkNo(workNo);
|
wrkDetl.setIoTime(new Date());
|
wrkDetl.setAnfme(locDetl.getAnfme());
|
VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制
|
wrkDetl.setAppeTime(new Date());
|
wrkDetl.setAppeUser(userId);
|
wrkDetl.setModiTime(new Date());
|
wrkDetl.setModiUser(userId);
|
if (!wrkDetlService.insert(wrkDetl)) {
|
throw new CoolException("保存工作档明细失败");
|
}
|
}
|
// 修改源库位状态
|
if (sourceLoc.getLocSts().equals("D") || sourceLoc.getLocSts().equals("F")) {
|
sourceLoc.setLocSts("R"); // R.出库预约
|
sourceLoc.setModiUser(userId);
|
sourceLoc.setModiTime(new Date());
|
if (!locMastService.updateById(sourceLoc)) {
|
throw new CoolException("更新源库位状态失败");
|
}
|
} else {
|
throw new CoolException("源库位出库失败,状态:" + sourceLoc.getLocSts$());
|
}
|
// 修改目标库位状态
|
if (loc.getLocSts().equals("O")) {
|
loc.setLocSts("S"); // S.入库预约
|
loc.setModiTime(new Date());
|
loc.setModiUser(userId);
|
if (!locMastService.updateById(loc)) {
|
throw new CoolException("更新目标库位状态失败");
|
}
|
} else {
|
throw new CoolException("移转失败,目标库位状态:" + loc.getLocSts$());
|
}
|
}
|
|
@Override
|
@Transactional
|
public void completeWrkMast(String workNo, Long userId) {
|
WrkMast wrkMast = wrkMastService.selectById(workNo);
|
if (Cools.isEmpty(wrkMast)) {
|
throw new CoolException(workNo + "工作档不存在");
|
}
|
if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 14) {
|
throw new CoolException("当前工作档已完成");
|
}
|
// 入库 + 库位转移
|
if (wrkMast.getWrkSts() < 4 || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType() == 11)) {
|
wrkMast.setWrkSts(4L);
|
// 出库
|
} else if (wrkMast.getWrkSts() > 10) {
|
wrkMast.setWrkSts(14L);
|
}
|
// 完成操作人员记录
|
wrkMast.setManuType("手动完成");
|
Date now = new Date();
|
wrkMast.setCrnStrTime(DateUtils.calculate(now, 1L, TimeUnit.SECONDS, true));
|
wrkMast.setCrnEndTime(now);
|
wrkMast.setModiTime(now);
|
wrkMast.setModiUser(userId);
|
if (!wrkMastService.updateById(wrkMast)) {
|
throw new CoolException("修改工作档失败");
|
}
|
}
|
|
@Override
|
@Transactional
|
public void adjustLocDetl(LocDetlAdjustParam param, Long userId) {
|
LocMast locMast = locMastService.selectById(param.getLocNo());
|
if (Cools.isEmpty(locMast)) {
|
throw new CoolException("库位不存在");
|
}
|
for (LocDetlAdjustParam.LocDetlAdjust adjust : param.getList()) {
|
if (Cools.isEmpty(adjust.getMatnr())) {
|
throw new CoolException(BaseRes.PARAM);
|
}
|
LocDetl sqlParam = new LocDetl();
|
sqlParam.setLocNo(locMast.getLocNo());
|
sqlParam.setMatnr(adjust.getMatnr());
|
LocDetl one = locDetlService.selectOne(new EntityWrapper<>(sqlParam));
|
// 保存新库存明细
|
if (Cools.isEmpty(one)) {
|
if (adjust.getCount() == 0) {
|
continue;
|
}
|
MatCode matCode = matCodeService.selectById(adjust.getMatnr());
|
LocDetl locDetl = new LocDetl();
|
locDetl.setLocNo(locMast.getLocNo());
|
locDetl.setAnfme(adjust.getCount()); // 数量
|
VersionUtils.setLocDetl(locDetl, matCode); // 版本控制
|
locDetl.setModiUser(userId); // 操作人员信息
|
locDetl.setModiTime(new Date());
|
locDetl.setAppeUser(userId);
|
locDetl.setAppeTime(new Date());
|
if (!locDetlService.insert(locDetl)) {
|
throw new CoolException("保存库存明细失败");
|
}
|
// 保存调整记录
|
AdjDetl adjDetl = new AdjDetl();
|
adjDetl.setLocNo(locDetl.getLocNo());
|
adjDetl.setMatNo(locDetl.getMatnr());
|
adjDetl.setOriQty(0.0D);
|
adjDetl.setAdjQty(adjust.getCount());
|
adjDetlService.save(adjDetl, userId);
|
// 调整库存,新增,StockCheckRecord插入盘盈数据
|
String ErpSql = "insert into StockCheckRecord(Fnumber, CheckQty, Fflag_rw, Fflag_finish) values (''{0}'', {1,number,#}, 0, 0)";
|
ErpSql = MessageFormat.format(ErpSql, adjust.getMatnr(), adjust.getCount());
|
erpSqlServer.update(ErpSql);
|
// 修改原库存明细
|
} else {
|
// 库存原数量
|
Double oldCount = one.getAnfme();
|
// 如果数量修改,则更新库存明细
|
if (!adjust.getCount().equals(one.getAnfme())) {
|
// 当数量被修改为 0 时,直接清除库存明细
|
if (adjust.getCount() == 0) {
|
if (!locDetlService.delete(new EntityWrapper<>(one))) {
|
throw new CoolException("清除库存明细失败");
|
}
|
} else {
|
LocDetl sqlParam1 = new LocDetl();
|
sqlParam1.setAnfme(adjust.getCount());
|
sqlParam1.setModiTime(new Date());
|
sqlParam1.setModiUser(userId);
|
if (!locDetlService.update(sqlParam1, new EntityWrapper<LocDetl>()
|
.eq("loc_no", locMast.getLocNo())
|
.eq("matnr", adjust.getMatnr()))) {
|
throw new CoolException("修改库存明细失败");
|
}
|
}
|
// 保存调整记录
|
AdjDetl adjDetl = new AdjDetl();
|
adjDetl.setLocNo(locMast.getLocNo());
|
adjDetl.setMatNo(adjust.getMatnr());
|
adjDetl.setOriQty(one.getAnfme());
|
adjDetl.setAdjQty(adjust.getCount());
|
adjDetlService.save(adjDetl, userId);
|
// 调整库存,修改,StockCheckRecord插入盘盈、盘亏数据
|
Double erpCount = 0D;
|
if (adjust.getCount() == 0) {
|
erpCount = 0 - oldCount;
|
} else {
|
erpCount = adjust.getCount() - oldCount;
|
}
|
String ErpSql = "insert into StockCheckRecord(Fnumber, CheckQty, Fflag_rw, Fflag_finish) values (''{0}'', {1,number,#}, 0, 0)";
|
ErpSql = MessageFormat.format(ErpSql, adjust.getMatnr(), erpCount);
|
erpSqlServer.update(ErpSql);
|
}
|
}
|
}
|
List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", param.getLocNo()));
|
if (locDetls.isEmpty()) {
|
locMast.setLocSts("D");
|
locMast.setModiUser(userId);
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("更新库位状态失败");
|
}
|
}
|
}
|
|
@Override
|
@Transactional
|
public void cancelWrkMast(String workNo, Long userId) {
|
WrkMast wrkMast = wrkMastService.selectById(workNo);
|
if (Cools.isEmpty(wrkMast)) {
|
throw new CoolException(workNo + "工作档不存在");
|
}
|
String locNo = ""; // 待修改目标库位
|
String locSts = ""; // 待修改目标库位状态
|
// 入库取消(修改目标库位)
|
if (wrkMast.getWrkSts() < 4) {
|
locNo = wrkMast.getLocNo();
|
locSts = "O";
|
/**
|
* 库位转移
|
* 取消后 源库位 ==>> F.在库
|
* 目标库位 ===>> O.空库位
|
**/
|
if (wrkMast.getIoType() == 11) {
|
// 库位转移:源库位
|
LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo());
|
if (Cools.isEmpty(locMast)) {
|
throw new CoolException("取消库位转移失败,源库位不存在:" + wrkMast.getSourceLocNo());
|
}
|
locMast.setLocSts(wrkMast.getEmptyMk().equals("Y") ? "D" : "F");
|
locMast.setModiTime(new Date());
|
locMast.setModiUser(userId);
|
locMastService.updateById(locMast);
|
}
|
// 出库取消(修改源库位)
|
} else if (wrkMast.getWrkSts() > 10 && wrkMast.getWrkSts() != 14) {
|
locNo = wrkMast.getSourceLocNo();
|
// 出库 ===>> F.在库
|
if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) {
|
locSts = "F";
|
// 空板出库 ===>> D.空桶/空栈板
|
} else if (wrkMast.getIoType() == 110) {
|
locSts = "D";
|
// 库位转移 ===>> D.空桶/空栈板
|
} else if (wrkMast.getIoType() == 11) {
|
locSts = wrkMast.getEmptyMk().equals("Y") ? "D" : "F";
|
// 库位转移:目标库位
|
LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
|
if (Cools.isEmpty(locMast)) {
|
throw new CoolException("取消库位转移失败,目标库位不存在:" + wrkMast.getSourceLocNo());
|
}
|
locMast.setLocSts("O");
|
locMast.setModiTime(new Date());
|
locMast.setModiUser(userId);
|
locMastService.updateById(locMast);
|
}
|
} else {
|
throw new CoolException("当前工作状态无法取消");
|
}
|
// 取消操作人员记录
|
wrkMast.setManuType("手动取消");
|
wrkMast.setModiUser(userId);
|
wrkMast.setModiTime(new Date());
|
if (!wrkMastService.updateById(wrkMast)) {
|
throw new CoolException("取消工作档失败");
|
}
|
// 保存工作主档历史档
|
if (!wrkMastLogService.save(wrkMast.getWrkNo())) {
|
throw new CoolException("保存工作历史档失败, workNo = " + wrkMast.getWrkNo());
|
}
|
// 删除工作主档
|
boolean wrkMastRes = wrkMastService.deleteById(wrkMast);
|
if (wrkMast.getIoType() != 10 && wrkMast.getIoType() != 110) {
|
// 保存工作明细档历史档
|
if (!wrkDetlLogService.save(wrkMast.getWrkNo())) {
|
throw new CoolException("保存工作明细历史档失败, workNo = " + wrkMast.getWrkNo());
|
}
|
// 删除工作档明细
|
boolean wrkDetlRes = wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", workNo));
|
}
|
// 修改库位状态
|
LocMast locMast = locMastService.selectById(locNo);
|
if (Cools.isEmpty(locMast)) {
|
throw new CoolException("取消工作档失败,库位不存在:" + locNo);
|
}
|
locMast.setLocSts(locSts);
|
locMast.setModiTime(new Date());
|
locMast.setModiUser(userId);
|
boolean locMastRes = locMastService.updateById(locMast);
|
if (!wrkMastRes || !locMastRes) {
|
throw new CoolException("保存数据失败");
|
}
|
}
|
|
@Override
|
@Transactional
|
public void pickWrkMast(String workNo, Long userId) {
|
WrkMast wrkMast = wrkMastService.selectById(workNo);
|
if (Cools.isEmpty(wrkMast)) {
|
throw new CoolException(workNo + "工作档不存在");
|
}
|
// 入出库类型判断
|
if (wrkMast.getIoType() != 103 && wrkMast.getIoType() != 104 && wrkMast.getIoType() != 107) {
|
throw new CoolException("当前入出库类型无法进行操作");
|
}
|
// 工作状态判断
|
if (wrkMast.getWrkSts() < 11 || wrkMast.getWrkSts() == 15) {
|
throw new CoolException("当前工作状态无法进行操作");
|
}
|
// 保存工作明细档历史档
|
if (!wrkDetlLogService.save(wrkMast.getWrkNo())) {
|
throw new CoolException("保存工作明细档历史档失败");
|
}
|
// 保存工作主档历史档
|
if (!wrkMastLogService.save(wrkMast.getWrkNo())) {
|
throw new CoolException("保存工作主档历史档失败");
|
}
|
// 获取目标站
|
Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
|
.eq("type_no", wrkMast.getIoType() - 50)
|
.eq("stn_no", wrkMast.getStaNo()) // 作业站点 = 拣料出库的目标站
|
.eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
|
StaDesc staDesc = staDescService.selectOne(wrapper);
|
if (Cools.isEmpty(staDesc)) {
|
throw new CoolException("入库路径不存在");
|
}
|
// 堆垛机站点(目标站)
|
Integer staNo = staDesc.getCrnStn();
|
// 更新工作档数据状态
|
wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
|
wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
|
wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
|
wrkMast.setStaNo(staNo); // 目标站
|
wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
|
wrkMast.setSourceLocNo(""); // 源库位清空
|
wrkMast.setModiTime(new Date());
|
wrkMast.setModiUser(userId);
|
if (!wrkMastService.updateById(wrkMast)) {
|
throw new CoolException("更新工作档数据状态失败");
|
}
|
// 修改库位状态 Q.拣料/盘点/并板再入库
|
LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
|
locMast.setLocSts("Q");
|
locMast.setModiTime(new Date());
|
locMast.setModiUser(userId);
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("修改库位状态失败");
|
}
|
}
|
|
@Override
|
public void specialPakIn(SpecialStoreParam param, Long useId) {
|
LocMast locMast = locMastService.selectById(param.getLocNo());
|
if (locMast == null) {
|
throw new CoolException(param.getLocNo() + "库位不存在");
|
}
|
if (locMast.getLocSts().equals("X")) {
|
throw new CoolException(param.getLocNo() + "库位已禁用");
|
}
|
if (param.getList() == null || param.getList().isEmpty()) {
|
throw new CoolException("请添加入库物料");
|
}
|
Date now = new Date();
|
// 保存库存明细
|
if (Cools.isEmpty(param.getProductCode())) {
|
for (SpecialStoreParam.MatCodeStore matDto : param.getList()) {
|
MatCode matCode = matCodeService.selectById(matDto.getMatNo());
|
if (matCode == null) {
|
throw new CoolException(matCode.getMatNo() + "物料信息错误");
|
}
|
|
LocDetl locDetl = new LocDetl();
|
locDetl.setLocNo(param.getLocNo()); // 库位号
|
VersionUtils.setLocDetl(locDetl, matCode); // 版本控制
|
locDetl.setModiTime(now);
|
locDetl.setModiUser(useId);
|
locDetl.setAppeTime(now);
|
locDetl.setAppeUser(useId);
|
if (!locDetlService.insert(locDetl)) {
|
throw new CoolException("保存库存明细失败");
|
}
|
}
|
} else {
|
LocDetl locDetl = new LocDetl();
|
locDetl.setLocNo(param.getLocNo()); // 库位号
|
|
locDetl.setMatnr(param.getProductCode()); // 物料编号
|
locDetl.setMaktx(param.getProductCode()); // 物料描述
|
locDetl.setLgnum(param.getProductCode()); // 规格
|
locDetl.setType(param.getProductCode()); // 物料类别
|
locDetl.setMnemonic(param.getProductCode()); // 助记码
|
locDetl.setSupplier(param.getProductCode()); // 默认供应商
|
locDetl.setWarehouse(param.getProductCode()); // 默认仓库
|
locDetl.setBrand(param.getProductCode()); // 品牌
|
locDetl.setAltme(param.getProductCode()); // 单位
|
|
locDetl.setModiTime(now);
|
locDetl.setModiUser(useId);
|
locDetl.setAppeTime(now);
|
locDetl.setAppeUser(useId);
|
if (!locDetlService.insert(locDetl)) {
|
throw new CoolException("保存库存明细失败");
|
}
|
}
|
|
// 修改库位状态
|
if (locMast.getLocSts().equals("O")) {
|
locMast.setLocSts("F");
|
}
|
locMast.setModiTime(now);
|
locMast.setModiUser(useId);
|
if (!locMastService.updateById(locMast)) {
|
throw new CoolException("修改库位状态失败");
|
}
|
}
|
|
}
|