package com.huaheng.pc.receipt.receiving.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.huaheng.common.utils.Wrappers; import com.huaheng.api.wcs.service.warecellAllocation.LocationAllocationService; import com.huaheng.common.constant.QuantityConstant; import com.huaheng.common.exception.service.ServiceException; import com.huaheng.common.support.Convert; import com.huaheng.common.utils.StringUtils; import com.huaheng.common.utils.security.ShiroUtils; import com.huaheng.framework.web.domain.AjaxResult; import com.huaheng.framework.web.service.ConfigService; import com.huaheng.pc.config.FilterConfigDetail.domain.FilterConfigDetail; import com.huaheng.pc.config.FilterConfigDetail.service.FilterConfigDetailService; import com.huaheng.pc.config.configValue.domain.ConfigValue; import com.huaheng.pc.config.configValue.service.ConfigValueService; 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.material.domain.Material; import com.huaheng.pc.config.material.service.MaterialService; import com.huaheng.pc.config.materialType.domain.MaterialType; import com.huaheng.pc.config.materialType.service.MaterialTypeService; import com.huaheng.pc.config.receiptPreference.domain.ReceiptPreference; import com.huaheng.pc.config.receiptPreference.service.ReceiptPreferenceService; import com.huaheng.pc.receipt.receiptContainerDetail.domain.ReceiptContainerDetail; import com.huaheng.pc.receipt.receiptContainerDetail.service.ReceiptContainerDetailService; import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader; import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService; import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail; import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader; import com.huaheng.pc.task.taskHeader.service.TaskHeaderService; import com.huaheng.pc.task.taskHeader.service.TransferTaskService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * @author mahua * @ClassName ReceivingService * @projectName huaheng * @description: TODO * @date 2019/8/3123:09 */ @Service public class ReceivingService { @Resource private ReceiptDetailService receiptDetailService; @Resource private ReceiptContainerHeaderService receiptContainerHeaderService; @Resource private ReceiptContainerDetailService receiptContainerDetailService; @Resource private LocationService locationService; @Resource private MaterialService materialService; @Resource private MaterialTypeService materialTypeService; @Resource private ConfigValueService configValueService; @Resource private ReceiptPreferenceService preferenceService; @Resource private FilterConfigDetailService filterConfigDetailService; @Resource private ContainerService containerService; @Resource private ConfigService configService; @Resource private TaskHeaderService taskHeaderService; @Resource private LocationTypeService locationTypeService; @Resource private TransferTaskService transferTaskService; @Resource private ContainerTypeService containerTypeService; @Resource private LocationAllocationService locationAllocationService; /** * 获取当前单号详情 * @param receiptCode 入库单号 * @return 入库单详情 */ public AjaxResult<List<ReceiptDetail>> scanReceiptCode(String receiptCode) { //根据仓库编码和入库单号查询入库单详情 LambdaQueryWrapper<ReceiptDetail> lambda = new LambdaQueryWrapper<>(); lambda.eq(ReceiptDetail::getReceiptCode, receiptCode) .eq(ReceiptDetail::getWarehouseCode, ShiroUtils.getWarehouseCode()); List<ReceiptDetail> detail = receiptDetailService.list(lambda); return AjaxResult.success(detail); } public String filter(List<Location> locationList, List<LocationType> locationTypeList, Container container){ String containerType1 = container.getContainerType(); LambdaQueryWrapper<ContainerType> containerTypeLambdaQueryWrapper = new LambdaQueryWrapper<>(); containerTypeLambdaQueryWrapper.eq(ContainerType::getCode, containerType1); containerTypeLambdaQueryWrapper.eq(ContainerType::getWarehouseCode, ShiroUtils.getWarehouseCode()); ContainerType containerType = containerTypeService.getOne(containerTypeLambdaQueryWrapper); String locationType = containerType.getLocationType(); String[] locationTypes = locationType.split(","); // List<String> codeList = locationTypeList.stream().map(t-> t.getCode()).collect(Collectors.toList()); List<String> codeList = new ArrayList<>(); for(String type : locationTypes) { codeList.add(type); } List<Location> newLocation = locationList.stream().filter(t-> codeList.contains(t.getLocationType())).collect(Collectors.toList()); if (newLocation.isEmpty()){ return null; } else{ return newLocation.get(0).getCode(); } } /** * 定位 * @param receiptContainerDetail 入库明细 * @return */ @Transactional(rollbackFor = Exception.class) public Boolean position(ReceiptContainerDetail receiptContainerDetail, String area){ ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId()); if (!QuantityConstant.RECEIPT_CONTAINER_BUILD.equals(receiptContainerHeader.getStatus())){ throw new ServiceException(receiptContainerHeader.getContainerCode()+"入库组盘已生成任务不能重新定位"); } //如果入库组盘表中有目标库位说明已经指定 if (StringUtils.isNotEmpty(receiptContainerHeader.getToLocation())){ return true; } /* 判断入盘容器是否在库位上*/ Container container = containerService.getContainerByCode(receiptContainerHeader.getContainerCode()); if (StringUtils.isNotEmpty(container.getLocationCode())) { receiptContainerHeader.setFromLocation(container.getLocationCode()); receiptContainerHeader.setToLocation(container.getLocationCode()); receiptContainerHeader.setTaskType(QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT); if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) { throw new ServiceException("更新定位失败"); } else { return true; } } String value = configService.getKey(QuantityConstant.RULE_ALLOCATION); if (StringUtils.isEmpty(value)) { throw new ServiceException("未绑定定位规则"); } int allocationRule = Integer.parseInt(value); Material material = materialService.getMaterialByCode(receiptContainerDetail.getMaterialCode()); String materialAreaCode = material.getMaterialAreaCode(); String locationCode = locationAllocationService.allocation(allocationRule, null, 0, area, null, ShiroUtils.getWarehouseCode(),container.getCode(), materialAreaCode); if (StringUtils.isNotEmpty(locationCode)){ locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_LOCK); } else { throw new ServiceException("定位失败,请检查定位规则是否正确"); } LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); locationLambdaQueryWrapper.eq(Location::getCode, locationCode); locationLambdaQueryWrapper.eq(Location::getWarehouseCode, ShiroUtils.getWarehouseCode()); Location location = locationService.getOne(locationLambdaQueryWrapper); int rowFlag = location.getRowFlag().intValue(); Integer preTaskNo = 0; //如果是外侧库位,那么就要判断该库位对应的内侧库位是不是有托盘 if(rowFlag == QuantityConstant.ROW_OUT) { Location insideLocation = locationService.getInsideNear(location); if(StringUtils.isNotEmpty(insideLocation.getContainerCode())) { Location destinationLocation = locationService.getEmptyLocation(insideLocation); AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(), destinationLocation.getCode(), ShiroUtils.getWarehouseCode()); preTaskNo = (Integer) ajaxResult.getData(); if(ajaxResult.hasErr()) { throw new ServiceException("创建移库任务失败"); } // taskHeaderService.sendTaskToWcs(Convert.toIntArray(String.valueOf(preTaskNo))); } } //更新库位编码到组盘头表 receiptContainerHeader.setToLocation(locationCode); receiptContainerHeader.setRecvDock("0"); if (!receiptContainerHeaderService.updateById(receiptContainerHeader)){ throw new ServiceException("更新库位失败"); } //把库位编码赋到该入库组盘头表下的所有明细 LambdaUpdateWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaUpdate(); lambda.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId()) .set(ReceiptContainerDetail::getLocationCode, locationCode); if (!receiptContainerDetailService.update(lambda)){throw new ServiceException("更新库位编码到入库组盘明细失败");} ReceiptDetail oldReceiptDetail = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId()); if (!oldReceiptDetail.getProcessStamp().equals("200")) { ReceiptDetail receiptDetail = receiptDetailService.queryflow(oldReceiptDetail); //更新入库单详情状态 if (!receiptDetailService.updateById(receiptDetail)){ throw new ServiceException("更新入库单详情失败");} //更新入库单头尾状态 receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId()); } return true; } /** * 取消定位 * @param receiptContainerDetail 入库组盘明细 * @return */ @Transactional(rollbackFor = Exception.class) public AjaxResult cancelPosition(ReceiptContainerDetail receiptContainerDetail){ //查询入库组盘头 ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId()); if (!(receiptContainerHeader.getStatus().shortValue() == QuantityConstant.RECEIPT_CONTAINER_BUILD)){ throw new ServiceException("组盘已生成任务不能取消定位"); } String locationCode = receiptContainerHeader.getToLocation(); if(StringUtils.isEmpty(locationCode)) { throw new ServiceException("组盘没有定位,不需要取消定位"); } //将入库组盘头表中的而库位编码赋值null receiptContainerHeader.setToLocation(""); if (!receiptContainerHeaderService.updateById(receiptContainerHeader)){ throw new ServiceException("回滚入库组盘头失败"); } //将入库组盘明细的库位修改为空 LambdaQueryWrapper<ReceiptContainerDetail> lambdaQueryWrapper = Wrappers.lambdaQuery(); lambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerDetail.getReceiptContainerId()); List<ReceiptContainerDetail> receiptContainerDetailList = receiptContainerDetailService.list(lambdaQueryWrapper); for (ReceiptContainerDetail receiptContainerDetail2 : receiptContainerDetailList) { receiptContainerDetail2.setLocationCode(""); if (!receiptContainerDetailService.updateById(receiptContainerDetail2)){ throw new ServiceException("回滚入库组盘明细失败"); } } //回滚入库明细状态 ReceiptDetail receiptDetail = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId()); receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_POSITION.toString()); if ( !receiptDetailService.updateById(receiptDetail)){ throw new ServiceException("回滚入库明细状态失败"); } locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_EMPTY); receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId()); return AjaxResult.success("取消定位成功"); } /** * 查找定位规则 * @param receiptContainerHeader 入库组盘头 * @param receiptContainerDetail 入库组盘明细 * @return */ public String findPositionRule(ReceiptContainerHeader receiptContainerHeader, ReceiptContainerDetail receiptContainerDetail) { /* 定位规则*/ String locatingRule = receiptContainerHeader.getLocatingRule(); if (StringUtils.isEmpty(locatingRule)){ locatingRule = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId()).getLocatingRule(); //入库单明细定位规则不为空时执行 if (StringUtils.isEmpty(locatingRule)){ //入库单明细为空时,查询物料表中是否含有定位规则 LambdaQueryWrapper<Material> materialLambda = Wrappers.lambdaQuery(); materialLambda.eq(Material::getCode, receiptContainerDetail.getMaterialCode()) .eq(Material::getWarehouseCode,ShiroUtils.getWarehouseCode()); Material material = materialService.getOne(materialLambda); locatingRule = material.getLocatingRule(); if (StringUtils.isEmpty(locatingRule)){ //物料表中定位规则为空时,查询物料类别 LambdaQueryWrapper<MaterialType> materialTypeLambda = Wrappers.lambdaQuery(); materialTypeLambda.eq(MaterialType::getCode, material.getType()) .eq(MaterialType::getWarehouseCode,ShiroUtils.getWarehouseCode()); MaterialType materialType = materialTypeService.getOne(materialTypeLambda); locatingRule = materialType.getLocatingRule(); if (StringUtils.isEmpty(locatingRule)){ //物料类别中定位规则为空时,查询入库首选项 LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery(); configValueLambda.eq(ConfigValue::getWarehouseCode, ShiroUtils.getWarehouseCode()) .eq(ConfigValue::getModuleType, "receipt") .eq(ConfigValue::getRecordType, "入库首选项"); ConfigValue configValue = configValueService.getOne(configValueLambda); LambdaQueryWrapper<ReceiptPreference> lambdaQueryWrapper = Wrappers.lambdaQuery(); lambdaQueryWrapper.eq(ReceiptPreference::getCode, configValue.getValue()) .eq(ReceiptPreference::getWarehouseCode,ShiroUtils.getWarehouseCode()); locatingRule = preferenceService.getOne(lambdaQueryWrapper).getLocationRule(); } } } } return locatingRule; } }