From 52d98d59dfa75bd18187e99e1e550701a1b27191 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 23 四月 2026 17:03:21 +0800
Subject: [PATCH] Merge branch 'dev_衡阳_鹏创电子' of http://114.132.189.42:9002/r/product-inventory-management-after into dev_衡阳_鹏创电子
---
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java | 3
src/main/resources/mapper/production/ProductionProductInputMapper.xml | 1
src/main/java/com/ruoyi/production/dto/ProductBomDto.java | 3
src/main/java/com/ruoyi/common/utils/BigDecimalUtils.java | 180 ++++++++++++++++++++++
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java | 66 +++++--
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java | 111 +++++++++++++
src/main/resources/mapper/production/ProductStructureMapper.xml | 8 +
src/main/java/com/ruoyi/production/controller/ProductBomController.java | 7
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java | 3
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | 33 ++++
src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java | 4
src/main/java/com/ruoyi/production/service/ProductBomService.java | 2
12 files changed, 399 insertions(+), 22 deletions(-)
diff --git a/src/main/java/com/ruoyi/common/utils/BigDecimalUtils.java b/src/main/java/com/ruoyi/common/utils/BigDecimalUtils.java
new file mode 100644
index 0000000..8d16cc3
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/utils/BigDecimalUtils.java
@@ -0,0 +1,180 @@
+package com.ruoyi.common.utils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * @author yuan
+ * @date 2026-04-23 13:10
+ * @description BigDecimal宸ュ叿绫�
+ */
+public class BigDecimalUtils {
+ public static BigDecimal getBigDecimalValue(BigDecimal val) {
+ return Optional.ofNullable(val).orElse(BigDecimal.ZERO);
+ }
+
+ public static BigDecimal of(Object val) {
+ if (val == null) {
+ return null;
+ }
+ try {
+ if (val instanceof Double || val instanceof Float) {
+ return BigDecimal.valueOf(((Number) val).doubleValue());
+ }
+ if (val instanceof Number) {
+ return new BigDecimal(val.toString());
+ }
+ return new BigDecimal(val.toString().trim());
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("鏃犳硶杞崲 " + val + " 涓� BigDecimal绫诲瀷 ", e);
+ }
+ }
+
+ /**
+ * 瀹夊叏杞崲鏂规硶锛屽皢瀵硅薄杞负BigDecimal锛宯ull瑙嗕负0
+ * @param number 鍙互鏄疦umber銆丼tring鎴朆igDecimal
+ * @return 瀵瑰簲鐨凚igDecimal锛宯ull杞负0
+ */
+ public static BigDecimal safe(Object number) {
+ if (number == null) return BigDecimal.ZERO;
+
+ if (number instanceof BigDecimal) return (BigDecimal) number;
+
+ if (number instanceof Number) return BigDecimal.valueOf(((Number) number).doubleValue());
+ try {
+ return new BigDecimal(number.toString());
+ } catch (NumberFormatException e) {
+ return BigDecimal.ZERO;
+ }
+ }
+
+ /**
+ * 鍔犳硶杩愮畻锛堣嚜鍔ㄥ鐞唍ull鍊硷級
+ * @param values 澶氫釜鍔犳暟
+ * @return 鍜�
+ */
+ public static BigDecimal add(Object... values) {
+ return Arrays.stream(values)
+ .map(BigDecimalUtils::safe)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+
+ /**
+ * 鍑忔硶杩愮畻锛堣嚜鍔ㄥ鐞唍ull鍊硷級
+ * @param minuend 琚噺鏁�
+ * @param subtrahends 鍑忔暟
+ * @return 宸�
+ */
+ public static BigDecimal subtract(Object minuend, Object... subtrahends) {
+ BigDecimal result = safe(minuend);
+ for (Object subtrahend : subtrahends) {
+ result = result.subtract(safe(subtrahend));
+ }
+ return result;
+ }
+
+ /**
+ * 涔樻硶杩愮畻锛堣嚜鍔ㄥ鐞唍ull鍊硷紝浠讳綍鍙傛暟涓簄ull鍒欒繑鍥�0锛�
+ * @param values 澶氫釜涔樻暟
+ * @return 绉�
+ */
+ public static BigDecimal multiply(Object... values) {
+ if (values == null || values.length == 0) {
+ return BigDecimal.ZERO;
+ }
+
+ BigDecimal result = Arrays.stream(values)
+ .map(BigDecimalUtils::safe)
+ .reduce(BigDecimal.ONE, BigDecimal::multiply);
+
+ // 鏍囧噯鍖栫粨鏋滐細濡傛灉鏄�0锛屽幓闄ゆ墍鏈夊皬鏁颁綅锛涘惁鍒欎繚鐣欏師鏈夊皬鏁颁綅
+ return stripTrailingZeros(result);
+ }
+
+ /**
+ * 闄ゆ硶杩愮畻锛堣嚜鍔ㄥ鐞唍ull鍊硷級
+ * @param dividend 琚櫎鏁�
+ * @param divisor 闄ゆ暟
+ * @param scale 灏忔暟浣嶆暟
+ * @param roundingMode 鑸嶅叆妯″紡
+ * @return 鍟�
+ */
+ public static BigDecimal divide(Object dividend, Object divisor,
+ int scale, RoundingMode roundingMode) {
+ BigDecimal d1 = safe(dividend);
+ BigDecimal d2 = safe(divisor);
+
+ if (d2.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ return stripTrailingZeros(d1.divide(d2, scale, roundingMode));
+ }
+
+ /**
+ * 闄ゆ硶杩愮畻锛堣嚜鍔ㄥ鐞唍ull鍊硷級
+ * @param dividend 琚櫎鏁�
+ * @param divisor 闄ゆ暟
+ * @param scale 灏忔暟浣嶆暟
+ * @param roundingMode 鑸嶅叆妯″紡
+ * @return 鍟�
+ */
+ public static BigDecimal dividePercentage(Object dividend, Object divisor,
+ int scale, RoundingMode roundingMode) {
+ BigDecimal d1 = safe(dividend);
+ BigDecimal d2 = safe(divisor);
+
+ if (d2.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ BigDecimal multiplied = d1.multiply(new BigDecimal("100"));
+ BigDecimal result = multiplied.divide(d2, scale, roundingMode);
+
+ return stripTrailingZeros(result);
+ }
+
+ /**
+ * 姣旇緝涓や釜鏁扮殑澶у皬锛堣嚜鍔ㄥ鐞唍ull鍊硷紝null瑙嗕负0锛�
+ * @param num1 绗竴涓暟
+ * @param num2 绗簩涓暟
+ * @return 1: num1 > num2; 0: num1 = num2; -1: num1 < num2
+ */
+ public static int compare(Object num1, Object num2) {
+ return safe(num1).compareTo(safe(num2));
+ }
+
+ /**
+ * 鍥涜垗浜斿叆锛堣嚜鍔ㄥ鐞唍ull鍊硷級
+ * @param value 鍘熷鍊�
+ * @param scale 淇濈暀灏忔暟浣嶆暟
+ * @return 鍥涜垗浜斿叆鍚庣殑鍊�
+ */
+ public static BigDecimal round(Object value, int scale) {
+ return safe(value).setScale(scale, RoundingMode.HALF_UP);
+ }
+
+ /**
+ * 姹傚拰锛堟祦寮忓鐞嗙増锛�
+ * @param numbers 鏁板瓧闆嗗悎
+ * @return 鍜�
+ */
+ public static BigDecimal sum(Collection<?> numbers) {
+ return numbers.stream()
+ .map(BigDecimalUtils::safe)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+
+ /**
+ * 鏍囧噯鍖朆igDecimal缁撴灉
+ * 1. 濡傛灉鏄�0锛屽幓闄ゆ墍鏈夊皬鏁颁綅
+ * 2. 濡傛灉涓嶆槸0锛屽幓闄ゆ湯灏炬棤鎰忎箟鐨�0
+ */
+ public static BigDecimal stripTrailingZeros(BigDecimal value) {
+ if (value.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ return new BigDecimal(value.stripTrailingZeros().toPlainString());
+ }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductBomController.java b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
index 3925b5c..79eb6e0 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductBomController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -69,6 +69,13 @@
return productBomService.add(productBom);
}
+ @ApiModelProperty("澶嶅埗BOM")
+ @PostMapping("/copy")
+ @Log(title = "澶嶅埗BOM", businessType = BusinessType.INSERT)
+ public AjaxResult copy(@RequestBody ProductBomDto productBom) {
+ return productBomService.copy(productBom);
+ }
+
@ApiOperation("鏇存柊BOM")
@Log(title = "淇敼", businessType = BusinessType.UPDATE)
@PutMapping("/update")
diff --git a/src/main/java/com/ruoyi/production/dto/ProductBomDto.java b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
index 30998d3..09ad814 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
@@ -17,4 +17,7 @@
//鐗╂枡缂栫爜
private String materialCode;
+
+ //鐗╂枡缂栫爜
+ private Long copyId;
}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
index bd59242..c264bc3 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
@@ -8,7 +8,9 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+import java.util.Collection;
import java.util.List;
+import java.util.Set;
@Mapper
public interface ProductStructureMapper extends BaseMapper<ProductStructure> {
@@ -16,4 +18,6 @@
List<ProductStructureDto> listBybomId(@Param("bomId") Integer bomId);
List<ProductStructureDto> listBybomAndProcess(@Param("bomId") Integer bomId, @Param("processId") Long processId);
+
+ List<ProductStructureDto> selectByIds(@Param("parentIds") Set<Long> parentIds);
}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
index 82bece9..e2ace30 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -23,6 +23,9 @@
@ApiModelProperty(value = "鏁伴噺")
private BigDecimal quantity;
+ @ApiModelProperty(value = "batchNo")
+ private String batchNo;
+
@ApiModelProperty(value = "鍒涘缓鏃堕棿")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
diff --git a/src/main/java/com/ruoyi/production/service/ProductBomService.java b/src/main/java/com/ruoyi/production/service/ProductBomService.java
index 7ec6d9a..927f4c6 100644
--- a/src/main/java/com/ruoyi/production/service/ProductBomService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductBomService.java
@@ -29,4 +29,6 @@
void exportBom(HttpServletResponse response, Integer bomId);
AjaxResult update(ProductBom productBom);
+
+ AjaxResult copy(ProductBomDto productBom);
}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
index b7b67bb..b91ba31 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.pojo.Product;
@@ -20,6 +21,7 @@
import com.ruoyi.production.service.ProductBomService;
import com.ruoyi.production.service.ProductProcessService;
import com.ruoyi.production.service.ProductStructureService;
+import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -188,6 +190,115 @@
@Override
@Transactional(rollbackFor = Exception.class)
+ public AjaxResult copy(ProductBomDto productBom) {
+ Long copyId = productBom.getCopyId();
+ if (copyId == null) {
+ throw new ServiceException("澶嶅埗婧怋OM ID涓嶈兘涓虹┖");
+ }
+ ProductBom sourceBom = productBomMapper.selectById(copyId);
+ if (sourceBom == null) {
+ throw new ServiceException("澶嶅埗婧怋OM涓嶅瓨鍦�");
+ }
+
+
+ ProductBom newBom = getProductBom(productBom, sourceBom);
+ productBomMapper.insert(newBom);
+ newBom.setBomNo("BM." + String.format("%05d", newBom.getId()));
+ productBomMapper.updateById(newBom);
+
+
+
+ ProductModel productModel = productModelService.getById(newBom.getProductModelId());
+ if (productModel == null) {
+ throw new ServiceException("閫夋嫨鐨勪骇鍝佹ā鍨嬩笉瀛樺湪");
+ }
+
+ ProductStructure newRoot = getProductStructure(newBom, productModel);
+ productStructureService.save(newRoot);
+ List<ProductStructure> sourceStructures = productStructureMapper.selectList(
+ Wrappers.<ProductStructure>lambdaQuery()
+ .eq(ProductStructure::getBomId, copyId.intValue()));
+ if (sourceStructures == null || sourceStructures.isEmpty()) {
+ return AjaxResult.success();
+ }
+
+ ProductStructure oldRoot = sourceStructures.stream()
+ .filter(s -> s.getParentId() == null)
+ .findFirst().orElse(new ProductStructure());
+
+ List<ProductStructure> children = sourceStructures
+ .stream()
+ .filter(s -> !s.getId().equals(oldRoot.getId()))
+ .collect(Collectors.toList());
+
+ Map<Long, Long> oldNewIdMap = new HashMap<>();
+
+ oldNewIdMap.put(oldRoot.getId(), newRoot.getId());
+
+ List<ProductStructure> insertList = children
+ .stream()
+ .map(item -> getProductStructures(item, newBom))
+ .collect(Collectors.toList());
+
+ productStructureService.saveBatch(insertList);
+
+ for (int i = 0; i < children.size(); i++) {
+ oldNewIdMap.put(
+ children.get(i).getId(),
+ insertList.get(i).getId()
+ );
+ }
+
+ List<ProductStructure> updateList = new ArrayList<>();
+ for (int i = 0; i < children.size(); i++) {
+ ProductStructure source = children.get(i);
+ ProductStructure inserted = insertList.get(i);
+ Long newParentId = oldNewIdMap.get(source.getParentId());
+ if (newParentId != null) {
+ inserted.setParentId(newParentId);
+ updateList.add(inserted);
+ }
+ }
+ if (!updateList.isEmpty()) {
+ productStructureService.updateBatchById(updateList);
+ }
+
+ return AjaxResult.success();
+ }
+
+ @NotNull
+ private static ProductStructure getProductStructures(ProductStructure item, ProductBom newBom) {
+ ProductStructure copy = new ProductStructure();
+ copy.setProductModelId(item.getProductModelId());
+ copy.setProcessId(item.getProcessId());
+ copy.setUnitQuantity(item.getUnitQuantity());
+ copy.setDemandedQuantity(item.getDemandedQuantity());
+ copy.setUnit(item.getUnit());
+ copy.setBomId(newBom.getId());
+ return copy;
+ }
+
+ @NotNull
+ private static ProductStructure getProductStructure(ProductBom newBom, ProductModel productModel) {
+ ProductStructure newRoot = new ProductStructure();
+ newRoot.setProductModelId(newBom.getProductModelId());
+ newRoot.setUnitQuantity(BigDecimal.valueOf(1));
+ newRoot.setUnit(productModel.getUnit());
+ newRoot.setBomId(newBom.getId());
+ return newRoot;
+ }
+
+ @NotNull
+ private static ProductBom getProductBom(ProductBomDto productBom, ProductBom sourceBom) {
+ ProductBom newBom = new ProductBom();
+ newBom.setProductModelId(productBom.getProductModelId() != null ? productBom.getProductModelId() : sourceBom.getProductModelId());
+ newBom.setRemark(productBom.getRemark());
+ newBom.setVersion(productBom.getVersion() != null ? productBom.getVersion() : sourceBom.getVersion());
+ return newBom;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
public AjaxResult uploadBom(MultipartFile file) {
ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class);
List<BomImportDto> list;
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index 84b382b..d22f0f4 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -18,6 +18,7 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.procurementrecord.utils.StockUtils;
+import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
@@ -33,12 +34,12 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@@ -175,23 +176,48 @@
productionProductMain.setStatus(0);
productionProductMainMapper.insert(productionProductMain);
/*鏂板鎶ュ伐鎶曞叆琛�*/
-// List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
-// if (productStructureDtos.isEmpty()) {
-// //濡傛灉璇ュ伐搴忔病鏈変骇鍝佺粨鏋勭殑鎶曞叆鍝�,閭h繖涓姇鍏ュ搧鍜屼骇鍑哄搧鏄悓涓�涓�
-// ProductStructureDto productStructureDto = new ProductStructureDto();
-// productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
-// productStructureDto.setUnitQuantity(BigDecimal.ONE);
-// productStructureDtos.add(productStructureDto);
-// }
-// for (ProductStructureDto productStructureDto : productStructureDtos) {
-// System.out.println(productStructureDto.getProductModelId());
-// ProductionProductInput productionProductInput = new ProductionProductInput();
-// productionProductInput.setProductModelId(productStructureDto.getProductModelId());
+ List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
+ if (productStructureDtos.isEmpty()) {
+ //濡傛灉璇ュ伐搴忔病鏈変骇鍝佺粨鏋勭殑鎶曞叆鍝�,閭h繖涓姇鍏ュ搧鍜屼骇鍑哄搧鏄悓涓�涓�
+ ProductStructureDto productStructureDto = new ProductStructureDto();
+ productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
+ productStructureDto.setUnitQuantity(BigDecimal.ONE);
+ productStructureDtos.add(productStructureDto);
+ }
+ Set<Long> parentIds = productStructureDtos.stream()
+ .map(ProductStructureDto::getParentId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ Map<Long, ProductStructureDto> parentMap =
+ productStructureMapper.selectByIds(parentIds)
+ .stream()
+ .collect(Collectors.toMap(
+ ProductStructureDto::getId,
+ Function.identity()
+ ));
+ for (ProductStructureDto productStructureDto : productStructureDtos) {
+ ProductionProductInput productionProductInput = new ProductionProductInput();
+ productionProductInput.setProductModelId(productStructureDto.getProductModelId());
// productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
-// productionProductInput.setProductMainId(productionProductMain.getId());
-// productionProductInputMapper.insert(productionProductInput);
-// stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(),dto.getBatchNo());
-// }
+ BigDecimal childQty = productStructureDto.getUnitQuantity();
+ BigDecimal parentQty = BigDecimal.ONE;
+ if (productStructureDto.getParentId() != null) {
+ ProductStructureDto parent = parentMap.get(productStructureDto.getParentId());
+ if (parent != null) {
+ parentQty = parent.getUnitQuantity();
+ }
+ }
+
+ // 鏍稿績璁$畻
+ BigDecimal needQty = childQty.divide(parentQty, 6, RoundingMode.HALF_UP).multiply(dto.getQuantity());
+
+
+ productionProductInput.setQuantity(needQty);
+
+ productionProductInput.setProductMainId(productionProductMain.getId());
+ productionProductInputMapper.insert(productionProductInput);
+ stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(), null);
+ }
/*鏂板鎶ュ伐浜у嚭琛�*/
ProductionProductOutput productionProductOutput = new ProductionProductOutput();
productionProductOutput.setProductMainId(productionProductMain.getId());
@@ -448,4 +474,4 @@
return productionProductMainDtos;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
index 34b6963..4154682 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -6,7 +6,6 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
@@ -61,7 +60,7 @@
int insertRows = stockInRecordMapper.insert(stockInRecord);
- Long insertId = stockInRecord.getId(); // 鏇挎崲涓轰綘鐨勫疄闄呬富閿瓧娈碉細getRecordId()/getInboundId() 绛�
+ Long insertId = stockInRecord.getId();
return insertRows > 0 ? insertId : null;
}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index 13968cb..72fc3fa 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -37,6 +37,7 @@
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
@@ -251,6 +252,38 @@
stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
stockOutRecordDto.setType("0");
stockOutRecordService.add(stockOutRecordDto);
+ if (ObjectUtils.isEmpty(stockInventoryDto.getBatchNo())) {
+ List<StockInventory> stockInventories = stockInventoryMapper.selectList(new QueryWrapper<StockInventory>().lambda()
+ .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())
+ .orderByAsc(StockInventory::getId));
+ if (ObjectUtils.isEmpty(stockInventories)) {
+ throw new RuntimeException("浜у搧搴撳瓨涓嶅瓨鍦�");
+ }
+
+ BigDecimal remainingQty = stockInventoryDto.getQualitity();
+ for (StockInventory stockInventory : stockInventories) {
+ BigDecimal lockedQty = stockInventory.getLockedQuantity() == null ? BigDecimal.ZERO : stockInventory.getLockedQuantity();
+ BigDecimal availableQty = stockInventory.getQualitity().subtract(lockedQty);
+ if (availableQty.compareTo(BigDecimal.ZERO) <= 0) {
+ continue;
+ }
+
+ BigDecimal deductQty = remainingQty.min(availableQty);
+ stockInventory.setQualitity(stockInventory.getQualitity().subtract(deductQty));
+ stockInventory.setVersion(stockInventory.getVersion() == null ? 1 : stockInventory.getVersion() + 1);
+ stockInventory.setUpdateTime(LocalDateTime.now());
+ stockInventoryMapper.updateById(stockInventory);
+
+ remainingQty = remainingQty.subtract(deductQty);
+ if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) {
+ return true;
+ }
+ }
+
+ ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
+ Product product = productMapper.selectById(productModel.getProductId());
+ throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "搴撳瓨涓嶈冻鏃犳硶鍑哄簱");
+ }
StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())
.eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo()));
if (ObjectUtils.isEmpty(oldStockInventory)) {
diff --git a/src/main/resources/mapper/production/ProductStructureMapper.xml b/src/main/resources/mapper/production/ProductStructureMapper.xml
index 61177af..31ad32f 100644
--- a/src/main/resources/mapper/production/ProductStructureMapper.xml
+++ b/src/main/resources/mapper/production/ProductStructureMapper.xml
@@ -41,4 +41,12 @@
and ps.process_id=#{processId}
order by ps.id
</select>
+ <select id="selectByIds" resultType="com.ruoyi.production.dto.ProductStructureDto">
+ select *
+ from product_structure
+ where id in
+ <foreach item="item" collection="parentIds" separator="," open="(" close=")" index="">
+ #{item}
+ </foreach>
+ </select>
</mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductInputMapper.xml b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
index 3eb9bda..35691be 100644
--- a/src/main/resources/mapper/production/ProductionProductInputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -7,6 +7,7 @@
<result property="productMainId" column="product_main_id"/>
<result property="productModelId" column="product_model_id"/>
<result property="quantity" column="quantity"/>
+ <result property="batchNo" column="batch_no"/>
<result property="tenantId" column="tenant_id"/>
<result property="createTime" column="create_time"/>
</resultMap>
--
Gitblit v1.9.3