TaskStocktakingServiceImpl.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package com.jsh.erp.service.impl;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  6. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7. import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
  8. import com.jsh.erp.datasource.entities.*;
  9. import com.jsh.erp.datasource.mappers.*;
  10. import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
  11. import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
  12. import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
  13. import com.jsh.erp.datasource.vo.TaskStocktakingVO;
  14. import com.jsh.erp.query.LambdaQueryWrapperX;
  15. import com.jsh.erp.service.DepotService;
  16. import com.jsh.erp.service.TaskStocktakingService;
  17. import com.jsh.erp.service.UserService;
  18. import com.jsh.erp.utils.DateUtils;
  19. import lombok.RequiredArgsConstructor;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.springframework.beans.BeanUtils;
  22. import org.springframework.stereotype.Service;
  23. import org.springframework.transaction.annotation.Transactional;
  24. import java.math.BigDecimal;
  25. import java.math.RoundingMode;
  26. import java.util.ArrayList;
  27. import java.util.Collections;
  28. import java.util.Date;
  29. import java.util.List;
  30. import java.util.stream.Collectors;
  31. @Service
  32. @RequiredArgsConstructor
  33. @Slf4j
  34. public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMapper, TaskStocktaking> implements TaskStocktakingService {
  35. private final MaterialExtendMapper materialExtendMapper;
  36. private final UserMapper userMapper;
  37. private final DepotService depotService;
  38. private final TaskStocktakingItemMapper taskStocktakingItemMapper;
  39. private final TaskStocktakingMapper taskStocktakingMapper;
  40. private final MaterialMapper materialMapper;
  41. private final UserService userService;
  42. @Override
  43. public List<TaskStocktakingVO> listBy() {
  44. return taskStocktakingMapper.listBy();
  45. }
  46. /**
  47. * 创建盘点任务
  48. * @param taskStocktakingDTO
  49. * @return
  50. */
  51. @Override
  52. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  53. public boolean add(TaskStocktakingDTO taskStocktakingDTO) {
  54. try {
  55. List<String> collect;
  56. List<MaterialExtend> materialExtendList;
  57. //全盘,抽盘,处理任务明细
  58. if (taskStocktakingDTO.getTaskType() == 1) {
  59. materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
  60. collect = materialExtendList
  61. .stream()
  62. .map(MaterialExtend::getPosition)
  63. .collect(Collectors.toList());
  64. List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
  65. List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
  66. List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
  67. taskStocktakingDTO.setCategoryCount(categoryIdList.size());
  68. taskStocktakingDTO.setMaterialCount(materialExtendList.size());
  69. } else {
  70. materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
  71. collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
  72. List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
  73. List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
  74. List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
  75. taskStocktakingDTO.setCategoryCount(categoryIdList.size());
  76. taskStocktakingDTO.setMaterialCount(materialExtendList.size());
  77. }
  78. //处理商品库位范围处理
  79. String positionRange = extractRangePair(collect);
  80. taskStocktakingDTO.setPositionRange(positionRange);
  81. User currentUser = userService.getCurrentUser();
  82. taskStocktakingDTO.setCreateBy(currentUser.getId());
  83. taskStocktakingDTO.setCreateTime(new Date());
  84. taskStocktakingDTO.setTaskStatus(1);
  85. //生成任务
  86. this.save(taskStocktakingDTO);
  87. //生成任务明细
  88. List<TaskStocktakingItem> taskStocktakingItemList = new ArrayList<>();
  89. materialExtendList.forEach(item -> {
  90. TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
  91. taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId());
  92. taskStocktakingItem.setMaterialItemId(item.getId());
  93. taskStocktakingItemList.add(taskStocktakingItem);
  94. });
  95. taskStocktakingItemMapper.insertBatch(taskStocktakingItemList);
  96. } catch (Exception e) {
  97. log.error("创建盘点任务失败", e);
  98. return false;
  99. }
  100. return true;
  101. }
  102. /**
  103. * 任务-详情
  104. * @param id 任务ID
  105. * @return
  106. * @throws Exception
  107. */
  108. @Override
  109. public TaskStocktakingVO detail(Long id) throws Exception{
  110. TaskStocktaking one = getOne(new LambdaQueryWrapperX<TaskStocktaking>().eq(TaskStocktaking::getId, id));
  111. TaskStocktakingVO taskStocktakingVO = new TaskStocktakingVO();
  112. BeanUtils.copyProperties(one, taskStocktakingVO);
  113. //获取负责人名称
  114. User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreator()));
  115. if (user != null) {
  116. taskStocktakingVO.setCreatorName(user.getLoginName());
  117. }
  118. //获取创建人名称
  119. User user1 = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreateBy()));
  120. if (user1 != null) {
  121. taskStocktakingVO.setCreateByName(user1.getLoginName());
  122. }
  123. //获取仓库名称
  124. Depot depot = depotService.getDepot(one.getDepotId());
  125. taskStocktakingVO.setDepotName(depot.getName());
  126. //当任务类型是抽盘时,返回商品盘点信息
  127. return taskStocktakingVO;
  128. }
  129. /**
  130. * 任务详情-修改
  131. * @param taskStocktakingDTO
  132. * @return
  133. */
  134. @Override
  135. public boolean detailUpdate(TaskStocktakingDTO taskStocktakingDTO) {
  136. try {
  137. List<String> collect;
  138. List<MaterialExtend> materialExtendList;
  139. //全盘,抽盘,处理任务明细
  140. if (taskStocktakingDTO.getTaskType() == 1) {
  141. materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
  142. collect = materialExtendList
  143. .stream()
  144. .map(MaterialExtend::getPosition)
  145. .collect(Collectors.toList());
  146. List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
  147. List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
  148. List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
  149. taskStocktakingDTO.setCategoryCount(categoryIdList.size());
  150. taskStocktakingDTO.setMaterialCount(materialExtendList.size());
  151. } else {
  152. materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
  153. collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
  154. List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
  155. List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
  156. List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
  157. taskStocktakingDTO.setCategoryCount(categoryIdList.size());
  158. taskStocktakingDTO.setMaterialCount(materialExtendList.size());
  159. }
  160. //处理商品库位范围处理
  161. String positionRange = extractRangePair(collect);
  162. taskStocktakingDTO.setPositionRange(positionRange);
  163. User currentUser = userService.getCurrentUser();
  164. taskStocktakingDTO.setCreateBy(currentUser.getId());
  165. taskStocktakingDTO.setCreateTime(new Date());
  166. taskStocktakingDTO.setTaskStatus(1);
  167. //生成任务
  168. this.save(taskStocktakingDTO);
  169. List<Long> taskStocktakingItemIdList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapperX<TaskStocktakingItem>().eq(TaskStocktakingItem::getTaskStocktakingId, taskStocktakingDTO.getId())).stream().map(TaskStocktakingItem::getId).collect(Collectors.toList());
  170. //生成任务明细
  171. List<TaskStocktakingItem> addTaskStocktakingItemList = new ArrayList<>();
  172. materialExtendList.forEach(item -> {
  173. if (!taskStocktakingItemIdList.contains(item.getId())) {
  174. TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
  175. taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId());
  176. taskStocktakingItem.setMaterialItemId(item.getId());
  177. addTaskStocktakingItemList.add(taskStocktakingItem);
  178. }
  179. });
  180. List<Long> materialExtendIdList = materialExtendList.stream().map(MaterialExtend::getId).collect(Collectors.toList());
  181. taskStocktakingItemIdList.forEach(item -> {
  182. if (!materialExtendIdList.contains(item)) {
  183. // taskStocktakingItemMapper.updateById();
  184. }
  185. });
  186. if (addTaskStocktakingItemList.size() > 0) {
  187. taskStocktakingItemMapper.insertBatch(addTaskStocktakingItemList);
  188. }
  189. } catch (Exception e) {
  190. log.error("创建盘点任务失败", e);
  191. return false;
  192. }
  193. return true;
  194. }
  195. /**
  196. * 任务详情-商品明细
  197. * @param taskStocktakingId 盘点任务ID
  198. * @return
  199. */
  200. @Override
  201. public List<TaskStocktakingItemVO> listByTaskStocktakingId(Long taskStocktakingId) {
  202. return taskStocktakingItemMapper.listByTaskStocktakingId(taskStocktakingId);
  203. }
  204. /**
  205. * PDA-盘点任务列表
  206. * @param number 盘点单号或者任务名称
  207. * @param taskStatus 盘点任务状态
  208. * @return
  209. */
  210. @Override
  211. public List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus) {
  212. return taskStocktakingMapper.pdaList(number , taskStatus);
  213. }
  214. /**
  215. * PDA-盘点任务详情
  216. * @param id 盘点任务ID
  217. * @return
  218. * @throws Exception
  219. */
  220. @Override
  221. public TaskStocktakingVO pdaDetail(Long id) throws Exception{
  222. TaskStocktakingVO detail = detail(id);
  223. List<TaskStocktakingItem> itemList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapper<TaskStocktakingItem>().eq(TaskStocktakingItem::getTaskStocktakingId, id));
  224. //已操作数量
  225. long finishCount = itemList.stream().filter(item -> item.getCreator() != null).count();
  226. //商品总数量
  227. long itemCount = itemList.size();
  228. //商品差异条数
  229. long itemDifferenceCount = itemList.stream().filter(item -> item.getCreator() != null
  230. && item.getDifferenceCount() != null
  231. && item.getDifferenceCount() > 0).count();
  232. //差异率
  233. double differenceRate = 0;
  234. //准确率
  235. double accuracyRate = 0;
  236. if (itemDifferenceCount > 0) {
  237. differenceRate = BigDecimal.valueOf(itemCount)
  238. .divide(BigDecimal.valueOf(itemDifferenceCount), 4, RoundingMode.HALF_UP)
  239. .doubleValue();
  240. accuracyRate = BigDecimal.valueOf(itemCount)
  241. .divide(BigDecimal.valueOf(finishCount)
  242. .subtract(BigDecimal.valueOf(itemDifferenceCount)), 4, RoundingMode.HALF_UP)
  243. .doubleValue();
  244. }
  245. detail.setDifferenceRate(differenceRate);
  246. detail.setAccuracyRate(accuracyRate);
  247. detail.setFinishCount(finishCount);
  248. return detail;
  249. }
  250. @Override
  251. public List<PDATaskStocktakingItemVO> pdaItemList(Long taskId) {
  252. return taskStocktakingItemMapper.pdaList(taskId);
  253. }
  254. /**
  255. * 计算库位范围
  256. * @param data 库位集合
  257. * @return
  258. */
  259. public static String extractRangePair(List<String> data) {
  260. // 用于存储提取的前两部分
  261. List<String> rangeParts = new ArrayList<>();
  262. for (String item : data) {
  263. // 提取前两部分(假设格式固定,以 "-" 分割,取前两部分)
  264. String[] parts = item.split("-");
  265. if (parts.length >= 2) {
  266. String rangePart = parts[0] + "-" + parts[1];
  267. rangeParts.add(rangePart); // 添加到列表
  268. }
  269. }
  270. // 如果范围为空,直接返回空字符串
  271. if (rangeParts.isEmpty()) {
  272. return "";
  273. }
  274. // 找到最小和最大范围
  275. String minRange = Collections.min(rangeParts); // 字典序最小
  276. String maxRange = Collections.max(rangeParts); // 字典序最大
  277. // 返回范围对
  278. return minRange + "——" + maxRange;
  279. }
  280. }