LocationAllocationServiceImpl.java 17.3 KB
package com.huaheng.api.wcs.service.warecellAllocation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.Wrappers;
import com.huaheng.framework.web.service.ConfigService;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.containerType.domain.ContainerType;
import com.huaheng.pc.config.containerType.service.ContainerTypeService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.locationType.domain.LocationType;
import com.huaheng.pc.config.locationType.service.LocationTypeService;
import com.huaheng.pc.config.zone.domain.Zone;
import com.huaheng.pc.config.zone.service.ZoneService;
import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static java.util.stream.Collectors.toList;

@Service
public class LocationAllocationServiceImpl implements LocationAllocationService {

    @Resource
    private LocationService locationService;
    @Resource
    private LocationTypeService locationTypeService;
    @Resource
    private ContainerService containerService;
    @Resource
    private ContainerTypeService containerTypeService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private ZoneService zoneService;
    @Resource
    private ConfigService configService;

    @Override
    public String allocation(int locationRule, List<String> locationTypeCodeList,
                             int high, String area, List<String> raodWays, String warehouseCode,
                             String containerCode, String materialAreaCode) {
        LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
        containerLambdaQueryWrapper.eq(Container::getCode, containerCode)
                .eq(Container::getWarehouseCode, warehouseCode);
        Container container = containerService.getOne(containerLambdaQueryWrapper);

        LambdaQueryWrapper<ContainerType> containerTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
        containerTypeLambdaQueryWrapper.eq(ContainerType::getCode, container.getContainerType())
                .eq(ContainerType::getWarehouseCode, warehouseCode);
        ContainerType containerType = containerTypeService.getOne(containerTypeLambdaQueryWrapper);
        List<LocationType> locationTypeList = new ArrayList<>();
        if (containerType != null) {
            String locationType = containerType.getLocationType();
            String[] list = locationType.split(",");
            for (String str : list) {
                LambdaQueryWrapper<LocationType> locationTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
                locationTypeLambdaQueryWrapper.eq(LocationType::getWarehouseCode, warehouseCode)
                        .eq(LocationType::getCode, str);
                LocationType locationType1 = locationTypeService.getOne(locationTypeLambdaQueryWrapper);
                if (locationType1 != null) {
                    locationTypeList.add(locationType1);
                }
            }
        } else {
            LambdaQueryWrapper<Zone> zoneLambdaQueryWrapper = Wrappers.lambdaQuery();
            zoneLambdaQueryWrapper.eq(Zone::getWarehouseCode, warehouseCode)
                    .eq(Zone::getArea, area);
            Zone zone = zoneService.getOne(zoneLambdaQueryWrapper);
            if (zone != null) {
                LambdaQueryWrapper<LocationType> locationTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
                locationTypeLambdaQueryWrapper.eq(LocationType::getWarehouseCode, warehouseCode)
                        .eq(LocationType::getZoneCode, zone.getCode());
                locationTypeList = locationTypeService.list(locationTypeLambdaQueryWrapper);
            }
        }

        List<String> locationTypeCodes = locationTypeList.stream().
                map(t -> t.getCode()).collect(toList());
        List<String> mergelocationTypeCodeList = locationTypeCodeList.stream().filter(item -> locationTypeCodes.contains(item)).collect(toList());
        switch (locationRule) {
            case QuantityConstant.DOUBLE_FORK:
                if (warehouseCode.equals(QuantityConstant.WAREHOUSE_XZ)) {
                    return doubleRkXZ(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
                } else {
                    return doubleRk(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
                }
            case QuantityConstant.SINGLE_FORK:
                return singleRk(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
        }
        return null;
    }

    /**
     * 双伸位库位入库分配库位--徐州
     */
    private String doubleRkXZ(String area, List<String> roadWays, int high, String warehouseCode,
                              List<String> locationTypeCodeList, String materialAreaCode) {
        if (roadWays == null || roadWays.size() < 1) {
            LambdaQueryWrapper<Location> locationLambdaQueryWrapper = com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getArea, area);
            locationLambdaQueryWrapper.eq(Location::getWarehouseCode, warehouseCode);
            List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
            roadWays = locationList.stream().map(Location::getRoadway).distinct().collect(toList());
        }
        String value = configService.getKey(QuantityConstant.DOUBLE_FORK_RESERVE_LOCATION, warehouseCode);
        int reserveNumber = 0;
        if (StringUtils.isNotEmpty(value)) {
            reserveNumber = Integer.parseInt(value);
        }

        StopWatch stopWatch = new StopWatch();
        stopWatch.start("aaa");
        List<String> removeRoadWays = new ArrayList<>();
        for (String roadWay : roadWays) {
            LambdaQueryWrapper<Location> locationLambdaQueryWrapper = com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getArea, area).
                    eq(Location::getWarehouseCode, warehouseCode)
                    .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .eq(Location::getHigh, high)
                    .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
                    .in(Location::getLocationType, locationTypeCodeList)
                    .eq(Location::getContainerCode, "")
                    .last("ORDER BY iLayer asc, id asc limit 20");
//                    .last("ORDER BY iColumn desc, iLayer asc, id asc limit 20");
            List<Location> totalLocationList = locationService.list(locationLambdaQueryWrapper);
            if (totalLocationList.size() <= reserveNumber) {
                removeRoadWays.add(roadWay);
            }
        }
        stopWatch.stop();
        System.out.println("waste aa:" + stopWatch.getLastTaskTimeMillis());
        stopWatch.start("bbb");
        roadWays.removeAll(removeRoadWays);
        Collections.shuffle(roadWays);
        String roadWay = roadWays.get(0);
        LambdaQueryWrapper<Location> locationLambda = com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery();
        locationLambda.eq(Location::getArea, area).
                eq(Location::getWarehouseCode, warehouseCode)
                .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .eq(Location::getHigh, high)
                .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
                .eq(Location::getRowFlag, QuantityConstant.ROW_OUT)
                .in(Location::getLocationType, locationTypeCodeList)
                .eq(Location::getContainerCode, "")
                .last("ORDER BY iLayer asc, id asc limit 20");
        List<Location> locationList = locationService.list(locationLambda);
        List<Location> removeLocaationList = new ArrayList<>();
        if (locationList != null && locationList.size() > 0) {
            for (Location location1 : locationList) {
                if (taskHeaderService.getUncompleteTaskInNearXZ(location1) > 0) {
                    removeLocaationList.add(location1);
                }
            }
        }
        locationList.removeAll(removeLocaationList);
        stopWatch.stop();
        System.out.println("waste bb:" + stopWatch.getLastTaskTimeMillis());
        if (locationList == null || locationList.size() == 0) {
            locationLambda = com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery();
            locationLambda.eq(Location::getArea, area).
                    eq(Location::getWarehouseCode, warehouseCode)
                    .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .eq(Location::getHigh, high)
                    .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
                    .eq(Location::getRowFlag, QuantityConstant.ROW_IN)
                    .in(Location::getLocationType, locationTypeCodeList)
                    .eq(Location::getContainerCode, "")
                    .last("ORDER BY iLayer asc, id asc limit 20");
            locationList = locationService.list(locationLambda);
            removeLocaationList = new ArrayList<>();
            if (locationList != null && locationList.size() > 0) {
                for (Location location1 : locationList) {
                    if (taskHeaderService.getUncompleteTaskInNearXZ(location1) > 0) {
                        removeLocaationList.add(location1);
                    }
                }
            }
            locationList.removeAll(removeLocaationList);
        }
        if (locationList == null || locationList.size() == 0) {
            return null;
        }
        Location location = locationList.stream().findFirst().orElse(null);
        String locationCode = location.getCode();
        return locationCode;
    }

    /**
     * 双伸位库位入库分配库位
     */
    private String doubleRk(String area, List<String> roadWays, int high, String warehouseCode,
                            List<String> locationTypeCodeList, String materialAreaCode) {
        if (roadWays == null) {
            LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getArea, area);
            List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
            roadWays = locationList.stream().map(Location::getRoadway).distinct().collect(toList());
        }
        String value = configService.getKey(QuantityConstant.DOUBLE_FORK_RESERVE_LOCATION, warehouseCode);
        int reserveNumber = Integer.parseInt(value);
        List<String> removeRoadWays = new ArrayList<>();
        for (String roadWay : roadWays) {
            LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getArea, area).
                    eq(Location::getWarehouseCode, warehouseCode)
                    .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .ge(Location::getHigh, high)
//                    .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
                    .in(!warehouseCode.equalsIgnoreCase("KS0001"), Location::getLocationType, locationTypeCodeList)
                    .eq(Location::getContainerCode, "")
                    .last(warehouseCode.equalsIgnoreCase("KS0001"), "ORDER BY high ASC, CASE WHEN iRow=3 THEN 1 WHEN iRow=1 THEN 2 WHEN iRow=2 THEN 3 END");
            List<Location> totalLocationList = locationService.list(locationLambdaQueryWrapper);
            if (totalLocationList.size() <= reserveNumber) {
                removeRoadWays.add(roadWay);
            }
        }
        roadWays.removeAll(removeRoadWays);

        LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
        locationLambda.eq(Location::getArea, area).
                eq(Location::getWarehouseCode, warehouseCode)
                .in(StringUtils.isNotEmpty(roadWays), Location::getRoadway, roadWays)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .ge(Location::getHigh, high)
//                .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
//                .eq(Location::getRowFlag, QuantityConstant.ROW_OUT)
                .in(!warehouseCode.equalsIgnoreCase("KS0001"), Location::getLocationType, locationTypeCodeList)
                .eq(Location::getContainerCode, "")
                .last(warehouseCode.equalsIgnoreCase("KS0001"), "ORDER BY high ASC, CASE WHEN iRow=3 THEN 1 WHEN iRow=1 THEN 2 WHEN iRow=2 THEN 3 END");
        List<Location> locationList = locationService.list(locationLambda);
        List<Location> removeLocaationList = new ArrayList<>();
        if (locationList != null && locationList.size() > 0) {
            for (Location location1 : locationList) {
                //查出未完成
                if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) {
                    removeLocaationList.add(location1);
                }
                if (warehouseCode.equalsIgnoreCase("KS0001") && location1.getIRow() == 1) {
                } else {
                    Location insideNear = locationService.getInsideNear(location1);
                    if (insideNear != null && StringUtils.isNotEmpty(insideNear.getContainerCode())) {
                        removeLocaationList.add(location1);
                    }
                }

            }
        }
        locationList.removeAll(removeLocaationList);


        if (locationList == null || locationList.size() == 0) {
            locationLambda = Wrappers.lambdaQuery();
            locationLambda.eq(Location::getArea, area).
                    eq(Location::getWarehouseCode, warehouseCode)
                    .in(StringUtils.isNotEmpty(roadWays), Location::getRoadway, roadWays)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .ge(Location::getHigh, high)
//                    .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
//                    .eq(Location::getRowFlag, QuantityConstant.ROW_IN)
                    .in(!warehouseCode.equalsIgnoreCase("KS0001"), Location::getLocationType, locationTypeCodeList)
                    .eq(Location::getContainerCode, "")
                    //昆山立库优先行顺序 1,3,2
                    .last(warehouseCode.equalsIgnoreCase("KS0001"), "ORDER BY high ASC, CASE WHEN iRow=3 THEN 1 WHEN iRow=1 THEN 2 WHEN iRow=2 THEN 3 END ");
            locationList = locationService.list(locationLambda);
            removeLocaationList = new ArrayList<>();
            if (locationList != null && locationList.size() > 0) {
                for (Location location1 : locationList) {
                    if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) {
                        removeLocaationList.add(location1);
                    }
                }
            }
            locationList.removeAll(removeLocaationList);
        }
        if (locationList == null || locationList.size() == 0) {
            return null;
        }
        Location location = locationList.stream().findFirst().orElse(null);
        String locationCode = location.getCode();
        return locationCode;
    }

    /**
     * 单伸位库位入库分配库位
     */
    private String singleRk(String area, List<String> roadWays, int high, String warehouseCode,
                            List<String> locationTypeCodeList, String materialAreaCode) {
        LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
        locationLambda.eq(Location::getArea, area).
                eq(Location::getWarehouseCode, warehouseCode)
                .in(StringUtils.isNotEmpty(roadWays), Location::getRoadway, roadWays)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .le(Location::getHigh, high)
                .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
                .in(Location::getLocationType, locationTypeCodeList)
                .eq(Location::getContainerCode, "");
        locationLambda.last("ORDER BY high ASC, id asc");
        List<Location> locationList = locationService.list(locationLambda);
        if (locationList == null || locationList.size() == 0) {
            return null;
        }
        Location location = locationList.stream().findFirst().orElse(null);
        String locationCode = location.getCode();
        return locationCode;
    }

}