Commit d99565d3ea563ef3a46ec0bb14dcff5c64b6f295

Authored by puff
1 parent 4dca1ced

bugfix:优化代码调用逻辑,减少控制层代码行数,增加redis同步物料排行接口

src/main/java/com/huaheng/pc/config/material/service/MaterialService.java
1 1 package com.huaheng.pc.config.material.service;
2 2  
  3 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
3 4 import com.huaheng.framework.web.domain.AjaxResult;
4 5 import com.huaheng.mobile.shipment.Materialforecast;
5 6 import com.huaheng.pc.config.material.domain.Material;
6 7 import com.baomidou.mybatisplus.extension.service.IService;
  8 +import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
7 9  
8 10 import java.util.List;
9 11 import java.util.Map;
... ... @@ -52,4 +54,21 @@ public interface MaterialService extends IService<Material>{
52 54 * @return
53 55 */
54 56 Map<String, String> getPhysicalDimensionByCodes(List<String> materialCodeList);
  57 +
  58 + /**
  59 + * 统计物料排行
  60 + * @param materialCode
  61 + * @param createdBegin
  62 + * @param createdEnd
  63 + * @return
  64 + */
  65 + QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type ,String materialCode, String createdBegin, String createdEnd);
  66 +
  67 + /**
  68 + * 物料日期统计排行
  69 + * @param createdBegin
  70 + * @param createdEnd
  71 + * @return
  72 + */
  73 + QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type ,String createdBegin, String createdEnd);
55 74 }
... ...
src/main/java/com/huaheng/pc/config/material/service/MaterialServiceImpl.java
... ... @@ -2,6 +2,7 @@ package com.huaheng.pc.config.material.service;
2 2  
3 3 import cn.hutool.core.util.ReUtil;
4 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 6 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 7 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 8 import com.huaheng.common.exception.BusinessException;
... ... @@ -19,6 +20,7 @@ import com.huaheng.pc.config.materialUnit.domain.MaterialUnit;
19 20 import com.huaheng.pc.config.materialUnit.service.MaterialUnitService;
20 21 import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
21 22 import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
  23 +import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
22 24 import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
23 25 import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
24 26 import org.springframework.stereotype.Service;
... ... @@ -242,6 +244,36 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
242 244 .collect(Collectors.toMap(Material::getCode,Material::getPhysicalDimension));
243 245 }
244 246  
  247 + @Override
  248 + public QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type ,String materialCode, String createdBegin, String createdEnd) {
  249 + String countSql="SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty," +
  250 + "ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty," +
  251 + "SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty," +
  252 + "materialName,materialSpec,materialUnit\n";
  253 + QueryWrapper<InventoryTransaction> materialQueryWrapper = new QueryWrapper<>();
  254 +
  255 + return materialQueryWrapper
  256 + .select(type,countSql)
  257 + //物料编码
  258 + .like(StringUtils.isNotEmpty(materialCode), "materialCode", materialCode)
  259 + .in("transactionType", 10, 20)
  260 + // 单独materialCode groupby 与SQL模式only_full_group_by不兼容
  261 + .groupBy("materialCode","materialName","materialSpec","materialUnit")
  262 + .ge(StringUtils.isNotEmpty(createdBegin), "created", createdBegin)
  263 + .le(StringUtils.isNotEmpty(createdEnd), "created", createdEnd)
  264 + .orderByDesc("taskQty");
  265 + }
  266 +
  267 + @Override
  268 + public QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type ,String createdBegin, String createdEnd) {
  269 + QueryWrapper<InventoryTransaction> datequeryWrapper = new QueryWrapper<>();
  270 + return datequeryWrapper.select("DATE(created) as datee, SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty, ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty, SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty")
  271 + .in("transactionType", 10, 20)
  272 + .between("created",createdBegin,createdEnd)
  273 + .groupBy("DATE(created)");
  274 +
  275 + }
  276 +
245 277 /**
246 278 * 生成物料编码
247 279 * @param code
... ...
src/main/java/com/huaheng/pc/inventory/inventoryTransaction/controller/FrequencyStatisticsController.java
... ... @@ -15,6 +15,7 @@ import com.huaheng.framework.web.domain.AjaxResult;
15 15 import com.huaheng.framework.web.page.PageDomain;
16 16 import com.huaheng.framework.web.page.TableDataInfo;
17 17 import com.huaheng.framework.web.page.TableSupport;
  18 +import com.huaheng.pc.config.material.service.MaterialService;
18 19 import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
19 20 import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService;
20 21 import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
... ... @@ -65,6 +66,9 @@ public class FrequencyStatisticsController extends BaseController {
65 66 }
66 67  
67 68  
  69 + @Resource
  70 + private MaterialService materialService;
  71 +
68 72 @PostMapping("/frequencyStatisticsList")
69 73 @ResponseBody
70 74 public TableDataInfo inventoryTransactionList(InventoryTransaction inventoryTransaction, String createdBegin, String createdEnd) {
... ... @@ -73,53 +77,22 @@ public class FrequencyStatisticsController extends BaseController {
73 77 Integer pageSize = pageDomain.getPageSize();
74 78  
75 79 String type = StringUtils.isNotBlank(inventoryTransaction.getStatisticalType()) ? inventoryTransaction.getStatisticalType() : "materialCode";
  80 + QueryWrapper<InventoryTransaction> materialQueryWrapper = new QueryWrapper<>();
76 81  
77   - //物料
78   - if (type.equals("materialCode")) {
79   - String countSql="SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty," +
80   - "ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty," +
81   - "SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty," +
82   - "materialName,materialSpec,materialUnit\n";
83   - QueryWrapper<InventoryTransaction> materialQueryWrapper = new QueryWrapper<>();
84   -
85   - materialQueryWrapper
86   - .select(type,countSql)
87   - .like(StringUtils.isNotEmpty(inventoryTransaction.getMaterialCode()), "materialCode", inventoryTransaction.getMaterialCode())//物料编码
88   - .in("transactionType", 10, 20)
89   - // 单独materialCode groupby 与SQL模式only_full_group_by不兼容
90   - .groupBy("materialCode","materialName","materialSpec","materialUnit")
91   - .ge(StringUtils.isNotEmpty(createdBegin), "created", createdBegin)
92   - .le(StringUtils.isNotEmpty(createdEnd), "created", createdEnd)
93   - .orderByDesc("taskQty");
94   -
95   - if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
96   - Page<InventoryTransaction> page = new Page<>(pageNum, pageSize);
97   - IPage<InventoryTransaction> iPage = inventoryTransactionService.page(page, materialQueryWrapper);
98   - return getMpDataTable(iPage.getRecords(), iPage.getTotal());
99   - } else {
100   - List<InventoryTransaction> list = inventoryTransactionService.list(materialQueryWrapper);
101   - return getDataTable(list);
102   - }
  82 + if ("materialCode".equals(type)) {
  83 + materialQueryWrapper = materialService.inventoryTurnoverAnalysis("materialCode",inventoryTransaction.getMaterialCode(),createdBegin,createdEnd);
  84 + }else if("created".equals(type)){
  85 + materialQueryWrapper = materialService.inventoryCreatedAnalysis("created",createdBegin,createdEnd);
103 86 }
104 87  
105   - //日期
106   - if (type.equals("created")){
107   - QueryWrapper<InventoryTransaction> datequeryWrapper = new QueryWrapper<>();
108   - datequeryWrapper.select("DATE(created) as datee, SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty, ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty, SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty")
109   - .in("transactionType", 10, 20)
110   - .between("created",createdBegin,createdEnd)
111   - .groupBy("DATE(created)");
112   -
113   - if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
114   - Page<InventoryTransaction> page = new Page<>(pageNum, pageSize);
115   - IPage<InventoryTransaction> iPage = inventoryTransactionService.page(page, datequeryWrapper);
116   - return getMpDataTable(iPage.getRecords(), iPage.getTotal());
117   - } else {
118   - List<InventoryTransaction> list = inventoryTransactionService.list(datequeryWrapper);
119   - return getDataTable(list);
120   - }
  88 + if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
  89 + Page<InventoryTransaction> page = new Page<>(pageNum, pageSize);
  90 + IPage<InventoryTransaction> iPage = inventoryTransactionService.page(page, materialQueryWrapper);
  91 + return getMpDataTable(iPage.getRecords(), iPage.getTotal());
  92 + } else {
  93 + List<InventoryTransaction> list = inventoryTransactionService.list(materialQueryWrapper);
  94 + return getDataTable(list);
121 95 }
122   - return null;
123 96 }
124 97  
125 98  
... ...
src/main/java/com/huaheng/pc/inventory/inventoryTransaction/domain/vo/InventoryRankVO.java 0 → 100644
  1 +package com.huaheng.pc.inventory.inventoryTransaction.domain.vo;
  2 +
  3 +import lombok.Builder;
  4 +import lombok.Data;
  5 +
  6 +import java.io.Serializable;
  7 +import java.math.BigDecimal;
  8 +
  9 +@Data
  10 +@Builder
  11 +public class InventoryRankVO implements Serializable {
  12 +
  13 + private static final long serialVersionUID = 2903643973589589715L;
  14 +
  15 + private String materialCode;
  16 + private Integer inQty;
  17 + private Integer outQty;
  18 + private BigDecimal taskQty;
  19 + private String materialName;
  20 + private String materialSpec;
  21 + private String materialUnit;
  22 +}
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/TaskHeaderServiceImpl.java
... ... @@ -757,6 +757,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
757 757 if (locations.size() == 0) {
758 758 throw new ServiceException("没有空闲库位!");
759 759 }
  760 + // TODO
760 761 //随机取库位
761 762 Random rand = new Random();
762 763 Location location = locations.get(rand.nextInt(locations.size()));
... ...
src/test/java/com.huaheng.test/Demo.java
1 1 package com.huaheng.test;
2 2  
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
3 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
4 8 import com.huaheng.HuaHengApplication;
  9 +import com.huaheng.framework.redis.RedisCache;
5 10 import com.huaheng.pc.config.location.domain.Location;
6 11 import com.huaheng.pc.config.location.service.LocationService;
  12 +import com.huaheng.pc.config.material.service.MaterialService;
  13 +import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
  14 +import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO;
  15 +import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
7 16 import lombok.extern.slf4j.Slf4j;
8 17 import org.junit.Test;
9 18 import org.junit.runner.RunWith;
10 19 import org.springframework.beans.factory.annotation.Autowired;
11 20 import org.springframework.boot.test.context.SpringBootTest;
  21 +import org.springframework.data.redis.core.RedisTemplate;
12 22 import org.springframework.test.context.junit4.SpringRunner;
13 23  
  24 +import javax.annotation.Resource;
  25 +import java.util.ArrayList;
14 26 import java.util.List;
  27 +import java.util.Map;
  28 +import java.util.stream.Collectors;
15 29  
16 30 /**
17 31 * @author yiwenpeng
... ... @@ -24,15 +38,77 @@ public class Demo {
24 38 @Autowired
25 39 private LocationService locationService;
26 40  
  41 + @Resource
  42 + private RedisCache redisCache;
  43 +
  44 +
  45 + @Resource
  46 + private MaterialService materialService;
  47 +
  48 + @Resource
  49 + private InventoryTransactionService inventoryTransactionService;
  50 +
  51 + /*
  52 + 将上一周物料出库次数排名前100的记录到数据库里面,每周更新一次这个排名,每次入库的时候用托盘中的所有物料,根据物料出入库次数排名计算出本次入库要分配的库位。
  53 +
  54 + 方案一:假设一个仓库前后各一个出口,离这两个出口近的前2列,包括所有行和层,都设置为常用库位(A区),前4列所有行和层的外侧库位,设置为一般常用库位(B区),其他的就是剩余库位了,不常用C区。
  55 +
  56 + 方案二:找到哪个离出口最近的库位,然后分配库位的时候,用方法找到离这个库位最近的库位,进行分配,但是每次分配只能分配离这个库位最近的。
  57 + */
  58 +
  59 + private final static String INVENTORY_RANKING_KEY = "INVENTORY_RANKING";
27 60 @Test
28 61 public void test() {
29   - List<Location> lists = locationService.list(new LambdaQueryWrapper<Location>().eq(Location::getZoneCode, "A"));
30   - String locationCode = "A020303";//假设这个是离出口最近的库位号
31   - Location nearestLocation = findNearestLocation(lists, locationCode);
32   - log.error("***********************************************" + nearestLocation);
  62 + // 统计物料出入库的频率,将常用的物料优先分配离出入口近的库位,外侧库位优先。
  63 + // 常用的物料,需要华恒自己根据物料出入库的频次进行判断
  64 +
  65 + // 获取统计排行前30位的物料信息
  66 + // 优先出库原始数据,历史数据(1期暂时不做考虑,不需要考虑原始数据)
  67 + // 入库数据存放至A区
  68 + // 常用库位(A区)
  69 + List<Object> rankList = redisCache.getCacheList(INVENTORY_RANKING_KEY);
  70 + if(CollectionUtil.isEmpty(rankList)){
  71 + QueryWrapper<InventoryTransaction> materialQueryWrapper = materialService.inventoryTurnoverAnalysis("materialCode","", "", "");
  72 + List<InventoryTransaction> inventoryTransactionList = inventoryTransactionService.page(new Page<>(0, 30), materialQueryWrapper).getRecords();
  73 + List<InventoryRankVO> rankVOList = new ArrayList<>();
  74 + inventoryTransactionList.forEach(inventory ->{
  75 + rankVOList.add(InventoryRankVO.builder()
  76 + .materialCode(inventory.getMaterialCode())
  77 + .inQty(inventory.getInQty())
  78 + .outQty(inventory.getOutQty())
  79 + .taskQty(inventory.getTaskQty())
  80 + .materialName(inventory.getMaterialName())
  81 + .materialSpec(inventory.getMaterialSpec())
  82 + .materialUnit(inventory.getMaterialUnit())
  83 + .build());
  84 + });
  85 + redisCache.setCacheList(INVENTORY_RANKING_KEY,rankVOList);
  86 + }
  87 + // key material code
  88 + // value material object
  89 + Map<String, InventoryRankVO> inventoryRankVOMap = rankList.stream()
  90 + .map(obj -> (InventoryRankVO) obj)
  91 + .collect(Collectors.toMap(InventoryRankVO::getMaterialCode, vo -> vo));
  92 +
  93 + String inOutMaterialCode = "DR-QB-01M";
  94 +
  95 +
  96 + InventoryRankVO inputMaterialCode = inventoryRankVOMap.get(inOutMaterialCode);
  97 + // 判断是否存在排行物料 true 存在
  98 + if(ObjectUtil.isNotEmpty(inputMaterialCode)){
  99 +
  100 + }
  101 +
  102 +//
  103 +// List<Location> lists = locationService.list(new LambdaQueryWrapper<Location>().eq(Location::getZoneCode, "A"));
  104 +// // 库位号
  105 +// String locationCode = "A020303";//假设这个是离出口最近的库位号
  106 +// Location nearestLocation = findNearestLocation(lists, locationCode);
  107 +// log.error("***********************************************" + nearestLocation);
33 108 }
34 109  
35 110  
  111 +
36 112 public static Location findNearestLocation(List<Location> locations, String locationCode) {
37 113 if (locations == null || locations.isEmpty() || locationCode == null) {
38 114 return null;
... ...