package com.ruoyi.ams.business; import com.alibaba.fastjson.JSON; import com.ruoyi.ams.common.Constant; import com.ruoyi.ams.config.domain.AsnSoStrategy; import com.ruoyi.ams.config.domain.dto.AgvCallDTO; import com.ruoyi.ams.config.domain.dto.InWarehouseDTO; import com.ruoyi.ams.config.domain.dto.LotattDTO; import com.ruoyi.ams.config.domain.dto.OutWarehouseDTO; import com.ruoyi.ams.config.domain.vo.FlowConfigHeaderVO; import com.ruoyi.ams.config.mapper.AsnSoStrategyMapper; import com.ruoyi.ams.config.service.IFlowConfigHeaderService; import com.ruoyi.ams.config.service.ILocationPriorityHeaderService; import com.ruoyi.ams.config.service.LocationAllocationStrategy; import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper; import com.ruoyi.ams.inv.service.IInvLotLocIdService; import com.ruoyi.ams.task.domain.WcsTask; import com.ruoyi.ams.task.mapper.WcsTaskMapper; import com.ruoyi.base.domain.BaseLocationInfo; import com.ruoyi.base.domain.BaseSku; import com.ruoyi.base.domain.vo.BaseLocationLotattVO; import com.ruoyi.base.mapper.BaseLocationInfoMapper; import com.ruoyi.base.service.IBaseLocationInfoService; import com.ruoyi.base.service.IBaseSkuService; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; @Slf4j @Service public class BusinessServiceImpl implements IBusinessService { @Autowired private IBusinessService businessService; @Autowired private IBaseLocationInfoService baseLocationInfoService; @Autowired private LocationAllocationStrategy locationAllocationStrategy; @Autowired private InvLotLocIdMapper invLotLocIdMapper; @Autowired private IInvLotLocIdService invLotLocIdService; @Autowired private WcsTaskMapper wcsTaskMapper; @Autowired private AsnSoStrategyMapper asnSoStrategyMapper; @Autowired private BaseLocationInfoMapper baseLocationInfoMapper; @Autowired private IBaseSkuService baseSkuService; @Autowired private IFlowConfigHeaderService flowConfigHeaderService; @Transactional @Override public AjaxResult agvCall(List agvCallDTOList) { AgvCallDTO agvCallDTO = new AgvCallDTO(); for (AgvCallDTO agvCall : agvCallDTOList) { agvCallDTO.setLocationFrom(agvCall.getLocationFrom()); agvCallDTO.setLocationTo(agvCall.getLocationTo()); agvCallDTO.setId(agvCall.getId()); agvCallDTO.setWarehouseId(agvCall.getWarehouseId()); agvCallDTO.setLotattDTO(agvCall.getLotattDTO()); break; } BaseLocationInfo locationFrom = null; BaseLocationInfo locationTo = null; //查询所属流程 FlowConfigHeaderVO flowConfigHeaderVO = flowConfigHeaderService.selectFlowConfigHeaderById(agvCallDTO.getId()); AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy(); if (flowConfigHeaderVO == null) { log.info("-----------指令查询不到对应的流程:" + JSON.toJSONString(agvCallDTOList)); return AjaxResult.error("指令查询不到对应的流程"); } String paramLocationFrom = agvCallDTO.getLocationFrom(); String paramLocationTo = agvCallDTO.getLocationTo(); if (StringUtils.isEmpty(paramLocationFrom)) { paramLocationFrom = flowConfigHeaderVO.getLocationFrom(); } if(StringUtils.isEmpty(paramLocationTo)) { paramLocationTo = flowConfigHeaderVO.getLocationTo(); } List locationFromList = this.convertLocation(paramLocationFrom, agvCallDTO.getWarehouseId()); List locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId()); if (flowConfigHeaderVO.getFlowType().equals("ASN")) { locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "ASN", asnSoStrategy, agvCallDTO); locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "ASN", asnSoStrategy, agvCallDTO); //2.初始化库存 for (AgvCallDTO agvCall : agvCallDTOList) { invLotLocIdService.initInv(locationFrom.getId().toString(), agvCall.getSku(), Constant.CUSTOMER_ID, agvCall.getQty(), agvCall.getLotattDTO()); } } else if (flowConfigHeaderVO.getFlowType().equals("SO")) { locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "SO", asnSoStrategy, agvCallDTO); locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "SO", asnSoStrategy, agvCallDTO); } else if (flowConfigHeaderVO.getFlowType().equals("MV")) { locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "MV", asnSoStrategy, agvCallDTO); locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "MV", asnSoStrategy, agvCallDTO); } String taskNo = System.currentTimeMillis() + ""; WcsTask wcsTask = new WcsTask(); wcsTask.setTaskNo(taskNo); wcsTask.setAreaFrom(locationFrom.getZoneId().toString()); wcsTask.setLocationFrom(locationFrom.getId().toString()); wcsTask.setAreaTo(locationTo.getZoneId() + ""); wcsTask.setLocationTo(locationTo.getId().toString()); wcsTask.setState(9L); wcsTask.setPriority(1L); wcsTask.setCreateDate(new Date()); wcsTask.setBusinessType("01"); wcsTask.setTaskType(""); return businessService.addTask(wcsTask); } @Transactional @Override public BaseLocationInfo inLocationAllocation(InWarehouseDTO inWarehouseDTO) { /** * 根据sku查询可以存放的zone * 根据每个zone的配置去分配可以存放的库位 * * force * optimization * ignore */ if (!StringUtils.isEmpty(inWarehouseDTO.getLocationTo())) { //指定库位则直接返回库位 BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(inWarehouseDTO.getLocationTo(), inWarehouseDTO.getWarehouseId()); return baseLocationInfo; } else { if (StringUtils.isEmpty(inWarehouseDTO.getLocationZoneTo()) && StringUtils.isEmpty(inWarehouseDTO.getLocationTo())) { //不指定目标库位和区域 // 没有指定目标的根据sku进行匹配并进行分配 // 如果可以混放的区域不匹配物料也可以选择,否则只选择可以存放的区域 AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy(); BaseSku baseSku = baseSkuService.selectBaseSkuByCustomerId(Constant.CUSTOMER_ID, inWarehouseDTO.getSku()); //判断是否强制同物料靠近, LotattDTO lotattDTO = inWarehouseDTO.getLotattDTO(); Map lotattMap = new HashMap<>(); if (asnSoStrategy.getAsnSameLotatt1Flag().equals("optimization")) { lotattMap.put(asnSoStrategy.getAsnSameLotatt1Value(), lotattDTO.getAttr(asnSoStrategy.getAsnSameLotatt1Value())); } if (asnSoStrategy.getAsnSameLotatt2Flag().equals("optimization")) { lotattMap.put(asnSoStrategy.getAsnSameLotatt2Value(), lotattDTO.getAttr(asnSoStrategy.getAsnSameLotatt2Value())); } List locationInfoList = new ArrayList<>(); if (asnSoStrategy.getAsnSameSku().equals("force")) { List colNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSku(), null, lotattMap); for (String s : colNo) { List locs = baseLocationInfoService.selectNeighborLocation(s, null); locationInfoList.addAll(locs); } if (colNo == null || colNo.size() == 0) { colNo = baseLocationInfoMapper.selectSameSkuTypeColNo(baseSku.getSkuType(), null); for (String s : colNo) { List locs = baseLocationInfoService.selectNeighborLocation(s, null); locationInfoList.addAll(locs); } } // List locs = baseLocationInfoMapper.selectLocationByColNos(colNo); } else if (asnSoStrategy.getAsnSameSku().equals("optimization") || asnSoStrategy.getAsnSameSkuType().equals("optimization")) { List skuColNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSku(), null, lotattMap); List skuTypeColNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSkuType(), null, lotattMap); List cols = new ArrayList<>(); cols.addAll(skuColNo); cols.addAll(skuTypeColNo); List locs = baseLocationInfoMapper.selectLocationByColNos(cols); locationInfoList.addAll(locs); } else { locationInfoList = baseLocationInfoMapper.selectLocationBindSku(baseSku.getSkuType()); } return locationAllocationStrategy.filterLockLocation(locationInfoList, inWarehouseDTO, asnSoStrategy); } else { // 指定区域的 List locationInfoList = baseLocationInfoService.selectSortedLocatinListByZoneId(Long.parseLong(inWarehouseDTO.getLocationZoneTo()), inWarehouseDTO.getWarehouseId()); return locationAllocationStrategy.filterLockLocation(locationInfoList); } } } @Transactional @Override public BaseLocationInfo outInvAllocation(OutWarehouseDTO outWarehouseDTO) { /** * 指定位置出库 */ if (!StringUtils.isEmpty(outWarehouseDTO.getLocationFrom())) { BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(outWarehouseDTO.getLocationFrom(), outWarehouseDTO.getWarehouseId()); return baseLocationInfo; } else { //未指定明确位置出库 List zoneIdList = new ArrayList<>(); if (!StringUtils.isEmpty(outWarehouseDTO.getLocationZoneFrom())) { zoneIdList.add(Long.parseLong(outWarehouseDTO.getLocationZoneFrom())); } else { List zoneList = invLotLocIdMapper.selectInvZoneBySkuLotatt(outWarehouseDTO.getSku(), outWarehouseDTO.getSkuType(), outWarehouseDTO.getLotattDTO()); for (BaseLocationLotattVO vo : zoneList) { zoneIdList.add(vo.getZoneId()); } } LotattDTO lotattDTO = outWarehouseDTO.getLotattDTO(); List locationInfoList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneIdList(zoneIdList, outWarehouseDTO.getWarehouseId(), lotattDTO.getAttr()); AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy(); return locationAllocationStrategy.filterLockInv(locationInfoList, outWarehouseDTO, asnSoStrategy); } } @Override public BaseLocationInfo zoneLocationAllocation(List locationInfoList, String locationType, String type, AsnSoStrategy asnSoStrategy, AgvCallDTO agvCallDTO) { BaseLocationInfo locationInfo = null; if (type.equals("ASN")) { //入库 if (locationType.equals("locationFrom")) { for (BaseLocationInfo b : locationInfoList) { if (!b.getStockStatus().equals("00")) { continue; } locationInfo = b; break; } if (locationInfo == null) { throw new RuntimeException("没有可以分配的库位"); } } else { if (locationInfoList != null && locationInfoList.size() > 0) { locationInfo = locationAllocationStrategy.filterLockLocation(locationInfoList); } else { InWarehouseDTO inWarehouseDTO = new InWarehouseDTO(); inWarehouseDTO.setWarehouseId(agvCallDTO.getWarehouseId()); inWarehouseDTO.setSku(agvCallDTO.getSku()); inWarehouseDTO.setLocationTo(agvCallDTO.getLocationTo()); inWarehouseDTO.setLocationFrom(agvCallDTO.getLocationFrom()); inWarehouseDTO.setQty(agvCallDTO.getQty()); inWarehouseDTO.setSupplier(agvCallDTO.getSupplier()); inWarehouseDTO.setWeight(agvCallDTO.getWeight()); inWarehouseDTO.setLotattDTO(agvCallDTO.getLotattDTO()); locationInfo = inLocationAllocation(inWarehouseDTO); } if (locationInfo == null) { throw new RuntimeException("没有可以分配的库位"); } return locationInfo; } } else if (type.equals("SO")) { //起始库位 if (locationType.equals("locationFrom")) { //指定库位 if (locationInfoList != null && locationInfoList.size() > 0) { List locationList = new ArrayList<>(); for (BaseLocationInfo b : locationInfoList) { locationList.add(b.getId()); } List locationLotattVOList = baseLocationInfoMapper.selectSortedLocationLotattListByLocationIdList(locationList, agvCallDTO.getWarehouseId(), agvCallDTO.getLotattDTO().getAttr()); OutWarehouseDTO outWarehouseDTO = new OutWarehouseDTO(); outWarehouseDTO.setSku(agvCallDTO.getSku()); outWarehouseDTO.setQty(agvCallDTO.getQty()); outWarehouseDTO.setWeight(agvCallDTO.getWeight()); outWarehouseDTO.setSupplier(agvCallDTO.getSupplier()); outWarehouseDTO.setLotattDTO(agvCallDTO.getLotattDTO()); outWarehouseDTO.setWarehouseId(agvCallDTO.getWarehouseId()); locationInfo = locationAllocationStrategy.filterLockInv(locationLotattVOList, outWarehouseDTO, asnSoStrategy); } else { OutWarehouseDTO outWarehouseDTO = new OutWarehouseDTO(); outWarehouseDTO.setSku(agvCallDTO.getSku()); outWarehouseDTO.setQty(agvCallDTO.getQty()); outWarehouseDTO.setWeight(agvCallDTO.getWeight()); outWarehouseDTO.setSupplier(agvCallDTO.getSupplier()); outWarehouseDTO.setLotattDTO(agvCallDTO.getLotattDTO()); outWarehouseDTO.setWarehouseId(agvCallDTO.getWarehouseId()); locationInfo = outInvAllocation(outWarehouseDTO); } if (locationInfo == null) { throw new RuntimeException("没有可分配的库存"); } return locationInfo; } else { //目标库位 for (BaseLocationInfo b : locationInfoList) { if (!b.getStockStatus().equals("00")) { continue; } locationInfo = b; break; } if (locationInfo == null) { throw new RuntimeException("没有可以分配的库位"); } } } else { //移库 for (BaseLocationInfo b : locationInfoList) { if (!b.getStockStatus().equals("00")) { continue; } locationInfo = b; break; } if (locationInfo == null) { throw new RuntimeException("没有可以分配的库位"); } } return locationInfo; } @Override public List convertLocation(String locationNoOrZoneId, Long warehouseId) { List locationInfoList = new ArrayList<>(); if (!StringUtils.isEmpty(locationNoOrZoneId)) { String[] arr = locationNoOrZoneId.split(","); for (String obj : arr) { boolean isLocation = baseLocationInfoService.checkIsLocation(obj, warehouseId); if (isLocation) { BaseLocationInfo info = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(obj, warehouseId); locationInfoList.add(info); } else { List infoList = baseLocationInfoService.selectSortedLocatinListByZoneId(Long.parseLong(obj), warehouseId); locationInfoList.addAll(infoList); } } } return locationInfoList; } @Transactional @Override public AjaxResult addTask(WcsTask wcsTask) { //锁定库位 if (!StringUtils.isEmpty(wcsTask.getLocationFrom())) { baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Constant.STOCK_STATUS.STOCK10.getValue()); } if (!StringUtils.isEmpty(wcsTask.getLocationTo())) { baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationTo()), Constant.STOCK_STATUS.STOCK10.getValue()); } Integer priority = 1; if (!wcsTask.getTaskType().equals("OB")) { if (wcsTask.getPriority() == 99) { int current = wcsTaskMapper.selectCurrentPriority(); priority = current - 100; } else { int current = wcsTaskMapper.selectCurrentPriority(); priority = current + 10; } } else { //倒库任务顺序由原任务中间插入不需要获取 priority = wcsTask.getPriority().intValue(); } wcsTask.setPriority((long) priority); int result = wcsTaskMapper.insertWcsTask(wcsTask); if (result > 0) { return AjaxResult.success("任务生成成功"); } else { throw new ServiceException("任务生成失败"); } } @Override public AjaxResult sendTask(WcsTask wcsTask) { return AjaxResult.success(); } }