From 050a6301777a6753c800f1999670f8d30f1589f9 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期一, 27 四月 2026 17:55:51 +0800
Subject: [PATCH] feat:1.根据bom结构领料 2.额外领取库存产品
---
src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml | 15
src/main/java/com/ruoyi/basic/service/IProductService.java | 3
src/main/resources/mapper/basic/ProductModelMapper.xml | 26 +
src/main/java/com/ruoyi/production/service/ProductionOrderPickService.java | 9
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java | 3
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java | 103 +++-
src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java | 4
src/main/java/com/ruoyi/production/service/ProductionOrderService.java | 3
src/main/java/com/ruoyi/basic/pojo/ProductModel.java | 3
src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java | 42 ++
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java | 25 +
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickVo.java | 32 +
src/main/java/com/ruoyi/production/controller/ProductionOrderController.java | 7
src/main/java/com/ruoyi/ai/config/XiaozhiAgentConfig.java | 67 +--
src/main/java/com/ruoyi/basic/controller/ProductController.java | 6
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java | 3
src/main/java/com/ruoyi/basic/vo/ProductModelVo.java | 14
src/main/resources/mapper/stock/StockInventoryMapper.xml | 14
src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java | 6
src/main/resources/mapper/production/ProductionOrderPickMapper.xml | 18
src/main/java/com/ruoyi/production/controller/ProductionOrderPickController.java | 34 +
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java | 2
src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java | 6
src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java | 15
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java | 641 +++++++++++++++++++++++++++++++++
src/main/java/com/ruoyi/production/mapper/ProductionOrderPickMapper.java | 5
src/main/resources/mapper/production/ProductionBomStructureMapper.xml | 19 +
27 files changed, 1,038 insertions(+), 87 deletions(-)
diff --git a/src/main/java/com/ruoyi/ai/config/XiaozhiAgentConfig.java b/src/main/java/com/ruoyi/ai/config/XiaozhiAgentConfig.java
index 58be3a6..f266a17 100644
--- a/src/main/java/com/ruoyi/ai/config/XiaozhiAgentConfig.java
+++ b/src/main/java/com/ruoyi/ai/config/XiaozhiAgentConfig.java
@@ -1,24 +1,15 @@
package com.ruoyi.ai.config;
import com.ruoyi.ai.store.MongoChatMemoryStore;
-import dev.langchain4j.data.document.Document;
-import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
-import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
-import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
-import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-
-import java.util.Collections;
-import java.util.List;
/**
* @author :yys
@@ -35,8 +26,8 @@
@Autowired
private EmbeddingModel embeddingModel;
- @Value("${knowledge.one}")
- private String one;
+// @Value("${knowledge.one}")
+// private String one;
//
// @Value("${knowledge.two}")
// private String two;
@@ -53,33 +44,33 @@
.build();
}
- @Bean
- ContentRetriever contentRetrieverXiaozhi() {
- //浣跨敤FileSystemDocumentLoader璇诲彇鎸囧畾鐩綍涓嬬殑鐭ヨ瘑搴撴枃妗�
- //骞朵娇鐢ㄩ粯璁ょ殑鏂囨。瑙f瀽鍣ㄥ鏂囨。杩涜瑙f瀽
- Document document1 = FileSystemDocumentLoader.loadDocument(one);
-// Document document2 = FileSystemDocumentLoader.loadDocument(two);
-// Document document3 = FileSystemDocumentLoader.loadDocument(three);
-// List<Document> documents = Arrays.asList(document1, document2, document3);
-
- List<Document> documents = Collections.singletonList(document1);
-// 2. 灏嗘暟鎹簱鏁版嵁杞负LangChain4j鐨凞ocument瀵硅薄
-// List<Document> documents = new ArrayList<>();
-
- //浣跨敤鍐呭瓨鍚戦噺瀛樺偍
- InMemoryEmbeddingStore<TextSegment> inMemoryEmbeddingStore = new InMemoryEmbeddingStore<>();
- //浣跨敤榛樿鐨勬枃妗e垎鍓插櫒
- EmbeddingStoreIngestor.builder()
- .embeddingModel(embeddingModel)
- .embeddingStore(inMemoryEmbeddingStore)
- .build()
- .ingest(documents);
- //浠庡祵鍏ュ瓨鍌紙EmbeddingStore锛夐噷妫�绱㈠拰鏌ヨ鍐呭鐩稿叧鐨勪俊鎭�
- return EmbeddingStoreContentRetriever.builder()
- .embeddingModel(embeddingModel)
- .embeddingStore(inMemoryEmbeddingStore)
- .build();
- }
+// @Bean
+// ContentRetriever contentRetrieverXiaozhi() {
+// //浣跨敤FileSystemDocumentLoader璇诲彇鎸囧畾鐩綍涓嬬殑鐭ヨ瘑搴撴枃妗�
+// //骞朵娇鐢ㄩ粯璁ょ殑鏂囨。瑙f瀽鍣ㄥ鏂囨。杩涜瑙f瀽
+//// Document document1 = FileSystemDocumentLoader.loadDocument(one);
+//// Document document2 = FileSystemDocumentLoader.loadDocument(two);
+//// Document document3 = FileSystemDocumentLoader.loadDocument(three);
+//// List<Document> documents = Arrays.asList(document1, document2, document3);
+//
+//// List<Document> documents = Collections.singletonList(document1);
+//// 2. 灏嗘暟鎹簱鏁版嵁杞负LangChain4j鐨凞ocument瀵硅薄
+//// List<Document> documents = new ArrayList<>();
+//
+// //浣跨敤鍐呭瓨鍚戦噺瀛樺偍
+// InMemoryEmbeddingStore<TextSegment> inMemoryEmbeddingStore = new InMemoryEmbeddingStore<>();
+// //浣跨敤榛樿鐨勬枃妗e垎鍓插櫒
+// EmbeddingStoreIngestor.builder()
+// .embeddingModel(embeddingModel)
+// .embeddingStore(inMemoryEmbeddingStore)
+// .build()
+// .ingest(documents);
+// //浠庡祵鍏ュ瓨鍌紙EmbeddingStore锛夐噷妫�绱㈠拰鏌ヨ鍐呭鐩稿叧鐨勪俊鎭�
+// return EmbeddingStoreContentRetriever.builder()
+// .embeddingModel(embeddingModel)
+// .embeddingStore(inMemoryEmbeddingStore)
+// .build();
+// }
@Bean
ContentRetriever contentRetrieverXiaozhiPincone() {
diff --git a/src/main/java/com/ruoyi/basic/controller/ProductController.java b/src/main/java/com/ruoyi/basic/controller/ProductController.java
index 77334e0..1c5224b 100644
--- a/src/main/java/com/ruoyi/basic/controller/ProductController.java
+++ b/src/main/java/com/ruoyi/basic/controller/ProductController.java
@@ -10,6 +10,7 @@
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductModelService;
import com.ruoyi.basic.service.IProductService;
+import com.ruoyi.basic.vo.ProductModelVo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -17,11 +18,8 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
-import com.ruoyi.sales.service.ISalesLedgerService;
-import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -118,7 +116,7 @@
@Operation(summary = "鍒嗛〉鏌ヨ鎵�鏈変骇鍝佸瀷鍙�")
@GetMapping("/pageModel")
- public IPage<ProductModel> listPageProductModel(Page<ProductModel> page, ProductModel productModel) {
+ public IPage<ProductModelVo> listPageProductModel(Page<ProductModelVo> page, ProductModel productModel) {
return productService.listPageProductModel(page, productModel);
}
diff --git a/src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java b/src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
index bddcca4..36876d0 100644
--- a/src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
+++ b/src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.vo.ProductModelVo;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import org.apache.ibatis.annotations.Param;
@@ -19,7 +20,7 @@
*/
public interface ProductModelMapper extends BaseMapper<ProductModel> {
- IPage<ProductModel> listPageProductModel(Page<ProductModel> page, @Param("c") ProductModel productModel);
+ IPage<ProductModelVo> listPageProductModel(Page<ProductModelVo> page, @Param("c") ProductModel productModel);
IPage<ProductModel> listPageProductionStock(Page<ProductModel> page, @Param("req") ProcurementPageDto req);
diff --git a/src/main/java/com/ruoyi/basic/pojo/ProductModel.java b/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
index 1e21583..0ec51b2 100644
--- a/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
+++ b/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
@@ -5,12 +5,13 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName("product_model")
-public class ProductModel {
+public class ProductModel implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/ruoyi/basic/service/IProductService.java b/src/main/java/com/ruoyi/basic/service/IProductService.java
index 7fba662..1abaad4 100644
--- a/src/main/java/com/ruoyi/basic/service/IProductService.java
+++ b/src/main/java/com/ruoyi/basic/service/IProductService.java
@@ -7,6 +7,7 @@
import com.ruoyi.basic.dto.ProductTreeDto;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.vo.ProductModelVo;
import java.util.List;
@@ -18,5 +19,5 @@
List<ProductTreeDto> selectProductList(ProductDto productDto);
- IPage<ProductModel> listPageProductModel(Page<ProductModel> page, ProductModel productModel);
+ IPage<ProductModelVo> listPageProductModel(Page<ProductModelVo> page, ProductModel productModel);
}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
index 437f804..5a7f679 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
@@ -12,6 +12,7 @@
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductService;
+import com.ruoyi.basic.vo.ProductModelVo;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.AjaxResult;
@@ -56,7 +57,7 @@
}
@Override
- public IPage<ProductModel> listPageProductModel(Page<ProductModel> page, ProductModel productModel) {
+ public IPage<ProductModelVo> listPageProductModel(Page<ProductModelVo> page, ProductModel productModel) {
return productModelMapper.listPageProductModel(page, productModel);
}
diff --git a/src/main/java/com/ruoyi/basic/vo/ProductModelVo.java b/src/main/java/com/ruoyi/basic/vo/ProductModelVo.java
new file mode 100644
index 0000000..cdcd893
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/vo/ProductModelVo.java
@@ -0,0 +1,14 @@
+package com.ruoyi.basic.vo;
+
+import com.ruoyi.basic.pojo.ProductModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductModelVo extends ProductModel {
+
+ private List<String> batchNoList;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java
new file mode 100644
index 0000000..0c7f5cc
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java
@@ -0,0 +1,42 @@
+package com.ruoyi.production.bean.dto;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.ruoyi.production.pojo.ProductionOrderPick;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@Schema(name = "ProductionOrderPickDto", description = "鐢熶骇璁㈠崟棰嗘枡淇濆瓨鍙傛暟")
+public class ProductionOrderPickDto extends ProductionOrderPick {
+
+ @Schema(description = "鐢熶骇璁㈠崟ID")
+ private Long productionOrderId;
+
+ @Schema(description = "鐢熶骇宸ュ崟ID")
+ private Long productionOperationTaskId;
+
+ @Schema(description = "鎵瑰彿")
+ private String batchNo;
+
+ @Schema(description = "鎵瑰彿鍒楄〃")
+ private List<String> batchNoList;
+
+ @Schema(description = "棰嗘枡鏁伴噺")
+ private BigDecimal pickQuantity;
+
+ @Schema(description = "棰嗘枡绫诲瀷锛�1姝e父棰嗘枡锛�2琛ユ枡")
+ private Byte pickType;
+
+ @Schema(description = "澶囨敞")
+ private String remark;
+
+ @Schema(description = "棰嗘枡鏄庣粏鍒楄〃")
+ @JsonAlias({"dto", "productionOrderPickDto"})
+ private List<ProductionOrderPickDto> pickList;
+
+ @Schema(description = "闇�瑕佸垹闄ょ殑棰嗘枡ID鍒楄〃")
+ private List<Long> deletePickIds;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java
new file mode 100644
index 0000000..b88aa8a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java
@@ -0,0 +1,25 @@
+package com.ruoyi.production.bean.vo;
+
+import com.ruoyi.production.pojo.ProductionOrderPickRecord;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Schema(name = "ProductionOrderPickRecordVo", description = "宸查鏂欒鎯�")
+public class ProductionOrderPickRecordVo extends ProductionOrderPickRecord {
+
+ @Schema(description = "宸ュ簭鍚嶇О")
+ private String operationName;
+
+ @Schema(description = "浜у搧鍚嶇О")
+ private String productName;
+
+ @Schema(description = "鍨嬪彿")
+ private String model;
+
+ @Schema(description = "鍗曚綅")
+ private String unit;
+}
+
diff --git a/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickVo.java b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickVo.java
new file mode 100644
index 0000000..d072634
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickVo.java
@@ -0,0 +1,32 @@
+package com.ruoyi.production.bean.vo;
+
+import com.ruoyi.production.pojo.ProductionOrderPick;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductionOrderPickVo extends ProductionOrderPick {
+
+ @Schema(description = "鍗曚綅")
+ private String unit;
+
+ @Schema(description = "搴撳瓨鏁伴噺")
+ private BigDecimal stockQuantity;
+
+ @Schema(description = "棰嗙敤鏁伴噺")
+ private BigDecimal pickQuantity;
+
+ @Schema(description = "浜у搧鍚嶇О")
+ private String productName;
+
+ @Schema(description = "瑙勬牸鍨嬪彿")
+ private String model;
+
+ @Schema(description = "鎵瑰彿")
+ private List<String> batchNoList;
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
index 60ce243..c152736 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.bean.vo.ProductionOrderVo;
import com.ruoyi.production.bean.vo.ProductionPlanVo;
import com.ruoyi.production.pojo.ProductionOrder;
@@ -75,4 +76,10 @@
public R<List<ProductionPlanVo>> getSource(@PathVariable Long id) {
return R.ok(productionOrderService.getSource(id));
}
+
+ @GetMapping("/pick/{productionOrderId}")
+ @Operation(summary = "鏍规嵁璁㈠崟id鏌ヨbom棰嗘枡鍗�")
+ public R<List<ProductionOrderPickVo>> pick(@PathVariable Long productionOrderId) {
+ return R.ok(productionOrderService.pick(productionOrderId));
+ }
}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderPickController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderPickController.java
index 7f48ba7..a8e2d2e 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderPickController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderPickController.java
@@ -1,7 +1,15 @@
package com.ruoyi.production.controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
+import com.ruoyi.production.service.ProductionOrderPickService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
/**
* <p>
@@ -13,6 +21,28 @@
*/
@RestController
@RequestMapping("/productionOrderPick")
+@Tag(name = "鐢熶骇璁㈠崟棰嗘枡")
+@RequiredArgsConstructor
public class ProductionOrderPickController {
+ private final ProductionOrderPickService productionOrderPickService;
+
+ @PostMapping("/savePick")
+ @Operation(summary = "棰嗘枡淇濆瓨鍒扮嚎杈逛粨")
+ public R<Boolean> savePick(@RequestBody ProductionOrderPickDto dto) {
+ return R.ok(productionOrderPickService.savePick(dto));
+ }
+
+ @PostMapping("/updatePick")
+ @Operation(summary = "鍙樻洿棰嗘枡")
+ public R<Boolean> updatePick(@RequestBody ProductionOrderPickDto dto) {
+ return R.ok(productionOrderPickService.updatePick(dto));
+ }
+
+ @GetMapping("/detail/{productionOrderId}")
+ @Operation(summary = "鏌ヨ宸查鏂欒鎯�")
+ public R<List<ProductionOrderPickVo>> listPickedDetail(@PathVariable Long productionOrderId) {
+ return R.ok(productionOrderPickService.listPickedDetail(productionOrderId));
+ }
}
+
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java
index 17c1c99..bb9ad78 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java
@@ -21,4 +21,10 @@
List<ProductionBomStructureVo> listByBomId(@Param("bomId") Long bomId);
+ /**
+ * 棰嗘枡bom
+ * @param bomId
+ * @return
+ */
+ List<ProductionBomStructureVo> pickByBomId(@Param("bomId") Long bomId);
}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickMapper.java
index 95c4324..3f2b9cc 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickMapper.java
@@ -1,8 +1,12 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.pojo.ProductionOrderPick;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
* <p>
@@ -15,4 +19,5 @@
@Mapper
public interface ProductionOrderPickMapper extends BaseMapper<ProductionOrderPick> {
+ List<ProductionOrderPickVo> listPickedDetailByOrderId(@Param("productionOrderId") Long productionOrderId);
}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java
index 711f244..dc909cd 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java
@@ -1,8 +1,12 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
* <p>
@@ -15,4 +19,6 @@
@Mapper
public interface ProductionOrderPickRecordMapper extends BaseMapper<ProductionOrderPickRecord> {
+ List<ProductionOrderPickVo> listPickedDetailByOrderId(@Param("productionOrderId") Long productionOrderId);
}
+
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java b/src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java
index e0180e1..a15270c 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java
@@ -28,7 +28,7 @@
private Long id;
@Schema(description = "浜у搧瑙勬牸id")
- private Integer productModelId;
+ private Long productModelId;
@Schema(description = "鏁伴噺")
private BigDecimal quantity;
@@ -56,4 +56,17 @@
@Schema(description = "閮ㄩ棬ID")
@TableField(fill = FieldFill.INSERT)
private Long deptId;
+
+ @Schema(description = "宸ュ簭鍚嶇О")
+ private String operationName;
+
+ @Schema(description = "宸ュ簭id")
+ private Long technologyOperationId;
+
+ @Schema(description = "闇�姹傛暟閲�")
+ private BigDecimal demandedQuantity;
+
+ @Schema(description = "鏄惁bom棰嗘枡")
+ @TableField("is_bom")
+ private Boolean bom;
}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java b/src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java
index dc610c2..75bf484 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java
@@ -3,8 +3,6 @@
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
-import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -39,7 +37,7 @@
private Long productionOperationTaskId;
@Schema(description = "浜у搧瑙勬牸id")
- private Integer productModelId;
+ private Long productModelId;
@Schema(description = "鎵瑰彿")
private String batchNo;
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderPickService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderPickService.java
index acffc16..82ee298 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderPickService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderPickService.java
@@ -1,7 +1,11 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.pojo.ProductionOrderPick;
+
+import java.util.List;
/**
* <p>
@@ -13,4 +17,9 @@
*/
public interface ProductionOrderPickService extends IService<ProductionOrderPick> {
+ Boolean savePick(ProductionOrderPickDto dto);
+
+ Boolean updatePick(ProductionOrderPickDto dto);
+
+ List<ProductionOrderPickVo> listPickedDetail(Long productionOrderId);
}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
index 95d3fc4..fa1186c 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.bean.vo.ProductionOrderVo;
import com.ruoyi.production.bean.vo.ProductionPlanVo;
import com.ruoyi.production.pojo.ProductionOrder;
@@ -27,4 +28,6 @@
Object bindingRoute(ProductionOrderDto productionOrderDto);
List<ProductionPlanVo> getSource(Long id);
+
+ List<ProductionOrderPickVo> pick(Long productionOrderId);
}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
index b4e3826..8f2f728 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -1,20 +1,657 @@
package com.ruoyi.production.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
+import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
+import com.ruoyi.production.mapper.ProductionOrderMapper;
import com.ruoyi.production.mapper.ProductionOrderPickMapper;
+import com.ruoyi.production.mapper.ProductionOrderPickRecordMapper;
+import com.ruoyi.production.pojo.ProductionOrder;
import com.ruoyi.production.pojo.ProductionOrderPick;
+import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import com.ruoyi.production.service.ProductionOrderPickService;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.pojo.StockInventory;
+import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* <p>
- * 璁㈠崟棰嗘枡绾胯竟浠� 鏈嶅姟瀹炵幇绫�
+ * 鐠併垹宕熸0鍡樻灐缁捐儻绔熸禒?閺堝秴濮熺�圭偟骞囩猾?
* </p>
*
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @author 閼侯垰顕辨潪顖欐閿涘牊鐫欓懟蹇ョ礆閺堝妾洪崗顒�寰�
* @since 2026-04-21 03:55:52
*/
@Service
+@RequiredArgsConstructor
public class ProductionOrderPickServiceImpl extends ServiceImpl<ProductionOrderPickMapper, ProductionOrderPick> implements ProductionOrderPickService {
+ private final ProductionOrderMapper productionOrderMapper;
+ private final ProductionOperationTaskMapper productionOperationTaskMapper;
+ private final ProductionOrderPickRecordMapper productionOrderPickRecordMapper;
+ private final StockInventoryMapper stockInventoryMapper;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean savePick(ProductionOrderPickDto dto) {
+ List<ProductionOrderPickDto> pickItems = resolvePickItems(dto);
+ for (int i = 0; i < pickItems.size(); i++) {
+ int rowNo = i + 1;
+ ProductionOrderPickDto resolvedDto = mergeDto(dto, pickItems.get(i));
+ validatePickParam(resolvedDto, rowNo);
+
+ List<String> batchNoList = resolveBatchNoList(resolvedDto);
+ String inventoryBatchNo = pickInventoryBatchNo(batchNoList);
+ String storedBatchNo = formatBatchNoStorage(batchNoList);
+ subtractInventory(resolvedDto.getProductModelId(), inventoryBatchNo, resolvedDto.getPickQuantity(), rowNo);
+
+ ProductionOrderPick orderPick = new ProductionOrderPick();
+ orderPick.setProductionOrderId(resolvedDto.getProductionOrderId());
+ orderPick.setProductModelId(resolvedDto.getProductModelId());
+ orderPick.setBatchNo(storedBatchNo);
+ orderPick.setQuantity(resolvedDto.getPickQuantity());
+ orderPick.setRemark(resolvedDto.getRemark());
+ orderPick.setOperationName(resolvedDto.getOperationName());
+ orderPick.setTechnologyOperationId(resolvedDto.getTechnologyOperationId());
+ orderPick.setDemandedQuantity(resolvedDto.getDemandedQuantity());
+ orderPick.setBom(resolvedDto.getBom());
+ baseMapper.insert(orderPick);
+
+ insertPickRecord(orderPick.getId(),
+ resolvedDto.getProductionOrderId(),
+ resolvedDto.getProductionOperationTaskId(),
+ resolvedDto.getProductModelId(),
+ inventoryBatchNo,
+ resolvedDto.getPickQuantity(),
+ BigDecimal.ZERO,
+ resolvedDto.getPickQuantity(),
+ resolvedDto.getPickType(),
+ resolvedDto.getRemark());
+ }
+ return true;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean updatePick(ProductionOrderPickDto dto) {
+ if (dto == null) {
+ throw new ServiceException("鍙樻洿鍙傛暟涓嶈兘涓虹┖");
+ }
+ Long productionOrderId = resolveProductionOrderId(dto);
+ if (productionOrderId == null) {
+ throw new ServiceException("鐢熶骇璁㈠崟ID涓嶈兘涓虹┖");
+ }
+ ProductionOrder productionOrder = productionOrderMapper.selectById(productionOrderId);
+ if (productionOrder == null) {
+ throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+ }
+
+ List<ProductionOrderPick> existingPickList = baseMapper.selectList(
+ Wrappers.<ProductionOrderPick>lambdaQuery()
+ .eq(ProductionOrderPick::getProductionOrderId, productionOrderId));
+ Map<Long, ProductionOrderPick> existingPickMap = existingPickList.stream()
+ .filter(item -> item.getId() != null)
+ .collect(Collectors.toMap(ProductionOrderPick::getId, Function.identity(), (a, b) -> a));
+
+ processDeletePickIds(dto, existingPickMap, productionOrderId);
+
+ List<ProductionOrderPickDto> pickItems = resolveUpdateItems(dto);
+ Set<Long> keepPickIdSet = new HashSet<>();
+ for (int i = 0; i < pickItems.size(); i++) {
+ int rowNo = i + 1;
+ ProductionOrderPickDto resolvedDto = mergeDto(dto, pickItems.get(i));
+ if (isEmptyUpdateItem(resolvedDto)) {
+ continue;
+ }
+ if (resolvedDto.getProductionOrderId() == null) {
+ resolvedDto.setProductionOrderId(productionOrderId);
+ }
+ validatePickParam(resolvedDto, rowNo);
+
+ if (resolvedDto.getId() == null) {
+ addNewPickInUpdate(resolvedDto, rowNo);
+ continue;
+ }
+ keepPickIdSet.add(resolvedDto.getId());
+ updateExistingPick(resolvedDto, rowNo, existingPickMap);
+ }
+ processMissingPickItems(dto, existingPickMap, productionOrderId, keepPickIdSet);
+ return true;
+ }
+
+ @Override
+ public List<ProductionOrderPickVo> listPickedDetail(Long productionOrderId) {
+ if (productionOrderId == null) {
+ return Collections.emptyList();
+ }
+ List<ProductionOrderPickVo> detailList = baseMapper.listPickedDetailByOrderId(productionOrderId);
+ fillBatchNoList(detailList);
+ fillSelectableBatchNoList(detailList);
+ return detailList;
+ }
+
+ private void processDeletePickIds(ProductionOrderPickDto rootDto,
+ Map<Long, ProductionOrderPick> existingPickMap,
+ Long productionOrderId) {
+ if (rootDto.getDeletePickIds() == null || rootDto.getDeletePickIds().isEmpty()) {
+ return;
+ }
+ Set<Long> deleteIdSet = new LinkedHashSet<>(rootDto.getDeletePickIds());
+ for (Long deleteId : deleteIdSet) {
+ if (deleteId == null) {
+ continue;
+ }
+ ProductionOrderPick existingPick = existingPickMap.get(deleteId);
+ if (existingPick == null || !Objects.equals(existingPick.getProductionOrderId(), productionOrderId)) {
+ throw new ServiceException("瑕佸垹闄ょ殑棰嗘枡璁板綍涓嶅瓨鍦ㄦ垨涓嶅睘浜庡綋鍓嶈鍗曪紝ID=" + deleteId);
+ }
+ String oldBatchNo = resolveInventoryBatchNoFromStored(existingPick.getBatchNo());
+ BigDecimal oldQuantity = defaultDecimal(existingPick.getQuantity());
+ addInventory(existingPick.getProductModelId(), oldBatchNo, oldQuantity);
+ int affected = baseMapper.deleteById(deleteId);
+ if (affected <= 0) {
+ throw new ServiceException("鍒犻櫎棰嗘枡澶辫触锛孖D=" + deleteId);
+ }
+ insertPickRecord(existingPick.getId(),
+ existingPick.getProductionOrderId(),
+ rootDto.getProductionOperationTaskId(),
+ existingPick.getProductModelId(),
+ oldBatchNo,
+ oldQuantity,
+ oldQuantity,
+ BigDecimal.ZERO,
+ rootDto.getPickType(),
+ rootDto.getRemark());
+ existingPickMap.remove(deleteId);
+ }
+ }
+
+ private void processMissingPickItems(ProductionOrderPickDto rootDto,
+ Map<Long, ProductionOrderPick> existingPickMap,
+ Long productionOrderId,
+ Set<Long> keepPickIdSet) {
+ if (rootDto.getPickList() == null) {
+ return;
+ }
+ List<ProductionOrderPick> missingPickList = existingPickMap.values().stream()
+ .filter(Objects::nonNull)
+ .filter(item -> item.getId() != null)
+ .filter(item -> Objects.equals(item.getProductionOrderId(), productionOrderId))
+ .filter(item -> !keepPickIdSet.contains(item.getId()))
+ .collect(Collectors.toList());
+ for (ProductionOrderPick missingPick : missingPickList) {
+ String oldBatchNo = resolveInventoryBatchNoFromStored(missingPick.getBatchNo());
+ BigDecimal oldQuantity = defaultDecimal(missingPick.getQuantity());
+ addInventory(missingPick.getProductModelId(), oldBatchNo, oldQuantity);
+ int affected = baseMapper.deleteById(missingPick.getId());
+ if (affected <= 0) {
+ throw new ServiceException("鍒犻櫎棰嗘枡澶辫触锛孖D=" + missingPick.getId());
+ }
+ insertPickRecord(missingPick.getId(),
+ missingPick.getProductionOrderId(),
+ rootDto.getProductionOperationTaskId(),
+ missingPick.getProductModelId(),
+ oldBatchNo,
+ oldQuantity,
+ oldQuantity,
+ BigDecimal.ZERO,
+ rootDto.getPickType(),
+ rootDto.getRemark());
+ existingPickMap.remove(missingPick.getId());
+ }
+ }
+
+ private void addNewPickInUpdate(ProductionOrderPickDto dto, int rowNo) {
+ List<String> batchNoList = resolveBatchNoList(dto);
+ String inventoryBatchNo = pickInventoryBatchNo(batchNoList);
+ String storedBatchNo = formatBatchNoStorage(batchNoList);
+ subtractInventory(dto.getProductModelId(), inventoryBatchNo, dto.getPickQuantity(), rowNo);
+
+ ProductionOrderPick orderPick = new ProductionOrderPick();
+ orderPick.setProductionOrderId(dto.getProductionOrderId());
+ orderPick.setProductModelId(dto.getProductModelId());
+ orderPick.setBatchNo(storedBatchNo);
+ orderPick.setQuantity(dto.getPickQuantity());
+ orderPick.setRemark(dto.getRemark());
+ orderPick.setOperationName(dto.getOperationName());
+ orderPick.setTechnologyOperationId(dto.getTechnologyOperationId());
+ orderPick.setDemandedQuantity(dto.getDemandedQuantity());
+ orderPick.setBom(dto.getBom());
+ baseMapper.insert(orderPick);
+
+ insertPickRecord(orderPick.getId(),
+ dto.getProductionOrderId(),
+ dto.getProductionOperationTaskId(),
+ dto.getProductModelId(),
+ inventoryBatchNo,
+ dto.getPickQuantity(),
+ BigDecimal.ZERO,
+ dto.getPickQuantity(),
+ dto.getPickType(),
+ dto.getRemark());
+ }
+
+ private void updateExistingPick(ProductionOrderPickDto dto,
+ int rowNo,
+ Map<Long, ProductionOrderPick> existingPickMap) {
+ ProductionOrderPick oldPick = existingPickMap.get(dto.getId());
+ if (oldPick == null || !Objects.equals(oldPick.getProductionOrderId(), dto.getProductionOrderId())) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欒褰曚笉瀛樺湪鎴栦笉灞炰簬褰撳墠璁㈠崟");
+ }
+
+ Long oldProductModelId = oldPick.getProductModelId();
+ String oldBatchNo = resolveInventoryBatchNoFromStored(oldPick.getBatchNo());
+ BigDecimal oldQuantity = defaultDecimal(oldPick.getQuantity());
+
+ Long newProductModelId = dto.getProductModelId();
+ List<String> newBatchNoList = resolveBatchNoList(dto);
+ String newBatchNo = pickInventoryBatchNo(newBatchNoList);
+ String newStoredBatchNo = formatBatchNoStorage(newBatchNoList);
+ BigDecimal newQuantity = dto.getPickQuantity();
+
+ boolean sameStockKey = Objects.equals(oldProductModelId, newProductModelId)
+ && Objects.equals(oldBatchNo, newBatchNo);
+ if (sameStockKey) {
+ BigDecimal delta = newQuantity.subtract(oldQuantity);
+ if (delta.compareTo(BigDecimal.ZERO) > 0) {
+ subtractInventory(newProductModelId, newBatchNo, delta, rowNo);
+ } else if (delta.compareTo(BigDecimal.ZERO) < 0) {
+ addInventory(oldProductModelId, oldBatchNo, delta.abs());
+ }
+ } else {
+ addInventory(oldProductModelId, oldBatchNo, oldQuantity);
+ subtractInventory(newProductModelId, newBatchNo, newQuantity, rowNo);
+ }
+
+ oldPick.setProductModelId(newProductModelId);
+ oldPick.setBatchNo(newStoredBatchNo);
+ oldPick.setQuantity(newQuantity);
+ oldPick.setRemark(dto.getRemark());
+ oldPick.setOperationName(dto.getOperationName());
+ oldPick.setTechnologyOperationId(dto.getTechnologyOperationId());
+ if (dto.getDemandedQuantity() != null) {
+ oldPick.setDemandedQuantity(dto.getDemandedQuantity());
+ }
+ if (dto.getBom() != null) {
+ oldPick.setBom(dto.getBom());
+ }
+ int affected = baseMapper.updateById(oldPick);
+ if (affected <= 0) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欐洿鏂板け璐�");
+ }
+
+ BigDecimal recordQuantity = sameStockKey ? oldQuantity.subtract(newQuantity).abs() : newQuantity;
+ if (recordQuantity.compareTo(BigDecimal.ZERO) > 0 || oldQuantity.compareTo(newQuantity) != 0 || !sameStockKey) {
+ insertPickRecord(oldPick.getId(),
+ dto.getProductionOrderId(),
+ dto.getProductionOperationTaskId(),
+ newProductModelId,
+ newBatchNo,
+ recordQuantity,
+ oldQuantity,
+ newQuantity,
+ dto.getPickType(),
+ dto.getRemark());
+ }
+ }
+
+ private void insertPickRecord(Long pickId,
+ Long productionOrderId,
+ Long productionOperationTaskId,
+ Long productModelId,
+ String batchNo,
+ BigDecimal pickQuantity,
+ BigDecimal beforeQuantity,
+ BigDecimal afterQuantity,
+ Byte pickType,
+ String remark) {
+ ProductionOrderPickRecord pickRecord = new ProductionOrderPickRecord();
+ pickRecord.setPickId(pickId);
+ pickRecord.setProductionOrderId(productionOrderId);
+ pickRecord.setProductionOperationTaskId(productionOperationTaskId);
+ pickRecord.setProductModelId(productModelId);
+ pickRecord.setBatchNo(batchNo);
+ pickRecord.setPickQuantity(defaultDecimal(pickQuantity));
+ pickRecord.setBeforeQuantity(defaultDecimal(beforeQuantity));
+ pickRecord.setAfterQuantity(defaultDecimal(afterQuantity));
+ pickRecord.setPickType(pickType == null ? (byte) 1 : pickType);
+ pickRecord.setRemark(remark);
+ productionOrderPickRecordMapper.insert(pickRecord);
+ }
+
+ private void subtractInventory(Long productModelId, String batchNo, BigDecimal quantity, int rowNo) {
+ StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, batchNo));
+ if (stockInventory == null) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欏搴斿簱瀛樹笉瀛樺湪");
+ }
+ BigDecimal availableQuantity = defaultDecimal(stockInventory.getQualitity())
+ .subtract(defaultDecimal(stockInventory.getLockedQuantity()));
+ if (quantity.compareTo(availableQuantity) > 0) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欏彲鐢ㄥ簱瀛樹笉瓒�");
+ }
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setProductModelId(productModelId);
+ stockInventoryDto.setBatchNo(batchNo);
+ stockInventoryDto.setQualitity(quantity);
+ int affected = stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
+ if (affected <= 0) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欐墸鍑忓簱瀛樺け璐�");
+ }
+ }
+
+ private void addInventory(Long productModelId, String batchNo, BigDecimal quantity) {
+ BigDecimal addQuantity = defaultDecimal(quantity);
+ if (addQuantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return;
+ }
+ StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, batchNo));
+ if (stockInventory == null) {
+ StockInventory newStockInventory = new StockInventory();
+ newStockInventory.setProductModelId(productModelId);
+ newStockInventory.setBatchNo(batchNo);
+ newStockInventory.setQualitity(addQuantity);
+ newStockInventory.setLockedQuantity(BigDecimal.ZERO);
+ newStockInventory.setVersion(1);
+ stockInventoryMapper.insert(newStockInventory);
+ return;
+ }
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setProductModelId(productModelId);
+ stockInventoryDto.setBatchNo(batchNo);
+ stockInventoryDto.setQualitity(addQuantity);
+ int affected = stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
+ if (affected <= 0) {
+ throw new ServiceException("搴撳瓨鍥為��澶辫触锛屼骇鍝佽鏍糏D=" + productModelId);
+ }
+ }
+
+ private List<ProductionOrderPickDto> resolvePickItems(ProductionOrderPickDto dto) {
+ if (dto == null) {
+ throw new ServiceException("棰嗘枡鍙傛暟涓嶈兘涓虹┖");
+ }
+ if (dto.getPickList() != null && !dto.getPickList().isEmpty()) {
+ return dto.getPickList();
+ }
+ return Collections.singletonList(dto);
+ }
+
+ private List<ProductionOrderPickDto> resolveUpdateItems(ProductionOrderPickDto dto) {
+ if (dto.getPickList() != null) {
+ return dto.getPickList();
+ }
+ if (isEmptyUpdateItem(dto)) {
+ return Collections.emptyList();
+ }
+ return Collections.singletonList(dto);
+ }
+
+ private boolean isEmptyUpdateItem(ProductionOrderPickDto dto) {
+ return dto.getId() == null
+ && dto.getProductModelId() == null
+ && dto.getPickQuantity() == null
+ && StringUtils.isEmpty(dto.getBatchNo())
+ && (dto.getBatchNoList() == null || dto.getBatchNoList().isEmpty())
+ && dto.getPickType() == null
+ && dto.getProductionOperationTaskId() == null
+ && dto.getTechnologyOperationId() == null
+ && StringUtils.isEmpty(dto.getOperationName())
+ && dto.getDemandedQuantity() == null
+ && dto.getBom() == null
+ && StringUtils.isEmpty(dto.getRemark());
+ }
+
+ private Long resolveProductionOrderId(ProductionOrderPickDto dto) {
+ if (dto.getProductionOrderId() != null) {
+ return dto.getProductionOrderId();
+ }
+ if (dto.getPickList() == null || dto.getPickList().isEmpty()) {
+ return null;
+ }
+ return dto.getPickList().stream()
+ .filter(Objects::nonNull)
+ .map(ProductionOrderPickDto::getProductionOrderId)
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
+ }
+
+ private ProductionOrderPickDto mergeDto(ProductionOrderPickDto rootDto, ProductionOrderPickDto itemDto) {
+ ProductionOrderPickDto merged = new ProductionOrderPickDto();
+ if (itemDto != null) {
+ merged.setId(itemDto.getId());
+ merged.setProductionOrderId(itemDto.getProductionOrderId());
+ merged.setProductionOperationTaskId(itemDto.getProductionOperationTaskId());
+ merged.setProductModelId(itemDto.getProductModelId());
+ merged.setBatchNo(itemDto.getBatchNo());
+ merged.setBatchNoList(itemDto.getBatchNoList());
+ merged.setPickQuantity(itemDto.getPickQuantity());
+ merged.setPickType(itemDto.getPickType());
+ merged.setRemark(itemDto.getRemark());
+ merged.setTechnologyOperationId(itemDto.getTechnologyOperationId());
+ merged.setOperationName(itemDto.getOperationName());
+ merged.setDemandedQuantity(itemDto.getDemandedQuantity());
+ merged.setBom(itemDto.getBom());
+ }
+ if (merged.getId() == null) {
+ merged.setId(rootDto.getId());
+ }
+ if (merged.getProductionOrderId() == null) {
+ merged.setProductionOrderId(rootDto.getProductionOrderId());
+ }
+ if (merged.getProductionOperationTaskId() == null) {
+ merged.setProductionOperationTaskId(rootDto.getProductionOperationTaskId());
+ }
+ if (merged.getProductModelId() == null) {
+ merged.setProductModelId(rootDto.getProductModelId());
+ }
+ if (merged.getBatchNo() == null) {
+ merged.setBatchNo(rootDto.getBatchNo());
+ }
+ if (merged.getBatchNoList() == null || merged.getBatchNoList().isEmpty()) {
+ merged.setBatchNoList(rootDto.getBatchNoList());
+ }
+ if (merged.getPickQuantity() == null) {
+ merged.setPickQuantity(rootDto.getPickQuantity());
+ }
+ if (merged.getPickType() == null) {
+ merged.setPickType(rootDto.getPickType());
+ }
+ if (merged.getRemark() == null) {
+ merged.setRemark(rootDto.getRemark());
+ }
+ if (merged.getTechnologyOperationId() == null) {
+ merged.setTechnologyOperationId(rootDto.getTechnologyOperationId());
+ }
+ if (merged.getOperationName() == null) {
+ merged.setOperationName(rootDto.getOperationName());
+ }
+ if (merged.getDemandedQuantity() == null) {
+ merged.setDemandedQuantity(rootDto.getDemandedQuantity());
+ }
+ if (merged.getBom() == null) {
+ merged.setBom(rootDto.getBom());
+ }
+ return merged;
+ }
+
+ private void validatePickParam(ProductionOrderPickDto dto, int rowNo) {
+ if (dto.getProductionOrderId() == null) {
+ throw new ServiceException("绗�" + rowNo + "鏉$敓浜ц鍗旾D涓嶈兘涓虹┖");
+ }
+ if (dto.getProductModelId() == null) {
+ throw new ServiceException("绗�" + rowNo + "鏉′骇鍝佽鏍糏D涓嶈兘涓虹┖");
+ }
+ if (dto.getPickQuantity() == null || dto.getPickQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欐暟閲忓繀椤诲ぇ浜�0");
+ }
+ if (dto.getPickType() != null && dto.getPickType() != 1 && dto.getPickType() != 2) {
+ throw new ServiceException("绗�" + rowNo + "鏉¢鏂欑被鍨嬪彧鑳芥槸1鎴�2");
+ }
+ }
+
+ private String normalizeBatchNo(String batchNo) {
+ if (StringUtils.isEmpty(batchNo)) {
+ return null;
+ }
+ String trimBatchNo = batchNo.trim();
+ return trimBatchNo.isEmpty() ? null : trimBatchNo;
+ }
+ private List<String> resolveBatchNoList(ProductionOrderPickDto dto) {
+ List<String> normalizedBatchNoList = normalizeBatchNoList(dto.getBatchNoList());
+ if (!normalizedBatchNoList.isEmpty()) {
+ return normalizedBatchNoList;
+ }
+ return parseBatchNoValue(dto.getBatchNo());
+ }
+
+ private String pickInventoryBatchNo(List<String> batchNoList) {
+ if (batchNoList == null || batchNoList.isEmpty()) {
+ return null;
+ }
+ return batchNoList.get(0);
+ }
+
+ private String resolveInventoryBatchNoFromStored(String storedBatchNo) {
+ return pickInventoryBatchNo(parseBatchNoValue(storedBatchNo));
+ }
+
+ private String formatBatchNoStorage(List<String> batchNoList) {
+ if (batchNoList == null || batchNoList.isEmpty()) {
+ return null;
+ }
+ if (batchNoList.size() == 1) {
+ return batchNoList.get(0);
+ }
+ return String.join(",", batchNoList);
+ }
+
+ private List<String> normalizeBatchNoList(List<String> batchNoList) {
+ if (batchNoList == null || batchNoList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ LinkedHashSet<String> normalizedSet = new LinkedHashSet<>();
+ for (String batchNo : batchNoList) {
+ String normalizedBatchNo = normalizeBatchNo(batchNo);
+ if (!StringUtils.isEmpty(normalizedBatchNo)) {
+ normalizedSet.add(normalizedBatchNo);
+ }
+ }
+ return new ArrayList<>(normalizedSet);
+ }
+
+ private void fillBatchNoList(List<ProductionOrderPickVo> detailList) {
+ if (detailList == null || detailList.isEmpty()) {
+ return;
+ }
+ Map<String, LinkedHashSet<String>> batchNoGroupMap = new HashMap<>();
+ for (ProductionOrderPickVo detail : detailList) {
+ String key = buildBatchNoGroupKey(detail);
+ LinkedHashSet<String> batchSet = batchNoGroupMap.computeIfAbsent(key, k -> new LinkedHashSet<>());
+ batchSet.addAll(parseBatchNoValue(detail.getBatchNo()));
+ if (detail.getBatchNoList() != null && !detail.getBatchNoList().isEmpty()) {
+ batchSet.addAll(normalizeBatchNoList(detail.getBatchNoList()));
+ }
+ }
+ for (ProductionOrderPickVo detail : detailList) {
+ String key = buildBatchNoGroupKey(detail);
+ LinkedHashSet<String> batchSet = batchNoGroupMap.get(key);
+ detail.setBatchNoList(batchSet == null ? Collections.emptyList() : new ArrayList<>(batchSet));
+ }
+ }
+
+ private void fillSelectableBatchNoList(List<ProductionOrderPickVo> detailList) {
+ if (detailList == null || detailList.isEmpty()) {
+ return;
+ }
+ Set<Long> productModelIdSet = detailList.stream()
+ .map(ProductionOrderPickVo::getProductModelId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ if (productModelIdSet.isEmpty()) {
+ return;
+ }
+ List<StockInventory> stockBatchList = stockInventoryMapper.listSelectableBatchNoByProductModelIds(
+ new ArrayList<>(productModelIdSet));
+ Map<Long, LinkedHashSet<String>> stockBatchMap = new HashMap<>();
+ for (StockInventory stockInventory : stockBatchList) {
+ if (stockInventory == null || stockInventory.getProductModelId() == null) {
+ continue;
+ }
+ String normalizedBatchNo = normalizeBatchNo(stockInventory.getBatchNo());
+ if (StringUtils.isEmpty(normalizedBatchNo)) {
+ continue;
+ }
+ stockBatchMap.computeIfAbsent(stockInventory.getProductModelId(), k -> new LinkedHashSet<>())
+ .add(normalizedBatchNo);
+ }
+ for (ProductionOrderPickVo detail : detailList) {
+ LinkedHashSet<String> mergedBatchSet = new LinkedHashSet<>();
+ mergedBatchSet.addAll(normalizeBatchNoList(detail.getBatchNoList()));
+ LinkedHashSet<String> selectableBatchSet = stockBatchMap.get(detail.getProductModelId());
+ if (selectableBatchSet != null) {
+ mergedBatchSet.addAll(selectableBatchSet);
+ }
+ detail.setBatchNoList(new ArrayList<>(mergedBatchSet));
+ }
+ }
+
+ private String buildBatchNoGroupKey(ProductionOrderPickVo detail) {
+ return String.valueOf(detail.getProductionOrderId()) + "|"
+ + String.valueOf(detail.getProductModelId()) + "|"
+ + String.valueOf(detail.getTechnologyOperationId()) + "|"
+ + String.valueOf(detail.getOperationName());
+ }
+
+ private List<String> parseBatchNoValue(String rawBatchNoValue) {
+ String normalizedValue = normalizeBatchNo(rawBatchNoValue);
+ if (StringUtils.isEmpty(normalizedValue)) {
+ return Collections.emptyList();
+ }
+ if (normalizedValue.startsWith("[") && normalizedValue.endsWith("]")) {
+ String value = normalizedValue.substring(1, normalizedValue.length() - 1);
+ if (StringUtils.isEmpty(value)) {
+ return Collections.emptyList();
+ }
+ List<String> parsed = Arrays.stream(value.split(","))
+ .map(item -> item == null ? null : item.trim().replace("\"", "").replace("'", ""))
+ .collect(Collectors.toList());
+ return normalizeBatchNoList(parsed);
+ }
+ if (normalizedValue.contains(",")) {
+ List<String> parsed = Arrays.stream(normalizedValue.split(","))
+ .map(item -> item == null ? null : item.trim())
+ .collect(Collectors.toList());
+ return normalizeBatchNoList(parsed);
+ }
+ return Collections.singletonList(normalizedValue);
+ }
+
+ private LambdaQueryWrapper<StockInventory> buildStockWrapper(Long productModelId, String batchNo) {
+ LambdaQueryWrapper<StockInventory> wrapper = Wrappers.<StockInventory>lambdaQuery()
+ .eq(StockInventory::getProductModelId, productModelId);
+ if (StringUtils.isEmpty(batchNo)) {
+ wrapper.isNull(StockInventory::getBatchNo);
+ } else {
+ wrapper.eq(StockInventory::getBatchNo, batchNo);
+ }
+ return wrapper;
+ }
+
+ private BigDecimal defaultDecimal(BigDecimal value) {
+ return value == null ? BigDecimal.ZERO : value;
+ }
}
+
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
index bb56608..31affd2 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -15,6 +15,8 @@
import com.ruoyi.common.constant.StorageAttachmentConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionBomStructureVo;
+import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.bean.vo.ProductionOrderVo;
import com.ruoyi.production.bean.vo.ProductionPlanVo;
import com.ruoyi.production.enums.ProductOrderStatusEnum;
@@ -23,6 +25,8 @@
import com.ruoyi.production.service.ProductionOrderService;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.technology.mapper.*;
import com.ruoyi.technology.pojo.*;
import lombok.RequiredArgsConstructor;
@@ -50,6 +54,7 @@
private final ProductionOrderPickMapper productionOrderPickMapper;
private final ProductionOrderPickRecordMapper productionOrderPickRecordMapper;
private final ProductionPlanMapper productionPlanMapper;
+ private final StockInventoryMapper stockInventoryMapper;
private final StorageAttachmentMapper storageAttachmentMapper;
private final StorageBlobMapper storageBlobMapper;
private final SalesLedgerMapper salesLedgerMapper;
@@ -112,11 +117,7 @@
|| productionOrderRoutingMapper.selectCount(Wrappers.<ProductionOrderRouting>lambdaQuery()
.eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0);
if (needSync) {
- // 宸ヨ壓銆佷骇鍝佹垨鏁伴噺鍙樺寲鍚庯紝璁㈠崟蹇収蹇呴』鍜屽綋鍓嶄笅鍗曟暟鎹噸鏂板榻愩��
syncProductionOrderSnapshot(productionOrder.getId());
- } else {
- // 鏈噸寤哄揩鐓ф椂锛屼篃瑕佺‘淇濆鏂欎富鍗曞拰璁㈠崟鏁伴噺淇濇寔鍚屾銆�
- upsertOrderPick(productionOrder);
}
return true;
}
@@ -274,8 +275,6 @@
syncedParamCount++;
}
}
-
- upsertOrderPick(productionOrder);
return syncedParamCount;
}
@@ -551,29 +550,6 @@
return issuedQuantity.compareTo(requiredQuantity) < 0 ? 1 : 2;
}
- private void upsertOrderPick(ProductionOrder productionOrder) {
- if (productionOrder == null || productionOrder.getId() == null) {
- return;
- }
- // 璁㈠崟涓嬭揪鍚庤嚜鍔ㄧ敓鎴愪竴寮犲鏂欎富鍗曪紝鍚庣画棰嗘枡璁板綍閮芥寕鍦ㄨ繖寮犲崟涓娿��
- ProductionOrderPick orderPick = productionOrderPickMapper.selectOne(
- Wrappers.<ProductionOrderPick>lambdaQuery()
- .eq(ProductionOrderPick::getProductionOrderId, productionOrder.getId())
- .last("limit 1"));
- if (orderPick == null) {
- orderPick = new ProductionOrderPick();
- orderPick.setProductionOrderId(productionOrder.getId());
- }
- orderPick.setProductModelId(productionOrder.getProductModelId() == null ? null : Math.toIntExact(productionOrder.getProductModelId()));
- orderPick.setQuantity(defaultDecimal(productionOrder.getQuantity()));
- orderPick.setRemark("涓嬪崟鑷姩鐢熸垚");
- if (orderPick.getId() == null) {
- productionOrderPickMapper.insert(orderPick);
- } else {
- productionOrderPickMapper.updateById(orderPick);
- }
- }
-
private List<Long> parsePlanIds(String productionPlanIds) {
if (productionPlanIds == null || productionPlanIds.trim().isEmpty()) {
return new ArrayList<>();
@@ -677,4 +653,73 @@
vo.setDownloadURL(fileUtil.buildSignedDownloadUrl(vo));
return vo;
}
+
+ @Override
+ public List<ProductionOrderPickVo> pick(Long productionOrderId) {
+ if (productionOrderId == null) {
+ return Collections.emptyList();
+ }
+
+ ProductionOrderBom orderBom = productionOrderBomMapper.selectOne(
+ Wrappers.<ProductionOrderBom>lambdaQuery()
+ .eq(ProductionOrderBom::getProductionOrderId, productionOrderId)
+ .orderByDesc(ProductionOrderBom::getId)
+ .last("limit 1"));
+ if (orderBom == null || orderBom.getId() == null) {
+ return Collections.emptyList();
+ }
+
+ List<ProductionBomStructureVo> bomStructureList = productionBomStructureMapper.pickByBomId(orderBom.getId());
+ if (bomStructureList == null || bomStructureList.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ List<Long> productModelIds = bomStructureList.stream()
+ .map(ProductionBomStructureVo::getProductModelId)
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+ Map<Long, BigDecimal> stockQuantityMap = new HashMap<>();
+ Map<Long, LinkedHashSet<String>> stockBatchNoMap = new HashMap<>();
+ if (!productModelIds.isEmpty()) {
+ List<StockInventory> stockList = stockInventoryMapper.selectList(
+ Wrappers.<StockInventory>lambdaQuery()
+ .in(StockInventory::getProductModelId, productModelIds));
+ for (StockInventory stockItem : stockList) {
+ if (stockItem == null || stockItem.getProductModelId() == null) {
+ continue;
+ }
+ Long productModelId = stockItem.getProductModelId();
+ stockQuantityMap.merge(productModelId, defaultDecimal(stockItem.getQualitity()), BigDecimal::add);
+ String batchNo = stockItem.getBatchNo();
+ if (batchNo != null && !batchNo.trim().isEmpty()) {
+ stockBatchNoMap.computeIfAbsent(productModelId, key -> new LinkedHashSet<>()).add(batchNo);
+ }
+ }
+ }
+
+ List<ProductionOrderPickVo> result = new ArrayList<>(bomStructureList.size());
+ for (ProductionBomStructureVo structure : bomStructureList) {
+ if (structure == null || structure.getProductModelId() == null) {
+ continue;
+ }
+ Long productModelId = structure.getProductModelId();
+ ProductionOrderPickVo vo = new ProductionOrderPickVo();
+ vo.setProductModelId(productModelId);
+ vo.setOperationName(structure.getOperationName());
+ vo.setTechnologyOperationId(structure.getTechnologyOperationId());
+ vo.setProductName(structure.getProductName());
+ vo.setModel(structure.getModel());
+ vo.setDemandedQuantity(defaultDecimal(structure.getDemandedQuantity()));
+ vo.setUnit(structure.getUnit());
+ List<String> batchNoList = stockBatchNoMap.get(productModelId) == null
+ ? Collections.emptyList()
+ : new ArrayList<>(stockBatchNoMap.get(productModelId));
+ vo.setBatchNoList(batchNoList);
+ vo.setStockQuantity(stockQuantityMap.getOrDefault(productModelId, BigDecimal.ZERO));
+ vo.setBom(true);
+ result.add(vo);
+ }
+ return result;
+ }
}
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
index f17065a..21fa421 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -52,4 +52,6 @@
BigDecimal selectTotalByDate(@Param("now") LocalDate now);
BigDecimal selectPendingOutQuantity(@Param("productModelId") Long productModelId, @Param("batchNo") String batchNo, @Param("type") String type);
+
+ List<StockInventory> listSelectableBatchNoByProductModelIds(@Param("productModelIds") List<Long> productModelIds);
}
diff --git a/src/main/resources/mapper/basic/ProductModelMapper.xml b/src/main/resources/mapper/basic/ProductModelMapper.xml
index 4ae5508..0a540bf 100644
--- a/src/main/resources/mapper/basic/ProductModelMapper.xml
+++ b/src/main/resources/mapper/basic/ProductModelMapper.xml
@@ -14,7 +14,16 @@
<result column="product_name" property="productName" />
<result column="product_id" property="productId" />
</resultMap>
- <select id="listPageProductModel" resultType="com.ruoyi.basic.pojo.ProductModel">
+
+ <resultMap id="ProductModelVoResultMap" type="com.ruoyi.basic.vo.ProductModelVo" extends="BaseResultMap">
+ <result column="create_time" property="createTime" />
+ <collection property="batchNoList"
+ ofType="java.lang.String"
+ column="{productModelId=id}"
+ select="selectBatchNoListByProductModelId"/>
+ </resultMap>
+
+ <select id="listPageProductModel" resultMap="ProductModelVoResultMap">
select pm.*,p.product_name
from product_model pm
left join product p on pm.product_id = p.id
@@ -31,9 +40,9 @@
SELECT id
FROM product
WHERE id = #{c.topProductParentId}
-
+
UNION ALL
-
+
SELECT p.id
FROM product p
INNER JOIN product_tree pt ON p.parent_id = pt.id
@@ -43,6 +52,15 @@
</if>
</where>
order by pm.id
+ </select>
+
+ <select id="selectBatchNoListByProductModelId" resultType="java.lang.String">
+ select distinct si.batch_no
+ from stock_inventory si
+ where si.product_model_id = #{productModelId}
+ and si.batch_no is not null
+ and si.batch_no != ''
+ order by si.batch_no
</select>
<select id="selectLatestRecord" resultType="com.ruoyi.basic.pojo.ProductModel">
SELECT * FROM product_model
@@ -123,4 +141,4 @@
order by p.id,pm.id desc
</select>
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductionBomStructureMapper.xml b/src/main/resources/mapper/production/ProductionBomStructureMapper.xml
index 13b534f..c116f6f 100644
--- a/src/main/resources/mapper/production/ProductionBomStructureMapper.xml
+++ b/src/main/resources/mapper/production/ProductionBomStructureMapper.xml
@@ -31,4 +31,23 @@
order by pbs.id
</select>
+ <select id="pickByBomId" resultType="com.ruoyi.production.bean.vo.ProductionBomStructureVo">
+ SELECT
+ pbs.*,
+ p.product_name AS productName,
+ pm.product_id AS productId,
+ pm.model,
+ top1.NAME AS operationName
+ FROM
+ production_bom_structure pbs
+ LEFT JOIN product_model pm ON pbs.product_model_id = pm.id
+ LEFT JOIN product p ON pm.product_id = p.id
+ LEFT JOIN technology_operation top1 ON pbs.technology_operation_id = top1.id
+ WHERE
+ pbs.parent_id IS NOT NULL
+ AND pbs.production_order_bom_id = #{bomId}
+ ORDER BY
+ pbs.id
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/production/ProductionOrderPickMapper.xml b/src/main/resources/mapper/production/ProductionOrderPickMapper.xml
index c4b11f8..7dd8a1f 100644
--- a/src/main/resources/mapper/production/ProductionOrderPickMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOrderPickMapper.xml
@@ -14,6 +14,24 @@
<result column="remark" property="remark" />
<result column="create_user" property="createUser" />
<result column="dept_id" property="deptId" />
+ <result column="operation_name" property="operationName" />
+ <result column="technology_operation_id" property="technologyOperationId" />
+ <result column="demanded_quantity" property="demandedQuantity" />
+ <result column="is_bom" property="bom" />
</resultMap>
+ <select id="listPickedDetailByOrderId" resultType="com.ruoyi.production.bean.vo.ProductionOrderPickVo">
+ select pop.*,
+ pop.is_bom as bom,
+ pop.quantity as pickQuantity,
+ p.product_name as productName,
+ pm.model as model,
+ pm.unit as unit
+ from production_order_pick pop
+ left join product_model pm on pop.product_model_id = pm.id
+ left join product p on pm.product_id = p.id
+ where pop.production_order_id = #{productionOrderId}
+ order by pop.create_time desc, pop.id desc
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml b/src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml
index 37c1285..818f4d9 100644
--- a/src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml
@@ -21,4 +21,19 @@
<result column="dept_id" property="deptId" />
</resultMap>
+ <select id="listPickedDetailByOrderId" resultType="com.ruoyi.production.bean.vo.ProductionOrderPickVo">
+ select popr.*,
+ poro.operation_name as operationName,
+ p.product_name as productName,
+ pm.model as model,
+ pm.unit as unit
+ from production_order_pick_record popr
+ left join production_operation_task pot on popr.production_operation_task_id = pot.id
+ left join production_order_routing_operation poro on pot.technology_routing_operation_id = poro.id
+ left join product_model pm on popr.product_model_id = pm.id
+ left join product p on pm.product_id = p.id
+ where popr.production_order_id = #{productionOrderId}
+ order by popr.create_time desc, popr.id desc
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index 6e8a3bc..d1eecb5 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -439,4 +439,18 @@
AND sor.approval_status = 0
</select>
+ <select id="listSelectableBatchNoByProductModelIds" resultType="com.ruoyi.stock.pojo.StockInventory">
+ select distinct si.product_model_id,
+ si.batch_no
+ from stock_inventory si
+ where si.product_model_id in
+ <foreach collection="productModelIds" item="productModelId" open="(" separator="," close=")">
+ #{productModelId}
+ </foreach>
+ and si.batch_no is not null
+ and si.batch_no != ''
+ and (si.qualitity - ifnull(si.locked_quantity, 0)) > 0
+ order by si.product_model_id, si.batch_no
+ </select>
+
</mapper>
--
Gitblit v1.9.3