瀏覽代碼

出入库新增是否叫车选项

dfsfs 1 年之前
父節點
當前提交
3145b027c9
共有 18 個文件被更改,包括 255 次插入61 次删除
  1. 3 22
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/ams/InvLotLocIdController.java
  2. 13 2
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/doc/BionutritionDocHeaderController.java
  3. 2 0
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/BionutritionDocDetailsService.java
  4. 2 0
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/BionutritionDocHeaderService.java
  5. 15 3
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/impl/BionutritionDocDetailsServiceImpl.java
  6. 18 8
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/impl/BionutritionDocHeaderServiceImpl.java
  7. 5 0
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/AsnAgvCallDTO.java
  8. 29 2
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/DocQcDTO.java
  9. 1 1
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/QcIntoStorageDTO.java
  10. 9 0
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/IPdaAgvCallService.java
  11. 40 13
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/impl/PdaAgvCallServiceImpl.java
  12. 33 5
      warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/impl/PdaDocQcServiceImpl.java
  13. 1 0
      warewms-ams/src/main/java/com/ruoyi/ams/inv/domain/form/InvLocIdSearchFrom.java
  14. 14 1
      warewms-ams/src/main/java/com/ruoyi/ams/inv/domain/vo/InvLotLocIdLotattVO.java
  15. 8 3
      warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java
  16. 4 1
      warewms-ams/src/main/resources/mapper/ams/InvLotLocIdMapper.xml
  17. 57 0
      warewms-base/src/main/java/com/ruoyi/base/constant/type/BizEnum.java
  18. 1 0
      warewms-base/src/main/resources/mapper/base/BaseSkuMapper.xml

+ 3 - 22
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/ams/InvLotLocIdController.java

@@ -1,10 +1,8 @@
 package com.ruoyi.web.controller.warewms.ams;
 
-import cn.hutool.core.lang.Assert;
 import com.ruoyi.ams.inv.domain.InvLotLocId;
 import com.ruoyi.ams.inv.domain.form.InvLocIdSearchFrom;
 import com.ruoyi.ams.inv.domain.form.InvLotLocIdAdjForm;
-import com.ruoyi.ams.inv.domain.form.InvLotLocIdMoveForm;
 import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
 import com.ruoyi.ams.inv.dto.InvMoveDTO;
 import com.ruoyi.ams.inv.service.IInvLotLocIdService;
@@ -14,7 +12,6 @@ import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -69,22 +66,6 @@ public class InvLotLocIdController extends BaseController {
         return invLotLocIdService.adj(invLotLocIdAdjForm);
     }
 
-
-/*    @PreAuthorize("@ss.hasPermi('ams:invLotLocId:move')")
-    @Log(title = "库位库存移动", businessType = BusinessType.UPDATE)
-    @PostMapping("/move")
-    public AjaxResult move(@RequestBody InvLotLocIdMoveForm invLotLocIdMoveForm) {
-        invLotLocIdMoveForm.setUpdateBy(getUsername());
-        invLotLocIdMoveForm.setWarehouseId(Constant.WAREHOUSE_ID);
-        // 判断是否叫车
-        if (invLotLocIdMoveForm != null
-                && invLotLocIdMoveForm.getIsCallCar().equals(Constant.IS_YES.Y.getValue())) {
-            return invLotLocIdService.move(invLotLocIdMoveForm);
-        } else {
-            return invLotLocIdService.moveDirect(invLotLocIdMoveForm);
-        }
-    }*/
-
     /**
      * 库存移动
      */
@@ -140,9 +121,9 @@ public class InvLotLocIdController extends BaseController {
     @PreAuthorize("@ss.hasPermi('ams:invLotLocId:export')")
     @Log(title = "库位库存信息", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(HttpServletResponse response, InvLotLocId invLotLocId) {
-        List<InvLotLocId> list = invLotLocIdService.selectInvLotLocIdList(invLotLocId);
-        ExcelUtil<InvLotLocId> util = new ExcelUtil<InvLotLocId>(InvLotLocId.class);
+    public void export(HttpServletResponse response, InvLocIdSearchFrom invLocIdSearchFrom) {
+        List<InvLotLocIdLotattVO> list = invLotLocIdService.selectInvLocIdLotattList(invLocIdSearchFrom);
+        ExcelUtil<InvLotLocIdLotattVO> util = new ExcelUtil<InvLotLocIdLotattVO>(InvLotLocIdLotattVO.class);
         util.exportExcel(response, list, "库位库存信息数据");
     }
 

+ 13 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/doc/BionutritionDocHeaderController.java

@@ -99,11 +99,22 @@ public class BionutritionDocHeaderController extends BaseController {
     /********************************** 单据明细 *********************************************/
 
     /**
-     * 根据单号和单据类型获取单据信息
+     * 根据单号和单据类型获取单据信息(pda)
+     */
+    @PreAuthorize("@ss.hasPermi('docAsn:docAsn:query')")
+    @GetMapping("/getInfoPda")
+    public AjaxResult getInfoByDocNoAndDocTypePda(DocQueryDto docQueryDto)
+    {
+        List<BionutritionDocBaseDTO> docBaseDTOList = bionutritionDocDetailsService.selectDetailsByDocNoAndDocTypePda(docQueryDto.getDocNo(), docQueryDto.getDocType());
+        return AjaxResult.success(docBaseDTOList);
+    }
+
+    /**
+     * 根据单号和单据类型获取单据信息(web)
      */
     @PreAuthorize("@ss.hasPermi('docAsn:docAsn:query')")
     @GetMapping("/getInfo")
-    public AjaxResult getInfoByDocNoAndDocType(DocQueryDto docQueryDto)
+    public AjaxResult getInfoByDocNoAndDocTypeWeb(DocQueryDto docQueryDto)
     {
         List<BionutritionDocBaseDTO> docBaseDTOList = bionutritionDocDetailsService.selectDetailsByDocNoAndDocType(docQueryDto.getDocNo(), docQueryDto.getDocType());
         return AjaxResult.success(docBaseDTOList);

+ 2 - 0
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/BionutritionDocDetailsService.java

@@ -58,4 +58,6 @@ public interface BionutritionDocDetailsService extends CrudService<BionutritionD
     int deleteByHeaderIds(String[] ids);
 
     List<BionutritionDocBaseDTO> selectDetailsByDocNoAndDocType(String docNo, String docType);
+
+    List<BionutritionDocBaseDTO> selectDetailsByDocNoAndDocTypePda(String docNo, String docType);
 }

+ 2 - 0
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/BionutritionDocHeaderService.java

@@ -111,4 +111,6 @@ public interface BionutritionDocHeaderService extends CrudService<BionutritionDo
     List<BionutritionDocBaseDTO> buildBionutritionDocBaseDTOByIdList(String docNo, String docType);
 
     List<BionutritionDocBaseDTO> getSODocInfo();
+
+    String customFormatDocNo(String dateFormat, String docType);
 }

+ 15 - 3
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/impl/BionutritionDocDetailsServiceImpl.java

@@ -20,15 +20,14 @@ import com.ruoyi.ams.bionutrition.doc.service.BionutritionDocDetailsService;
 import com.ruoyi.ams.bionutrition.doc.service.BionutritionDocHeaderService;
 import com.ruoyi.base.constant.Constant;
 import com.ruoyi.base.constant.type.BizEnum;
+import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.utils.ConvertUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.service.impl.CrudServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -150,7 +149,20 @@ public class BionutritionDocDetailsServiceImpl extends CrudServiceImpl<Bionutrit
 
     @Override
     public List<BionutritionDocBaseDTO> selectDetailsByDocNoAndDocType(String docNo, String docType) {
+        return bionutritionDocHeaderService.buildBionutritionDocBaseDTOByIdList(docNo, docType);
+    }
+
+    @Override
+    public List<BionutritionDocBaseDTO> selectDetailsByDocNoAndDocTypePda(String docNo, String docType) {
         List<BionutritionDocBaseDTO> docBaseDTOList = bionutritionDocHeaderService.buildBionutritionDocBaseDTOByIdList(docNo, docType);
+        docBaseDTOList.stream().forEach(item->{
+            List<BionutritionDocDetailsBaseDTO> detailsBaseDTOList = item.getBionutritionDocDetailsBaseDTOList();
+            detailsBaseDTOList = detailsBaseDTOList.stream()
+                    .filter(details -> !StringUtils.equals(Constant.ASN_STS.STS40.getValue(), details.getLineStatus()))
+                    .filter(details -> !StringUtils.equals(Constant.ORDER_STS.STS20.getValue(), details.getLineStatus()))
+                    .collect(Collectors.toList());
+            item.setBionutritionDocDetailsBaseDTOList(detailsBaseDTOList);
+        });
         return docBaseDTOList;
     }
 

+ 18 - 8
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/doc/service/impl/BionutritionDocHeaderServiceImpl.java

@@ -62,6 +62,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -111,11 +112,28 @@ public class BionutritionDocHeaderServiceImpl extends CrudServiceImpl<Bionutriti
     @Override
     public String insertDocHeader(BionutritionDocHeaderDTO docHeaderDTO) {
         Assert.notNull(docHeaderDTO, "不允许插入空数据");
+        String docNo = this.customFormatDocNo("yyyyMMddHHmmssSSSSSSS", docHeaderDTO.getDocType());
+        docHeaderDTO.setDocNo(docNo);
         BionutritionDocHeader docHeader = ConvertUtils.sourceToTarget(docHeaderDTO, BionutritionDocHeader.class);
         int result = baseDao.insert(docHeader);
         return result > 0 ? docHeader.getId() : String.valueOf(result);
     }
 
+    /**
+     * 根据单据类型生成单号
+     * @param dateFormat
+     * @return
+     */
+    public String customFormatDocNo(String dateFormat, String docType) {
+        BizEnum.DocTypeBusinessTypeEnum[] businessTypeEnums = BizEnum.DocTypeBusinessTypeEnum.values();
+        BizEnum.DocTypeBusinessTypeEnum businessTypeEnum = Arrays.stream(businessTypeEnums).filter(item -> StringUtils.equals(item.getDocType(), docType)).findFirst().orElse(null);
+        Assert.isTrue(ObjectUtil.isNotEmpty(businessTypeEnum), "未找到对应单据类型");
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
+        Date date = new Date();
+        String str = simpleDateFormat.format(date);
+        return businessTypeEnum.getBusinessType() + str;
+    }
+
     /**
      * 修改单据头
      *
@@ -707,14 +725,6 @@ public class BionutritionDocHeaderServiceImpl extends CrudServiceImpl<Bionutriti
                 , bionutritionDocHeaderBaseDTO.getDocStatus(), docDetails.getLineStatus());
     }
 
-    public static void main(String[] args) {
-        BigDecimal sub = NumberUtil.sub("35", "26");
-        // 需搬运数量大于已搬运数量,设置单据为部分入库,否则为全部入库
-        boolean b = sub.compareTo(BigDecimal.ZERO) > 0;
-        System.out.println(b);
-
-    }
-
     /**
      * 比较单据的一条明细已生成任务的搬运总数量和明细需要搬运总数量大小
      * @param wcsTask

+ 5 - 0
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/AsnAgvCallDTO.java

@@ -59,6 +59,11 @@ public class AsnAgvCallDTO implements Serializable {
      */
     private String ifSample;
 
+    /**
+     * 是否叫车 Y:叫车 N:不叫车
+     */
+    private String ifCallCar;
+
     /**
      * 操作人
      */

+ 29 - 2
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/DocQcDTO.java

@@ -1,15 +1,17 @@
 package com.ruoyi.ams.bionutrition.dto;
 
 import lombok.Data;
+import org.jetbrains.annotations.NotNull;
 
 import javax.validation.constraints.NotBlank;
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 /**
  * 单据质检参数对象
  */
 @Data
-public class DocQcDTO implements Serializable {
+public class DocQcDTO implements Serializable{
 
     private static final long serialVersionUID = -35010226008676367L;
 
@@ -20,7 +22,7 @@ public class DocQcDTO implements Serializable {
     private String skuCode;
     /**
      * 批次状态
-     * HG:合格 BHG:不合格 DJ:待检 FX:放行{@link com.ruoyi.base.constant.Constant.QUALITY_STATUS}
+     * HG:合格 BHG:不合格 DJ:待检{@link com.ruoyi.base.constant.Constant.QUALITY_STATUS}
      */
     @NotBlank(message = "状态不能为空")
     private String status;
@@ -34,5 +36,30 @@ public class DocQcDTO implements Serializable {
      */
     private String docNo;
 
+    /**
+     * 数量
+     */
+    private String qty;
+
+    /**
+     * 件数
+     */
+    private String packagesNumber;
+
+    // 、规格、计量单位、批号、数量、件数。
+    /**
+     * 物料名称
+     */
+    private String skuName;
+    /**
+     * 包装规格
+     */
+    private String skuPackagingSpecs;
+    /**
+     * 计量单位
+     */
+    private String skuUom;
+
     private String user;
+
 }

+ 1 - 1
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/dto/QcIntoStorageDTO.java

@@ -33,7 +33,7 @@ public class QcIntoStorageDTO implements Serializable {
     private BigDecimal totalAmount;
     /**
      * 批次状态
-     * HG:合格 BHG:不合格 DJ:待检 FX:放行{@link com.ruoyi.base.constant.Constant.QUALITY_STATUS}
+     * HG:合格 BHG:不合格 DJ:待检{@link com.ruoyi.base.constant.Constant.QUALITY_STATUS}
      */
     @NotBlank(message = "状态不能为空")
     private String status;

+ 9 - 0
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/IPdaAgvCallService.java

@@ -11,6 +11,7 @@ import com.ruoyi.ams.config.domain.dto.AgvCallDTO;
 import com.ruoyi.ams.config.domain.dto.LotattDTO;
 import com.ruoyi.base.domain.BaseSku;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -52,4 +53,12 @@ public interface IPdaAgvCallService {
      * @param returningInventoryDTO
      */
     void returningToInventory(ReturningInventoryDTO returningInventoryDTO);
+
+    /**
+     * 根据物料编码和数量计算件数
+     * @param skuCode
+     * @param totalAmount
+     * @return
+     */
+    String getQtyBySpecs(String skuCode, BigDecimal totalAmount);
 }

+ 40 - 13
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/impl/PdaAgvCallServiceImpl.java

@@ -43,7 +43,9 @@ 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.type.BizEnum;
+import com.ruoyi.base.domain.BaseLocationInfo;
 import com.ruoyi.base.domain.BaseSku;
+import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.base.service.IBaseSkuService;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.base.EnumUtils;
@@ -88,6 +90,8 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
     private IInvLotLocIdService invLotLocIdService;
     @Autowired
     private IInvLotAttService invLotAttService;
+    @Autowired
+    private IBaseLocationInfoService baseLocationInfoService;
 
     /**
      * 根据单号和单据类型生成入库任务
@@ -121,17 +125,40 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
         if (StringUtils.equals(docType, BizEnum.BionutritionExcelDocTitleEnum.PURCHASE_ORDER.getDocType())) {
             this.addPurchaseReceiptDoc(bionutritionDocBaseDTO, docDetailsBaseDTO, asnAgvCallDTO);
         }
-        // 4.获取配置信息单据类型或物料类型对应流程id
+        // 4.生成agv呼叫对象
+        AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, bionutritionDocHeaderBaseDTO, docDetailsBaseDTO);
+        // 如果不叫车,只需生成库存,锁定库位
+        if (StringUtils.equals(asnAgvCallDTO.getIfCallCar(), Constant.IS_YES.N.name())) {
+            this.initInventoryWithOutCallCar(asnAgvCallDTO, agvCallDTO);
+            return;
+        }
+        // 5.获取配置信息单据类型或物料类型对应流程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任务
-        AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, bionutritionDocHeaderBaseDTO, docDetailsBaseDTO, null);
+        // 6.生成对应wcs任务
         businessService.agvCall(flowId, agvCallDTO);
     }
 
+    /**
+     * 不呼叫车,直接生成库存
+     * @param asnAgvCallDTO
+     * @param agvCallDTO
+     */
+    private void initInventoryWithOutCallCar(AsnAgvCallDTO asnAgvCallDTO, AgvCallDTO agvCallDTO) {
+        BaseLocationInfo locationFrom = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(asnAgvCallDTO.getLocationFrom()));
+        Assert.isTrue(ObjectUtil.isNotEmpty(locationFrom), "未找到对应库位信息");
+        Assert.isTrue(StringUtils.equals(locationFrom.getStockStatus(), Constant.STOCK_STATUS.STOCK00.getValue()), "入库起始点位不是空闲状态");
+        // 初始化库存
+        // 删除起始点库存
+        invLotLocIdService.deleteInvLotLocIdById(locationFrom.getId());
+        // 添加批次和库存信息
+        invLotLocIdService.initInv(locationFrom.getId().toString(), agvCallDTO);
+        baseLocationInfoService.updateLocationStockStatus(Long.parseLong(asnAgvCallDTO.getLocationFrom()), Constant.STOCK_STATUS.STOCK10.getValue());
+    }
+
     /**
      * 根据明细行号筛选明细
      * @param lineNo
@@ -229,12 +256,11 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
         /*long qty = docDetailsBaseDTOList.stream().filter(item -> StringUtils.isNotBlank(item.getSkuQty()))
                 .mapToLong(item -> Long.parseLong(item.getSkuQty())).sum();*/
         // 判断已搬运的数量加上当前搬运数量是否小于采购单对应明细的总数量
-        long qty = StrUtil.isBlank(docDetailsBaseDTO.getTransferredQty()) ? 0 : Long.valueOf(docDetailsBaseDTO.getTransferredQty());
-        long qtySupposed = Long.parseLong(docDetailsBaseDTO.getSkuQty());
-        long qtyRemain = qtySupposed - qty;
-        boolean ifLessEqualQty = qty <= qtySupposed;
+        BigDecimal qtyTransferred = StrUtil.isBlank(docDetailsBaseDTO.getTransferredQty()) ? BigDecimal.ZERO : new BigDecimal(docDetailsBaseDTO.getTransferredQty());
+        BigDecimal qtySupposed = new BigDecimal(docDetailsBaseDTO.getSkuQty());
+        BigDecimal qtyRemain = qtySupposed.subtract(qtyTransferred);
         log.info("当前搬运数量{},剩余未搬运数量{}",asnAgvCallDTO.getQty(), qtyRemain);
-        Assert.isTrue(ifLessEqualQty, "搬运数量超出范围,剩余数量为"+qtyRemain);
+        Assert.isTrue(NumberUtil.isLessOrEqual(qtyTransferred, qtySupposed), "搬运数量超出范围,剩余数量为"+qtyRemain);
     }
 
     /**
@@ -242,7 +268,7 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
      * @param asnAgvCallDTO
      * @return
      */
-    private AgvCallDTO getASNAgvCallDTO(AsnAgvCallDTO asnAgvCallDTO, BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO, BigDecimal totalAmount) {
+    private AgvCallDTO getASNAgvCallDTO(AsnAgvCallDTO asnAgvCallDTO, BionutritionDocHeaderBaseDTO docHeaderBaseDTO, BionutritionDocDetailsBaseDTO docDetailsBaseDTO) {
         DocLotattDTO docLotattDTO = ConvertUtils.sourceToTarget(docDetailsBaseDTO, DocLotattDTO.class);
         // 根据物料编码查询物料信息
         BaseSku baseSku = skuService.selectBaseSkuByCustomerId(Constants.DEFAULT_CUSTOMER_ID, asnAgvCallDTO.getSkuCode());
@@ -255,8 +281,8 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
         agvCallItemDTO.setSku(asnAgvCallDTO.getSkuCode());
         agvCallItemDTO.setQty(Double.valueOf(asnAgvCallDTO.getQty()));
         // 计算一托盘总量
-        if (ObjectUtil.isEmpty(totalAmount)) totalAmount = this.buildTotalAmount(baseSku, asnAgvCallDTO.getQty());
-        agvCallItemDTO.setTotalAmount(totalAmount);
+//        if (ObjectUtil.isEmpty(totalAmount)) totalAmount = this.buildTotalAmount(baseSku, asnAgvCallDTO.getQty());
+//        agvCallItemDTO.setTotalAmount(totalAmount);
         agvCallItemDTO.setLotattDTO(lotattDTO);
         agvCallItemDTOList.add(agvCallItemDTO);
         AgvCallDTO agvCallDTO = new AgvCallDTO();
@@ -406,7 +432,8 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
         asnAgvCallDTO.setLineNo(asnDocDetailsBaseDTO.getDocLineNo());
         asnAgvCallDTO.setDocType(asnDocHeaderBaseDTO.getDocType());
         asnAgvCallDTO.setStatus(invLotAtt.getLotatt05());
-        AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, asnDocHeaderBaseDTO, asnDocDetailsBaseDTO, returningInventoryDTO.getTotalAmount());
+        asnAgvCallDTO.setIfSample(invLotLocId.getIfSample());
+        AgvCallDTO agvCallDTO = this.getASNAgvCallDTO(asnAgvCallDTO, asnDocHeaderBaseDTO, asnDocDetailsBaseDTO);
         // 6.生成搬运任务
         List<Long> flowIds = this.getFlowIdByDocTypeOrSkuType(asnDocHeaderBaseDTO.getDocType(), asnDocDetailsBaseDTO.getSkuCode());
         List<FlowConfigHeaderVO> flowConfigHeaderVOList = flowConfigHeaderService.selectFlowConfigHeaderByIds(flowIds);
@@ -423,7 +450,7 @@ public class PdaAgvCallServiceImpl implements IPdaAgvCallService {
      * @param totalAmount
      * @return
      */
-    private String getQtyBySpecs(String skuCode, BigDecimal totalAmount){
+    public String getQtyBySpecs(String skuCode, BigDecimal totalAmount){
         Assert.isTrue(ObjectUtil.isNotEmpty(totalAmount),"请填写回库物料总量");
         // 根据物料编码查询物料信息
         BaseSku baseSku = skuService.selectBaseSkuByCustomerId("default", skuCode);

+ 33 - 5
warewms-ams/src/main/java/com/ruoyi/ams/bionutrition/pda/impl/PdaDocQcServiceImpl.java

@@ -15,6 +15,7 @@ import com.ruoyi.ams.bionutrition.doc.service.BionutritionDocHeaderService;
 import com.ruoyi.ams.bionutrition.dto.DocQcDTO;
 import com.ruoyi.ams.bionutrition.dto.QcIntoStorageDTO;
 import com.ruoyi.ams.bionutrition.dto.QcOutboundDTO;
+import com.ruoyi.ams.bionutrition.pda.IPdaAgvCallService;
 import com.ruoyi.ams.bionutrition.pda.IPdaDocQcService;
 import com.ruoyi.ams.bionutrition.sku.service.ISkuService;
 import com.ruoyi.ams.business.IBusinessService;
@@ -42,10 +43,12 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Slf4j
 @Service
@@ -65,6 +68,8 @@ public class PdaDocQcServiceImpl implements IPdaDocQcService {
     private BionutritionDocDetailsService bionutritionDocDetailsService;
     @Autowired
     private IBaseSkuService baseSkuService;
+    @Autowired
+    private IPdaAgvCallService pdaAgvCallService;
 
     /**
      * PDA质检
@@ -154,7 +159,7 @@ public class PdaDocQcServiceImpl implements IPdaDocQcService {
     public List<DocQcDTO> getQcList(String sku) {
         //1.查出所有状态为40的明细 List<Details>
         List<BionutritionDocDetailsDTO> docDetailsDTOList = bionutritionDocDetailsService.getBionutritionDocDetailsDTOListByLineStatus(Constant.ASN_STS.STS40.getValue());
-        Assert.isTrue(CollUtil.isNotEmpty(docDetailsDTOList), "没有状态为上架的信息");
+        Assert.isTrue(CollUtil.isNotEmpty(docDetailsDTOList), "未匹配到完全入库的单据信息");
         //2. 查出单据 List<Header>
         List<String> headerIdList = docDetailsDTOList.stream().filter(item->StringUtils.isNotBlank(item.getDocHeaderId()))
                 .map(BionutritionDocDetailsDTO::getDocHeaderId).collect(Collectors.toList());
@@ -168,11 +173,29 @@ public class PdaDocQcServiceImpl implements IPdaDocQcService {
         Assert.isTrue(CollUtil.isNotEmpty(invLotAttList), " 对应批次未找到");
         List<String> lotNumList = invLotAttList.stream().map(InvLotAtt::getLotnum).collect(Collectors.toList());
         List<InvLotLocId> invLotLocIds = invLotLocIdService.selectInvLotLocIdByLotnumList(lotNumList);
-
-        //对每一个库存: 找到对应的批次 根据批次的lot10 找到对应的明细
+        // 5.根据lotatt02分组,计算同一批号的库存数量
         List<String> lotNumListHasLoc = invLotLocIds.stream().map(InvLotLocId::getLotnum).distinct().collect(Collectors.toList());
-        // 所有状态为40的明细行号
+        // 过滤出有库存的且是合格状态的批次信息,然后按照批号分组
+        Map<String, List<InvLotAtt>> invLotAttListMap = invLotAttList.stream()
+                .filter(item -> CollUtil.contains(lotNumListHasLoc, item.getLotnum()))
+                .filter(item->StringUtils.equals(item.getLotatt05(), Constant.QUALITY_STATUS.HG.getValue()))
+                .collect(Collectors.groupingBy(InvLotAtt::getLotatt02));
+        // 找出分组后的每组批次对应的库存, 过滤掉所有已出库的库存
+        Map<String, List<InvLotLocId>> invLotLocIdListMap = invLotAttListMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, item -> {
+            List<String> lotNumGroupList = item.getValue().stream().map(InvLotAtt::getLotnum).collect(Collectors.toList());
+            return invLotLocIds.stream().filter(invId -> CollUtil.contains(lotNumGroupList, invId.getLotnum()))
+                    .filter(invId -> !StringUtils.equals(invId.getLocationId(), Constant.LOC_SORTATION_FINISH.toString()))
+                    .collect(Collectors.toList());
+        }));
+        // 计算每组库存的所有数量
+        Map<String, BigDecimal> lotNumQtyMap = invLotLocIdListMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, item -> {
+            List<InvLotLocId> invLotLocIdList = item.getValue();
+            return invLotLocIdList.stream().map(InvLotLocId::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }));
+        // 6.构建质检/出库库存列表
         List<String> lineNoList = docDetailsDTOList.stream().map(item -> item.getDocLineNo()).collect(Collectors.toList());
+        List<BaseSku> baseSkuList = baseSkuService.selectBaseSkuList(new BaseSku());
+        Map<String, BaseSku> skuMap = baseSkuList.stream().collect(Collectors.toMap(BaseSku::getSku, item -> item));
         List<DocQcDTO> docQcDTOList = invLotAttList.stream().filter(item -> CollUtil.contains(lotNumListHasLoc, item.getLotnum()))
                 .filter(item -> CollUtil.contains(lineNoList, item.getLotatt10()))
                 .filter(item->StringUtils.equals(item.getLotatt05(), Constant.QUALITY_STATUS.HG.getValue()))
@@ -180,8 +203,13 @@ public class PdaDocQcServiceImpl implements IPdaDocQcService {
                     DocQcDTO docQcDTO = new DocQcDTO();
                     docQcDTO.setBatchNumber(item.getLotatt02());
                     docQcDTO.setSkuCode(item.getSku());
+                    docQcDTO.setSkuName(skuMap.get(item.getSku()).getSkuName());
+                    docQcDTO.setSkuPackagingSpecs(skuMap.get(item.getSku()).getSkuPackagingSpecs());
+                    docQcDTO.setSkuUom(skuMap.get(item.getSku()).getSkuUom());
                     docQcDTO.setDocNo(map.get(item.getLotatt09()));
                     docQcDTO.setStatus(item.getLotatt05());
+                    docQcDTO.setQty(String.valueOf(lotNumQtyMap.get(item.getLotatt02())));
+                    docQcDTO.setPackagesNumber(pdaAgvCallService.getQtyBySpecs(item.getSku(), new BigDecimal(docQcDTO.getQty())));
                     return docQcDTO;
                 }).distinct().collect(Collectors.toList());
 //        invLotAttService.selectInvLotAttByLotnum()
@@ -255,7 +283,7 @@ public class PdaDocQcServiceImpl implements IPdaDocQcService {
             }
         }
         // 如果质量状态是放行 无需生成搬运任务
-        if (StringUtils.equals(qcIntoStorageDTO.getStatus(), Constant.QUALITY_STATUS.FX.getValue())) return;
+        //if (StringUtils.equals(qcIntoStorageDTO.getStatus(), Constant.QUALITY_STATUS.FX.getValue())) return;
         // 2.更新对应库位库存物料总量
         List<InvLotLocId> invLotLocIdList = invLotLocIdService.selectInvLotLocIdList(Long.parseLong(qcIntoStorageDTO.getLocationFrom()));
         Assert.isTrue(CollUtil.isNotEmpty(invLotLocIdList), "质检入库起始点库存未找到");

+ 1 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/domain/form/InvLocIdSearchFrom.java

@@ -12,6 +12,7 @@ import lombok.Data;
 @Data
 public class InvLocIdSearchFrom {
     private String sku;
+    private String skuName;
     private String zoneId;
     private String locationNo;
     private String isFull;

+ 14 - 1
warewms-ams/src/main/java/com/ruoyi/ams/inv/domain/vo/InvLotLocIdLotattVO.java

@@ -1,5 +1,6 @@
 package com.ruoyi.ams.inv.domain.vo;
 
+import com.ruoyi.common.annotation.Excel;
 import lombok.Data;
 
 /**
@@ -12,18 +13,30 @@ public class InvLotLocIdLotattVO {
     private Long locationId;
     private String lotnum;
     private String customerId;
+    @Excel(name = "物料编码", sort = 2)
     private String sku;
+    @Excel(name = "物料名称", sort = 3)
     private String skuName;
+    @Excel(name = "存货编码", sort = 1)
+    private String inventoryCode;
+    @Excel(name = "包装规格", sort = 4)
+    private String skuPackagingSpecs;
+    @Excel(name = "计量单位", sort = 5)
+    private String skuUom;
+    @Excel(name = "件数", sort = 8)
+    private String packagesNumber;
+    @Excel(name = "数量", sort = 7)
+    private Double qty;
     private String skuTypeName;
     private String locationNo;
     private String zoneName;
-    private Double qty;
     private Double qtyallocated;
     private Double weight;
     private String palletNo;
     private String isFull;
     private String isExpire;
     private String lotatt01;
+    @Excel(name = "批号", sort = 6)
     private String lotatt02;
     private String lotatt03;
     private String lotatt04;

+ 8 - 3
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java

@@ -7,6 +7,7 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.ruoyi.ams.bionutrition.pda.IPdaAgvCallService;
 import com.ruoyi.ams.box.domain.WmsBoxInfo;
 import com.ruoyi.ams.box.service.IWmsBoxInfoService;
 import com.ruoyi.ams.business.IBusinessService;
@@ -73,6 +74,8 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
     private IBusinessService iBusinessService;
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private IPdaAgvCallService pdaAgvCallService;
 
     /**
      * 查询库位库存信息
@@ -131,7 +134,9 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
 
     @Override
     public List<InvLotLocIdLotattVO> selectInvLocIdLotattList(InvLocIdSearchFrom invLocIdSearchFrom) {
-        return invLotLocIdMapper.selectInvLocIdLotattList(invLocIdSearchFrom);
+        List<InvLotLocIdLotattVO> invLotLocIdLotattVOS = invLotLocIdMapper.selectInvLocIdLotattList(invLocIdSearchFrom);
+        invLotLocIdLotattVOS.stream().forEach(item->item.setPackagesNumber(pdaAgvCallService.getQtyBySpecs(item.getSku(), BigDecimal.valueOf(item.getQty()))));
+        return invLotLocIdLotattVOS;
     }
 
     /**
@@ -567,7 +572,7 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
             invLotLocId.setSku(sku);
             invLotLocId.setCustomerId(customerId);
             invLotLocId.setQty(new BigDecimal(qty));
-            invLotLocId.setTotalAmount(agvCallItemDTO.getTotalAmount());
+//            invLotLocId.setTotalAmount(agvCallItemDTO.getTotalAmount());
             invLotLocId.setIfSample(Constant.IS_YES.N.name());
             invLotLocId.setIsExpire(Constant.EXPIRE_STATUS.UNEXPIRED.getValue());
             invLotLocId.setCreateTime(new Date());
@@ -746,7 +751,7 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         lotattVOList = lotattVOList.stream().filter(
                 item->!StringUtils.equals(item.getIsExpire(), Constant.EXPIRE_STATUS.EXPIRED.getValue()))
                 .collect(Collectors.toList());
-        return lotattVOList.stream().allMatch(v -> !v.getLotatt05().equals("FX"));
+        return lotattVOList.stream().allMatch(v -> !v.getLotatt05().equals("HG"));
     }
 
     @Override

+ 4 - 1
warewms-ams/src/main/resources/mapper/ams/InvLotLocIdMapper.xml

@@ -37,6 +37,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="customerId"    column="customer_id"    />
         <result property="sku"    column="sku"    />
         <result property="skuName"    column="sku_name"    />
+        <result property="inventoryCode"    column="inventory_code"    />
+        <result property="skuPackagingSpecs"    column="sku_packaging_specs"    />
         <result property="skuTypeName"    column="item_name"    />
         <result property="qty"    column="qty"    />
         <result property="qtyallocated"    column="qtyallocated"    />
@@ -132,6 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="locationId != null  and locationId != ''"> and location_id = #{locationId}</if>
             <if test="customerId != null  and customerId != ''"> and customer_id = #{customerId}</if>
             <if test="sku != null  and sku != ''"> and sku = #{sku}</if>
+            <if test="skuName != null  and skuName != ''"> and sku_name = #{skuName}</if>
             <if test="lotnum != null  and lotnum != ''"> and lotnum = #{lotnum}</if>
             <if test="traceid != null  and traceid != ''"> and traceid = #{traceid}</if>
         </where>
@@ -344,7 +347,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectInvLocIdLotattList" resultMap="InvLotLocIdLotattResult">
         select
         inv.*,
-        att.lotnum, att.customer_id,z.zone_name, sk.sku_name, skt.item_name
+        att.lotnum, att.customer_id,z.zone_name, sk.sku_name, sk.inventory_code, sk.sku_packaging_specs, skt.item_name
         ,lotatt01, lotatt02, lotatt03, lotatt04,lotatt05, lotatt06
         ,lotatt07, lotatt08, lotatt09, lotatt10, lotatt11, lotatt12, lotatt13, lotatt14, lotatt15, lotatt16, lotatt17
         ,lotatt18

+ 57 - 0
warewms-base/src/main/java/com/ruoyi/base/constant/type/BizEnum.java

@@ -345,6 +345,63 @@ public class BizEnum {
 
     }
 
+    /**
+     * 单据类型, 类型对应单据头指向类
+     */
+    public enum DocTypeBusinessTypeEnum implements IBaseEnum {
+        /**
+         * 成品入库单
+         */
+        FINISHED_PRODUCT_RECEIPT("FinishedProductReceipt", "ASN"),
+        /**
+         * 生产领料单
+         */
+        PRODUCTION_PICKING_RECEIPT("ProductionPickingReceipt", "SO"),
+        /**
+         * 生产退库单
+         */
+        PRODUCTION_RETURN_ORDER("ProductionReturnOrder", "ASN"),
+        /**
+         * 采购收货单
+         */
+        PURCHASE_RECEIPT("PurchaseReceipt", "ASN"),
+        /**
+         * 销售出库单
+         */
+        SALE_OUTBOUND_ORDER("SaleOutboundOrder", "SO"),
+        /**
+         * 销售退库单
+         */
+        SALE_RETURN_ORDER("SaleReturnOrder", "ASN"),
+        /**
+         * 采购单
+         */
+        PURCHASE_ORDER("PurchaseOrder","PO");
+
+        private String docType;
+
+        private String businessType;
+
+        DocTypeBusinessTypeEnum(String docType, String businessType) {
+            this.docType = docType;
+            this.businessType = businessType;
+        }
+
+        public String getBusinessType() {
+            return businessType;
+        }
+
+        public String getDocType() {
+            return docType;
+        }
+
+        @Override
+        public String getCode() {
+            return getDocType();
+        }
+
+    }
+
 
 
 }

+ 1 - 0
warewms-base/src/main/resources/mapper/base/BaseSkuMapper.xml

@@ -67,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <where>
             <if test="skuCustomerId != null  and skuCustomerId != ''"> and b.sku_customer_id = #{skuCustomerId}</if>
             <if test="sku != null  and sku != ''"> and b.sku like concat('%', #{sku}, '%')</if>
+            <if test="skuName != null  and skuName != ''"> and b.sku_name like concat('%', #{skuName}, '%')</if>
             <if test="skuType != null"> and b.sku_type = #{skuType}</if>
             <if test="skuStatus != null  and skuStatus != ''"> and b.sku_status = #{skuStatus}</if>
         </where>