|
@@ -11,6 +11,7 @@ import cn.hutool.json.JSONArray;
|
|
import cn.hutool.json.JSONObject;
|
|
import cn.hutool.json.JSONObject;
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.json.JSONUtil;
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
|
+import com.google.common.collect.Lists;
|
|
import com.ruoyi.ams.agv.ndc.common.Aci;
|
|
import com.ruoyi.ams.agv.ndc.common.Aci;
|
|
import com.ruoyi.ams.bionutrition.doc.domain.BionutritionDocDetails;
|
|
import com.ruoyi.ams.bionutrition.doc.domain.BionutritionDocDetails;
|
|
import com.ruoyi.ams.bionutrition.doc.domain.BionutritionDocHeader;
|
|
import com.ruoyi.ams.bionutrition.doc.domain.BionutritionDocHeader;
|
|
@@ -27,32 +28,45 @@ import com.ruoyi.ams.bionutrition.doc.service.BionutritionDocHeaderService;
|
|
import com.ruoyi.ams.bionutrition.dto.AsnAgvCallDTO;
|
|
import com.ruoyi.ams.bionutrition.dto.AsnAgvCallDTO;
|
|
import com.ruoyi.ams.bionutrition.dto.GroundingDTO;
|
|
import com.ruoyi.ams.bionutrition.dto.GroundingDTO;
|
|
import com.ruoyi.ams.bionutrition.dto.OrderAgvCallDTO;
|
|
import com.ruoyi.ams.bionutrition.dto.OrderAgvCallDTO;
|
|
|
|
+import com.ruoyi.ams.bionutrition.dto.ReturningInventoryDTO;
|
|
import com.ruoyi.ams.bionutrition.pda.IPdaAgvCallService;
|
|
import com.ruoyi.ams.bionutrition.pda.IPdaAgvCallService;
|
|
import com.ruoyi.ams.business.IBusinessService;
|
|
import com.ruoyi.ams.business.IBusinessService;
|
|
import com.ruoyi.ams.config.domain.dto.AgvCallDTO;
|
|
import com.ruoyi.ams.config.domain.dto.AgvCallDTO;
|
|
import com.ruoyi.ams.config.domain.dto.AgvCallItemDTO;
|
|
import com.ruoyi.ams.config.domain.dto.AgvCallItemDTO;
|
|
import com.ruoyi.ams.config.domain.dto.LotattDTO;
|
|
import com.ruoyi.ams.config.domain.dto.LotattDTO;
|
|
|
|
+import com.ruoyi.ams.config.domain.vo.FlowConfigHeaderVO;
|
|
|
|
+import com.ruoyi.ams.config.service.IFlowConfigHeaderService;
|
|
|
|
+import com.ruoyi.ams.inv.domain.InvLotAtt;
|
|
|
|
+import com.ruoyi.ams.inv.domain.InvLotLocId;
|
|
|
|
+import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
|
|
|
|
+import com.ruoyi.ams.inv.service.IInvLotAttService;
|
|
|
|
+import com.ruoyi.ams.inv.service.IInvLotLocIdService;
|
|
import com.ruoyi.base.constant.Constant;
|
|
import com.ruoyi.base.constant.Constant;
|
|
import com.ruoyi.base.constant.type.BizEnum;
|
|
import com.ruoyi.base.constant.type.BizEnum;
|
|
import com.ruoyi.base.domain.BaseSku;
|
|
import com.ruoyi.base.domain.BaseSku;
|
|
import com.ruoyi.base.service.IBaseSkuService;
|
|
import com.ruoyi.base.service.IBaseSkuService;
|
|
|
|
+import com.ruoyi.common.constant.Constants;
|
|
import com.ruoyi.common.constant.base.EnumUtils;
|
|
import com.ruoyi.common.constant.base.EnumUtils;
|
|
import com.ruoyi.common.core.domain.AjaxResult;
|
|
import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
import com.ruoyi.common.utils.ConvertUtils;
|
|
import com.ruoyi.common.utils.ConvertUtils;
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
import com.ruoyi.system.service.ISysConfigService;
|
|
import com.ruoyi.system.service.ISysConfigService;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
+import org.jetbrains.annotations.Nullable;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
+import javax.validation.constraints.NotEmpty;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Arrays;
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.List;
|
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
@Service
|
|
@Service
|
|
@@ -68,6 +82,12 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
|
|
private ISysConfigService iSysConfigService;
|
|
private ISysConfigService iSysConfigService;
|
|
@Autowired
|
|
@Autowired
|
|
private IBaseSkuService skuService;
|
|
private IBaseSkuService skuService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IFlowConfigHeaderService flowConfigHeaderService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IInvLotLocIdService invLotLocIdService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IInvLotAttService invLotAttService;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 根据单号和单据类型生成入库任务
|
|
* 根据单号和单据类型生成入库任务
|
|
@@ -84,16 +104,11 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
|
|
Assert.isTrue(ObjectUtil.isNotNull(bionutritionDocBaseDTO), "该单据不存在");
|
|
Assert.isTrue(ObjectUtil.isNotNull(bionutritionDocBaseDTO), "该单据不存在");
|
|
BionutritionDocHeaderBaseDTO bionutritionDocHeaderBaseDTO = bionutritionDocBaseDTO.getBionutritionDocHeaderBaseDTO();
|
|
BionutritionDocHeaderBaseDTO bionutritionDocHeaderBaseDTO = bionutritionDocBaseDTO.getBionutritionDocHeaderBaseDTO();
|
|
String docType = bionutritionDocHeaderBaseDTO.getDocType();
|
|
String docType = bionutritionDocHeaderBaseDTO.getDocType();
|
|
- Assert.isTrue(StringUtils.isNotEmpty(docType), "单据信息中单据类型为空");
|
|
|
|
Assert.isTrue(StringUtils.equals(bionutritionDocHeaderBaseDTO.getBusinessType(),Constant.BUSINESS_TYPE.ASN.getValue())
|
|
Assert.isTrue(StringUtils.equals(bionutritionDocHeaderBaseDTO.getBusinessType(),Constant.BUSINESS_TYPE.ASN.getValue())
|
|
|| StringUtils.equals(bionutritionDocHeaderBaseDTO.getBusinessType(),Constant.BUSINESS_TYPE.PO.getValue())
|
|
|| StringUtils.equals(bionutritionDocHeaderBaseDTO.getBusinessType(),Constant.BUSINESS_TYPE.PO.getValue())
|
|
, "该单据不是入库单据");
|
|
, "该单据不是入库单据");
|
|
- List<BionutritionDocDetailsBaseDTO> docDetailsList = bionutritionDocBaseDTO.getBionutritionDocDetailsBaseDTOList();
|
|
|
|
- Assert.isTrue(CollUtil.isNotEmpty(docDetailsList), "单据明细数据为空");
|
|
|
|
// 2.根据明细行号筛选明细信息
|
|
// 2.根据明细行号筛选明细信息
|
|
- BionutritionDocDetailsBaseDTO docDetailsBaseDTO = docDetailsList.stream().filter(item -> StringUtils.equals(item.getDocLineNo(), asnAgvCallDTO.getLineNo()))
|
|
|
|
- .findFirst().orElse(null);
|
|
|
|
- Assert.isTrue(ObjectUtil.isNotEmpty(docDetailsBaseDTO), "对应明细行号数据未找到");
|
|
|
|
|
|
+ BionutritionDocDetailsBaseDTO docDetailsBaseDTO = this.filterBionutritionDocDetailsBaseDTOByLineNo(asnAgvCallDTO.getLineNo(), bionutritionDocBaseDTO);
|
|
// 3.判断数量是否超出范围
|
|
// 3.判断数量是否超出范围
|
|
// 记录当前明细已搬运数量
|
|
// 记录当前明细已搬运数量
|
|
BigDecimal transferredQty = NumberUtil.add(docDetailsBaseDTO.getTransferredQty(), asnAgvCallDTO.getQty());
|
|
BigDecimal transferredQty = NumberUtil.add(docDetailsBaseDTO.getTransferredQty(), asnAgvCallDTO.getQty());
|
|
@@ -102,57 +117,65 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
|
|
, "入库数量超出范围,剩余数量"+NumberUtil.sub(docDetailsBaseDTO.getSkuQty(), docDetailsBaseDTO.getTransferredQty()));
|
|
, "入库数量超出范围,剩余数量"+NumberUtil.sub(docDetailsBaseDTO.getSkuQty(), docDetailsBaseDTO.getTransferredQty()));
|
|
docDetailsBaseDTO.setTransferredQty(transferredQty.toString());
|
|
docDetailsBaseDTO.setTransferredQty(transferredQty.toString());
|
|
bionutritionDocDetailsService.updateDocDetails(ConvertUtils.sourceToTarget(docDetailsBaseDTO, BionutritionDocDetailsDTO.class));
|
|
bionutritionDocDetailsService.updateDocDetails(ConvertUtils.sourceToTarget(docDetailsBaseDTO, BionutritionDocDetailsDTO.class));
|
|
-
|
|
|
|
// 如果是采购入库 需要根据采购单生成采购入库单
|
|
// 如果是采购入库 需要根据采购单生成采购入库单
|
|
if (StringUtils.equals(docType, BizEnum.BionutritionExcelDocTitleEnum.PURCHASE_ORDER.getDocType())) {
|
|
if (StringUtils.equals(docType, BizEnum.BionutritionExcelDocTitleEnum.PURCHASE_ORDER.getDocType())) {
|
|
this.addPurchaseReceiptDoc(bionutritionDocBaseDTO, docDetailsBaseDTO, asnAgvCallDTO);
|
|
this.addPurchaseReceiptDoc(bionutritionDocBaseDTO, docDetailsBaseDTO, asnAgvCallDTO);
|
|
}
|
|
}
|
|
- // 4.获取配置信息单据类型对应流程id
|
|
|
|
- Long flowId = this.getFlowIdByDocType(docType);
|
|
|
|
|
|
+ // 4.获取配置信息单据类型或物料类型对应流程id
|
|
|
|
+ List<Long> flowIds = this.getFlowIdByDocTypeOrSkuType(docType, docDetailsBaseDTO.getSkuCode());
|
|
|
|
+ List<FlowConfigHeaderVO> flowConfigHeaderVOList = flowConfigHeaderService.selectFlowConfigHeaderByIds(flowIds);
|
|
|
|
+ Long flowId = flowConfigHeaderVOList.stream().filter(f -> StringUtils.equals(Constant.BUSINESS_TYPE.ASN.getValue(), f.getFlowType()))
|
|
|
|
+ .map(FlowConfigHeaderVO::getId)
|
|
|
|
+ .findFirst().orElse(null);
|
|
// 5.生成agv呼叫对象,生成对应wcs任务
|
|
// 5.生成agv呼叫对象,生成对应wcs任务
|
|
- AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, bionutritionDocHeaderBaseDTO, docDetailsBaseDTO);
|
|
|
|
|
|
+ AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, bionutritionDocHeaderBaseDTO, docDetailsBaseDTO, null);
|
|
businessService.agvCall(flowId, agvCallDTO);
|
|
businessService.agvCall(flowId, agvCallDTO);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 上架
|
|
|
|
- * @param groundingDTO
|
|
|
|
|
|
+ * 根据明细行号筛选明细
|
|
|
|
+ * @param lineNo
|
|
|
|
+ * @param bionutritionDocBaseDTO
|
|
|
|
+ * @return
|
|
*/
|
|
*/
|
|
- @Override
|
|
|
|
- @Transactional(rollbackFor = RuntimeException.class)
|
|
|
|
- public void grounding(GroundingDTO groundingDTO) {
|
|
|
|
- // 根据单号和单据类型查询单据信息
|
|
|
|
- BionutritionDocBaseDTO bionutritionDocBaseDTO =
|
|
|
|
- bionutritionDocHeaderService.selectDocByDocNoAndDocType(groundingDTO.getDocNo(), groundingDTO.getDocType());
|
|
|
|
- Assert.isTrue(ObjectUtil.isNotNull(bionutritionDocBaseDTO), "该单据不存在");
|
|
|
|
|
|
+ @Nullable
|
|
|
|
+ private BionutritionDocDetailsBaseDTO filterBionutritionDocDetailsBaseDTOByLineNo(String lineNo, BionutritionDocBaseDTO bionutritionDocBaseDTO) {
|
|
List<BionutritionDocDetailsBaseDTO> docDetailsList = bionutritionDocBaseDTO.getBionutritionDocDetailsBaseDTOList();
|
|
List<BionutritionDocDetailsBaseDTO> docDetailsList = bionutritionDocBaseDTO.getBionutritionDocDetailsBaseDTOList();
|
|
Assert.isTrue(CollUtil.isNotEmpty(docDetailsList), "单据明细数据为空");
|
|
Assert.isTrue(CollUtil.isNotEmpty(docDetailsList), "单据明细数据为空");
|
|
- BionutritionDocDetailsBaseDTO docDetailsBaseDTO = docDetailsList.stream().filter(item -> StringUtils.equals(item.getDocLineNo(), groundingDTO.getLineNo()))
|
|
|
|
|
|
+ BionutritionDocDetailsBaseDTO docDetailsBaseDTO = docDetailsList.stream().filter(item -> StringUtils.equals(item.getDocLineNo(), lineNo))
|
|
.findFirst().orElse(null);
|
|
.findFirst().orElse(null);
|
|
- Assert.isTrue(ObjectUtil.isNotEmpty(docDetailsBaseDTO), "行号对应明细数据未找到");
|
|
|
|
- // 修改单据明细状态为完全上架
|
|
|
|
- docDetailsBaseDTO.setLineStatus(Constant.ASN_STS.STS60.getValue());
|
|
|
|
- bionutritionDocDetailsService.updateDocDetails(ConvertUtils.sourceToTarget(docDetailsBaseDTO, BionutritionDocDetailsDTO.class));
|
|
|
|
|
|
+ Assert.isTrue(ObjectUtil.isNotEmpty(docDetailsBaseDTO), "对应明细行号数据未找到");
|
|
|
|
+ return docDetailsBaseDTO;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 根据单据类型获取流程id
|
|
|
|
|
|
+ * 根据单据类型或者物料类型获取流程id
|
|
* @param docType
|
|
* @param docType
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
@NotNull
|
|
@NotNull
|
|
- public Long getFlowIdByDocType(String docType) {
|
|
|
|
|
|
+ public List<Long> getFlowIdByDocTypeOrSkuType(String docType, String skuCode) {
|
|
JSONArray docTypeFlowObjects = JSONUtil.parseArray(iSysConfigService.selectConfigByKey("sys.docType.corresponding.business"));
|
|
JSONArray docTypeFlowObjects = JSONUtil.parseArray(iSysConfigService.selectConfigByKey("sys.docType.corresponding.business"));
|
|
- JSONObject jsonObject = docTypeFlowObjects.stream().map(o -> JSONUtil.parseObj(o.toString()))
|
|
|
|
- .filter(entry -> StringUtils.equals(docType, (String) entry.get("docType"))).findFirst().orElse(null);
|
|
|
|
- Assert.notNull(jsonObject, "未查找到该单据号对应单据类型");
|
|
|
|
- Assert.notNull(jsonObject.get("flowId"), "未找到对应的任务下发流程");
|
|
|
|
- Long flowId = Long.parseLong(jsonObject.get("flowId").toString());
|
|
|
|
- return flowId;
|
|
|
|
|
|
+ List<JSONObject> jsonObjects = docTypeFlowObjects.stream().map(o -> JSONUtil.parseObj(o.toString()))
|
|
|
|
+ .filter(entry -> StringUtils.equals(docType, (String) entry.get("docType"))).collect(Collectors.toList());
|
|
|
|
+ // 如果根据单据类型查询不到流程,则根据物料类型获取
|
|
|
|
+ if (CollUtil.isEmpty(jsonObjects)){
|
|
|
|
+ BaseSku queryBaseSku = new BaseSku();
|
|
|
|
+ queryBaseSku.setSku(skuCode);
|
|
|
|
+ List<BaseSku> baseSkuList = skuService.selectBaseSkuList(queryBaseSku);
|
|
|
|
+ Assert.isTrue(CollUtil.isNotEmpty(baseSkuList), "未找到对应物料信息");
|
|
|
|
+ BaseSku baseSku = baseSkuList.stream().findFirst().get();
|
|
|
|
+ jsonObjects = docTypeFlowObjects.stream().map(o -> JSONUtil.parseObj(o.toString()))
|
|
|
|
+ .filter(entry -> StringUtils.equals(String.valueOf(baseSku.getSkuType()), (String) entry.get("skuType")))
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+ Assert.isTrue(CollUtil.isNotEmpty(jsonObjects), "未找到对应的任务下发流程");
|
|
|
|
+ List<Long> flowIds = jsonObjects.stream().map(o->Long.parseLong(o.get("flowId").toString())).collect(Collectors.toList());
|
|
|
|
+ return flowIds;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 添加采购入库单
|
|
|
|
|
|
+ * 生成采购入库单
|
|
* @param bionutritionDocBaseDTO
|
|
* @param bionutritionDocBaseDTO
|
|
* @param docDetailsBaseDTO
|
|
* @param docDetailsBaseDTO
|
|
*/
|
|
*/
|
|
@@ -219,56 +242,79 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
|
|
* @param asnAgvCallDTO
|
|
* @param asnAgvCallDTO
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- private AgvCallDTO getASNAgvCallDTO(AsnAgvCallDTO asnAgvCallDTO, BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO) {
|
|
|
|
|
|
+ private AgvCallDTO getASNAgvCallDTO(AsnAgvCallDTO asnAgvCallDTO, BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO, BigDecimal totalAmount) {
|
|
DocLotattDTO docLotattDTO = ConvertUtils.sourceToTarget(docDetailsBaseDTO, DocLotattDTO.class);
|
|
DocLotattDTO docLotattDTO = ConvertUtils.sourceToTarget(docDetailsBaseDTO, DocLotattDTO.class);
|
|
// 根据物料编码查询物料信息
|
|
// 根据物料编码查询物料信息
|
|
- BaseSku baseSku = skuService.selectBaseSkuByCustomerId("default", asnAgvCallDTO.getSkuCode());
|
|
|
|
|
|
+ BaseSku baseSku = skuService.selectBaseSkuByCustomerId(Constants.DEFAULT_CUSTOMER_ID, asnAgvCallDTO.getSkuCode());
|
|
Assert.isTrue(ObjectUtil.isNotEmpty(baseSku), "物料信息未找到");
|
|
Assert.isTrue(ObjectUtil.isNotEmpty(baseSku), "物料信息未找到");
|
|
List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
|
|
List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
|
|
AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
|
|
AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
|
|
// 构建批次属性
|
|
// 构建批次属性
|
|
- LotattDTO lotattDTO = this.buildLotattArgument(docHeaderBaseDTO, docDetailsBaseDTO, docLotattDTO, baseSku);
|
|
|
|
|
|
+ LotattDTO lotattDTO = this.buildLotattArgument(docHeaderBaseDTO, docDetailsBaseDTO, docLotattDTO, baseSku, asnAgvCallDTO.getStatus());
|
|
|
|
|
|
agvCallItemDTO.setSku(asnAgvCallDTO.getSkuCode());
|
|
agvCallItemDTO.setSku(asnAgvCallDTO.getSkuCode());
|
|
agvCallItemDTO.setQty(Double.valueOf(asnAgvCallDTO.getQty()));
|
|
agvCallItemDTO.setQty(Double.valueOf(asnAgvCallDTO.getQty()));
|
|
|
|
+ // 计算一托盘总量
|
|
|
|
+ if (ObjectUtil.isEmpty(totalAmount)) totalAmount = this.buildTotalAmount(baseSku, asnAgvCallDTO.getQty());
|
|
|
|
+ agvCallItemDTO.setTotalAmount(totalAmount);
|
|
agvCallItemDTO.setLotattDTO(lotattDTO);
|
|
agvCallItemDTO.setLotattDTO(lotattDTO);
|
|
agvCallItemDTOList.add(agvCallItemDTO);
|
|
agvCallItemDTOList.add(agvCallItemDTO);
|
|
AgvCallDTO agvCallDTO = new AgvCallDTO();
|
|
AgvCallDTO agvCallDTO = new AgvCallDTO();
|
|
|
|
+ if (StringUtils.isNotBlank(asnAgvCallDTO.getIfSample())) agvCallDTO.setIfSample(asnAgvCallDTO.getIfSample());
|
|
agvCallDTO.setLocationFrom(asnAgvCallDTO.getLocationFrom());
|
|
agvCallDTO.setLocationFrom(asnAgvCallDTO.getLocationFrom());
|
|
|
|
+ agvCallDTO.setDocNo(asnAgvCallDTO.getDocNo());
|
|
|
|
+ agvCallDTO.setDocType(asnAgvCallDTO.getDocType());
|
|
agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
|
|
agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
|
|
- agvCallDTO.setDocNo(asnAgvCallDTO.getDocNo());// 设置单号
|
|
|
|
|
|
+ agvCallDTO.setHeaderId(docHeaderBaseDTO.getId());// 设置单头id
|
|
agvCallDTO.setDocLineNo(asnAgvCallDTO.getLineNo()); // 设置明细行号
|
|
agvCallDTO.setDocLineNo(asnAgvCallDTO.getLineNo()); // 设置明细行号
|
|
agvCallDTO.setBusinessType(Constant.BUSINESS_TYPE.ASN.getValue()); // 设置单据业务类型 -- 入库
|
|
agvCallDTO.setBusinessType(Constant.BUSINESS_TYPE.ASN.getValue()); // 设置单据业务类型 -- 入库
|
|
- agvCallDTO.setDocType(asnAgvCallDTO.getDocType()); // 设置单据类型
|
|
|
|
agvCallDTO.setCreateUser(asnAgvCallDTO.getUser()); // 设置操作人
|
|
agvCallDTO.setCreateUser(asnAgvCallDTO.getUser()); // 设置操作人
|
|
return agvCallDTO;
|
|
return agvCallDTO;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 构建单拖库存总量(可能是数量、质量、体积)
|
|
|
|
+ * @param baseSku
|
|
|
|
+ * @param qty
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public BigDecimal buildTotalAmount(BaseSku baseSku, String qty) {
|
|
|
|
+ String packagingSpecs = baseSku.getSkuPackagingSpecs();
|
|
|
|
+ if (StringUtils.isBlank(packagingSpecs)) return BigDecimal.ZERO;
|
|
|
|
+ Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)?");
|
|
|
|
+ Matcher matcher = pattern.matcher(packagingSpecs.trim());
|
|
|
|
+ if (!matcher.find()) return BigDecimal.ZERO;
|
|
|
|
+ String numStr = matcher.group();
|
|
|
|
+ BigDecimal c = new BigDecimal(numStr);
|
|
|
|
+ BigDecimal specs = c.stripTrailingZeros();
|
|
|
|
+ return specs.multiply(new BigDecimal(qty));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 构建批次属性
|
|
* 构建批次属性
|
|
* @param docHeaderBaseDTO
|
|
* @param docHeaderBaseDTO
|
|
* @param docLotattDTO
|
|
* @param docLotattDTO
|
|
* @param baseSku
|
|
* @param baseSku
|
|
*/
|
|
*/
|
|
- public LotattDTO buildLotattArgument(BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO, DocLotattDTO docLotattDTO, BaseSku baseSku) {
|
|
|
|
|
|
+ public LotattDTO buildLotattArgument(BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO, DocLotattDTO docLotattDTO, BaseSku baseSku, String status) {
|
|
LotattDTO lotattDTO = new LotattDTO();
|
|
LotattDTO lotattDTO = new LotattDTO();
|
|
lotattDTO.setLotatt01(docLotattDTO.getVendorCode());// 供应商编码
|
|
lotattDTO.setLotatt01(docLotattDTO.getVendorCode());// 供应商编码
|
|
- if (StringUtils.equals(BizEnum.BionutritionDetailDocTypeEnum.PURCHASE_ORDER.getDocType(), docHeaderBaseDTO.getDocType())){
|
|
|
|
- lotattDTO.setLotatt02(docLotattDTO.getOriginalLotNumber()); // 采购收货:原厂批号
|
|
|
|
- } else if (StringUtils.equals(BizEnum.BionutritionDetailDocTypeEnum.PRODUCTION_RETURN_ORDER.getDocType(), docHeaderBaseDTO.getDocType())){
|
|
|
|
- lotattDTO.setLotatt02(docLotattDTO.getIncomeLotNumber()); // 成品入库、销售退库:产品批号
|
|
|
|
|
|
+ if (StringUtils.equals(BizEnum.BionutritionDetailDocTypeEnum.PURCHASE_ORDER.getDocType(), docHeaderBaseDTO.getDocType())
|
|
|
|
+ || StringUtils.equals(BizEnum.BionutritionDetailDocTypeEnum.PRODUCTION_RETURN_ORDER.getDocType(), docHeaderBaseDTO.getDocType())
|
|
|
|
+ || StringUtils.equals(BizEnum.BionutritionDetailDocTypeEnum.PURCHASE_RECEIPT.getDocType(), docHeaderBaseDTO.getDocType())){
|
|
|
|
+ lotattDTO.setLotatt02(docLotattDTO.getIncomeLotNumber()); // 采购收货、生产退料:进厂批号
|
|
} else {
|
|
} else {
|
|
- lotattDTO.setLotatt02(docLotattDTO.getProductLotNumber()); // 生产退库:进厂批号
|
|
|
|
|
|
+ lotattDTO.setLotatt02(docLotattDTO.getProductLotNumber()); // 成品入库、销售退库:产品批号
|
|
}
|
|
}
|
|
String manufactureDate = DateUtil.format(docLotattDTO.getManufactureDate(), "yyyy-MM-dd");
|
|
String manufactureDate = DateUtil.format(docLotattDTO.getManufactureDate(), "yyyy-MM-dd");
|
|
lotattDTO.setLotatt03(manufactureDate);// 生产日期
|
|
lotattDTO.setLotatt03(manufactureDate);// 生产日期
|
|
// 计算有效截止日期:生产日期加上有效期(天)
|
|
// 计算有效截止日期:生产日期加上有效期(天)
|
|
DateTime dateTime = DateUtil.offsetDay(DateUtil.parse(manufactureDate), baseSku.getSkuShelflife());
|
|
DateTime dateTime = DateUtil.offsetDay(DateUtil.parse(manufactureDate), baseSku.getSkuShelflife());
|
|
lotattDTO.setLotatt04(DateUtil.format(dateTime,"yyyy-MM-dd"));// 有效截止日期
|
|
lotattDTO.setLotatt04(DateUtil.format(dateTime,"yyyy-MM-dd"));// 有效截止日期
|
|
- lotattDTO.setLotatt05(Constant.QUALITY_STATUS.DJ.getValue());// 质检状态 默认待检
|
|
|
|
|
|
+ lotattDTO.setLotatt05(StringUtils.isNotBlank(status) ? status : Constant.QUALITY_STATUS.DJ.getValue());// 质检状态 默认待检
|
|
lotattDTO.setLotatt06(DateUtil.format(new Date(), "yyyy-MM-dd"));// 入库日期
|
|
lotattDTO.setLotatt06(DateUtil.format(new Date(), "yyyy-MM-dd"));// 入库日期
|
|
lotattDTO.setLotatt07(docLotattDTO.getIncomeLotNumber());// 进厂批号
|
|
lotattDTO.setLotatt07(docLotattDTO.getIncomeLotNumber());// 进厂批号
|
|
- lotattDTO.setLotatt08(docLotattDTO.getProductLotNumber());// 生产批号
|
|
|
|
|
|
+ lotattDTO.setLotatt08(docLotattDTO.getProductLotNumber());// 产品批号
|
|
lotattDTO.setLotatt09(docHeaderBaseDTO.getId());// 入库单头id
|
|
lotattDTO.setLotatt09(docHeaderBaseDTO.getId());// 入库单头id
|
|
lotattDTO.setLotatt10(docDetailsBaseDTO.getDocLineNo()); // 明细行号
|
|
lotattDTO.setLotatt10(docDetailsBaseDTO.getDocLineNo()); // 明细行号
|
|
return lotattDTO;
|
|
return lotattDTO;
|
|
@@ -280,24 +326,119 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
- public AgvCallDTO getOrderAgvCallDTO(OrderAgvCallDTO orderAgvCallDTO) {
|
|
|
|
|
|
+ public AgvCallDTO getOrderAgvCallDTO(OrderAgvCallDTO orderAgvCallDTO, BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO) {
|
|
// 根据物料编码查询物料信息
|
|
// 根据物料编码查询物料信息
|
|
- BaseSku baseSku = skuService.selectBaseSkuByCustomerId("default", orderAgvCallDTO.getSkuCode());
|
|
|
|
|
|
+ BaseSku baseSku = skuService.selectBaseSkuByCustomerId(Constants.DEFAULT_CUSTOMER_ID, orderAgvCallDTO.getSkuCode());
|
|
Assert.isTrue(ObjectUtil.isNotEmpty(baseSku), "物料信息未找到");
|
|
Assert.isTrue(ObjectUtil.isNotEmpty(baseSku), "物料信息未找到");
|
|
List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
|
|
List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
|
|
AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
|
|
AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
|
|
|
|
|
|
agvCallItemDTO.setSku(orderAgvCallDTO.getSkuCode());
|
|
agvCallItemDTO.setSku(orderAgvCallDTO.getSkuCode());
|
|
agvCallItemDTO.setQty(Double.valueOf(orderAgvCallDTO.getQty()));
|
|
agvCallItemDTO.setQty(Double.valueOf(orderAgvCallDTO.getQty()));
|
|
|
|
+ LotattDTO lotattDTO = new LotattDTO();
|
|
|
|
+ lotattDTO.setLotatt02(orderAgvCallDTO.getBatchNumber());
|
|
|
|
+ agvCallItemDTO.setLotattDTO(lotattDTO);
|
|
agvCallItemDTOList.add(agvCallItemDTO);
|
|
agvCallItemDTOList.add(agvCallItemDTO);
|
|
AgvCallDTO agvCallDTO = new AgvCallDTO();
|
|
AgvCallDTO agvCallDTO = new AgvCallDTO();
|
|
|
|
+ agvCallDTO.setDocDetailsBaseDTO(docDetailsBaseDTO);
|
|
agvCallDTO.setLocationFrom(orderAgvCallDTO.getLocationTo());
|
|
agvCallDTO.setLocationFrom(orderAgvCallDTO.getLocationTo());
|
|
agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
|
|
agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
|
|
- agvCallDTO.setDocNo(orderAgvCallDTO.getDocNo());// 设置单号
|
|
|
|
|
|
+ agvCallDTO.setDocNo(orderAgvCallDTO.getDocNo());
|
|
|
|
+ agvCallDTO.setDocType(orderAgvCallDTO.getDocType());
|
|
|
|
+ agvCallDTO.setHeaderId(docHeaderBaseDTO.getId());// 设置单头id
|
|
agvCallDTO.setDocLineNo(orderAgvCallDTO.getLineNo()); // 设置明细行号
|
|
agvCallDTO.setDocLineNo(orderAgvCallDTO.getLineNo()); // 设置明细行号
|
|
agvCallDTO.setBusinessType(Constant.BUSINESS_TYPE.ORDER.getValue()); // 设置单据业务类型 -- 出库
|
|
agvCallDTO.setBusinessType(Constant.BUSINESS_TYPE.ORDER.getValue()); // 设置单据业务类型 -- 出库
|
|
agvCallDTO.setDocType(orderAgvCallDTO.getDocType()); // 设置单据类型
|
|
agvCallDTO.setDocType(orderAgvCallDTO.getDocType()); // 设置单据类型
|
|
agvCallDTO.setCreateUser(orderAgvCallDTO.getUser()); // 设置操作人
|
|
agvCallDTO.setCreateUser(orderAgvCallDTO.getUser()); // 设置操作人
|
|
return agvCallDTO;
|
|
return agvCallDTO;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 回库任务下发
|
|
|
|
+ * @param returningInventoryDTO
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ @Transactional(rollbackFor = RuntimeException.class)
|
|
|
|
+ public void returningToInventory(ReturningInventoryDTO returningInventoryDTO) {
|
|
|
|
+ // 1.校验参数
|
|
|
|
+ // 根据单号和单据类型查询出库单据信息
|
|
|
|
+ BionutritionDocBaseDTO bionutritionDocBaseDTO =
|
|
|
|
+ bionutritionDocHeaderService.selectDocByDocNoAndDocType(returningInventoryDTO.getDocNo(), returningInventoryDTO.getDocType());
|
|
|
|
+ Assert.isTrue(ObjectUtil.isNotNull(bionutritionDocBaseDTO), "该单据不存在");
|
|
|
|
+ BionutritionDocHeaderBaseDTO soDocHeaderBaseDTO = bionutritionDocBaseDTO.getBionutritionDocHeaderBaseDTO();
|
|
|
|
+ Assert.isTrue(StringUtils.equals(soDocHeaderBaseDTO.getBusinessType(),Constant.BUSINESS_TYPE.ORDER.getValue())
|
|
|
|
+ , "该单据不是出库单据");
|
|
|
|
+ // 2.根据明细行号筛选明细信息
|
|
|
|
+ BionutritionDocDetailsBaseDTO soDocDetailsBaseDTO = this.filterBionutritionDocDetailsBaseDTOByLineNo(returningInventoryDTO.getLineNo(), bionutritionDocBaseDTO);
|
|
|
|
+ // 3.更新出库单明细的已搬运数量--之前的已搬运数量减去回库的数量
|
|
|
|
+ String qty = this.getQtyBySpecs(returningInventoryDTO.getSkuCode(), returningInventoryDTO.getTotalAmount());
|
|
|
|
+ BigDecimal transferredQty = NumberUtil.sub(soDocDetailsBaseDTO.getTransferredQty(), qty);
|
|
|
|
+ Assert.isTrue(transferredQty.compareTo(BigDecimal.ZERO) >= 0, "回库数量大于出库数量");
|
|
|
|
+
|
|
|
|
+ // 4.更新库存信息
|
|
|
|
+ // 根据库位id查询库存
|
|
|
|
+// List<InvLotLocIdLotattVO> invLotLocIdLotattVOS = invLotLocIdService.selectInvLocIdLotattByLocationId(Long.parseLong(returningInventoryDTO.getLocationFrom()));
|
|
|
|
+ List<InvLotLocId> invLotLocIdList = invLotLocIdService.selectInvLotLocIdList(Long.parseLong(returningInventoryDTO.getLocationFrom()));
|
|
|
|
+ Assert.isTrue(CollUtil.isNotEmpty(invLotLocIdList), "未找到对应库位库存信息");
|
|
|
|
+ InvLotLocId invLotLocId = invLotLocIdList.stream().findFirst().orElse(null);
|
|
|
|
+ // 获取库存对应批次信息
|
|
|
|
+ InvLotAtt invLotAtt = invLotAttService.selectInvLotAttByLotnum(invLotLocId.getLotnum());
|
|
|
|
+ // 库位id更新为出库终点位, 更新分配数量
|
|
|
|
+ int updateNum = invLotLocIdService.updateInvLotLocIdByLocationId(invLotAtt.getLotnum(), Long.parseLong(invLotLocId.getLocationId()), Constant.LOC_SORTATION_FINISH.toString(), transferredQty);
|
|
|
|
+ if (!(updateNum > 0)) throw new ServiceException("库存信息修改失败");
|
|
|
|
+ // 如果回库数量为0,只修改库存的locationId,和分配数量,不修改单据已搬运数量,也无需生成搬运任务
|
|
|
|
+ if (returningInventoryDTO.getTotalAmount().equals(BigDecimal.ZERO)) return;
|
|
|
|
+ soDocDetailsBaseDTO.setTransferredQty(String.valueOf(transferredQty));
|
|
|
|
+ bionutritionDocDetailsService.updateDocDetails(ConvertUtils.sourceToTarget(soDocDetailsBaseDTO, BionutritionDocDetailsDTO.class));
|
|
|
|
+
|
|
|
|
+ // 5.构建入库搬运任务DTO
|
|
|
|
+ AsnAgvCallDTO asnAgvCallDTO = new AsnAgvCallDTO();
|
|
|
|
+ asnAgvCallDTO.setSkuCode(soDocDetailsBaseDTO.getSkuCode());
|
|
|
|
+ asnAgvCallDTO.setQty(qty);
|
|
|
|
+ asnAgvCallDTO.setLocationFrom(returningInventoryDTO.getLocationFrom());
|
|
|
|
+ // 根据批次查询入库单据
|
|
|
|
+ List<BionutritionDocBaseDTO> docBaseDTOList = bionutritionDocHeaderService.getDicListByIds(Lists.newArrayList(invLotAtt.getLotatt09()));
|
|
|
|
+ Assert.isTrue(CollUtil.isNotEmpty(docBaseDTOList), "入库单据信息未找到");
|
|
|
|
+ BionutritionDocBaseDTO asnDocBaseDTO = docBaseDTOList.stream().findFirst().get();
|
|
|
|
+ BionutritionDocHeaderBaseDTO asnDocHeaderBaseDTO = asnDocBaseDTO.getBionutritionDocHeaderBaseDTO();
|
|
|
|
+ BionutritionDocDetailsBaseDTO asnDocDetailsBaseDTO = this.filterBionutritionDocDetailsBaseDTOByLineNo(invLotAtt.getLotatt10(), asnDocBaseDTO);
|
|
|
|
+ asnAgvCallDTO.setDocNo(asnDocHeaderBaseDTO.getDocNo());
|
|
|
|
+ asnAgvCallDTO.setLineNo(asnDocDetailsBaseDTO.getDocLineNo());
|
|
|
|
+ asnAgvCallDTO.setDocType(asnDocHeaderBaseDTO.getDocType());
|
|
|
|
+ asnAgvCallDTO.setStatus(invLotAtt.getLotatt05());
|
|
|
|
+ AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, asnDocHeaderBaseDTO, asnDocDetailsBaseDTO, returningInventoryDTO.getTotalAmount());
|
|
|
|
+ // 6.生成搬运任务
|
|
|
|
+ List<Long> flowIds = this.getFlowIdByDocTypeOrSkuType(asnDocHeaderBaseDTO.getDocType(), asnDocDetailsBaseDTO.getSkuCode());
|
|
|
|
+ List<FlowConfigHeaderVO> flowConfigHeaderVOList = flowConfigHeaderService.selectFlowConfigHeaderByIds(flowIds);
|
|
|
|
+ Long flowId = flowConfigHeaderVOList.stream().filter(f -> StringUtils.equals(Constant.BUSINESS_TYPE.ASN.getValue(), f.getFlowType()))
|
|
|
|
+ .map(FlowConfigHeaderVO::getId)
|
|
|
|
+ .findFirst().orElse(null);
|
|
|
|
+ businessService.agvCall(flowId, agvCallDTO);
|
|
|
|
+// throw new ServiceException("ddd");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据物料总量计算物料对应包装规格下的数量
|
|
|
|
+ * @param skuCode
|
|
|
|
+ * @param totalAmount
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private String getQtyBySpecs(String skuCode, BigDecimal totalAmount){
|
|
|
|
+ Assert.isTrue(ObjectUtil.isNotEmpty(totalAmount),"请填写回库物料总量");
|
|
|
|
+ // 根据物料编码查询物料信息
|
|
|
|
+ BaseSku baseSku = skuService.selectBaseSkuByCustomerId("default", skuCode);
|
|
|
|
+ Assert.isTrue(ObjectUtil.isNotEmpty(baseSku), "物料信息未找到");
|
|
|
|
+ String packagingSpecs = baseSku.getSkuPackagingSpecs();
|
|
|
|
+ if (StringUtils.isBlank(packagingSpecs)) String.valueOf(BigDecimal.ZERO);
|
|
|
|
+ // 提取规格中前面的数字
|
|
|
|
+ Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)?");
|
|
|
|
+ Matcher matcher = pattern.matcher(packagingSpecs.trim());
|
|
|
|
+ if (!matcher.find()) return String.valueOf(BigDecimal.ZERO);
|
|
|
|
+ String numStr = matcher.group();
|
|
|
|
+ BigDecimal c = new BigDecimal(numStr);
|
|
|
|
+ BigDecimal specs = c.stripTrailingZeros();
|
|
|
|
+ // 计算当前总量下对应的包装数量, 向上取整
|
|
|
|
+ BigDecimal qtyBigDecimal = totalAmount.divide(specs, BigDecimal.ROUND_CEILING);
|
|
|
|
+ return String.valueOf(qtyBigDecimal);
|
|
|
|
+ }
|
|
}
|
|
}
|