From 1e123568c2f561013f5636e45dc0db30b17a3517 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 10 九月 2026 16:39:26 +0800
Subject: [PATCH] feat(basic): 添加产品条码功能并完善生产统计报表
---
src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java | 417 +++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 347 insertions(+), 70 deletions(-)
diff --git a/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java b/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
index 09d85df..0aabe70 100644
--- a/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
+++ b/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.technology.service.impl;
+import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -11,27 +12,37 @@
import com.ruoyi.basic.service.IProductService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.dto.BomImportDto;
-import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.procurementrecord.pojo.ProcurementDemand;
+import com.ruoyi.procurementrecord.service.ProcurementDemandService;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.technology.bean.dto.BomImportDto;
+import com.ruoyi.technology.bean.dto.BomKitCheckDto;
import com.ruoyi.technology.bean.dto.TechnologyBomDto;
+import com.ruoyi.technology.bean.dto.TechnologyBomStructureDto;
+import com.ruoyi.technology.bean.vo.BomKitCheckItemVo;
+import com.ruoyi.technology.bean.vo.TechnologyBomStructureVo;
import com.ruoyi.technology.bean.vo.TechnologyBomVo;
import com.ruoyi.technology.mapper.TechnologyBomMapper;
+import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
import com.ruoyi.technology.pojo.TechnologyBom;
import com.ruoyi.technology.pojo.TechnologyBomStructure;
import com.ruoyi.technology.pojo.TechnologyRouting;
import com.ruoyi.technology.service.TechnologyBomService;
import com.ruoyi.technology.service.TechnologyBomStructureService;
+import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
-import jakarta.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
@Service
@@ -43,6 +54,9 @@
private final TechnologyBomStructureService technologyBomStructureService;
private final TechnologyRoutingMapper technologyRoutingMapper;
private final IProductService productService;
+ private final TechnologyBomStructureMapper technologyBomStructureMapper;
+ private final StockInventoryMapper stockInventoryMapper;
+ private final ProcurementDemandService procurementDemandService;
/**
* 鍒嗛〉鏌ヨBOM鍒楄〃銆�
@@ -84,12 +98,18 @@
@Transactional(rollbackFor = Exception.class)
public R add(TechnologyBom technologyBom) {
validateProductModel(technologyBom.getProductModelId());
+ if (technologyBom.getStatus() == null) {
+ technologyBom.setStatus(1);
+ }
boolean saved = technologyBomMapper.insert(technologyBom) > 0;
if (!saved) {
return R.fail("Add BOM failed");
}
technologyBom.setBomNo("BM." + String.format("%05d", technologyBom.getId()));
technologyBomMapper.updateById(technologyBom);
+ if (Integer.valueOf(1).equals(technologyBom.getStatus())) {
+ deactivateOtherVersions(technologyBom.getProductModelId(), technologyBom.getId().longValue());
+ }
initRootStructure(technologyBom.getId().longValue(), technologyBom.getProductModelId());
return R.ok();
}
@@ -101,12 +121,12 @@
@Transactional(rollbackFor = Exception.class)
public R update(TechnologyBom technologyBom) {
if (technologyBom.getId() == null) {
- throw new ServiceException("BOM id is required");
+ throw new ServiceException("BOM ID涓嶈兘涓虹┖");
}
validateProductModel(technologyBom.getProductModelId());
TechnologyBom oldBom = technologyBomMapper.selectById(technologyBom.getId());
if (oldBom == null) {
- throw new ServiceException("BOM not found");
+ throw new ServiceException("BOM涓嶅瓨鍦�");
}
if (oldBom.getProductModelId() != null && !oldBom.getProductModelId().equals(technologyBom.getProductModelId())) {
technologyRoutingMapper.updateProductModelByBomId(technologyBom.getProductModelId(), technologyBom.getId().longValue());
@@ -118,7 +138,24 @@
technologyBom.setBomNo(oldBom.getBomNo());
}
technologyBomMapper.updateById(technologyBom);
+ if (Integer.valueOf(1).equals(technologyBom.getStatus())) {
+ deactivateOtherVersions(technologyBom.getProductModelId(), technologyBom.getId().longValue());
+ }
return R.ok();
+ }
+
+ /**
+ * 鍚屼竴浜у搧瑙勬牸鍙繚鐣欎竴涓惎鐢ㄧ増鏈�
+ */
+ private void deactivateOtherVersions(Long productModelId, Long keepId) {
+ if (productModelId == null) {
+ return;
+ }
+ technologyBomMapper.update(null, Wrappers.<TechnologyBom>lambdaUpdate()
+ .set(TechnologyBom::getStatus, 0)
+ .eq(TechnologyBom::getProductModelId, productModelId)
+ .ne(TechnologyBom::getId, keepId)
+ .eq(TechnologyBom::getStatus, 1));
}
/**
@@ -126,14 +163,14 @@
*/
@Override
@Transactional(rollbackFor = Exception.class)
- public boolean batchDelete(List<Integer> ids) {
+ public boolean batchDelete(List<Long> ids) {
if (ids == null || ids.isEmpty()) {
- throw new ServiceException("Select at least one BOM");
+ throw new ServiceException("璇疯嚦灏戦�夋嫨涓�涓狟OM");
}
List<TechnologyRouting> list = technologyRoutingMapper.selectList(Wrappers.<TechnologyRouting>lambdaQuery()
.in(TechnologyRouting::getBomId, ids));
if (!list.isEmpty()) {
- throw new ServiceException("BOM is referenced by routing");
+ throw new ServiceException("BOM宸茶宸ヨ壓璺嚎寮曠敤锛屼笉鑳藉垹闄�");
}
technologyBomStructureService.remove(Wrappers.<TechnologyBomStructure>lambdaQuery()
.in(TechnologyBomStructure::getBomId, ids));
@@ -145,11 +182,11 @@
*/
private void validateProductModel(Long productModelId) {
if (productModelId == null) {
- throw new ServiceException("Product model is required");
+ throw new ServiceException("浜у搧瑙勬牸ID涓嶈兘涓虹┖");
}
ProductModel productModel = productModelService.getById(productModelId);
if (productModel == null) {
- throw new ServiceException("Product model not found");
+ throw new ServiceException("浜у搧瑙勬牸涓嶅瓨鍦�");
}
}
@@ -256,70 +293,100 @@
@Override
- public void exportBom(HttpServletResponse response, Integer bomId) {
+ public void exportBom(HttpServletResponse response, Long bomId) {
if (bomId == null) {
+ throw new ServiceException("BOM ID涓嶈兘涓虹┖");
+ }
+
+ List<TechnologyBomStructureVo> treeData = technologyBomStructureService.listByBomId(bomId);
+ if (treeData == null || treeData.isEmpty()) {
return;
}
-// List<ProductStructureDto> treeData = productStructureService.listBybomId(bomId);
-// if (treeData == null || treeData.isEmpty()) {
-// return;
-// }
-//
-// // 灏嗘爲褰㈢粨鏋勬墎骞冲寲 浣跨敤 BFS绠楁硶 瀵煎嚭,鎸夊眰绾ч『搴�
-// List<BomImportDto> exportList = new ArrayList<>();
-//
-// // Map<ID, Node> idMap 鐢ㄤ簬鏌ユ壘鐖惰妭鐐�
-// Map<Long, ProductStructureDto> idMap = new HashMap<>();
-// populateMap(treeData, idMap);
-//
-// // treeData 鐨勭涓�涓槸鏍硅妭鐐�
-// for (ProductStructureDto root : treeData) {
-// // 娣诲姞鏍硅妭鐐�
-// BomImportDto rootRow = new BomImportDto();
-// rootRow.setParentName(root.getProductName());
-// rootRow.setParentSpec(root.getModel());
-// rootRow.setUnitQty(root.getUnitQuantity());
-// rootRow.setRemark("");
-// exportList.add(rootRow);
-//
-// // BFS 閬嶅巻-闃熷垪
-// Queue<ProductStructureDto> queue = new LinkedList<>();
-// if (root.getChildren() != null) {
-// queue.addAll(root.getChildren());
-// }
-//
-// while (!queue.isEmpty()) {
-// ProductStructureDto child = queue.poll();
-//
-// // 鏌ユ壘鐖惰妭鐐�
-// ProductStructureDto parent = idMap.get(child.getParentId());
-// if (parent == null) {
-// // 闄や簡鏈�澶栧眰鑺傜偣,鍏朵粬鑺傜偣鐨勭埗绫昏偗瀹氭槸涓嶄細涓虹┖鐨�
-// continue;
-// }
-//
-// BomImportDto row = new BomImportDto();
-// // 鐖剁被淇℃伅
-// row.setParentName(parent.getProductName());
-// row.setParentSpec(parent.getModel());
-// // 瀛愮被淇℃伅
-// row.setChildName(child.getProductName());
-// row.setChildSpec(child.getModel());
-// row.setUnitQty(child.getUnitQuantity());
-// row.setProcess(child.getProcessName());
-//
-// exportList.add(row);
-//
-// // 灏嗗瓙鑺傜偣鐨勫瓙鑺傜偣鍔犲叆闃熷垪-涓嬩竴灞�
-// if (child.getChildren() != null && !child.getChildren().isEmpty()) {
-// queue.addAll(child.getChildren());
-// }
-// }
-// }
+ // 灏嗘爲褰㈢粨鏋勬墎骞冲寲 浣跨敤 BFS绠楁硶 瀵煎嚭,鎸夊眰绾ч『搴�
+ List<BomImportDto> exportList = new ArrayList<>();
+
+ // Map<ID, Node> idMap 鐢ㄤ簬鏌ユ壘鐖惰妭鐐�
+ Map<Long, TechnologyBomStructureVo> idMap = new HashMap<>();
+ populateMap(treeData, idMap);
+
+ // treeData 鐨勭涓�涓槸鏍硅妭鐐�
+ for (TechnologyBomStructureVo root : treeData) {
+ // 娣诲姞鏍硅妭鐐�
+ BomImportDto rootRow = new BomImportDto();
+ rootRow.setParentName(root.getProductName());
+ rootRow.setParentSpec(root.getModel());
+ rootRow.setUnitQty(root.getUnitQuantity());
+ rootRow.setParentCode(root.getProductCode());
+ rootRow.setRemark("");
+ exportList.add(rootRow);
+
+ // BFS 閬嶅巻-闃熷垪
+ Queue<TechnologyBomStructureVo> queue = new LinkedList<>();
+ if (root.getChildren() != null) {
+ queue.addAll(root.getChildren());
+ }
+
+ while (!queue.isEmpty()) {
+ TechnologyBomStructureVo child = queue.poll();
+
+ // 鏌ユ壘鐖惰妭鐐�
+ TechnologyBomStructureVo parent = idMap.get(child.getParentId());
+ if (parent == null) {
+ // 闄や簡鏈�澶栧眰鑺傜偣,鍏朵粬鑺傜偣鐨勭埗绫昏偗瀹氭槸涓嶄細涓虹┖鐨�
+ continue;
+ }
+
+ BomImportDto row = new BomImportDto();
+ // 鐖剁被淇℃伅
+ row.setParentName(parent.getProductName());
+ row.setParentSpec(parent.getModel());
+ // 瀛愮被淇℃伅
+ row.setChildName(child.getProductName());
+ row.setChildSpec(child.getModel());
+ row.setUnitQty(child.getUnitQuantity());
+ row.setProcess(child.getOperationName());
+ row.setChildCode(child.getProductCode());
+
+ exportList.add(row);
+
+ // 灏嗗瓙鑺傜偣鐨勫瓙鑺傜偣鍔犲叆闃熷垪-涓嬩竴灞�
+ if (child.getChildren() != null && !child.getChildren().isEmpty()) {
+ queue.addAll(child.getChildren());
+ }
+ }
+ }
ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class);
-// util.exportExcel(response, exportList, "BOM缁撴瀯瀵煎嚭");
+ util.exportExcel(response, exportList, "BOM缁撴瀯瀵煎嚭");
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R copy(TechnologyBom technologyBom) {
+ TechnologyBom oldTechnologyBom = technologyBomMapper.selectById(technologyBom.getId());
+ List<TechnologyBomStructureVo> oldTechnologyBomStructureVos = technologyBomStructureService.listByBomId(technologyBom.getId().longValue());
+ //鏍¢獙浜у搧瑙勬牸鏄惁瀛樺湪銆�
+ validateProductModel(oldTechnologyBom.getProductModelId());
+ TechnologyBom newTechnologyBom = new TechnologyBom();
+ newTechnologyBom.setProductModelId(oldTechnologyBom.getProductModelId());
+ newTechnologyBom.setVersion("FZ" + oldTechnologyBom.getVersion());
+ newTechnologyBom.setRemark(oldTechnologyBom.getRemark());
+ newTechnologyBom.setStatus(0);
+ boolean saved = technologyBomMapper.insert(newTechnologyBom) > 0;
+ if (!saved) {
+ return R.fail("Copy BOM failed");
+ }
+ newTechnologyBom.setBomNo("BM." + String.format("%05d", newTechnologyBom.getId()));
+ technologyBomMapper.updateById(newTechnologyBom);
+ //鍒濆鍖朆OM鏍硅妭鐐圭粨鏋勩��
+ initRootStructure(newTechnologyBom.getId().longValue(), newTechnologyBom.getProductModelId());
+ //鎶婁骇鍝佺粨鏋勯噷闈㈢殑鏁版嵁涔熷叏閮ㄩ兘澶嶅埗
+ TechnologyBomStructureVo technologyBomStructureVo = oldTechnologyBomStructureVos.get(0);
+ TechnologyBomStructureDto technologyBomStructureDto = convertTree(technologyBomStructureVo);
+ technologyBomStructureDto.setBomId(newTechnologyBom.getId().longValue());
+ technologyBomStructureService.addTechnologyBomStructure(technologyBomStructureDto);
+ return R.ok();
}
private ProductModel findModel(String name, String spec) {
@@ -374,13 +441,223 @@
return s.replaceAll("[\\u00A0\\u3000]", "").trim();
}
- private void populateMap(List<ProductStructureDto> nodes, Map<Long, ProductStructureDto> map) {
+ private void populateMap(List<TechnologyBomStructureVo> nodes, Map<Long, TechnologyBomStructureVo> map) {
if (nodes == null || nodes.isEmpty()) {
return;
}
- for (ProductStructureDto node : nodes) {
+ for (TechnologyBomStructureVo node : nodes) {
map.put(node.getId(), node);
populateMap(node.getChildren(), map);
}
}
+
+ /**
+ * 閫掑綊杞崲鏍戝舰缁撴瀯 VO -> DTO
+ * 鑷姩鐢熸垚铏氭嫙 tempId / parentTempId锛屼繚璇佷换鎰忓眰绾ф爲缁撴瀯姝g‘
+ */
+ public static TechnologyBomStructureDto convertTree(TechnologyBomStructureVo vo) {
+ if (vo == null) {
+ return null;
+ }
+ TechnologyBomStructureDto realDto = convertNode(vo, "0"); // 鏍硅妭鐐圭埗ID=0锛堢函鏁板瓧锛�
+ TechnologyBomStructureDto rootDto = new TechnologyBomStructureDto();
+ rootDto.setTempId("0");
+ rootDto.setChildren(Collections.singletonList(realDto));
+
+ return rootDto;
+ }
+
+ /**
+ * 鏍稿績閫掑綊鏂规硶
+ * @param vo 鍘熷鑺傜偣
+ * @param parentTempId 鐖惰妭鐐� 绾暟瀛桰D
+ * @return 杞崲鍚嶥TO
+ */
+ private static TechnologyBomStructureDto convertNode(TechnologyBomStructureVo vo, String parentTempId) {
+ if (vo == null) {
+ return null;
+ }
+
+ TechnologyBomStructureDto dto = new TechnologyBomStructureDto();
+ BeanUtils.copyProperties(vo, dto);
+
+ String currentTempId = getNumberId();
+ dto.setTempId(currentTempId);
+ dto.setParentTempId(parentTempId);
+
+
+ dto.setId(null);
+ dto.setParentId(null);
+
+ // ===================== 閫掑綊瀛愯妭鐐� =====================
+ List<TechnologyBomStructureVo> voChildren = vo.getChildren();
+ if (CollUtil.isNotEmpty(voChildren)) {
+ List<TechnologyBomStructureDto> dtoChildren = new ArrayList<>();
+ for (TechnologyBomStructureVo childVo : voChildren) {
+ // 瀛愯妭鐐圭殑鐖禝D = 褰撳墠鑺傜偣鐨勬暟瀛桰D
+ dtoChildren.add(convertNode(childVo, currentTempId));
+ }
+ dto.setChildren(dtoChildren);
+ } else {
+ dto.setChildren(new ArrayList<>());
+ }
+
+ return dto;
+ }
+
+ /**
+ * 鐢熸垚 13浣� 绾暟瀛楅殢鏈篒D锛堝畨鍏ㄣ�佷笉閲嶅銆侀珮鎬ц兘锛�
+ */
+ private static String getNumberId() {
+ // 鐢熸垚 1000000000000 ~ 9999999999999 涔嬮棿鐨勬暟瀛�
+ long min = 1000000000000L;
+ long max = 9999999999999L;
+ long randomNum = ThreadLocalRandom.current().nextLong(min, max + 1);
+ return String.valueOf(randomNum);
+ }
+
+ /**
+ * BOM榻愬鍒嗘瀽锛氶�愬眰灞曞紑鏍戯紙闇�姹傞噺=鐖堕渶姹偯楀崟浣嶇敤閲忥級锛屾寜瑙勬牸姹囨�诲悗涓庡彲鐢ㄥ簱瀛樻瘮瀵广��
+ * 鍙敤搴撳瓨 = 危(搴撳瓨鏁伴噺 - 閿佸畾鏁伴噺)锛岀己鍙� = max(闇�姹傞噺 - 鍙敤搴撳瓨, 0)銆�
+ */
+ @Override
+ public List<BomKitCheckItemVo> kitCheck(BomKitCheckDto dto) {
+ if (dto == null || dto.getBomId() == null || dto.getDemandQty() == null
+ || dto.getDemandQty().compareTo(BigDecimal.ZERO) <= 0) {
+ throw new ServiceException("璇蜂紶鍏omId鍜岄渶姹傛暟閲�(椤诲ぇ浜�0)");
+ }
+ TechnologyBom bom = technologyBomMapper.selectById(dto.getBomId());
+ if (bom == null) {
+ throw new ServiceException("BOM涓嶅瓨鍦�");
+ }
+ List<TechnologyBomStructureVo> roots = technologyBomStructureService.listByBomId(dto.getBomId());
+ if (CollUtil.isEmpty(roots)) {
+ throw new ServiceException("BOM缁撴瀯涓虹┖锛岃鍏堢淮鎶ょ墿鏂欐竻鍗�");
+ }
+
+ Map<Long, BigDecimal> requiredMap = new LinkedHashMap<>();
+ for (TechnologyBomStructureVo root : roots) {
+ expandRequirements(root, dto.getDemandQty(), requiredMap, true);
+ }
+ if (requiredMap.isEmpty()) {
+ throw new ServiceException("BOM涓嬫棤鐗╂枡鑺傜偣");
+ }
+
+ Map<Long, BigDecimal> availMap = new HashMap<>();
+ List<StockInventory> stocks = stockInventoryMapper.selectList(Wrappers.<StockInventory>lambdaQuery()
+ .in(StockInventory::getProductModelId, requiredMap.keySet()));
+ for (StockInventory s : stocks) {
+ BigDecimal avail = s.getQualitity() == null ? BigDecimal.ZERO : s.getQualitity();
+ avail = avail.subtract(s.getLockedQuantity() == null ? BigDecimal.ZERO : s.getLockedQuantity());
+ availMap.merge(s.getProductModelId(), avail, BigDecimal::add);
+ }
+
+ List<ProductModel> models = productModelService.listByIds(requiredMap.keySet());
+ Map<Long, ProductModel> modelMap = models.stream()
+ .collect(Collectors.toMap(ProductModel::getId, m -> m, (a, b) -> a));
+ Map<Long, String> productNameMap = new HashMap<>();
+ Set<Long> productIds = models.stream().map(ProductModel::getProductId)
+ .filter(Objects::nonNull).collect(Collectors.toSet());
+ if (!productIds.isEmpty()) {
+ productService.listByIds(productIds)
+ .forEach(p -> productNameMap.put(p.getId().longValue(), p.getProductName()));
+ }
+
+ List<BomKitCheckItemVo> result = new ArrayList<>();
+ for (Map.Entry<Long, BigDecimal> entry : requiredMap.entrySet()) {
+ BigDecimal required = entry.getValue();
+ BigDecimal available = availMap.getOrDefault(entry.getKey(), BigDecimal.ZERO);
+ ProductModel pm = modelMap.get(entry.getKey());
+ BomKitCheckItemVo vo = new BomKitCheckItemVo();
+ vo.setProductModelId(entry.getKey());
+ vo.setProductName(pm == null ? null : productNameMap.get(pm.getProductId()));
+ vo.setModel(pm == null ? null : pm.getModel());
+ vo.setUnit(pm == null ? null : pm.getUnit());
+ vo.setRequiredQty(required);
+ vo.setAvailableQty(available);
+ vo.setShortageQty(required.subtract(available).max(BigDecimal.ZERO));
+ result.add(vo);
+ }
+ result.sort(Comparator.comparing(BomKitCheckItemVo::getShortageQty).reversed());
+ return result;
+ }
+
+ private void expandRequirements(TechnologyBomStructureVo node, BigDecimal requiredQty,
+ Map<Long, BigDecimal> requiredMap, boolean isRoot) {
+ if (!isRoot && node.getProductModelId() != null) {
+ requiredMap.merge(node.getProductModelId(), requiredQty, BigDecimal::add);
+ }
+ if (CollUtil.isNotEmpty(node.getChildren())) {
+ for (TechnologyBomStructureVo child : node.getChildren()) {
+ BigDecimal unitQty = child.getUnitQuantity() == null ? BigDecimal.ZERO : child.getUnitQuantity();
+ expandRequirements(child, requiredQty.multiply(unitQty), requiredMap, false);
+ }
+ }
+ }
+
+ /**
+ * 灏嗙己鍙g墿鏂欏啓鍏ラ噰璐渶姹傦細鍚岃鏍煎凡瀛樺湪寰呭鐞嗚褰曞垯绱姞缂哄彛锛屽惁鍒欐柊澧炪��
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R generateProcurementDemand(BomKitCheckDto dto) {
+ List<BomKitCheckItemVo> items = kitCheck(dto);
+ List<BomKitCheckItemVo> shortages = items.stream()
+ .filter(item -> item.getShortageQty().compareTo(BigDecimal.ZERO) > 0)
+ .collect(Collectors.toList());
+ if (shortages.isEmpty()) {
+ return R.ok("搴撳瓨榻愬锛屾棤闇�鐢熸垚閲囪喘闇�姹�");
+ }
+ TechnologyBom bom = technologyBomMapper.selectById(dto.getBomId());
+ int created = 0;
+ int merged = 0;
+ for (BomKitCheckItemVo item : shortages) {
+ ProcurementDemand exist = procurementDemandService.getOne(Wrappers.<ProcurementDemand>lambdaQuery()
+ .eq(ProcurementDemand::getProductModelId, item.getProductModelId())
+ .eq(ProcurementDemand::getStatus, 0)
+ .last("limit 1"));
+ if (exist != null) {
+ exist.setDemandQuantity(exist.getDemandQuantity().add(item.getShortageQty()));
+ exist.setStockQuantity(item.getAvailableQty());
+ exist.setSourceBomId(dto.getBomId());
+ exist.setSourceBomNo(bom == null ? null : bom.getBomNo());
+ procurementDemandService.updateById(exist);
+ merged++;
+ } else {
+ ProcurementDemand demand = new ProcurementDemand();
+ demand.setProductModelId(item.getProductModelId());
+ demand.setProductName(item.getProductName());
+ demand.setProductModel(item.getModel());
+ demand.setUnit(item.getUnit());
+ demand.setDemandQuantity(item.getShortageQty());
+ demand.setStockQuantity(item.getAvailableQty());
+ demand.setSourceBomId(dto.getBomId());
+ demand.setSourceBomNo(bom == null ? null : bom.getBomNo());
+ demand.setStatus(0);
+ procurementDemandService.save(demand);
+ created++;
+ }
+ }
+ return R.ok(String.format("閲囪喘闇�姹傜敓鎴愬畬鎴愶細鏂板 %d 鏉★紝绱姞鍚堝苟 %d 鏉�", created, merged));
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R changeStatus(Integer id, Integer status) {
+ if (id == null || status == null || (status != 0 && status != 1)) {
+ return R.fail("鍙傛暟閿欒锛氶渶浼犲叆id鍜岀姸鎬�(1鍚敤/0鍋滅敤)");
+ }
+ TechnologyBom bom = technologyBomMapper.selectById(id);
+ if (bom == null) {
+ return R.fail("BOM涓嶅瓨鍦�");
+ }
+ TechnologyBom update = new TechnologyBom();
+ update.setId(id);
+ update.setStatus(status);
+ technologyBomMapper.updateById(update);
+ if (Integer.valueOf(1).equals(status)) {
+ deactivateOtherVersions(bom.getProductModelId(), id.longValue());
+ }
+ return R.ok();
+ }
}
--
Gitblit v1.9.3