zhangxin преди 1 година
родител
ревизия
0c5c0c7ae9
променени са 18 файла, в които са добавени 674 реда и са изтрити 16 реда
  1. 26 1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/pda/PdaController.java
  2. 103 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/wms/order/PalletMatchLogController.java
  3. 22 0
      warewms-ams/src/main/java/com/ruoyi/ams/inv/dto/InvLotAttPalletTotalDTO.java
  4. 3 1
      warewms-ams/src/main/java/com/ruoyi/ams/inv/mapper/InvLotAttMapper.java
  5. 10 0
      warewms-ams/src/main/java/com/ruoyi/ams/inv/service/IInvLotAttService.java
  6. 46 1
      warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotAttServiceImpl.java
  7. 202 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/domain/PalletMatchLog.java
  8. 23 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/PalletMatchLogMapper.java
  9. 2 1
      warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/WmsDocOrderDetailsMapper.java
  10. 2 1
      warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/WmsDocOrderHeaderMapper.java
  11. 31 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/IPalletMatchLogService.java
  12. 7 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/IWmsDocOrderDetailsService.java
  13. 9 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/IWmsDocOrderHeaderService.java
  14. 45 0
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/PalletMatchLogServiceImpl.java
  15. 11 1
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/WmsDocOrderDetailsServiceImpl.java
  16. 82 7
      warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/WmsDocOrderHeaderServiceImpl.java
  17. 2 3
      warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java
  18. 48 0
      warewms-ams/src/main/resources/mapper/docOrder/PalletMatchLogMapper.xml

+ 26 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/pda/PdaController.java

@@ -430,7 +430,7 @@ public class PdaController {
     }
 
     //endregion
-
+    /**********************************************托盘分配出库*****************************************************/
     //region PDA出库
 
     /**
@@ -521,6 +521,31 @@ public class PdaController {
         return AjaxResult.success("任务下发成功!");
     }
 
+    /*************************************************托盘匹配出库**********************************************************/
+
+    /**
+     * 出库单库存匹配
+     * @param orderNos
+     * @return
+     */
+    @PostMapping("/docOrder/inventoryMatching")
+    public AjaxResult inventoryMatch(@RequestParam String orderNos) {
+        List<String> orderList = JSONArray.parseArray(orderNos, String.class);
+        return AjaxResult.success(wmsDocOrderHeaderService.inventoryMatch(orderList));
+    }
+
+    /**
+     * 出库单库存反馈
+     * @param orderNos
+     * @return
+     */
+    @GetMapping("/docOrder/queryPalletMatchInfoList")
+    public AjaxResult queryPalletMatchInfoList(@RequestParam String orderNos) {
+        return AjaxResult.success(wmsDocOrderHeaderService.queryPalletMatchInfoList(orderNos));
+    }
+
+
+
     /**
      * 分拣出库
      *

+ 103 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/wms/order/PalletMatchLogController.java

@@ -0,0 +1,103 @@
+package com.ruoyi.web.controller.warewms.wms.order;
+
+import com.ruoyi.ams.order.domain.PalletMatchLog;
+import com.ruoyi.ams.order.service.IPalletMatchLogService;
+import com.ruoyi.common.annotation.Log;
+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.DateUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 托盘匹配记录Controller
+ * 
+ * @author ruoyi
+ * @date 2023-08-23
+ */
+@RestController
+@RequestMapping("/order/pallet")
+public class PalletMatchLogController extends BaseController
+{
+    @Autowired
+    private IPalletMatchLogService palletMatchLogService;
+
+    /**
+     * 查询托盘匹配记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(PalletMatchLog palletMatchLog)
+    {
+        startPage();
+        List<PalletMatchLog> list = palletMatchLogService.selectPalletMatchLogList(palletMatchLog);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出托盘匹配记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:export')")
+    @Log(title = "托盘匹配记录", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, PalletMatchLog palletMatchLog)
+    {
+        List<PalletMatchLog> list = palletMatchLogService.selectPalletMatchLogList(palletMatchLog);
+        ExcelUtil<PalletMatchLog> util = new ExcelUtil<PalletMatchLog>(PalletMatchLog.class);
+        util.exportExcel(response, list, "托盘匹配记录数据");
+    }
+
+    /**
+     * 获取托盘匹配记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(palletMatchLogService.selectById(id));
+    }
+
+    /**
+     * 新增托盘匹配记录
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:add')")
+    @Log(title = "托盘匹配记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody PalletMatchLog palletMatchLog)
+    {
+        palletMatchLog.setCreateTime(DateUtils.getNowDate());
+        return toAjax(palletMatchLogService.insert(palletMatchLog));
+    }
+
+    /**
+     * 修改托盘匹配记录
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:edit')")
+    @Log(title = "托盘匹配记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody PalletMatchLog palletMatchLog)
+    {
+        palletMatchLog.setUpdateTime(DateUtils.getNowDate());
+        return toAjax(palletMatchLogService.updateById(palletMatchLog));
+    }
+
+    /**
+     * 删除托盘匹配记录
+     */
+    @PreAuthorize("@ss.hasPermi('order:pallet:remove')")
+    @Log(title = "托盘匹配记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(palletMatchLogService.deleteBatchIds(Arrays.stream(ids).collect(Collectors.toList())));
+    }
+}

+ 22 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/dto/InvLotAttPalletTotalDTO.java

@@ -0,0 +1,22 @@
+package com.ruoyi.ams.inv.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class InvLotAttPalletTotalDTO implements Serializable {
+    private static final long serialVersionUID = -1856279805338688093L;
+
+    @ApiModelProperty("产品")
+    private String sku;
+
+    @ApiModelProperty("托盘")
+    private String palletNo;
+
+    @ApiModelProperty("托盘sku总数量")
+    private BigDecimal totalQty;
+}

+ 3 - 1
warewms-ams/src/main/java/com/ruoyi/ams/inv/mapper/InvLotAttMapper.java

@@ -1,6 +1,8 @@
 package com.ruoyi.ams.inv.mapper;
 
 import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.ams.inv.domain.InvLotAtt;
 
 /**
@@ -9,7 +11,7 @@ import com.ruoyi.ams.inv.domain.InvLotAtt;
  * @author andy
  * @date 2022-03-09
  */
-public interface InvLotAttMapper
+public interface InvLotAttMapper extends BaseMapper<InvLotAtt>
 {
     /**
      * 查询批次属性

+ 10 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/IInvLotAttService.java

@@ -1,7 +1,10 @@
 package com.ruoyi.ams.inv.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.ruoyi.ams.inv.domain.InvLotAtt;
+import com.ruoyi.ams.inv.dto.InvLotAttPalletTotalDTO;
 
 /**
  * 批次属性Service接口
@@ -72,4 +75,11 @@ public interface IInvLotAttService
      * 根据入库单号查询当前入库单内的成品批次列表
      */
     List<InvLotAtt> queryAttributesByAsnno(String asnNo);
+
+    /**
+     * 根据多sku获取不同sku各托盘上总数(根据托盘所关联批次数量计算产品数量,只限产品!!! 物料需联表库位库存表获取总数!!!)
+     * @param skuList
+     * @return
+     */
+    Map<String, List<InvLotAttPalletTotalDTO>> buildInvLotAttPalletTotalMap(List<String> skuList);
 }

+ 46 - 1
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotAttServiceImpl.java

@@ -1,8 +1,14 @@
 package com.ruoyi.ams.inv.service.impl;
 
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.ams.inv.dto.InvLotAttPalletTotalDTO;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.ams.inv.mapper.InvLotAttMapper;
@@ -104,4 +110,43 @@ public class InvLotAttServiceImpl implements IInvLotAttService {
     public List<InvLotAtt> queryAttributesByAsnno(String asnNo) {
         return invLotAttMapper.selectAttributesByAsnno(asnNo);
     }
+
+    /**
+     * 根据多sku获取不同sku各托盘上总数(根据托盘所关联批次数量计算产品数量,只限产品!!! 物料需联表库位库存表获取总数!!!)
+     * @param skuList
+     * @return
+     */
+    @Override
+    public Map<String, List<InvLotAttPalletTotalDTO>> buildInvLotAttPalletTotalMap(List<String> skuList){
+        List<InvLotAtt> invLotAttList = queryInvLotAttBySkuList(skuList);
+        if (CollectionUtil.isEmpty(invLotAttList)) {
+            return new HashMap<>();
+        }
+        Map<String, List<InvLotAttPalletTotalDTO>> result = new HashMap<>();
+        //根据sku对批次分类
+        Map<String, List<InvLotAtt>> skuInvLotAttMap = invLotAttList.stream().collect(Collectors.groupingBy(InvLotAtt::getSku));
+        skuInvLotAttMap.forEach((key, value) -> {
+            //相同sku根据托盘分类,计算托盘上产品数量
+            Map<String, List<InvLotAtt>> palletMap = value.stream().filter(item -> StringUtils.isNotBlank(item.getLotatt07())).collect(Collectors.groupingBy(InvLotAtt::getLotatt07));
+            //根据托盘产品数量对托盘进行排序(倒序)
+            List<InvLotAttPalletTotalDTO> invLotAttPalletTotalDTOList = palletMap.entrySet().stream().map(item -> {
+                InvLotAttPalletTotalDTO invLotAttPalletTotalDTO = new InvLotAttPalletTotalDTO();
+                invLotAttPalletTotalDTO.setSku(key);
+                invLotAttPalletTotalDTO.setPalletNo(item.getKey());
+                invLotAttPalletTotalDTO.setTotalQty(new BigDecimal(item.getValue().size()));
+                return invLotAttPalletTotalDTO;
+            }).sorted(Comparator.comparing(InvLotAttPalletTotalDTO::getTotalQty).reversed()).collect(Collectors.toList());
+            result.put(key, invLotAttPalletTotalDTOList);
+        });
+        return result;
+    }
+
+    /**
+     * 根据多sku获取批次list信息
+     * @param skuList
+     * @return
+     */
+    public List<InvLotAtt> queryInvLotAttBySkuList(List<String> skuList){
+        return invLotAttMapper.selectList(Wrappers.<InvLotAtt>lambdaQuery().in(InvLotAtt::getSku));
+    }
 }

+ 202 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/domain/PalletMatchLog.java

@@ -0,0 +1,202 @@
+package com.ruoyi.ams.order.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+import static com.baomidou.mybatisplus.annotation.IdType.ASSIGN_UUID;
+
+/**
+ * 托盘匹配记录对象 pallet_match_log
+ * 
+ * @author ruoyi
+ * @date 2023-08-23
+ */
+public class PalletMatchLog extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    @TableId(type = IdType.ASSIGN_UUID)
+    private String id;
+
+    /** 托盘 */
+    @Excel(name = "托盘")
+    private String palletNo;
+
+    /** 物料/产品 */
+    @Excel(name = "物料/产品")
+    private String sku;
+
+    /** 数量 */
+    @Excel(name = "数量")
+    private String totalQty;
+
+    /** 所扫描出库单(多出库单以,隔开) */
+    @Excel(name = "所扫描出库单", readConverterExp = "多=出库单以,隔开")
+    private String orderNos;
+
+    /** 库位id */
+    @Excel(name = "库位id")
+    private String locationId;
+
+    /** agv车号 */
+    @Excel(name = "agv车号")
+    private String agvNo;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String userdefine1;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String userdefine2;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String userdefine3;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String userdefine4;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String userdefine5;
+
+    public void setId(String id) 
+    {
+        this.id = id;
+    }
+
+    public String getId() 
+    {
+        return id;
+    }
+    public void setPalletNo(String palletNo) 
+    {
+        this.palletNo = palletNo;
+    }
+
+    public String getPalletNo() 
+    {
+        return palletNo;
+    }
+    public void setSku(String sku) 
+    {
+        this.sku = sku;
+    }
+
+    public String getSku() 
+    {
+        return sku;
+    }
+    public void setTotalQty(String totalQty) 
+    {
+        this.totalQty = totalQty;
+    }
+
+    public String getTotalQty() 
+    {
+        return totalQty;
+    }
+    public void setOrderNos(String orderNos) 
+    {
+        this.orderNos = orderNos;
+    }
+
+    public String getOrderNos() 
+    {
+        return orderNos;
+    }
+    public void setLocationId(String locationId) 
+    {
+        this.locationId = locationId;
+    }
+
+    public String getLocationId() 
+    {
+        return locationId;
+    }
+    public void setAgvNo(String agvNo) 
+    {
+        this.agvNo = agvNo;
+    }
+
+    public String getAgvNo() 
+    {
+        return agvNo;
+    }
+    public void setUserdefine1(String userdefine1) 
+    {
+        this.userdefine1 = userdefine1;
+    }
+
+    public String getUserdefine1() 
+    {
+        return userdefine1;
+    }
+    public void setUserdefine2(String userdefine2) 
+    {
+        this.userdefine2 = userdefine2;
+    }
+
+    public String getUserdefine2() 
+    {
+        return userdefine2;
+    }
+    public void setUserdefine3(String userdefine3) 
+    {
+        this.userdefine3 = userdefine3;
+    }
+
+    public String getUserdefine3() 
+    {
+        return userdefine3;
+    }
+    public void setUserdefine4(String userdefine4) 
+    {
+        this.userdefine4 = userdefine4;
+    }
+
+    public String getUserdefine4() 
+    {
+        return userdefine4;
+    }
+    public void setUserdefine5(String userdefine5) 
+    {
+        this.userdefine5 = userdefine5;
+    }
+
+    public String getUserdefine5() 
+    {
+        return userdefine5;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("palletNo", getPalletNo())
+            .append("sku", getSku())
+            .append("totalQty", getTotalQty())
+            .append("orderNos", getOrderNos())
+            .append("locationId", getLocationId())
+            .append("agvNo", getAgvNo())
+            .append("remark", getRemark())
+            .append("userdefine1", getUserdefine1())
+            .append("userdefine2", getUserdefine2())
+            .append("userdefine3", getUserdefine3())
+            .append("userdefine4", getUserdefine4())
+            .append("userdefine5", getUserdefine5())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 23 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/PalletMatchLogMapper.java

@@ -0,0 +1,23 @@
+package com.ruoyi.ams.order.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.ams.order.domain.PalletMatchLog;
+
+import java.util.List;
+
+/**
+ * 托盘匹配记录Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2023-08-23
+ */
+public interface PalletMatchLogMapper extends BaseMapper<PalletMatchLog>
+{
+    /**
+     * 查询托盘匹配记录列表
+     *
+     * @param palletMatchLog 托盘匹配记录
+     * @return 托盘匹配记录集合
+     */
+    List<PalletMatchLog> selectPalletMatchLogList(PalletMatchLog palletMatchLog);
+}

+ 2 - 1
warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/WmsDocOrderDetailsMapper.java

@@ -2,6 +2,7 @@ package com.ruoyi.ams.order.mapper;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.vo.StockOrderVO;
 import org.apache.ibatis.annotations.Param;
@@ -12,7 +13,7 @@ import org.apache.ibatis.annotations.Param;
  * @author ruoyi
  * @date 2022-10-28
  */
-public interface WmsDocOrderDetailsMapper {
+public interface WmsDocOrderDetailsMapper extends BaseMapper<WmsDocOrderDetails> {
     /**
      * 查询出库单
      *

+ 2 - 1
warewms-ams/src/main/java/com/ruoyi/ams/order/mapper/WmsDocOrderHeaderMapper.java

@@ -2,6 +2,7 @@ package com.ruoyi.ams.order.mapper;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
 import com.ruoyi.ams.order.vo.CheckOutVO;
@@ -13,7 +14,7 @@ import org.apache.ibatis.annotations.Param;
  * @author ruoyi
  * @date 2022-10-18
  */
-public interface WmsDocOrderHeaderMapper {
+public interface WmsDocOrderHeaderMapper extends BaseMapper<WmsDocOrderHeader> {
     /**
      * 查询出库单头
      *

+ 31 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/service/IPalletMatchLogService.java

@@ -0,0 +1,31 @@
+package com.ruoyi.ams.order.service;
+
+import com.ruoyi.ams.order.domain.PalletMatchLog;
+import com.ruoyi.framework.service.BaseService;
+
+import java.util.List;
+
+/**
+ * 托盘匹配记录Service接口
+ * 
+ * @author ruoyi
+ * @date 2023-08-23
+ */
+public interface IPalletMatchLogService extends BaseService<PalletMatchLog>
+{
+
+    /**
+     * 查询托盘匹配记录列表
+     *
+     * @param palletMatchLog 托盘匹配记录
+     * @return 托盘匹配记录集合
+     */
+    List<PalletMatchLog> selectPalletMatchLogList(PalletMatchLog palletMatchLog);
+
+    /**
+     * 根据单号获取托盘匹配信息
+     * @param orderNos
+     * @return
+     */
+    List<PalletMatchLog> queryPalletMatchLogByOrderNos(String orderNos);
+}

+ 7 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/service/IWmsDocOrderDetailsService.java

@@ -82,4 +82,11 @@ public interface IWmsDocOrderDetailsService {
      * @return
      */
     int deleteWmsDocOrderDetailsByOrderNoLineNos(List<HashMap<String,Object>> list);
+
+    /**
+     * 根据入库单号list获取明细
+     * @param orderNoList 入库单号list
+     * @return
+     */
+    List<WmsDocOrderDetails> queryWmsDocOrderDetailsByOrderNoList(List<String> orderNoList);
 }

+ 9 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/service/IWmsDocOrderHeaderService.java

@@ -5,6 +5,7 @@ import java.util.List;
 
 import com.ruoyi.ams.erp.domain.ErpOrderList;
 import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
+import com.ruoyi.ams.order.domain.PalletMatchLog;
 import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
 import com.ruoyi.ams.order.form.*;
@@ -413,4 +414,12 @@ public interface IWmsDocOrderHeaderService {
     AjaxResult modifystockCompletionStatusAsnUntie(String orderNo, String sku, BigDecimal qty
             ,String sn);
 
+    /**
+     * 库存分配
+     * @param orderList
+     * @return
+     */
+    Boolean inventoryMatch(List<String> orderList);
+
+    List<PalletMatchLog> queryPalletMatchInfoList(String orderNos);
 }

+ 45 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/PalletMatchLogServiceImpl.java

@@ -0,0 +1,45 @@
+package com.ruoyi.ams.order.service.impl;
+
+import cn.hutool.db.sql.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.ams.order.domain.PalletMatchLog;
+import com.ruoyi.ams.order.mapper.PalletMatchLogMapper;
+import com.ruoyi.ams.order.service.IPalletMatchLogService;
+import com.ruoyi.framework.service.impl.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 托盘匹配记录Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2023-08-23
+ */
+@Service
+public class PalletMatchLogServiceImpl extends BaseServiceImpl<PalletMatchLogMapper, PalletMatchLog> implements IPalletMatchLogService
+{
+
+    /**
+     * 查询托盘匹配记录列表
+     *
+     * @param palletMatchLog 托盘匹配记录
+     * @return 托盘匹配记录
+     */
+    @Override
+    public List<PalletMatchLog> selectPalletMatchLogList(PalletMatchLog palletMatchLog)
+    {
+        return baseDao.selectPalletMatchLogList(palletMatchLog);
+    }
+
+    /**
+     * 根据单号获取托盘匹配信息
+     * @param orderNos
+     * @return
+     */
+    @Override
+    public List<PalletMatchLog> queryPalletMatchLogByOrderNos(String orderNos) {
+        return baseDao.selectList(Wrappers.<PalletMatchLog>lambdaQuery().eq(PalletMatchLog::getOrderNos, orderNos));
+    }
+
+}

+ 11 - 1
warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/WmsDocOrderDetailsServiceImpl.java

@@ -3,7 +3,7 @@ package com.ruoyi.ams.order.service.impl;
 import java.util.HashMap;
 import java.util.List;
 
-import com.ruoyi.ams.asn.domain.WmsDocAsnDetails;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.common.exception.ServiceException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -130,4 +130,14 @@ public class WmsDocOrderDetailsServiceImpl implements IWmsDocOrderDetailsService
         return 1;
     }
 
+    /**
+     * 根据入库单号list获取明细
+     * @param orderNoList 入库单号list
+     * @return
+     */
+    @Override
+    public List<WmsDocOrderDetails> queryWmsDocOrderDetailsByOrderNoList(List<String> orderNoList){
+        return wmsDocOrderDetailsMapper.selectList(Wrappers.<WmsDocOrderDetails>lambdaQuery().in(WmsDocOrderDetails::getOrderNo, orderNoList));
+    }
+
 }

+ 82 - 7
warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/WmsDocOrderHeaderServiceImpl.java

@@ -1,5 +1,10 @@
 package com.ruoyi.ams.order.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
 import com.ruoyi.ams.asn.service.IWmsDocAsnHeaderService;
 import com.ruoyi.ams.box.domain.WmsBoxInfo;
 import com.ruoyi.ams.box.mapper.WmsBoxInfoMapper;
@@ -18,36 +23,36 @@ import com.ruoyi.ams.inv.domain.InvLotLocId;
 import com.ruoyi.ams.inv.domain.form.InvLocIdSearchFrom;
 import com.ruoyi.ams.inv.domain.form.InvLotLocIdForm;
 import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
+import com.ruoyi.ams.inv.dto.InvLotAttPalletTotalDTO;
 import com.ruoyi.ams.inv.mapper.InvLotAttMapper;
 import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper;
 import com.ruoyi.ams.inv.service.IActTransactionLogService;
 import com.ruoyi.ams.inv.service.IInvLotAttService;
 import com.ruoyi.ams.inv.service.IInvLotLocIdService;
 import com.ruoyi.ams.order.domain.ActAllocationDetails;
+import com.ruoyi.ams.order.domain.PalletMatchLog;
 import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
 import com.ruoyi.ams.order.form.*;
 import com.ruoyi.ams.order.mapper.WmsDocOrderDetailsMapper;
 import com.ruoyi.ams.order.mapper.WmsDocOrderHeaderMapper;
-import com.ruoyi.ams.order.service.IActAllocationDetailsService;
-import com.ruoyi.ams.order.service.IWmsDocOrderHeaderService;
-import com.ruoyi.ams.order.service.UpdateOrderStockingProcess;
+import com.ruoyi.ams.order.service.*;
 import com.ruoyi.ams.order.vo.CheckOutVO;
 import com.ruoyi.ams.order.vo.PickingListVO;
 import com.ruoyi.ams.order.vo.StockOrderVO;
 import com.ruoyi.base.constant.Constant;
 import com.ruoyi.base.domain.BaseLocationInfo;
-import com.ruoyi.base.domain.BaseSku;
 import com.ruoyi.base.domain.vo.CodeSkuRelationshipSoVO;
 import com.ruoyi.base.domain.vo.CodeSkuRelationshipVO;
 import com.ruoyi.base.form.SnCheckSoForm;
 import com.ruoyi.base.service.IBaseLocationInfoService;
-import com.ruoyi.base.service.IBaseSkuService;
 import com.ruoyi.base.service.ICodeSkuRelationshipService;
 import com.ruoyi.base.utils.IdSequenceUtils;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.ConvertUtils;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -78,6 +83,8 @@ public class WmsDocOrderHeaderServiceImpl implements IWmsDocOrderHeaderService {
     @Autowired
     private WmsDocOrderDetailsMapper wmsDocOrderDetailsMapper;
     @Autowired
+    private IWmsDocOrderDetailsService wmsDocOrderDetailsService;
+    @Autowired
     private IActAllocationDetailsService actAllocationDetailsService;
     @Autowired
     private IWmsDocOrderHeaderService wmsDocOrderHeaderService;
@@ -108,10 +115,11 @@ public class WmsDocOrderHeaderServiceImpl implements IWmsDocOrderHeaderService {
     @Autowired
     private IWmsDocAsnHeaderService iWmsDocAsnHeaderService;
     @Autowired
-    private IBaseSkuService baseSkuService;
-    @Autowired
     private UpdateOrderStockingProcess updateOrderStockingProcess;
 
+    @Autowired
+    private IPalletMatchLogService palletMatchLogService;
+
     /**
      * 查询出库单头
      *
@@ -2727,4 +2735,71 @@ public class WmsDocOrderHeaderServiceImpl implements IWmsDocOrderHeaderService {
 
         return AjaxResult.success();
     }
+
+    /**
+     * 库存分配
+     * @param orderList
+     * @return
+     */
+    @Override
+    public Boolean inventoryMatch(List<String> orderList) {
+        //根据erp单号获取出库单头列表
+        List<WmsDocOrderHeader> wmsDocOrderHeaderList = wmsDocOrderHeaderMapper.selectList(Wrappers.<WmsDocOrderHeader>lambdaQuery().in(WmsDocOrderHeader::getSoReference1, orderList).orderByDesc(WmsDocOrderHeader::getCreateTime));
+        if (CollectionUtil.isEmpty(wmsDocOrderHeaderList)) {
+            throw new BaseException("请扫描正确的出库单号");
+        }
+        List<WmsDocOrderHeader> wmsDocOrderHeaderFilterList = wmsDocOrderHeaderList.stream().filter(item -> item.getOrderStatus().equals(Constant.ORDER_STS.STS00.getValue())
+                || item.getOrderStatus().equals(Constant.ORDER_STS.STS10.getValue()) || item.getOrderStatus().equals(Constant.ORDER_STS.STS22.getValue())).collect(Collectors.toList());
+        if (CollectionUtil.isEmpty(wmsDocOrderHeaderFilterList)){
+            throw new BaseException("出库单状态不可分配!");
+        }
+        List<WmsDocOrderDetails> wmsDocOrderDetailsList = wmsDocOrderDetailsService.queryWmsDocOrderDetailsByOrderNoList(wmsDocOrderHeaderFilterList.stream().filter(item -> StringUtils.isNotBlank(item.getOrderNo())).map(WmsDocOrderHeader::getOrderNo).collect(Collectors.toList()));
+        if (CollectionUtil.isEmpty(wmsDocOrderDetailsList)){
+            throw new BaseException("出库单明细为空!");
+        }
+        Map<String, List<WmsDocOrderDetails>> wmsDocOrderDetailsGroupBySkuMap = wmsDocOrderDetailsList.stream().filter(item -> StringUtils.isNotBlank(item.getSku())).collect(Collectors.groupingBy(WmsDocOrderDetails::getSku));
+        if (CollectionUtil.isEmpty(wmsDocOrderDetailsGroupBySkuMap)){
+            throw new BaseException("出库单明细绑定sku为空!");
+        }
+        Map<String, List<InvLotAttPalletTotalDTO>> invLotAttPalletTotalMap = invLotAttService.buildInvLotAttPalletTotalMap(wmsDocOrderDetailsGroupBySkuMap.entrySet().stream().map(Map.Entry::getKey).collect(Collectors.toList()));
+        if (CollectionUtil.isEmpty(invLotAttPalletTotalMap)){
+            throw new BaseException("所选出库单绑定sku无库存!");
+        }
+        //所需出库托盘
+        List<InvLotAttPalletTotalDTO> result = new ArrayList<>();
+        for (Map.Entry<String, List<WmsDocOrderDetails>> wmsDocOrderDetailsGroupBySkuMapEntry : wmsDocOrderDetailsGroupBySkuMap.entrySet()) {
+            //扫描出库单各sku需求总数
+            BigDecimal total = wmsDocOrderDetailsGroupBySkuMapEntry.getValue().stream().filter(item -> ObjectUtil.isNotNull(item.getQtyOrdered())).map(item -> ObjectUtil.isNotNull(item.getQtyAllocated())
+                    ? item.getQtyOrdered().subtract(item.getQtyAllocated()) : item.getQtyOrdered()).reduce(BigDecimal.ZERO, BigDecimal::add);
+            if (CompareUtil.compare(total, BigDecimal.ZERO) <= 0) continue;
+            List<InvLotAttPalletTotalDTO> invLotAttPalletTotalDTOList = invLotAttPalletTotalMap.get(wmsDocOrderDetailsGroupBySkuMapEntry.getKey());
+            if (CollectionUtil.isEmpty(invLotAttPalletTotalDTOList)) continue;
+            for (InvLotAttPalletTotalDTO invLotAttPalletTotalDTO : invLotAttPalletTotalDTOList) {
+                BigDecimal palletTotal = invLotAttPalletTotalDTO.getTotalQty();
+                if (CompareUtil.compare(total, palletTotal) <= 0){
+                    result.add(invLotAttPalletTotalDTO);
+                    break;
+                }
+                total = total.subtract(palletTotal);
+                result.add(invLotAttPalletTotalDTO);
+            }
+        }
+        return palletMatchLogService.insertBatch(buildPalletMatchLogList(result, orderList));
+    }
+
+    @Override
+    public List<PalletMatchLog> queryPalletMatchInfoList(String orderNos) {
+        return palletMatchLogService.queryPalletMatchLogByOrderNos(orderNos);
+    }
+
+    private List<PalletMatchLog> buildPalletMatchLogList(List<InvLotAttPalletTotalDTO> invLotAttPalletTotalDTOList, List<String> orderList){
+        String orderNos = orderList.stream().collect(Collectors.joining(","));
+        Date createTime = DateUtils.getNowDate();
+        return invLotAttPalletTotalDTOList.stream().map(item -> {
+            PalletMatchLog palletMatchLog = ConvertUtils.sourceToTarget(item, PalletMatchLog.class);
+            palletMatchLog.setCreateTime(createTime);
+            palletMatchLog.setOrderNos(orderNos);
+            return palletMatchLog;
+        }).collect(Collectors.toList());
+    }
 }

+ 2 - 3
warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java

@@ -449,13 +449,12 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                     case 7://取消
                         wcsTask.setEndTime(new Date());
                         //如果取到货就只解锁终点库位
-                        boolean flag = "待分配".equals(wcsTask.getLocationTo());
                         if (wcsTask.getState() == 4 || wcsTask.getState() == 5) {
                             // 解锁终点库位
                             baseLocationInfoService.unLockLocationStockStatus(Long.parseLong(wcsTask.getLocationTo())
                                     , Constant.WAREHOUSE_ID, updateBy);
                         } else {
-                            boolean unlock = flag ?  baseLocationInfoService.unLockLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Constant.WAREHOUSE_ID, updateBy)
+                            boolean unlock = "待分配".equals(wcsTask.getLocationTo()) ?  baseLocationInfoService.unLockLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Constant.WAREHOUSE_ID, updateBy)
                                     : baseLocationInfoService.unLockLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Long.parseLong(wcsTask.getLocationTo()), Constant.WAREHOUSE_ID, updateBy);
                         }
                         //释放redis锁
@@ -463,7 +462,7 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                             redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()));
                         }
                         // 如果是入库任务,任务结束,减去当前AGV任务数量
-                        if (!flag) {
+                        if (!"待分配".equals(wcsTask.getLocationTo())) {
                             subtractTheNumberOfTasks(wcsTask.getLocationTo());
                         }
                         // 取消任务删除中间缓存库存

+ 48 - 0
warewms-ams/src/main/resources/mapper/docOrder/PalletMatchLogMapper.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.ams.order.mapper.PalletMatchLogMapper">
+
+    <resultMap type="PalletMatchLog" id="PalletMatchLogResult">
+        <result property="id"    column="id"    />
+        <result property="palletNo"    column="pallet_no"    />
+        <result property="sku"    column="sku"    />
+        <result property="totalQty"    column="total_qty"    />
+        <result property="orderNos"    column="order_nos"    />
+        <result property="locationId"    column="location_id"    />
+        <result property="agvNo"    column="agv_no"    />
+        <result property="remark"    column="remark"    />
+        <result property="userdefine1"    column="userdefine1"    />
+        <result property="userdefine2"    column="userdefine2"    />
+        <result property="userdefine3"    column="userdefine3"    />
+        <result property="userdefine4"    column="userdefine4"    />
+        <result property="userdefine5"    column="userdefine5"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectPalletMatchLogVo">
+        select id, pallet_no, sku, total_qty, order_nos, location_id, agv_no, remark, userdefine1, userdefine2, userdefine3, userdefine4, userdefine5, create_by, create_time, update_by, update_time from pallet_match_log
+    </sql>
+
+    <select id="selectPalletMatchLogList" parameterType="PalletMatchLog" resultMap="PalletMatchLogResult">
+        <include refid="selectPalletMatchLogVo"/>
+        <where>
+            <if test="palletNo != null  and palletNo != ''"> and pallet_no = #{palletNo}</if>
+            <if test="sku != null  and sku != ''"> and sku = #{sku}</if>
+            <if test="totalQty != null  and totalQty != ''"> and total_qty = #{totalQty}</if>
+            <if test="orderNos != null  and orderNos != ''"> and order_nos = #{orderNos}</if>
+            <if test="locationId != null  and locationId != ''"> and location_id = #{locationId}</if>
+            <if test="agvNo != null  and agvNo != ''"> and agv_no = #{agvNo}</if>
+            <if test="userdefine1 != null  and userdefine1 != ''"> and userdefine1 = #{userdefine1}</if>
+            <if test="userdefine2 != null  and userdefine2 != ''"> and userdefine2 = #{userdefine2}</if>
+            <if test="userdefine3 != null  and userdefine3 != ''"> and userdefine3 = #{userdefine3}</if>
+            <if test="userdefine4 != null  and userdefine4 != ''"> and userdefine4 = #{userdefine4}</if>
+            <if test="userdefine5 != null  and userdefine5 != ''"> and userdefine5 = #{userdefine5}</if>
+        </where>
+    </select>
+
+</mapper>