Demo.java 5.58 KB
package com.huaheng.test;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaheng.HuaHengApplication;
import com.huaheng.framework.redis.RedisCache;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.domain.LocationStatus;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO;
import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yiwenpeng
 * @date 2023/7/20 09:49
 */
@Slf4j
@SpringBootTest(classes = HuaHengApplication.class)
@RunWith(SpringRunner.class)
public class Demo {
    @Autowired
    private LocationService locationService;

    @Resource
    private RedisCache redisCache;


    @Resource
    private MaterialService materialService;

    @Resource
    private InventoryTransactionService inventoryTransactionService;

    /*
    将上一周物料出库次数排名前100的记录到数据库里面,每周更新一次这个排名,每次入库的时候用托盘中的所有物料,根据物料出入库次数排名计算出本次入库要分配的库位。

    方案一:假设一个仓库前后各一个出口,离这两个出口近的前2列,包括所有行和层,都设置为常用库位(A区),前4列所有行和层的外侧库位,设置为一般常用库位(B区),其他的就是剩余库位了,不常用C区。

    方案二:找到哪个离出口最近的库位,然后分配库位的时候,用方法找到离这个库位最近的库位,进行分配,但是每次分配只能分配离这个库位最近的。
    */

    private final static String INVENTORY_RANKING_KEY = "INVENTORY_RANKING";

    @Test
    public void test() {
        // 统计物料出入库的频率,将常用的物料优先分配离出入口近的库位,外侧库位优先。
        // 常用的物料,需要华恒自己根据物料出入库的频次进行判断

        // 获取统计排行前30位的物料信息
        // 优先出库原始数据,历史数据(1期暂时不做考虑,不需要考虑原始数据)
        // 入库数据存放至A区
        // 常用库位(A区)

        Map<String, InventoryRankVO> inventoryRankMap =
                inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_KEY);

        String inputOrOutMaterialCode = "DR-QB-01M";

        InventoryRankVO inputMaterialCode = inventoryRankMap.get(inputOrOutMaterialCode);

        // 判断是否存在排行物料
        if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
            // 获取常用库区
            List<Location> locationList = locationService
                    .list(new LambdaQueryWrapper<Location>()
                            .eq(Location::getZoneCode, "A"));
//                            .eq(Location::getStatus, LocationStatus.));
            if (CollectionUtil.isNotEmpty(locationList)) {
                LinkedList<Location> locationLinkedList = new LinkedList<>(locationList);
                locationLinkedList.sort(Comparator.comparingInt(Location::getId));
                Location nearestLocation = locationLinkedList.pollFirst();
                if (ObjectUtil.isNotEmpty(nearestLocation)) {
                    System.out.print("Nearest Location: " + nearestLocation);
                } else {
                    System.out.print("No locations available.");
                }
            }
        }
    }


    public static Location findNearestLocation(List<Location> locations, String locationCode) {
        if (locations == null || locations.isEmpty() || locationCode == null) {
            return null;
        }
        Location targetLocation = null;
        int minDistance = Integer.MAX_VALUE;

        int targetRow = Integer.parseInt(locationCode.substring(1, 3)); // Extract row number from locationCode
        int targetColumn = Integer.parseInt(locationCode.substring(3, 5)); // Extract column number from locationCode
        int targetLayer = Integer.parseInt(locationCode.substring(5, 7)); // Extract layer number from locationCode

        for (Location location : locations) {
            if (location.getCode().equals(locationCode)) {
                continue; // Skip the location with the same code as the target code
            }

            int rowDistance = Math.abs(targetRow - location.getIRow());
            int columnDistance = Math.abs(targetColumn - location.getIColumn());
            int layerDistance = Math.abs(targetLayer - location.getILayer());

            int totalDistance = rowDistance + columnDistance + layerDistance;

            if (totalDistance < minDistance) {
                minDistance = totalDistance;
                targetLocation = location;
            }
        }

        return targetLocation;
    }

}