doc/add.sql
ÎļþÒÑɾ³ý src/main/java/com/ruoyi/procurementrecord/pojo/ReturnSaleProduct.java
@@ -38,7 +38,7 @@ private Long returnManagementId; @Schema(description = "é货产åid") private Long returnSaleLedgerProductId; private Long returnsalesLedgerProductId; @Schema(description = "éè´§äº§åæ°é") private BigDecimal num; src/main/java/com/ruoyi/production/bean/vo/ProductionBomStructureVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,27 @@ package com.ruoyi.production.bean.vo; import com.ruoyi.production.pojo.ProductionBomStructure; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; @Data @EqualsAndHashCode(callSuper = true) public class ProductionBomStructureVo extends ProductionBomStructure { @Schema(description = "å·¥åºåç§°") private String operationName; @Schema(description = "产ååç§°") private String productName; @Schema(description = "产åID") private Long productId; @Schema(description = "è§æ ¼åå·") private String model; private List<ProductionBomStructureVo> children; } src/main/java/com/ruoyi/production/bean/vo/ProductionOrderRoutingOperationVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,23 @@ package com.ruoyi.production.bean.vo; import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data public class ProductionOrderRoutingOperationVo extends ProductionOrderRoutingOperation { @Schema(description = "产ååç§°") private String productName; @Schema(description = "è§æ ¼åå·") private String model; @Schema(description = "åä½") private String unit; @Schema(description = "åºç¡å·¥åºID") private Long technologyOperationId; } src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java
@@ -4,9 +4,11 @@ import com.ruoyi.production.pojo.ProductionOrder; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; @EqualsAndHashCode(callSuper = true) @Data @Schema(name = "ProductionOrderVo", description = "ç产订åè¿å对象") public class ProductionOrderVo extends ProductionOrder { @@ -27,4 +29,7 @@ @Schema(description = "产åå¾ç") private List<StorageBlobVO> productImages; @Schema(description = "bomç¼å·") private String bomNo; } src/main/java/com/ruoyi/production/controller/ProductionBomStructureController.java
@@ -1,7 +1,16 @@ package com.ruoyi.production.controller; import com.ruoyi.framework.web.domain.R; import com.ruoyi.production.bean.vo.ProductionBomStructureVo; import com.ruoyi.production.service.ProductionBomStructureService; import io.swagger.v3.oas.annotations.Operation; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * <p> @@ -13,6 +22,15 @@ */ @RestController @RequestMapping("/productionBomStructure") @AllArgsConstructor public class ProductionBomStructureController { private ProductionBomStructureService productionBomStructureService; @GetMapping("/listByBomId/{bomId}") @Operation(summary = "æ ¹æ®BOMæ¥è¯¢ç产订åBOMç»ææ ") public R<List<ProductionBomStructureVo>> listByBomId(@PathVariable Long bomId) { return R.ok(productionBomStructureService.listByBomId(bomId)); } } src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
@@ -7,19 +7,12 @@ import com.ruoyi.production.bean.vo.ProductionOrderVo; import com.ruoyi.production.pojo.ProductionOrder; import com.ruoyi.production.service.ProductionOrderService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -45,36 +38,35 @@ @GetMapping("/{id}") @Operation(summary = "ç产订å详æ ") public R<ProductionOrderVo> getInfo(@PathVariable("id") Long id) { public R<ProductionOrderVo> getInfo(@PathVariable Long id) { return R.ok(productionOrderService.getProductionOrderInfo(id)); } @PostMapping @Operation( summary = "æ°å¢ç产订å", description = "æ°å¢ä¸ååªæ¯æä¸¤ç§æ¹å¼ï¼1. ç产计åçæï¼ä¼ productionPlanIdsï¼ç³»ç»èªå¨æ±æ»è®¡åå¾å°äº§åè§æ ¼åæ°éï¼" @PostMapping("/addOrder") @Operation(summary = "æ°å¢ç产订å", description = "æ°å¢ä¸ååªæ¯æä¸¤ç§æ¹å¼ï¼1. ç产计åçæï¼ä¼ productionPlanIdsï¼ç³»ç»èªå¨æ±æ»è®¡åå¾å°äº§åè§æ ¼åæ°éï¼" + "2. æå¨æ°å¢ï¼å¿ é¡»ä¼ productModelId å quantityã" + "technologyRoutingId 为空æ¶ä¼èªå¨å¹é 该产åè§æ ¼ææ°å·¥èºè·¯çº¿ï¼quantity æç»å¿ é¡»å¤§äº 0ã" ) @io.swagger.v3.oas.annotations.parameters.RequestBody( required = true, description = "å端å好æç¤ºï¼å¦ææ¯ç产计åçæï¼è¯·ä¼ productionPlanIdsï¼" + "å¦ææ¯æå¨æ°å¢ï¼è¯·è³å°å¡«å productModelIdãquantityï¼ä¸ quantity å¿ é¡»å¤§äº 0ã", content = @Content(schema = @Schema(implementation = ProductionOrder.class)) ) + "technologyRoutingId 为空æ¶ä¼èªå¨å¹é 该产åè§æ ¼ææ°å·¥èºè·¯çº¿ï¼quantity æç»å¿ é¡»å¤§äº 0ã") @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, description = "å端å好æç¤ºï¼å¦ææ¯ç产计åçæï¼è¯·ä¼ productionPlanIdsï¼" + "å¦ææ¯æå¨æ°å¢ï¼è¯·è³å°å¡«å productModelIdãquantityï¼ä¸ quantity å¿ é¡»å¤§äº 0ã", content = @Content(schema = @Schema(implementation = ProductionOrder.class))) public R<Boolean> add(@RequestBody ProductionOrder productionOrder) { return R.ok(productionOrderService.saveProductionOrder(productionOrder)); } @PutMapping @PutMapping("/editOrder") @Operation(summary = "ä¿®æ¹ç产订å") public R<Boolean> edit(@RequestBody ProductionOrder productionOrder) { return R.ok(productionOrderService.saveProductionOrder(productionOrder)); } @Operation(summary = "ç»å®å·¥èºè·¯çº¿") @PostMapping("/bindingRoute") public R bindingRoute(@RequestBody ProductionOrderDto productionOrderDto) { return R.ok(productionOrderService.bindingRoute(productionOrderDto)); } @PostMapping("/syncSnapshot/{id}") @Operation(summary = "忥ç产订åå·¥èº/BOMå¿«ç §") public R<Integer> syncSnapshot(@PathVariable("id") Long id) { public R<Integer> syncSnapshot(@PathVariable Long id) { return R.ok(productionOrderService.syncProductionOrderSnapshot(id)); } src/main/java/com/ruoyi/production/mapper/ProductionBomStructureMapper.java
@@ -1,8 +1,12 @@ package com.ruoyi.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.production.bean.vo.ProductionBomStructureVo; import com.ruoyi.production.pojo.ProductionBomStructure; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> @@ -15,4 +19,6 @@ @Mapper public interface ProductionBomStructureMapper extends BaseMapper<ProductionBomStructure> { List<ProductionBomStructureVo> listByBomId(@Param("bomId") Long bomId); } src/main/java/com/ruoyi/production/mapper/ProductionOrderRoutingOperationMapper.java
@@ -1,8 +1,12 @@ package com.ruoyi.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationVo; import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> @@ -15,4 +19,6 @@ @Mapper public interface ProductionOrderRoutingOperationMapper extends BaseMapper<ProductionOrderRoutingOperation> { List<ProductionOrderRoutingOperationVo> selectVoListByOrderId(@Param("orderId") Long orderId); } src/main/java/com/ruoyi/production/pojo/ProductionOrder.java
@@ -65,7 +65,7 @@ private LocalDateTime endTime; @Schema(description = "éå®äº§åè§æ ¼idãç产ä¸åæ¥å£ä¸è¬ä¸ä½ä¸ºåç«¯å¿ å¡«é¡¹ï¼åå¨é宿¥æºæ¶ç±ç³»ç»å é¨å ³èã") private Integer saleLedgerProductId; private Integer salesLedgerProductId; @Schema(description = "å建人ID") @TableField(fill = FieldFill.INSERT) src/main/java/com/ruoyi/production/pojo/ProductionOrderRouting.java
@@ -48,8 +48,11 @@ @Schema(description = "å·¥èºè·¯çº¿ç¼ç ") private String processRouteCode; @Schema(description = "å ³èbomçid") private Integer bomId; @Schema(description = "åºç¡bomçid") private Long bomId; @Schema(description = "订åbomçid") private Long orderBomId; @Schema(description = "å建人ID") @TableField(fill = FieldFill.INSERT) src/main/java/com/ruoyi/production/pojo/ProductionOrderRoutingOperation.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.time.LocalDateTime; @@ -53,6 +51,9 @@ @Schema(description = "æ¯å¦è´¨æ£å·¥åº") private Boolean isQuality; @Schema(description = "æ¯å¦ç产") private Boolean isProduction; @Schema(description = "å建人ID") @TableField(fill = FieldFill.INSERT) private Long createUser; @@ -60,4 +61,7 @@ @Schema(description = "é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; @Schema(description = "å·¥åºåç§°") private String operationName; } src/main/java/com/ruoyi/production/pojo/ProductionPlan.java
@@ -71,6 +71,9 @@ @Schema(description = "éæ±æ°é") private BigDecimal qtyRequired; @Schema(description = "å·²ä¸åæ°é") private BigDecimal quantityIssued; @Schema(description = "æ¯å¦ä¸åå¶é 订å") private Boolean issued; src/main/java/com/ruoyi/production/service/ProductionBomStructureService.java
@@ -1,7 +1,10 @@ package com.ruoyi.production.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.production.bean.vo.ProductionBomStructureVo; import com.ruoyi.production.pojo.ProductionBomStructure; import java.util.List; /** * <p> @@ -13,4 +16,6 @@ */ public interface ProductionBomStructureService extends IService<ProductionBomStructure> { List<ProductionBomStructureVo> listByBomId(Long bomId); } src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java
@@ -1,8 +1,8 @@ package com.ruoyi.production.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationVo; import com.ruoyi.production.pojo.ProductionOrderRouting; import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; import java.util.List; @@ -10,5 +10,5 @@ ProductionOrderRouting listMain(Long orderId); List<ProductionOrderRoutingOperation> listItem(Long orderId); List<ProductionOrderRoutingOperationVo> listItem(Long orderId); } src/main/java/com/ruoyi/production/service/ProductionOrderService.java
@@ -22,4 +22,6 @@ boolean removeProductionOrder(List<Long> ids); int syncProductionOrderSnapshot(Long productionOrderId); Object bindingRoute(ProductionOrderDto productionOrderDto); } src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -1,10 +1,17 @@ package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.production.bean.vo.ProductionBomStructureVo; import com.ruoyi.production.mapper.ProductionBomStructureMapper; import com.ruoyi.production.pojo.ProductionBomStructure; import com.ruoyi.production.service.ProductionBomStructureService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <p> @@ -15,6 +22,36 @@ * @since 2026-04-21 03:55:52 */ @Service @RequiredArgsConstructor() public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService { private final ProductionBomStructureMapper productionBomStructureMapper; /** * æ ¹æ®BOMæ¥è¯¢å¹¶ç»è£ ç»ææ ã */ @Override public List<ProductionBomStructureVo> listByBomId(Long bomId) { List<ProductionBomStructureVo> list = productionBomStructureMapper.listByBomId(bomId); Map<Long, ProductionBomStructureVo> map = new HashMap<>(); for (ProductionBomStructureVo node : list) { node.setChildren(new ArrayList<>()); map.put(node.getId(), node); } List<ProductionBomStructureVo> tree = new ArrayList<>(); for (ProductionBomStructureVo node : list) { Long parentId = node.getParentId(); if (parentId == null || parentId == 0L) { tree.add(node); continue; } ProductionBomStructureVo parent = map.get(parentId); if (parent != null) { parent.getChildren().add(node); } } return tree; } } src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java
@@ -2,10 +2,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationVo; import com.ruoyi.production.mapper.ProductionOrderRoutingMapper; import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper; import com.ruoyi.production.pojo.ProductionOrderRouting; import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; import com.ruoyi.production.service.ProductionOrderRoutingService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -29,11 +29,7 @@ } @Override public List<ProductionOrderRoutingOperation> listItem(Long orderId) { return productionOrderRoutingOperationMapper.selectList( Wrappers.<ProductionOrderRoutingOperation>lambdaQuery() .eq(ProductionOrderRoutingOperation::getProductionOrderId, orderId) .orderByAsc(ProductionOrderRoutingOperation::getDragSort) .orderByAsc(ProductionOrderRoutingOperation::getId)); public List<ProductionOrderRoutingOperationVo> listItem(Long orderId) { return productionOrderRoutingOperationMapper.selectVoListByOrderId(orderId); } } src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -58,6 +58,7 @@ private final TechnologyRoutingMapper technologyRoutingMapper; private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper; private final TechnologyRoutingOperationParamMapper technologyRoutingOperationParamMapper; private final TechnologyOperationMapper technologyOperationMapper; private final TechnologyBomMapper technologyBomMapper; private final TechnologyBomStructureMapper technologyBomStructureMapper; private final FileUtil fileUtil; @@ -136,20 +137,64 @@ } @Override public Integer bindingRoute(ProductionOrderDto productionOrderDto) { if (productionOrderDto == null || productionOrderDto.getId() == null) { throw new ServiceException("ç产订åIDä¸è½ä¸ºç©º"); } ProductionOrder productionOrder = this.getById(productionOrderDto.getId()); if (productionOrder == null) { throw new ServiceException("ç产订åä¸åå¨"); } Long targetRoutingId = productionOrderDto.getTechnologyRoutingId() == null ? productionOrder.getTechnologyRoutingId() : productionOrderDto.getTechnologyRoutingId(); if (targetRoutingId == null) { throw new ServiceException("å·¥èºè·¯çº¿IDä¸è½ä¸ºç©º"); } TechnologyRouting targetRouting = technologyRoutingMapper.selectById(targetRoutingId); if (targetRouting == null) { throw new ServiceException("å·¥èºè·¯çº¿ä¸åå¨"); } if (productionOrder.getProductModelId() != null && !Objects.equals(productionOrder.getProductModelId(), targetRouting.getProductModelId())) { throw new ServiceException("å·¥èºè·¯çº¿ä¸ç产订å产åè§æ ¼ä¸å¹é "); } if (ProductOrderStatusEnum.isStarted(productionOrder.getStatus()) && !Objects.equals(productionOrder.getTechnologyRoutingId(), targetRoutingId)) { throw new ServiceException("ç产订åå·²å¼å·¥ï¼ä¸è½ä¿®æ¹å·¥èºè·¯çº¿"); } if (!Objects.equals(productionOrder.getTechnologyRoutingId(), targetRoutingId)) { ProductionOrder update = new ProductionOrder(); update.setId(productionOrder.getId()); update.setTechnologyRoutingId(targetRoutingId); if (!this.updateById(update)) { throw new ServiceException("ç»å®å·¥èºè·¯çº¿å¤±è´¥"); } } // ç»å®è·¯çº¿ä» é建订åä¾§å¿«ç §æ°æ® return syncProductionOrderSnapshot(productionOrder.getId()); } @Override public int syncProductionOrderSnapshot(Long productionOrderId) { ProductionOrder productionOrder = this.getById(productionOrderId); if (productionOrder == null) { throw new ServiceException("Production order not found"); throw new ServiceException("ç产订åä¸åå¨"); } if (productionOrder.getTechnologyRoutingId() == null) { throw new ServiceException("technologyRoutingId is required"); throw new ServiceException("å·¥èºè·¯çº¿IDä¸è½ä¸ºç©º"); } TechnologyRouting technologyRouting = technologyRoutingMapper.selectById(productionOrder.getTechnologyRoutingId()); if (technologyRouting == null) { throw new ServiceException("Technology routing not found"); throw new ServiceException("å·¥èºè·¯çº¿ä¸åå¨"); } // 订åå¿«ç §æâå æ¸ å建âå¤çï¼ä¿è¯å·¥èºè·¯çº¿ãå·¥åºãåæ°ãBOM å ¨é¨æ¥èªåä¸çæ¬ã clearProductionSnapshot(productionOrderId); ProductionOrderBom orderBom = syncProductionOrderBomSnapshot(productionOrder, technologyRouting); ProductionOrderRouting orderRouting = new ProductionOrderRouting(); orderRouting.setProductionOrderId(productionOrder.getId()); @@ -158,6 +203,7 @@ orderRouting.setProcessRouteCode(technologyRouting.getProcessRouteCode()); orderRouting.setDescription(technologyRouting.getDescription()); orderRouting.setBomId(technologyRouting.getBomId()); orderRouting.setOrderBomId(orderBom == null ? null : orderBom.getId()); productionOrderRoutingMapper.insert(orderRouting); int syncedParamCount = 0; @@ -166,6 +212,13 @@ .eq(TechnologyRoutingOperation::getTechnologyRoutingId, technologyRouting.getId()) .orderByAsc(TechnologyRoutingOperation::getDragSort) .orderByAsc(TechnologyRoutingOperation::getId)); Map<Long, String> operationNameMap = technologyOperationMapper.selectBatchIds( routingOperations.stream() .map(TechnologyRoutingOperation::getTechnologyOperationId) .filter(Objects::nonNull) .collect(Collectors.toSet())) .stream() .collect(Collectors.toMap(TechnologyOperation::getId, TechnologyOperation::getName, (a, b) -> a)); for (TechnologyRoutingOperation sourceOperation : routingOperations) { // 订åå·¥åºä¿åçæ¯å·¥èºå·¥åºå¿«ç §ï¼åç»æ¥å·¥åªä¾èµå¿«ç §ï¼ä¸åç´æ¥å¼ç¨å·¥èºä¸»æ°æ®ã ProductionOrderRoutingOperation targetOperation = new ProductionOrderRoutingOperation(); @@ -175,6 +228,7 @@ targetOperation.setProductModelId(sourceOperation.getProductModelId()); targetOperation.setDragSort(sourceOperation.getDragSort()); targetOperation.setIsQuality(sourceOperation.getIsQuality()); targetOperation.setOperationName(operationNameMap.get(sourceOperation.getTechnologyOperationId())); productionOrderRoutingOperationMapper.insert(targetOperation); ProductionOperationTask task = new ProductionOperationTask(); @@ -212,18 +266,17 @@ } } syncProductionOrderBomSnapshot(productionOrder, technologyRouting); upsertOrderPick(productionOrder); return syncedParamCount; } private void syncProductionOrderBomSnapshot(ProductionOrder productionOrder, TechnologyRouting technologyRouting) { private ProductionOrderBom syncProductionOrderBomSnapshot(ProductionOrder productionOrder, TechnologyRouting technologyRouting) { if (technologyRouting.getBomId() == null) { return; return null; } TechnologyBom technologyBom = technologyBomMapper.selectById(technologyRouting.getBomId()); if (technologyBom == null) { throw new ServiceException("Technology BOM not found"); throw new ServiceException("å·¥èºBOMä¸åå¨"); } List<TechnologyBomStructure> structureList = technologyBomStructureMapper.selectList( Wrappers.<TechnologyBomStructure>lambdaQuery() @@ -257,6 +310,7 @@ productionBomStructureMapper.insert(target); idMap.put(source.getId(), target.getId()); } return orderBom; } private void clearProductionSnapshot(Long productionOrderId) { @@ -265,7 +319,7 @@ Wrappers.<ProductionOrderPickRecord>lambdaQuery() .eq(ProductionOrderPickRecord::getProductionOrderId, productionOrderId)) > 0; if (hasPickRecord) { throw new ServiceException("Production order pick records already exist, snapshot cannot be regenerated"); throw new ServiceException("ç产订åå·²åå¨é¢æè®°å½ï¼ä¸è½éæ°çæå¿«ç §"); } List<Long> taskIds = productionOperationTaskMapper.selectList( Wrappers.<ProductionOperationTask>lambdaQuery() @@ -277,7 +331,7 @@ Wrappers.<ProductionProductMain>lambdaQuery() .in(ProductionProductMain::getProductionOperationTaskId, taskIds)) > 0; if (started) { throw new ServiceException("Production order already started, snapshot cannot be regenerated"); throw new ServiceException("ç产订åå·²å¼å·¥ï¼ä¸è½éæ°çæå¿«ç §"); } productionOperationTaskMapper.delete(Wrappers.<ProductionOperationTask>lambdaQuery() .eq(ProductionOperationTask::getProductionOrderId, productionOrderId)); @@ -350,15 +404,15 @@ private void validateAndFillOrder(ProductionOrder productionOrder, ProductionOrder oldOrder) { if (productionOrder == null) { throw new ServiceException("Production order is required"); throw new ServiceException("ç产订åä¸è½ä¸ºç©º"); } fillFromSalesLedgerProduct(productionOrder); fillFromProductionPlans(productionOrder); if (productionOrder.getProductModelId() == null) { throw new ServiceException("productModelId is required"); throw new ServiceException("产åè§æ ¼IDä¸è½ä¸ºç©º"); } if (defaultDecimal(productionOrder.getQuantity()).compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("quantity must be greater than 0"); throw new ServiceException("ä¸åæ°éå¿ é¡»å¤§äº0"); } // if (productionOrder.getTechnologyRoutingId() == null) { // // æªæ¾å¼æå®å·¥èºè·¯çº¿æ¶ï¼æäº§åè§æ ¼éææ°ä¸æ¡å·¥èºä½ä¸ºé»è®¤è·¯çº¿ã @@ -368,7 +422,7 @@ // .orderByDesc(TechnologyRouting::getId) // .last("limit 1")); // if (technologyRouting == null) { // throw new ServiceException("No technology routing found for the product model"); // throw new ServiceException("æªæ¾å°è¯¥äº§åè§æ ¼å¯¹åºçå·¥èºè·¯çº¿"); // } // productionOrder.setTechnologyRoutingId(technologyRouting.getId()); // } @@ -377,29 +431,29 @@ if (!Objects.equals(oldOrder.getProductModelId(), productionOrder.getProductModelId()) || !Objects.equals(oldOrder.getTechnologyRoutingId(), productionOrder.getTechnologyRoutingId()) || compareDecimal(oldOrder.getQuantity(), productionOrder.getQuantity()) != 0) { throw new ServiceException("Started production orders cannot modify product, routing or quantity"); throw new ServiceException("ç产订åå·²å¼å·¥ï¼ä¸è½ä¿®æ¹äº§åãå·¥èºè·¯çº¿ææ°é"); } } } private void fillFromSalesLedgerProduct(ProductionOrder productionOrder) { if (productionOrder.getSaleLedgerProductId() == null) { if (productionOrder.getSalesLedgerProductId() == null) { return; } // éå®æç»æ¯è®¢åæ¥æºæ¶ï¼ä»¥é宿ç»ä¸ºååå¡«éå®å°è´¦ã产åè§æ ¼åé»è®¤æ°éã SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(productionOrder.getSaleLedgerProductId().longValue()); SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(productionOrder.getSalesLedgerProductId().longValue()); if (salesLedgerProduct == null) { throw new ServiceException("Sales ledger product not found"); throw new ServiceException("éå®å°è´¦äº§åä¸åå¨"); } if (productionOrder.getSalesLedgerId() == null) { productionOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId()); } else if (!Objects.equals(productionOrder.getSalesLedgerId(), salesLedgerProduct.getSalesLedgerId())) { throw new ServiceException("salesLedgerId does not match the sales ledger product"); throw new ServiceException("éå®å°è´¦IDä¸éå®å°è´¦äº§åä¸ä¸è´"); } if (productionOrder.getProductModelId() == null) { productionOrder.setProductModelId(salesLedgerProduct.getProductModelId()); } else if (!Objects.equals(productionOrder.getProductModelId(), salesLedgerProduct.getProductModelId())) { throw new ServiceException("productModelId does not match the sales ledger product"); throw new ServiceException("产åè§æ ¼IDä¸éå®å°è´¦äº§åä¸ä¸è´"); } if (productionOrder.getQuantity() == null || productionOrder.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { productionOrder.setQuantity(salesLedgerProduct.getQuantity()); @@ -420,22 +474,22 @@ // å¤è®¡ååå¹¶è½¬åæ¶ï¼ææè®¡åå¿ é¡»å±äºåä¸è§æ ¼ï¼ä¸åªè½ä¸å䏿¬¡ã List<ProductionPlan> productionPlans = productionPlanMapper.selectBatchIds(planIds); if (productionPlans.size() != planIds.size()) { throw new ServiceException("Some production plans do not exist"); throw new ServiceException("é¨åç产计åä¸åå¨"); } Set<Long> productModelIds = productionPlans.stream() .map(ProductionPlan::getProductModelId) .collect(Collectors.toSet()); if (productModelIds.size() > 1) { throw new ServiceException("Selected production plans must belong to the same product model"); throw new ServiceException("æéç产计åå¿ é¡»å±äºåä¸äº§åè§æ ¼"); } if (Boolean.TRUE.equals(productionPlans.stream().anyMatch(item -> Boolean.TRUE.equals(item.getIssued())))) { throw new ServiceException("Selected production plans already issued"); if (productionPlans.stream().anyMatch(item -> item.getStatus() != null && item.getStatus() == 2)) { throw new ServiceException("æéç产计åå·²ä¸å"); } ProductionPlan firstPlan = productionPlans.get(0); if (productionOrder.getProductModelId() == null) { productionOrder.setProductModelId(firstPlan.getProductModelId()); } else if (!Objects.equals(productionOrder.getProductModelId(), firstPlan.getProductModelId())) { throw new ServiceException("productModelId does not match the production plans"); throw new ServiceException("产åè§æ ¼IDä¸ç产计åä¸ä¸è´"); } if (productionOrder.getQuantity() == null || productionOrder.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { productionOrder.setQuantity(productionPlans.stream() src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
@@ -73,31 +73,30 @@ throw new ServiceException("ä¸åå¤±è´¥ï¼æªéæ©ç产计å"); } List<ProductionPlanDto> plans = productionPlanMapper.selectWithMaterialByIds(planIds); if (plans == null || plans.isEmpty() || plans.size() != planIds.size()) { List<ProductionPlanDto> planLists = productionPlanMapper.selectWithMaterialByIds(planIds); if (planLists == null || planLists.isEmpty() || planLists.size() != planIds.size()) { throw new ServiceException("ä¸å失败ï¼ç产计åä¸åå¨æå·²è¢«å é¤"); } ProductionPlanDto firstPlan = plans.getFirst(); ProductionPlanDto firstPlan = planLists.getFirst(); if (firstPlan.getProductModelId() == null) { throw new ServiceException("ä¸å失败ï¼ç产计å缺å°äº§ååå·"); } boolean hasDifferentModel = plans.stream() boolean hasDifferentModel = planLists.stream() .anyMatch(item -> !Objects.equals(item.getProductModelId(), firstPlan.getProductModelId())); if (hasDifferentModel) { throw new BaseException("åå¹¶å¤±è´¥ï¼æéç产计åç产ååå·ä¸ä¸è´"); } boolean hasIssuedPlan = plans.stream() .anyMatch(item -> item.getStatus() != null && item.getStatus() != PLAN_STATUS_WAIT); boolean hasIssuedPlan = planLists.stream() .anyMatch(item -> item.getStatus() != null && item.getStatus() == PLAN_STATUS_ISSUED); if (hasIssuedPlan) { throw new BaseException("åå¹¶å¤±è´¥ï¼æéç产计ååå¨å·²ä¸åæé¨åä¸åæ°æ®"); } BigDecimal totalRequiredQuantity = plans.stream() .map(ProductionPlan::getQtyRequired) .filter(Objects::nonNull) BigDecimal totalRequiredQuantity = planLists.stream() .map(this::resolveRemainingQuantity) .reduce(BigDecimal.ZERO, BigDecimal::add); if (totalRequiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("ä¸åå¤±è´¥ï¼æéç产计åéæ±æ»éå¿ é¡»å¤§äº0"); @@ -111,8 +110,25 @@ throw new ServiceException("ä¸å失败ï¼ä¸åæ°éä¸è½å¤§äºè®¡åéæ±æ»é"); } BigDecimal remainingForOrderBind = assignedQuantity; List<Long> issuedPlanIds = new ArrayList<>(); for (ProductionPlanDto plan : planLists) { BigDecimal remainingQuantity = resolveRemainingQuantity(plan); if (remainingForOrderBind.compareTo(BigDecimal.ZERO) <= 0 || remainingQuantity.compareTo(BigDecimal.ZERO) <= 0) { continue; } BigDecimal issueForThisPlan = remainingForOrderBind.min(remainingQuantity); remainingForOrderBind = remainingForOrderBind.subtract(issueForThisPlan); if (issueForThisPlan.compareTo(BigDecimal.ZERO) > 0) { issuedPlanIds.add(plan.getId()); } } if (issuedPlanIds.isEmpty()) { throw new ServiceException("Issue failed, no quantity available for dispatch"); } ProductionOrder productionOrder = new ProductionOrder(); productionOrder.setProductionPlanIds(formatPlanIds(planIds)); productionOrder.setProductionPlanIds(formatPlanIds(issuedPlanIds)); productionOrder.setProductModelId(firstPlan.getProductModelId()); productionOrder.setQuantity(assignedQuantity); productionOrder.setPlanCompleteTime(productionPlanDto.getPlanCompleteTime()); @@ -122,13 +138,31 @@ throw new ServiceException("ä¸å失败ï¼ç产订åä¿å失败"); } int targetStatus = assignedQuantity.compareTo(totalRequiredQuantity) < 0 ? PLAN_STATUS_PARTIAL : PLAN_STATUS_ISSUED; List<ProductionPlan> updates = planIds.stream().map(id -> { //å·²ä¸åæ°é BigDecimal remainingAssignedQuantity = assignedQuantity; List<ProductionPlan> updates = new ArrayList<>(); for (ProductionPlanDto plan : planLists) { BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO); if (requiredQuantity.compareTo(BigDecimal.ZERO) < 0) { requiredQuantity = BigDecimal.ZERO; } BigDecimal remainingQuantity = resolveRemainingQuantity(plan); BigDecimal historicalIssuedQuantity = requiredQuantity.subtract(remainingQuantity); BigDecimal issuedQuantity = BigDecimal.ZERO; if (remainingAssignedQuantity.compareTo(BigDecimal.ZERO) > 0 && remainingQuantity.compareTo(BigDecimal.ZERO) > 0) { issuedQuantity = remainingAssignedQuantity.min(remainingQuantity); remainingAssignedQuantity = remainingAssignedQuantity.subtract(issuedQuantity); } BigDecimal totalIssuedQuantity = historicalIssuedQuantity.add(issuedQuantity); int planStatus = resolvePlanStatus(requiredQuantity, totalIssuedQuantity); ProductionPlan update = new ProductionPlan(); update.setId(id); update.setStatus(targetStatus); return update; }).collect(Collectors.toList()); update.setId(plan.getId()); update.setStatus(planStatus); update.setQuantityIssued(totalIssuedQuantity); update.setIssued(planStatus == PLAN_STATUS_ISSUED); updates.add(update); } if (!updates.isEmpty()) { this.updateBatchById(updates); } @@ -261,6 +295,34 @@ util.exportExcel(response, exportList, "主ç产计å"); } private BigDecimal resolveRemainingQuantity(ProductionPlan plan) { if (plan == null) { return BigDecimal.ZERO; } BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO); if (requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { return BigDecimal.ZERO; } BigDecimal issuedQuantity = Optional.ofNullable(plan.getQuantityIssued()).orElse(BigDecimal.ZERO); if (issuedQuantity.compareTo(BigDecimal.ZERO) <= 0) { return requiredQuantity; } if (issuedQuantity.compareTo(requiredQuantity) >= 0) { return BigDecimal.ZERO; } return requiredQuantity.subtract(issuedQuantity); } private int resolvePlanStatus(BigDecimal requiredQuantity, BigDecimal issuedQuantity) { if (requiredQuantity == null || requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { return PLAN_STATUS_WAIT; } if (issuedQuantity == null || issuedQuantity.compareTo(BigDecimal.ZERO) <= 0) { return PLAN_STATUS_WAIT; } return issuedQuantity.compareTo(requiredQuantity) < 0 ? PLAN_STATUS_PARTIAL : PLAN_STATUS_ISSUED; } private String formatPlanIds(List<Long> planIds) { return planIds.stream() .filter(Objects::nonNull) src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -246,7 +246,7 @@ ProductionAccount productionAccount = new ProductionAccount(); productionAccount.setProductionProductMainId(productionProductMain.getId()); productionAccount.setSalesLedgerId(productionOrder.getSalesLedgerId()); productionAccount.setSalesLedgerProductId(productionOrder.getSaleLedgerProductId() == null ? null : productionOrder.getSaleLedgerProductId().longValue()); productionAccount.setSalesLedgerProductId(productionOrder.getSalesLedgerProductId() == null ? null : productionOrder.getSalesLedgerProductId().longValue()); productionAccount.setSchedulingUserId(user == null ? null : user.getUserId()); productionAccount.setSchedulingUserName(user == null ? dto.getUserName() : user.getNickName()); productionAccount.setFinishedNum(productQty); src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -211,7 +211,6 @@ result = salesLedgerProductMapper.updateById(salesLedgerProduct); /*å é¤å¯¹åºççäº§æ°æ®å¹¶éæ°æ°å¢*/ deleteProductionData(Arrays.asList(salesLedgerProduct.getId())); // å é¤çäº§æ ¸ç®æ°æ® addProductionData(salesLedgerProduct); } @@ -273,7 +272,7 @@ List<ProductionPlan> productionPlans = productionPlanMapper.selectList( new LambdaQueryWrapper<ProductionPlan>() .in(ProductionPlan::getSalesLedgerProductId, productIds.stream().map(Long::intValue).collect(Collectors.toList()))); if (org.springframework.util.CollectionUtils.isEmpty(productionPlans)) { if (CollectionUtils.isEmpty(productionPlans)) { return; } //妿ç产计åå·²ä¸ååä¸è½å é¤ src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -22,7 +22,7 @@ @RequiredArgsConstructor public class StockInRecordController { private StockInRecordService stockInRecordService; private final StockInRecordService stockInRecordService; @GetMapping("/listPage") @Log(title = "çäº§å ¥åº-å ¥åºç®¡ç-å表", businessType = BusinessType.OTHER) src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -1,6 +1,7 @@ package com.ruoyi.stock.dto; import com.ruoyi.stock.pojo.StockInRecord; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -26,4 +27,7 @@ //ç°åé private String currentStock; @Schema(description = "é¡¶é¨ç¶äº§åid") private Long topParentProductId; } src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
@@ -1,6 +1,7 @@ package com.ruoyi.stock.dto; import com.ruoyi.stock.pojo.StockOutRecord; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -25,4 +26,7 @@ private String timeStr; private String createBy; @Schema(description = "é¡¶é¨ç¶äº§åid") private Long topParentProductId; } src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
@@ -27,6 +27,9 @@ @Schema(description = "å ¥åºæ°é") private BigDecimal stockInNum; @Schema(description = "æ¹å·") private String batchNo; @Schema(description = "è®°å½ç±»å æä¸¾") private String recordType; src/main/java/com/ruoyi/stock/pojo/StockInventory.java
@@ -37,6 +37,9 @@ @NotBlank(message = "ä¸è½ä¸ºç©º") private Long productModelId; @Schema(description = "æ¹å·") private String batchNo; @Schema(description = "æ°é") private BigDecimal qualitity; src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
@@ -33,6 +33,9 @@ @Schema(description = "å ¥åºæ¹æ¬¡") private String outboundBatches; @Schema(description = "æ¹å·") private String batchNo; @Schema(description = "å ¥åºæ°é") private BigDecimal stockOutNum; src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
@@ -35,6 +35,9 @@ @Schema(description = "è§æ ¼id") private Long productModelId; @Schema(description = "æ¹å·") private String batchNo; @Schema(description = "æ°é") private BigDecimal qualitity; src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -9,6 +9,7 @@ import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.EnumUtil; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.stock.dto.StockInRecordDto; @@ -73,22 +74,38 @@ for (Long id : ids) { StockInRecord stockInRecord = stockInRecordMapper.selectById(id); if (stockInRecord.getType().equals("0")) { StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>().eq(StockInventory::getProductModelId, stockInRecord.getProductModelId())); LambdaQueryWrapper<StockInventory> eq = new LambdaQueryWrapper<StockInventory>() .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()); if (StringUtils.isEmpty(stockInRecord.getBatchNo())) { eq.isNull(StockInventory::getBatchNo); } else { eq.eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()); } StockInventory stockInventory = stockInventoryMapper.selectOne(eq); if (stockInventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); }else { StockInventoryDto stockInRecordDto = new StockInventoryDto(); stockInRecordDto.setProductModelId(stockInventory.getProductModelId()); stockInRecordDto.setBatchNo(stockInventory.getBatchNo()); stockInRecordDto.setQualitity(stockInRecord.getStockInNum()); stockInventoryMapper.updateSubtractStockInventory(stockInRecordDto); } }else if (stockInRecord.getType().equals("1")) { StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId())); LambdaQueryWrapper<StockUninventory> eq = new LambdaQueryWrapper<StockUninventory>() .eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId()); if (StringUtils.isEmpty(stockInRecord.getBatchNo())) { eq.isNull(StockUninventory::getBatchNo); } else { eq.eq(StockUninventory::getBatchNo, stockInRecord.getBatchNo()); } StockUninventory stockUninventory = stockUninventoryMapper.selectOne(eq); if (stockUninventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); }else { StockUninventoryDto stockUninventoryDto = new StockUninventoryDto(); stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId()); stockUninventoryDto.setBatchNo(stockUninventory.getBatchNo()); stockUninventoryDto.setQualitity(stockInRecord.getStockInNum()); stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto); } src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -1,5 +1,6 @@ package com.ruoyi.stock.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; @@ -8,6 +9,7 @@ import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.R; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; @@ -66,23 +68,33 @@ @Override @Transactional(rollbackFor = Exception.class) public Boolean addstockInventory(StockInventoryDto stockInventoryDto) { LambdaQueryWrapper<StockInventory> eq = new QueryWrapper<StockInventory>().lambda() .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()); if (StringUtils.isEmpty(stockInventoryDto.getBatchNo())) { eq.isNull(StockInventory::getBatchNo); stockInventoryDto.setBatchNo(null); } else { eq.eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo()); } //æ°å¢å ¥åºè®°å½åæ·»å åºå StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockInRecordDto.setRecordType(stockInventoryDto.getRecordType()); stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity()); stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo()); stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockInRecordDto.setType("0"); stockInRecordService.add(stockInRecordDto); //åè¿è¡æ°å¢åºåæ°éåºå //å æ¥è¯¢åºå表ä¸çäº§åæ¯å¦åå¨ï¼ä¸å卿°å¢ï¼å卿´æ° StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())); StockInventory oldStockInventory = stockInventoryMapper.selectOne(eq); if (ObjectUtils.isEmpty(oldStockInventory)) { StockInventory newStockInventory = new StockInventory(); newStockInventory.setProductModelId(stockInventoryDto.getProductModelId()); newStockInventory.setQualitity(stockInventoryDto.getQualitity()); newStockInventory.setVersion(1); newStockInventory.setRemark(stockInventoryDto.getRemark()); newStockInventory.setBatchNo(stockInventoryDto.getBatchNo()); newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity()); newStockInventory.setWarnNum(stockInventoryDto.getWarnNum()); stockInventoryMapper.insert(newStockInventory); @@ -96,15 +108,26 @@ @Override @Transactional(rollbackFor = Exception.class) public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) { LambdaQueryWrapper<StockInventory> eq = new QueryWrapper<StockInventory>().lambda() .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()); if (StringUtils.isEmpty(stockInventoryDto.getBatchNo())) { eq.isNull(StockInventory::getBatchNo); stockInventoryDto.setBatchNo(null); } else { eq.eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo()); } // æ°å¢åºåºè®°å½ StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity()); stockOutRecordDto.setBatchNo(stockInventoryDto.getBatchNo()); stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockOutRecordDto.setType("0"); stockOutRecordService.add(stockOutRecordDto); StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())); StockInventory oldStockInventory = stockInventoryMapper.selectOne(eq); if (ObjectUtils.isEmpty(oldStockInventory)) { throw new RuntimeException("产ååºåä¸åå¨"); } @@ -145,7 +168,7 @@ // æå»ºæ¥æ¾é® String key = dto.getProductName() + "|" + dto.getModel(); SalesLedgerProduct matchedProduct = productMap.get(key); if (matchedProduct != null) { // å¤çåæ ¼åºå if (dto.getQualifiedQuantity() != null && dto.getQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) { @@ -155,7 +178,7 @@ stockInventoryDto.setQualitity(dto.getQualifiedQuantity()); stockInventoryDto.setRemark(dto.getRemark()); stockInventoryDto.setWarnNum(dto.getWarnNum()); // éªè¯åæ ¼å»ç»æ°é if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) { if (dto.getQualifiedLockedQuantity().compareTo(dto.getQualifiedQuantity()) > 0) { @@ -165,7 +188,7 @@ } else { stockInventoryDto.setLockedQuantity(BigDecimal.ZERO); } stockInventoryDto.setProductModelId(matchedProduct.getProductModelId()); this.addstockInventory(stockInventoryDto); successCount++; @@ -178,7 +201,7 @@ stockUninventoryDto.setRecordType(StockInUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode()); stockUninventoryDto.setQualitity(dto.getUnQualifiedQuantity()); stockUninventoryDto.setRemark(dto.getRemark()); // éªè¯ä¸åæ ¼å»ç»æ°é if (ObjectUtils.isNotEmpty(dto.getUnQualifiedLockedQuantity())) { if (dto.getUnQualifiedLockedQuantity().compareTo(dto.getUnQualifiedQuantity()) > 0) { @@ -199,7 +222,7 @@ unmatchedRecords.add(unmatchedRecord); } } // æå»ºè¿åä¿¡æ¯ StringBuilder message = new StringBuilder(); if (!unmatchedRecords.isEmpty()) { @@ -209,7 +232,7 @@ } return R.ok(message.toString()); } return R.ok("å¯¼å ¥æåï¼å ±å¤ç " + successCount + " æ¡è®°å½"); } catch (Exception e) { log.error("å¯¼å ¥åºå失败", e); @@ -259,4 +282,4 @@ stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity())); return this.updateById(stockInventory); } } } src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -9,6 +9,7 @@ import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.EnumUtil; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.stock.dto.StockInventoryDto; @@ -76,23 +77,39 @@ for (Long id : ids) { StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id); if (stockOutRecord.getType().equals("0")) { StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>().eq(StockInventory::getProductModelId, stockOutRecord.getProductModelId())); LambdaQueryWrapper<StockInventory> wrapper = new LambdaQueryWrapper<StockInventory>() .eq(StockInventory::getProductModelId, stockOutRecord.getProductModelId()); if (StringUtils.isEmpty(stockOutRecord.getBatchNo())) { wrapper.isNull(StockInventory::getBatchNo); } else { wrapper.eq(StockInventory::getBatchNo, stockOutRecord.getBatchNo()); } StockInventory stockInventory = stockInventoryMapper.selectOne(wrapper); if (stockInventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); }else { StockInventoryDto stockInRecordDto = new StockInventoryDto(); stockInRecordDto.setProductModelId(stockInventory.getProductModelId()); stockInRecordDto.setQualitity(stockOutRecord.getStockOutNum()); stockInRecordDto.setBatchNo(stockInventory.getBatchNo()); stockInventoryMapper.updateAddStockInventory(stockInRecordDto); } }else if (stockOutRecord.getType().equals("1")) { StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockOutRecord.getProductModelId())); LambdaQueryWrapper<StockUninventory> wrapper = new LambdaQueryWrapper<StockUninventory>() .eq(StockUninventory::getProductModelId, stockOutRecord.getProductModelId()); if (StringUtils.isEmpty(stockOutRecord.getBatchNo())) { wrapper.isNull(StockUninventory::getBatchNo); } else { wrapper.eq(StockUninventory::getBatchNo, stockOutRecord.getBatchNo()); } StockUninventory stockUninventory = stockUninventoryMapper.selectOne(wrapper); if (stockUninventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); }else { StockUninventoryDto stockUninventoryDto = new StockUninventoryDto(); stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId()); stockUninventoryDto.setQualitity(stockOutRecord.getStockOutNum()); stockUninventoryDto.setBatchNo(stockUninventory.getBatchNo()); stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto); } } src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -1,10 +1,12 @@ package com.ruoyi.stock.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInventoryDto; @@ -12,6 +14,7 @@ import com.ruoyi.stock.dto.StockUninventoryDto; import com.ruoyi.stock.execl.StockUnInventoryExportData; import com.ruoyi.stock.mapper.StockUninventoryMapper; import com.ruoyi.stock.pojo.StockInventory; import com.ruoyi.stock.pojo.StockUninventory; import com.ruoyi.stock.service.StockInRecordService; import com.ruoyi.stock.service.StockOutRecordService; @@ -47,22 +50,32 @@ @Override @Transactional(rollbackFor = Exception.class) public Integer addStockUninventory(StockUninventoryDto stockUninventoryDto) { LambdaQueryWrapper<StockUninventory> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()); if (StringUtils.isEmpty(stockUninventoryDto.getBatchNo())) { stockUninventoryDto.setBatchNo(null); wrapper.isNull(StockUninventory::getBatchNo); } else { wrapper.eq(StockUninventory::getBatchNo, stockUninventoryDto.getBatchNo()); } //æ°å¢å ¥åºè®°å½åæ·»å åºå StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId()); stockInRecordDto.setRecordType(stockUninventoryDto.getRecordType()); stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity()); stockInRecordDto.setBatchNo(stockUninventoryDto.getBatchNo()); stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId()); stockInRecordDto.setType("1"); stockInRecordService.add(stockInRecordDto); //åè¿è¡æ°å¢åºåæ°éåºå //å æ¥è¯¢åºå表ä¸çäº§åæ¯å¦åå¨ï¼ä¸å卿°å¢ï¼å卿´æ° StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(new QueryWrapper<StockUninventory>().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId())); StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(wrapper); if (ObjectUtils.isEmpty(oldStockUnInventory)) { StockUninventory newStockUnInventory = new StockUninventory(); newStockUnInventory.setProductModelId(stockUninventoryDto.getProductModelId()); newStockUnInventory.setQualitity(stockUninventoryDto.getQualitity()); newStockUnInventory.setLockedQuantity(stockUninventoryDto.getLockedQuantity()); newStockUnInventory.setBatchNo(stockUninventoryDto.getBatchNo()); newStockUnInventory.setVersion(1); newStockUnInventory.setRemark(stockUninventoryDto.getRemark()); stockUninventoryMapper.insert(newStockUnInventory); src/main/java/com/ruoyi/technology/controller/TechnologyBomStructureController.java
@@ -27,7 +27,7 @@ @GetMapping("/listByBomId/{bomId}") @Operation(summary = "æ ¹æ®BOMæ¥è¯¢ç»ææ ") public R<List<TechnologyBomStructureVo>> listByBomId(@PathVariable("bomId") Long bomId) { public R<List<TechnologyBomStructureVo>> listByBomId(@PathVariable Long bomId) { return R.ok(technologyBomStructureService.listByBomId(bomId)); } } src/main/java/com/ruoyi/technology/controller/TechnologyRoutingController.java
@@ -43,7 +43,7 @@ /** * æ°å¢å·¥èºè·¯çº¿ã */ @PostMapping @PostMapping("/addTechRoute") @Operation(summary = "æ°å¢å·¥èºè·¯çº¿") public R add(@RequestBody TechnologyRouting technologyRouting) { return R.ok(technologyRoutingService.saveTechnologyRouting(technologyRouting)); @@ -52,7 +52,7 @@ /** * ä¿®æ¹å·¥èºè·¯çº¿ã */ @PutMapping @PutMapping("editTechRoute") @Operation(summary = "ä¿®æ¹å·¥èºè·¯çº¿") public R edit(@RequestBody TechnologyRouting technologyRouting) { return R.ok(technologyRoutingService.updateTechnologyRouting(technologyRouting)); src/main/java/com/ruoyi/technology/pojo/TechnologyBomStructure.java
@@ -17,7 +17,7 @@ */ @Data @TableName("technology_bom_structure") @Schema(name = "TechnologyBomStructure对象", description = "BOM产åç»æè¡¨") @Schema(name = "TechnologyStructure对象", description = "BOM产åç»æè¡¨") public class TechnologyBomStructure implements Serializable { private static final long serialVersionUID = 1L; src/main/java/com/ruoyi/technology/pojo/TechnologyRouting.java
@@ -43,7 +43,7 @@ private String processRouteCode; @Schema(description = "å ³èbomçid") private Integer bomId; private Long bomId; @Schema(description = "å建人ID") @TableField(fill = FieldFill.INSERT) src/main/java/com/ruoyi/technology/pojo/TechnologyRoutingOperation.java
@@ -48,6 +48,9 @@ @Schema(description = "æ¯å¦è´¨æ£å·¥åº") private Boolean isQuality; @Schema(description = "æ¯å¦ç产") private Boolean isProduction; @Schema(description = "å建人ID") @TableField(fill = FieldFill.INSERT) private Long createUser; src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml
@@ -27,7 +27,7 @@ from sales_refund_amount_order srao left join return_management rm on srao.return_management_id = rm.id left join return_sale_product rs on rm.id = rs.return_management_id left join sales_ledger_product slp on rs.return_sale_ledger_product_id = slp.id left join sales_ledger_product slp on rs.return_sales_ledger_product_id = slp.id left join sales_ledger sl on slp.sales_ledger_id = sl.id <where> <if test="ew.salesContractNo != null and ew.salesContractNo !=''"> src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
@@ -6,7 +6,7 @@ <resultMap id="BaseResultMap" type="com.ruoyi.procurementrecord.pojo.ReturnSaleProduct"> <id column="id" property="id" /> <result column="return_management_id" property="returnManagementId" /> <result column="return_sale_ledger_product_id" property="returnSaleLedgerProductId" /> <result column="return_sales_ledger_product_id" property="returnsalesLedgerProductId" /> <result column="num" property="num" /> <result column="status" property="status" /> </resultMap> @@ -21,18 +21,18 @@ LEFT JOIN return_management rm ON rm.id = rsp.return_management_id LEFT JOIN shipping_info si ON si.id = rm.shipping_id LEFT JOIN sales_ledger_product slp ON si.sales_ledger_product_id = slp.id and slp.type = 1 LEFT JOIN (SELECT return_sale_ledger_product_id, LEFT JOIN (SELECT return_sales_ledger_product_id, SUM(num) AS total_return_num FROM return_sale_product WHERE 1 = 1 and return_management_id != #{returnManagementId} GROUP BY return_sale_ledger_product_id) rs ON rs.return_sale_ledger_product_id = slp.id GROUP BY return_sales_ledger_product_id) rs ON rs.return_sales_ledger_product_id = slp.id where rm.id =#{returnManagementId} </select> <select id="listReturnSaleProduct" resultType="com.ruoyi.procurementrecord.dto.ReturnSaleProductDto"> select rsp.*,slp.tax_inclusive_unit_price ,slp.tax_inclusive_total_price*rsp.num as price from return_sale_product rsp left join sales_ledger_product slp on slp.id = rsp.return_sale_ledger_product_id left join sales_ledger_product slp on slp.id = rsp.return_sales_ledger_product_id where rsp.return_management_id = #{returnManagementId} </select> src/main/resources/mapper/production/ProductionBomStructureMapper.xml
@@ -17,4 +17,18 @@ <result column="dept_id" property="deptId" /> </resultMap> <select id="listByBomId" 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.production_order_bom_id = #{bomId} order by pbs.id </select> </mapper> src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -16,7 +16,7 @@ <result column="complete_quantity" property="completeQuantity" /> <result column="start_time" property="startTime" /> <result column="end_time" property="endTime" /> <result column="sale_ledger_product_id" property="saleLedgerProductId" /> <result column="sales_ledger_product_id" property="salesLedgerProductId" /> <result column="create_user" property="createUser" /> <result column="dept_id" property="deptId" /> <result column="plan_complete_time" property="planCompleteTime" /> @@ -44,7 +44,7 @@ po.complete_quantity, po.start_time, po.end_time, po.sale_ledger_product_id, po.sales_ledger_product_id, po.create_user, po.dept_id, po.plan_complete_time, @@ -53,7 +53,8 @@ sl.customer_name as customerName, p.product_name as productName, pm.model as model, tr.process_route_code as processRouteCode tr.process_route_code as processRouteCode, tb.bom_no as bomNo </sql> <sql id="ProductionOrderVoFrom"> @@ -62,6 +63,7 @@ left join product_model pm on po.product_model_id = pm.id left join product p on pm.product_id = p.id left join technology_routing tr on po.technology_routing_id = tr.id left join technology_bom tb on tb.id = tr.bom_id </sql> <sql id="ProductionOrderWhere"> @@ -79,8 +81,8 @@ <if test="c.technologyRoutingId != null"> and po.technology_routing_id = #{c.technologyRoutingId} </if> <if test="c.saleLedgerProductId != null"> and po.sale_ledger_product_id = #{c.saleLedgerProductId} <if test="c.salesLedgerProductId != null"> and po.sales_ledger_product_id = #{c.salesLedgerProductId} </if> <if test="c.status != null"> and po.status = #{c.status} src/main/resources/mapper/production/ProductionOrderRoutingOperationMapper.xml
@@ -17,4 +17,26 @@ <result column="dept_id" property="deptId" /> </resultMap> <resultMap id="OperationVoResultMap" type="com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationVo" extends="BaseResultMap"> <result column="technologyOperationId" property="technologyOperationId" /> <result column="productName" property="productName" /> <result column="model" property="model" /> <result column="unit" property="unit" /> </resultMap> <select id="selectVoListByOrderId" resultMap="OperationVoResultMap"> SELECT poro.*, tro.technology_operation_id AS technologyOperationId, p.product_name AS productName, pm.model AS model, pm.unit AS unit FROM production_order_routing_operation poro LEFT JOIN technology_routing_operation tro ON poro.technology_routing_operation_id = tro.id LEFT JOIN product_model pm ON poro.product_model_id = pm.id LEFT JOIN product p ON pm.product_id = p.id WHERE poro.production_order_id = #{orderId} ORDER BY poro.drag_sort ASC, poro.id ASC </select> </mapper> src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -31,7 +31,7 @@ left join production_product_main ppm on qi.product_main_id = ppm.id left join product_work_order pwo on ppm.work_order_id = pwo.id left join product_order po on pwo.product_order_id = po.id left join sales_ledger_product slp on po.sale_ledger_product_id = slp.id and slp.type = 1 left join sales_ledger_product slp on po.sales_ledger_product_id = slp.id and slp.type = 1 where qi.product_main_id = #{productMainId} src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -67,14 +67,14 @@ LEFT JOIN sales_ledger_product slp ON si.sales_ledger_product_id = slp.id and slp.type = 1 LEFT JOIN ( SELECT return_sale_ledger_product_id, return_sales_ledger_product_id, SUM(num) AS total_return_num FROM return_sale_product rsp left join return_management rm on rm.id = rsp.return_management_id left join shipping_info si on si.id = rm.shipping_id WHERE 1=1 GROUP BY return_sale_ledger_product_id ) rs ON rs.return_sale_ledger_product_id = slp.id GROUP BY return_sales_ledger_product_id ) rs ON rs.return_sales_ledger_product_id = slp.id <where> <if test="shippingId != null"> si.id = #{shippingId} @@ -86,4 +86,4 @@ left join sales_ledger sl on si.sales_ledger_id = sl.id where si.status = 'å·²åè´§' and sl.customer_name = #{customerName} </select> </mapper> </mapper> src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -3,6 +3,17 @@ <mapper namespace="com.ruoyi.stock.mapper.StockInRecordMapper"> <select id="listPage" resultType="com.ruoyi.stock.dto.StockInRecordDto"> WITH RECURSIVE product_tree AS ( SELECT id FROM product WHERE id = #{params.topParentProductId} UNION ALL SELECT p.id FROM product p INNER JOIN product_tree pt ON p.parent_id = pt.id ) SELECT sir.*, p.product_name as product_name, @@ -25,6 +36,9 @@ </if> <if test="params.recordType != null and params.recordType != ''"> and sir.record_type = #{params.recordType} </if> <if test="params.topParentProductId != null and params.topParentProductId > 0"> and p.id in (select id from product_tree) </if> </where> order by sir.id desc @@ -56,4 +70,4 @@ </where> order by sir.id desc </select> </mapper> </mapper> src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -34,6 +34,12 @@ update_time = now() </set> where product_model_id = #{ew.productModelId} <if test="ew.batchNo == null"> and batch_no is null </if> <if test="ew.batchNo != null"> and batch_no = #{ew.batchNo} </if> </update> <update id="updateSubtractStockInventory"> update stock_inventory @@ -50,6 +56,12 @@ update_time = now() </set> where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity} <if test="ew.batchNo == null"> and batch_no is null </if> <if test="ew.batchNo != null"> and batch_no = #{ew.batchNo} </if> </update> <select id="pagestockInventory" resultType="com.ruoyi.stock.dto.StockInventoryDto"> select si.id, @@ -87,6 +99,7 @@ INNER JOIN product_tree pt ON p.parent_id = pt.id ) select batch_no, MAX(qualifiedId) as qualifiedId, MAX(unQualifiedId) as unQualifiedId, SUM(qualifiedQuantity) as qualifiedQuantity, @@ -108,6 +121,7 @@ 'combined' as stockType from ( select si.batch_no, si.id as qualifiedId, null as unQualifiedId, si.qualitity as qualifiedQuantity, @@ -133,6 +147,7 @@ union all select su.batch_no, null as qualifiedId, su.id as unQualifiedId, 0 as qualifiedQuantity, @@ -168,7 +183,7 @@ and combined.product_id in (select id from product_tree) </if> </where> group by product_model_id, model, unit, product_name, product_id group by batch_no, product_model_id, model, unit, product_name, product_id </select> <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData"> @@ -395,4 +410,4 @@ ORDER BY DATE(sor.create_time) ASC </select> </mapper> </mapper> src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -18,6 +18,17 @@ </resultMap> <select id="listPage" resultType="com.ruoyi.stock.dto.StockOutRecordDto"> WITH RECURSIVE product_tree AS ( SELECT id FROM product WHERE id = #{params.topParentProductId} UNION ALL SELECT p.id FROM product p INNER JOIN product_tree pt ON p.parent_id = pt.id ) SELECT sor.*, p.product_name as productName, @@ -41,6 +52,9 @@ <if test="params.recordType != null and params.recordType != ''"> and sor.record_type = #{params.recordType} </if> <if test="params.topParentProductId != null and params.topParentProductId > 0"> and p.id in (select id from product_tree) </if> </where> order by sor.id desc </select> src/main/resources/mapper/stock/StockUninventoryMapper.xml
@@ -25,7 +25,15 @@ </if> update_time = now() </set> where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity} where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity} <if test="ew.batchNo == null"> and batch_no is null </if> <if test="ew.batchNo != null"> and batch_no = #{ew.batchNo} </if> </update> <update id="updateAddStockUnInventory"> update stock_uninventory @@ -45,6 +53,12 @@ update_time = now() </set> where product_model_id = #{ew.productModelId} <if test="ew.batchNo == null"> and batch_no is null </if> <if test="ew.batchNo != null"> and batch_no = #{ew.batchNo} </if> </update> <select id="pageStockUninventory" resultType="com.ruoyi.stock.dto.StockUninventoryDto"> select su.id, src/main/resources/mapper/technology/TechnologyRoutingMapper.xml
@@ -16,17 +16,17 @@ <select id="pageTechnologyRouting" resultType="com.ruoyi.technology.bean.vo.TechnologyRoutingVo"> select tr.id, tr.product_model_id as productModelId, tr.description, tr.create_time as createTime, tr.update_time as updateTime, tr.process_route_code as processRouteCode, tr.bom_id as bomId, tr.create_user as createUser, tr.dept_id as deptId, p.product_name as productName, pm.model, tb.bom_no as bomNo tr.product_model_id as productModelId, tr.description, tr.create_time as createTime, tr.update_time as updateTime, tr.process_route_code as processRouteCode, tr.bom_id as bomId, tr.create_user as createUser, tr.dept_id as deptId, p.product_name as productName, pm.model, tb.bom_no as bomNo from technology_routing tr left join product_model pm on tr.product_model_id = pm.id left join product p on pm.product_id = p.id @@ -47,15 +47,6 @@ </if> <if test="c.description != null and c.description != ''"> and tr.description like concat('%', #{c.description}, '%') </if> <if test="c.model != null and c.model != ''"> and pm.model like concat('%', #{c.model}, '%') </if> <if test="c.productName != null and c.productName != ''"> and p.product_name like concat('%', #{c.productName}, '%') </if> <if test="c.bomNo != null and c.bomNo != ''"> and tb.bom_no like concat('%', #{c.bomNo}, '%') </if> </if> </where>