package com.jsh.erp.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.jsh.erp.datasource.dto.TaskStocktakingDTO; import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO; import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO; import com.jsh.erp.datasource.entities.*; import com.jsh.erp.datasource.mappers.*; import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO; import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO; import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO; import com.jsh.erp.datasource.vo.TaskStocktakingItemVO; import com.jsh.erp.datasource.vo.TaskStocktakingVO; import com.jsh.erp.query.LambdaQueryWrapperX; import com.jsh.erp.service.DepotService; import com.jsh.erp.service.SequenceService; import com.jsh.erp.service.TaskStocktakingService; import com.jsh.erp.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @Service @RequiredArgsConstructor @Slf4j public class TaskStocktakingServiceImpl extends ServiceImpl implements TaskStocktakingService { private final MaterialExtendMapper materialExtendMapper; private final UserMapper userMapper; private final DepotService depotService; private final TaskStocktakingItemMapper taskStocktakingItemMapper; private final TaskStocktakingMapper taskStocktakingMapper; private final MaterialMapper materialMapper; private final UserService userService; private final SequenceService sequenceService; @Override public List listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO) { return taskStocktakingMapper.listBy(taskStocktakingQueryDTO); } /** * 创建盘点任务 * @param taskStocktakingDTO * @return */ @Override @Transactional(value = "transactionManager", rollbackFor = Exception.class) public boolean add(TaskStocktakingDTO taskStocktakingDTO) { try { List collect; List materialExtendList; //全盘,抽盘,处理任务明细 if (taskStocktakingDTO.getTaskType() == 1) { materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory)); collect = materialExtendList .stream() .map(MaterialExtend::getPosition) .collect(Collectors.toList()); List materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList()); List materialList = materialMapper.selectList(new LambdaQueryWrapperX().eq(Material::getId, materialIdList)); List categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList()); taskStocktakingDTO.setCategoryCount(categoryIdList.size()); taskStocktakingDTO.setMaterialCount(materialExtendList.size()); } else { materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList())); collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList()); List materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList()); List materialList = materialMapper.selectList(new LambdaQueryWrapperX().in(Material::getId, materialIdList)); List categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList()); taskStocktakingDTO.setCategoryCount(categoryIdList.size()); taskStocktakingDTO.setMaterialCount(materialExtendList.size()); } //处理商品库位范围处理 String positionRange = extractRangePair(collect); taskStocktakingDTO.setPositionRange(positionRange); User currentUser = userService.getCurrentUser(); taskStocktakingDTO.setCreateBy(currentUser.getId()); taskStocktakingDTO.setCreateTime(new Date()); taskStocktakingDTO.setTaskStatus(1); //生成单据编号 taskStocktakingDTO.setNumber("PDRW"+sequenceService.buildOnlyNumber()); //生成任务 this.save(taskStocktakingDTO); //生成任务明细 List taskStocktakingItemList = new ArrayList<>(); materialExtendList.forEach(item -> { TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem(); taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId()); taskStocktakingItem.setMaterialItemId(item.getId()); taskStocktakingItemList.add(taskStocktakingItem); }); taskStocktakingItemMapper.insertBatch(taskStocktakingItemList); } catch (Exception e) { log.error("创建盘点任务失败", e); return false; } return true; } /** * 任务-详情 * @param id 任务ID * @return * @throws Exception */ @Override public TaskStocktakingVO detail(Long id) throws Exception{ TaskStocktaking one = getOne(new LambdaQueryWrapperX().eq(TaskStocktaking::getId, id)); TaskStocktakingVO taskStocktakingVO = new TaskStocktakingVO(); BeanUtils.copyProperties(one, taskStocktakingVO); //获取负责人名称 User user = userMapper.selectOne(new LambdaQueryWrapper().eq(User::getId, one.getCreator())); if (user != null) { taskStocktakingVO.setCreatorName(user.getLoginName()); } //获取创建人名称 User user1 = userMapper.selectOne(new LambdaQueryWrapper().eq(User::getId, one.getCreateBy())); if (user1 != null) { taskStocktakingVO.setCreateByName(user1.getLoginName()); } //获取仓库名称 Depot depot = depotService.getDepot(one.getDepotId()); taskStocktakingVO.setDepotName(depot.getName()); //当任务类型是抽盘时,返回商品盘点信息 return taskStocktakingVO; } /** * 任务详情-修改 * @param taskStocktakingDTO * @return */ @Override public boolean detailUpdate(TaskStocktakingDTO taskStocktakingDTO) { try { List collect; List materialExtendList; //全盘,抽盘,处理任务明细 if (taskStocktakingDTO.getTaskType() == 1) { materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory)); collect = materialExtendList .stream() .map(MaterialExtend::getPosition) .collect(Collectors.toList()); List materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList()); List materialList = materialMapper.selectList(new LambdaQueryWrapperX().eq(Material::getId, materialIdList)); List categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList()); taskStocktakingDTO.setCategoryCount(categoryIdList.size()); taskStocktakingDTO.setMaterialCount(materialExtendList.size()); } else { materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList())); collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList()); List materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList()); List materialList = materialMapper.selectList(new LambdaQueryWrapperX().in(Material::getId, materialIdList)); List categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList()); taskStocktakingDTO.setCategoryCount(categoryIdList.size()); taskStocktakingDTO.setMaterialCount(materialExtendList.size()); } //处理商品库位范围处理 String positionRange = extractRangePair(collect); taskStocktakingDTO.setPositionRange(positionRange); User currentUser = userService.getCurrentUser(); taskStocktakingDTO.setCreateBy(currentUser.getId()); taskStocktakingDTO.setCreateTime(new Date()); taskStocktakingDTO.setTaskStatus(1); //生成任务 this.updateById(taskStocktakingDTO); List taskStocktakingItemIdList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapperX().eq(TaskStocktakingItem::getTaskStocktakingId, taskStocktakingDTO.getId())).stream().map(TaskStocktakingItem::getId).collect(Collectors.toList()); //生成任务明细 List addTaskStocktakingItemList = new ArrayList<>(); materialExtendList.forEach(item -> { if (!taskStocktakingItemIdList.contains(item.getId())) { TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem(); taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId()); taskStocktakingItem.setMaterialItemId(item.getId()); addTaskStocktakingItemList.add(taskStocktakingItem); } }); List materialExtendIdList = materialExtendList.stream().map(MaterialExtend::getId).collect(Collectors.toList()); taskStocktakingItemIdList.forEach(item -> { if (!materialExtendIdList.contains(item)) { TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem(); taskStocktakingItem.setId(item); taskStocktakingItem.setDeleteFlag(true); taskStocktakingItemMapper.updateById(taskStocktakingItem); } }); if (addTaskStocktakingItemList.size() > 0) { taskStocktakingItemMapper.insertBatch(addTaskStocktakingItemList); } } catch (Exception e) { log.error("修改盘点任务失败", e); return false; } return true; } /** * 任务详情-商品明细 * @param taskStocktakingItemQueryDTO 筛选参数 * @return */ @Override public List listByTaskStocktakingId(TaskStocktakingItemQueryDTO taskStocktakingItemQueryDTO) { return taskStocktakingItemMapper.listByTaskStocktakingId(taskStocktakingItemQueryDTO); } /** * PDA-盘点任务列表 * @param number 盘点单号或者任务名称 * @param taskStatus 盘点任务状态 * @return */ @Override public List pdaList(String number , Integer taskStatus) { return taskStocktakingMapper.pdaList(number , taskStatus); } /** * PDA-盘点任务详情 * @param id 盘点任务ID * @return * @throws Exception */ @Override public TaskStocktakingVO pdaDetail(Long id) throws Exception{ TaskStocktakingVO detail = detail(id); List itemList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapper().eq(TaskStocktakingItem::getTaskStocktakingId, id)); //已操作数量 long finishCount = itemList.stream().filter(item -> item.getCreator() != null).count(); //操作人数 long operCount = itemList.stream().filter(item -> item.getCreator() != null).map(TaskStocktakingItem::getCreator).distinct().count(); //商品总数量 long itemCount = itemList.size(); //商品差异条数 long itemDifferenceCount = itemList.stream().filter(item -> item.getCreator() != null && item.getDifferenceCount() != null && item.getDifferenceCount() > 0).count(); //差异率 double differenceRate = 0; //准确率 double accuracyRate = 100; if (itemDifferenceCount > 0) { //差异率 = 商品差异条数/商品总数量*100% differenceRate = BigDecimal.valueOf(itemDifferenceCount) .divide(BigDecimal.valueOf(itemCount), 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)) .doubleValue(); //准确数 = 已操作数量-商品差异条数 BigDecimal subtract = BigDecimal.valueOf(finishCount).subtract(BigDecimal.valueOf(itemDifferenceCount)); //准确率 = 准确数/商品总数量*100% if (!subtract.equals(BigDecimal.ZERO)) { accuracyRate = subtract.divide(BigDecimal.valueOf(itemCount), 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)) .doubleValue(); } } detail.setItemCount(itemCount); detail.setDifferenceRate(differenceRate); detail.setAccuracyRate(accuracyRate); detail.setFinishCount(finishCount); detail.setOperCount(operCount); return detail; } @Override public List pdaItemList(PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO) { return taskStocktakingItemMapper.pdaList(pdaTaskStocktakingItemDTO); } /** * 计算库位范围 * @param data 库位集合 * @return */ public static String extractRangePair(List data) { // 用于存储提取的前两部分 List rangeParts = new ArrayList<>(); for (String item : data) { // 提取前两部分(假设格式固定,以 "-" 分割,取前两部分) String[] parts = item.split("-"); if (parts.length >= 2) { String rangePart = parts[0] + "-" + parts[1]; rangeParts.add(rangePart); // 添加到列表 } } // 如果范围为空,直接返回空字符串 if (rangeParts.isEmpty()) { return ""; } // 找到最小和最大范围 String minRange = Collections.min(rangeParts); // 字典序最小 String maxRange = Collections.max(rangeParts); // 字典序最大 // 返回范围对 return minRange + "——" + maxRange; } }