feat(production): 新增生产工单管理功能
- 创建 ProductionOperationTask 实体类定义工单数据结构
- 实现 ProductionOperationTaskController 提供工单的增删改查接口
- 开发 ProductionOperationTaskService 和实现类处理业务逻辑
- 配置 ProductionOperationTaskMapper 及 XML 文件实现数据库操作
- 添加 ProductionOperationTaskVo 视图对象用于数据展示
- 扩展 ProductionOrder 实体类增加生产订单相关属性
- 更新 ProductionOrderMapper.xml 完善订单查询映射配置
- 优化 ProductionOrderPickRecordMapper.xml 记录物料领取明细
- 新增 ProductionOrderRoutingOperationParam 参数配置实体
- 完善 工序参数处理逻辑
| | |
| | | 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 |
| | |
| | | @Autowired |
| | | private EmbeddingModel embeddingModel; |
| | | |
| | | @Value("${knowledge.one}") |
| | | private String one; |
| | | // @Value("${knowledge.one}") |
| | | // private String one; |
| | | // |
| | | // @Value("${knowledge.two}") |
| | | // private String two; |
| | |
| | | package com.ruoyi.production.bean.dto; |
| | | |
| | | import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam; |
| | | import com.ruoyi.production.pojo.ProductionProductMain; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class ProductionProductMainDto { |
| | | @Schema(description = "主键ID") |
| | | private Long id; |
| | | @Schema(description = "产品编号") |
| | | private String productNo; |
| | | @Schema(description = "用户ID") |
| | | private Long userId; |
| | | @Schema(description = "用户名称") |
| | | private String userName; |
| | | @Schema(name = "ProductionProductMainDto", description = "生产报工查询对象") |
| | | public class ProductionProductMainDto extends ProductionProductMain { |
| | | |
| | | @Schema(description = "产品工艺路线明细ID") |
| | | private Long productProcessRouteItemId; |
| | | @Schema(description = "工单ID") |
| | | private Long workOrderId; |
| | | @Schema(description = "生产工序任务ID") |
| | | private Long productionOperationTaskId; |
| | | @Schema(description = "状态") |
| | | private Integer status; |
| | | @Schema(description = "创建时间") |
| | | private LocalDateTime createTime; |
| | | @Schema(description = "更新时间") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "生产报工表id") |
| | | private Long productMainId; |
| | | |
| | | @Schema(description = "租户ID") |
| | | private Long tenantId; |
| | | @Schema(description = "创建人") |
| | | private Integer createUser; |
| | | @Schema(description = "更新人") |
| | | private Integer updateUser; |
| | | @Schema(description = "部门ID") |
| | | private Long deptId; |
| | | |
| | | @Schema(description = "工单编号") |
| | | private String workOrderNo; |
| | | |
| | | @Schema(description = "工单状态") |
| | | private String workOrderStatus; |
| | | |
| | | @Schema(description = "昵称") |
| | | private String nickName; |
| | | |
| | | @Schema(description = "数量") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "报废数量") |
| | | private BigDecimal scrapQty; |
| | | |
| | | @Schema(description = "产品名称") |
| | | private String productName; |
| | | |
| | | @Schema(description = "产品型号名称") |
| | | private String productModelName; |
| | | |
| | | @Schema(description = "单位") |
| | | private String unit; |
| | | |
| | | @Schema(description = "销售合同编号") |
| | | private String salesContractNo; |
| | | |
| | | @Schema(description = "排产日期") |
| | | private LocalDate schedulingDate; |
| | | |
| | | @Schema(description = "排产人员名称") |
| | | private String schedulingUserName; |
| | | |
| | | @Schema(description = "客户名称") |
| | | private String customerName; |
| | | |
| | | @Schema(description = "工序") |
| | | private String process; |
| | | |
| | | @Schema(description = "工序参数列表") |
| | | private List<ProductionOrderRoutingOperationParam> productionOperationParamList; |
| | | } |
| | |
| | | package com.ruoyi.production.bean.vo; |
| | | |
| | | import com.ruoyi.production.pojo.ProductionOperationTask; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class ProductionOperationTaskVo extends ProductionOperationTask { |
| | | |
| | | @Schema(description = "订单号") |
| | | private String npsNo; |
| | | |
| | | @Schema(description = "产品名称") |
| | | private String productName; |
| | | |
| | | @Schema(description = "规格型号") |
| | | private String model; |
| | | |
| | | @Schema(description = "单位") |
| | | private String unit; |
| | | |
| | | @Schema(description = "工序名称") |
| | | private String operationName; |
| | | |
| | | @Schema(description = "工单类型 正常 /返工返修") |
| | | private String workOrderType; |
| | | |
| | | @Schema(description = "完成进度") |
| | | private BigDecimal completionStatus; |
| | | } |
| | |
| | | import com.ruoyi.production.bean.vo.ProductionOperationTaskVo; |
| | | import com.ruoyi.production.pojo.ProductionOperationTask; |
| | | import com.ruoyi.production.service.ProductionOperationTaskService; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | public R<Boolean> remove(@RequestBody List<Long> ids) { |
| | | return R.ok(productionOperationTaskService.removeProductionOperationTask(ids)); |
| | | } |
| | | |
| | | @Operation(summary = "产品工单更新") |
| | | @PostMapping("/updateProductWorkOrder") |
| | | public R updateProductWorkOrder(@RequestBody ProductionOperationTaskDto dto) { |
| | | return R.ok(productionOperationTaskService.updateProductWorkOrder(dto)); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.ruoyi.production.service.ProductionProductInputService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @RequestMapping("productionProductInput") |
| | | @RequestMapping("/productionProductInput") |
| | | @RestController |
| | | @Tag(name = "生产投入") |
| | | @AllArgsConstructor |
| | |
| | | |
| | | private ProductionProductInputService productionProductInputService; |
| | | |
| | | @GetMapping("listPage") |
| | | @GetMapping("/listPage") |
| | | public R page(Page<ProductionProductInputDto> page, ProductionProductInputDto productionProductInputDto) { |
| | | return R.ok(productionProductInputService.listPageProductionProductInputDto(page, productionProductInputDto)); |
| | | } |
| | |
| | | import com.ruoyi.framework.web.domain.R; |
| | | import com.ruoyi.production.bean.dto.ProductionProductMainDto; |
| | | import com.ruoyi.production.service.ProductionProductMainService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | @RequestMapping("productionProductMain") |
| | | @RequestMapping("/productionProductMain") |
| | | @RestController |
| | | @Tag(name = "生产报工") |
| | | @AllArgsConstructor |
| | |
| | | * @param productionProductMainDto |
| | | * @return |
| | | */ |
| | | @GetMapping("listPage") |
| | | @GetMapping("/listPage") |
| | | public R page(Page<ProductionProductMainDto> page, ProductionProductMainDto productionProductMainDto) { |
| | | return R.ok(productionProductMainService.listPageProductionProductMainDto(page, productionProductMainDto)); |
| | | } |
| | |
| | | * @param productionProductMainDto |
| | | * @return |
| | | */ |
| | | @PostMapping("addProductMain") |
| | | @PostMapping("/addProductMain") |
| | | public R addProductMain(@RequestBody ProductionProductMainDto productionProductMainDto) { |
| | | return R.ok(productionProductMainService.addProductMain(productionProductMainDto)); |
| | | } |
| | |
| | | package com.ruoyi.production.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.home.dto.ProductionTaskStatisticsDto; |
| | | import com.ruoyi.home.dto.processDataProductionStatisticsDto; |
| | | import com.ruoyi.production.bean.dto.ProductionOperationTaskDto; |
| | | import com.ruoyi.production.bean.vo.ProductionOperationTaskVo; |
| | | import com.ruoyi.production.pojo.ProductionOperationTask; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | |
| | | @Mapper |
| | | public interface ProductionOperationTaskMapper extends BaseMapper<ProductionOperationTask> { |
| | | |
| | | IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskVo> page, |
| | | @Param("c") ProductionOperationTaskDto dto); |
| | | |
| | | List<ProductionTaskStatisticsDto> selectTaskStatisticsByDate(@Param("startDate") LocalDate startDate, |
| | | @Param("endDate") LocalDate endDate); |
| | | |
| | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @Schema(description = "工艺路线工序表id") |
| | | private Long technologyRoutingOperationId; |
| | | @Schema(description = "生产工艺路线工序表id") |
| | | private Long productionOrderRoutingOperationId; |
| | | |
| | | @Schema(description = "录入时间") |
| | | @TableField(fill = FieldFill.INSERT) |
| | |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate planCompleteTime; |
| | | |
| | | @Schema(description = "状态(1.待开始、2.进行中、3.已完成、4.已取消)") |
| | | @Schema(description = "状态(1.待开始 2.进行中 3.已完成 4.已取消)") |
| | | private Integer status; |
| | | } |
| | |
| | | @Schema(description = "标准值") |
| | | private String standardValue; |
| | | |
| | | @Schema(description = "输入值") |
| | | private String inputValue; |
| | | |
| | | @Schema(description = "生产订单工艺路线工序ID") |
| | | private Long productionOrderRoutingOperationId; |
| | | } |
| | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "租户ID") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | @Schema(description = "创建用户") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "租户ID") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @Schema(description = "报废数量") |
| | | private BigDecimal scrapQty; |
| | | @Schema(description = "创建用户") |
| | |
| | | boolean saveProductionOperationTask(ProductionOperationTask productionOperationTask); |
| | | |
| | | boolean removeProductionOperationTask(List<Long> ids); |
| | | |
| | | int updateProductWorkOrder(ProductionOperationTaskDto dto); |
| | | } |
| | |
| | | |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask> |
| | | implements ProductionOperationTaskService { |
| | | public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask> implements ProductionOperationTaskService { |
| | | |
| | | |
| | | |
| | | @Override |
| | | public IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskDto> page, |
| | | ProductionOperationTaskDto dto) { |
| | | Page<ProductionOperationTask> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); |
| | | return this.page(entityPage, buildQueryWrapper(dto)).convert(item -> BeanUtil.copyProperties(item, ProductionOperationTaskVo.class)); |
| | | public IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskDto> page, ProductionOperationTaskDto dto) { |
| | | Page<ProductionOperationTaskVo> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); |
| | | return baseMapper.pageProductionOperationTask(voPage, dto); |
| | | } |
| | | |
| | | @Override |
| | |
| | | return Wrappers.<ProductionOperationTask>lambdaQuery() |
| | | .eq(query.getId() != null, ProductionOperationTask::getId, query.getId()) |
| | | .eq(query.getProductionOrderId() != null, ProductionOperationTask::getProductionOrderId, query.getProductionOrderId()) |
| | | .eq(query.getTechnologyRoutingOperationId() != null, |
| | | ProductionOperationTask::getTechnologyRoutingOperationId, query.getTechnologyRoutingOperationId()) |
| | | .eq(query.getProductionOrderRoutingOperationId() != null, |
| | | ProductionOperationTask::getProductionOrderRoutingOperationId, query.getProductionOrderRoutingOperationId()) |
| | | .eq(query.getStatus() != null, ProductionOperationTask::getStatus, query.getStatus()) |
| | | .like(query.getWorkOrderNo() != null && !query.getWorkOrderNo().trim().isEmpty(), |
| | | ProductionOperationTask::getWorkOrderNo, query.getWorkOrderNo()) |
| | | .orderByDesc(ProductionOperationTask::getId); |
| | | } |
| | | |
| | | @Override |
| | | public int updateProductWorkOrder(ProductionOperationTaskDto dto) { |
| | | return baseMapper.updateById(dto); |
| | | } |
| | | } |
| | |
| | | } |
| | | String workOrderNoStr = "GD" + String.format("%s%03d", datePrefix, sequenceNumber); |
| | | ProductionOperationTask productionOperationTask = new ProductionOperationTask(); |
| | | productionOperationTask.setTechnologyRoutingOperationId(productionOrderRoutingOperation.getId()); |
| | | productionOperationTask.setProductionOrderRoutingOperationId(productionOrderRoutingOperation.getId()); |
| | | productionOperationTask.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId()); |
| | | productionOperationTask.setPlanQuantity(BigDecimal.ZERO); |
| | | productionOperationTask.setCompleteQuantity(BigDecimal.ZERO); |
| | |
| | | try { |
| | | ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne( |
| | | new LambdaQueryWrapper<ProductionOperationTask>() |
| | | .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id) |
| | | .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id) |
| | | .last("limit 1")); |
| | | if (productionOperationTask == null) { |
| | | throw new RuntimeException("删除失败:未找到关联的生产工单"); |
| | |
| | | routingId = deleteItem.getOrderRoutingId(); |
| | | } |
| | | productionOperationTaskMapper.delete(new LambdaQueryWrapper<ProductionOperationTask>() |
| | | .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id)); |
| | | .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id)); |
| | | productionOrderRoutingOperationMapper.deleteById(id); |
| | | if (routingId != null) { |
| | | List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList( |
| | |
| | | productionOrderRoutingOperationMapper.insert(targetOperation); |
| | | |
| | | ProductionOperationTask task = new ProductionOperationTask(); |
| | | task.setTechnologyRoutingOperationId(targetOperation.getId()); |
| | | task.setProductionOrderRoutingOperationId(targetOperation.getId()); |
| | | task.setProductionOrderId(productionOrder.getId()); |
| | | task.setPlanQuantity(defaultDecimal(productionOrder.getQuantity())); |
| | | task.setCompleteQuantity(BigDecimal.ZERO); |
| | |
| | | if (productionPlans.size() != planIds.size()) { |
| | | throw new ServiceException("部分生产计划不存在"); |
| | | } |
| | | Map<Long, ProductionPlan> planMap = productionPlans.stream() |
| | | .collect(Collectors.toMap(ProductionPlan::getId, item -> item, (left, right) -> left)); |
| | | ProductionPlan mainPlan = planMap.get(planIds.get(0)); |
| | | if (mainPlan == null) { |
| | | throw new ServiceException("主生产计划不存在"); |
| | | } |
| | | Set<Long> productModelIds = productionPlans.stream() |
| | | .map(ProductionPlan::getProductModelId) |
| | | .collect(Collectors.toSet()); |
| | |
| | | if (productionPlans.stream().anyMatch(item -> item.getStatus() != null && item.getStatus() == 2)) { |
| | | throw new ServiceException("所选生产计划已下发"); |
| | | } |
| | | ProductionPlan firstPlan = productionPlans.get(0); |
| | | ProductionPlan firstPlan = mainPlan; |
| | | if (productionOrder.getProductModelId() == null) { |
| | | productionOrder.setProductModelId(firstPlan.getProductModelId()); |
| | | } else if (!Objects.equals(productionOrder.getProductModelId(), firstPlan.getProductModelId())) { |
| | |
| | | } |
| | | } |
| | | |
| | | List<ProductionOrderPickVo> result = new ArrayList<>(bomStructureList.size()); |
| | | Map<String, ProductionOrderPickVo> mergedPickMap = new LinkedHashMap<>(); |
| | | 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); |
| | | String mergeKey = String.valueOf(structure.getTechnologyOperationId()) + "#" + productModelId; |
| | | ProductionOrderPickVo vo = mergedPickMap.get(mergeKey); |
| | | if (vo == null) { |
| | | vo = new ProductionOrderPickVo(); |
| | | vo.setProductModelId(productModelId); |
| | | vo.setOperationName(structure.getOperationName()); |
| | | vo.setTechnologyOperationId(structure.getTechnologyOperationId()); |
| | | vo.setProductName(structure.getProductName()); |
| | | vo.setModel(structure.getModel()); |
| | | vo.setDemandedQuantity(BigDecimal.ZERO); |
| | | 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); |
| | | mergedPickMap.put(mergeKey, vo); |
| | | } |
| | | vo.setDemandedQuantity(defaultDecimal(vo.getDemandedQuantity()).add(defaultDecimal(structure.getDemandedQuantity()))); |
| | | } |
| | | return result; |
| | | return new ArrayList<>(mergedPickMap.values()); |
| | | } |
| | | } |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | |
| | | private final ProductionAccountMapper productionAccountMapper; |
| | | private final ProductionOperationTaskMapper productionOperationTaskMapper; |
| | | private final ProductionOrderMapper productionOrderMapper; |
| | | private final ProductionOrderBomMapper productionOrderBomMapper; |
| | | private final ProductionBomStructureMapper productionBomStructureMapper; |
| | | private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper; |
| | | private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper; |
| | | private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper; |
| | | private final TechnologyOperationMapper technologyOperationMapper; |
| | | private final StockUtils stockUtils; |
| | |
| | | |
| | | @Override |
| | | public Boolean addProductMain(ProductionProductMainDto dto) { |
| | | if (dto.getProductionOperationTaskId() == null) { |
| | | Long taskId = resolveTaskId(dto); |
| | | if (taskId == null) { |
| | | throw new ServiceException("请传入生产工单ID"); |
| | | } |
| | | return addProductMainByProductionTask(dto); |
| | |
| | | |
| | | private Boolean addProductMainByProductionTask(ProductionProductMainDto dto) { |
| | | // 报工以订单工序快照为准,避免工艺主数据变更后影响历史工单执行。 |
| | | Long taskId = resolveTaskId(dto); |
| | | if (taskId == null) { |
| | | throw new ServiceException("productionOperationTaskId can not be null"); |
| | | } |
| | | SysUser user = userMapper.selectUserById(dto.getUserId()); |
| | | ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(dto.getProductionOperationTaskId()); |
| | | ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(taskId); |
| | | if (productionOperationTask == null) { |
| | | throw new ServiceException("生产工单不存在"); |
| | | } |
| | | ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getTechnologyRoutingOperationId()); |
| | | ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId()); |
| | | if (routingOperation == null) { |
| | | throw new ServiceException("订单工艺路线工序不存在"); |
| | | } |
| | |
| | | if (productionOrder == null) { |
| | | throw new ServiceException("生产订单不存在"); |
| | | } |
| | | syncOperationParamInputValue(dto, routingOperation.getId()); |
| | | TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); |
| | | TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null |
| | | : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); |
| | |
| | | |
| | | ProductionProductMain productionProductMain = new ProductionProductMain(); |
| | | productionProductMain.setProductNo(generateProductNo()); |
| | | productionProductMain.setUserId(dto.getUserId()); |
| | | productionProductMain.setUserName(dto.getUserName()); |
| | | productionProductMain.setProductionOperationTaskId(productionOperationTask.getId()); |
| | | productionProductMain.setUserId(user == null ? dto.getUserId() : user.getUserId()); |
| | | productionProductMain.setUserName(user == null ? dto.getUserName() : user.getNickName()); |
| | | productionProductMain.setProductionOperationTaskId(taskId); |
| | | productionProductMain.setStatus(0); |
| | | productionProductMainMapper.insert(productionProductMain); |
| | | |
| | | List<ProductStructureDto> productStructureDtos = new ArrayList<>(); |
| | | ProductStructureDto productStructureDto = new ProductStructureDto(); |
| | | productStructureDto.setProductModelId(productModel.getId()); |
| | | productStructureDto.setUnitQuantity(BigDecimal.ONE); |
| | | productStructureDtos.add(productStructureDto); |
| | | List<ProductStructureDto> productStructureDtos = resolveInputStructures( |
| | | productionOrder.getId(), routingOperation, productModel.getId()); |
| | | if (productStructureDtos.isEmpty()) { |
| | | throw new ServiceException("未找到当前工序对应的BOM投入节点"); |
| | | } |
| | | for (ProductStructureDto item : productStructureDtos) { |
| | | // 当前实现按工序成品直接作为投入,后续若接入领料记录可在这里替换来源。 |
| | | ProductionProductInput productionProductInput = new ProductionProductInput(); |
| | |
| | | productionProductInput.setInputQuantity(item.getUnitQuantity().multiply(defaultDecimal(dto.getQuantity()))); |
| | | productionProductInput.setQuantity(productionProductInput.getInputQuantity()); |
| | | productionProductInputMapper.insert(productionProductInput); |
| | | stockUtils.substractStock(item.getProductModelId(), productionProductInput.getInputQuantity(), |
| | | StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId()); |
| | | } |
| | | |
| | | ProductionProductOutput productionProductOutput = new ProductionProductOutput(); |
| | |
| | | return true; |
| | | } |
| | | |
| | | private void syncOperationParamInputValue(ProductionProductMainDto dto, Long productionOrderRoutingOperationId) { |
| | | if (dto == null || productionOrderRoutingOperationId == null) { |
| | | return; |
| | | } |
| | | List<ProductionOrderRoutingOperationParam> paramList = dto.getProductionOperationParamList(); |
| | | if (paramList == null || paramList.isEmpty()) { |
| | | return; |
| | | } |
| | | List<ProductionOrderRoutingOperationParam> dbParamList = productionOrderRoutingOperationParamMapper.selectList( |
| | | Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() |
| | | .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, productionOrderRoutingOperationId)); |
| | | if (dbParamList == null || dbParamList.isEmpty()) { |
| | | return; |
| | | } |
| | | Map<Long, ProductionOrderRoutingOperationParam> dbParamMap = dbParamList.stream() |
| | | .filter(item -> item != null && item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionOrderRoutingOperationParam::getId, item -> item, (left, right) -> left)); |
| | | for (ProductionOrderRoutingOperationParam param : paramList) { |
| | | if (param == null || param.getId() == null) { |
| | | continue; |
| | | } |
| | | ProductionOrderRoutingOperationParam dbParam = dbParamMap.get(param.getId()); |
| | | if (dbParam == null) { |
| | | throw new ServiceException("工序参数不存在或不属于当前工单工序,ID=" + param.getId()); |
| | | } |
| | | if (Objects.equals(dbParam.getInputValue(), param.getInputValue())) { |
| | | continue; |
| | | } |
| | | ProductionOrderRoutingOperationParam updateParam = new ProductionOrderRoutingOperationParam(); |
| | | updateParam.setId(dbParam.getId()); |
| | | updateParam.setInputValue(param.getInputValue()); |
| | | productionOrderRoutingOperationParamMapper.updateById(updateParam); |
| | | } |
| | | } |
| | | |
| | | private List<ProductStructureDto> resolveInputStructures(Long productionOrderId, |
| | | ProductionOrderRoutingOperation routingOperation, |
| | | Long outputProductModelId) { |
| | | if (productionOrderId == null || routingOperation == null || routingOperation.getTechnologyOperationId() == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | ProductionOrderBom orderBom = productionOrderBomMapper.selectOne( |
| | | Wrappers.<ProductionOrderBom>lambdaQuery() |
| | | .eq(ProductionOrderBom::getProductionOrderId, productionOrderId) |
| | | .orderByDesc(ProductionOrderBom::getId) |
| | | .last("limit 1")); |
| | | if (orderBom == null || orderBom.getId() == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | List<ProductionBomStructure> bomNodeList = productionBomStructureMapper.selectList( |
| | | Wrappers.<ProductionBomStructure>lambdaQuery() |
| | | .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId()) |
| | | .orderByAsc(ProductionBomStructure::getId)); |
| | | if (bomNodeList.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | Map<Long, ProductionBomStructure> nodeMap = bomNodeList.stream() |
| | | .filter(item -> item != null && item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionBomStructure::getId, item -> item, (left, right) -> left)); |
| | | Long currentOutputModelId = routingOperation.getProductModelId() != null |
| | | ? routingOperation.getProductModelId() |
| | | : outputProductModelId; |
| | | |
| | | Map<Long, BigDecimal> unitQtyByProductModel = new LinkedHashMap<>(); |
| | | for (ProductionBomStructure node : bomNodeList) { |
| | | if (node == null || node.getParentId() == null || node.getProductModelId() == null) { |
| | | continue; |
| | | } |
| | | if (!Objects.equals(node.getTechnologyOperationId(), routingOperation.getTechnologyOperationId())) { |
| | | continue; |
| | | } |
| | | ProductionBomStructure parent = nodeMap.get(node.getParentId()); |
| | | if (parent == null || !Objects.equals(parent.getProductModelId(), currentOutputModelId)) { |
| | | continue; |
| | | } |
| | | unitQtyByProductModel.merge(node.getProductModelId(), defaultDecimal(node.getUnitQuantity()), BigDecimal::add); |
| | | } |
| | | |
| | | List<ProductStructureDto> result = new ArrayList<>(); |
| | | for (Map.Entry<Long, BigDecimal> entry : unitQtyByProductModel.entrySet()) { |
| | | if (entry.getValue().compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | ProductStructureDto item = new ProductStructureDto(); |
| | | item.setProductModelId(entry.getKey()); |
| | | item.setUnitQuantity(entry.getValue()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private Boolean removeProductMainByProductionTask(ProductionProductMain productionProductMain) { |
| | | // 删除报工需要同步回滚质检、库存、工时核算和订单/工单进度。 |
| | | List<QualityInspect> qualityInspects = qualityInspectMapper.selectList( |
| | |
| | | productionOperationTaskMapper.updateById(productionOperationTask); |
| | | |
| | | ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId()); |
| | | ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getTechnologyRoutingOperationId()); |
| | | ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId()); |
| | | if (productionOrder != null && routingOperation != null) { |
| | | // 只有最后一道工序的报工才会影响生产订单完工数量。 |
| | | List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList( |
| | |
| | | return value == null ? BigDecimal.ZERO : value; |
| | | } |
| | | |
| | | private Long resolveTaskId(ProductionProductMainDto dto) { |
| | | if (dto == null) { |
| | | return null; |
| | | } |
| | | return dto.getProductionOperationTaskId(); |
| | | } |
| | | |
| | | @Override |
| | | public ArrayList<Long> listMain(List<Long> idList) { |
| | | return productionProductMainMapper.listMain(idList); |
| | |
| | | productionOrderRoutingOperationMapper.insert(newOperation); |
| | | |
| | | ProductionOperationTask newTask = new ProductionOperationTask(); |
| | | newTask.setTechnologyRoutingOperationId(newOperation.getId()); |
| | | newTask.setProductionOrderRoutingOperationId(newOperation.getId()); |
| | | newTask.setProductionOrderId(newOrder.getId()); |
| | | newTask.setPlanQuantity(newOrder.getQuantity()); |
| | | newTask.setCompleteQuantity(BigDecimal.ZERO); |
| | |
| | | package com.ruoyi.technology.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | import com.ruoyi.common.utils.OrderUtils; |
| | | import com.ruoyi.technology.bean.dto.TechnologyRoutingDto; |
| | | import com.ruoyi.technology.bean.vo.TechnologyRoutingVo; |
| | | import com.ruoyi.technology.mapper.TechnologyBomStructureMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyOperationMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyOperationParamMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyParamMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyRoutingMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyRoutingOperationParamMapper; |
| | | import com.ruoyi.technology.pojo.TechnologyBomStructure; |
| | | import com.ruoyi.technology.pojo.TechnologyOperation; |
| | | import com.ruoyi.technology.pojo.TechnologyOperationParam; |
| | | import com.ruoyi.technology.pojo.TechnologyParam; |
| | | import com.ruoyi.technology.pojo.TechnologyRouting; |
| | | import com.ruoyi.technology.pojo.TechnologyRoutingOperation; |
| | | import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam; |
| | | import com.ruoyi.technology.mapper.*; |
| | | import com.ruoyi.technology.pojo.*; |
| | | import com.ruoyi.technology.service.TechnologyRoutingService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | } |
| | | List<TechnologyBomStructure> bomStructures = technologyBomStructureMapper.selectList( |
| | | Wrappers.<TechnologyBomStructure>lambdaQuery() |
| | | .eq(TechnologyBomStructure::getBomId, Long.valueOf(technologyRouting.getBomId())) |
| | | .eq(TechnologyBomStructure::getBomId, technologyRouting.getBomId()) |
| | | .isNotNull(TechnologyBomStructure::getOperationId) |
| | | .orderByAsc(TechnologyBomStructure::getId) |
| | | ); |
| | |
| | | } |
| | | |
| | | // 同一个 BOM 中可能重复引用相同工序,这里按首次出现顺序去重。 |
| | | Map<Long, TechnologyBomStructure> uniqueOperationMap = new LinkedHashMap<>(); |
| | | Map<Long, TechnologyBomStructure> structureById = new HashMap<>(); |
| | | for (TechnologyBomStructure bomStructure : bomStructures) { |
| | | uniqueOperationMap.putIfAbsent(bomStructure.getOperationId(), bomStructure); |
| | | if (bomStructure != null && bomStructure.getId() != null) { |
| | | structureById.put(bomStructure.getId(), bomStructure); |
| | | } |
| | | } |
| | | |
| | | Map<String, TechnologyBomStructure> uniqueOperationMap = new LinkedHashMap<>(); |
| | | for (TechnologyBomStructure bomStructure : bomStructures) { |
| | | Long outputProductModelId = resolveOutputProductModelId(bomStructure, structureById, technologyRouting.getProductModelId()); |
| | | uniqueOperationMap.putIfAbsent(buildBomOperationDedupKey(bomStructure, outputProductModelId), bomStructure); |
| | | } |
| | | |
| | | int dragSort = 1; |
| | | for (TechnologyBomStructure bomStructure : uniqueOperationMap.values()) { |
| | | TechnologyRoutingOperation routingOperation = new TechnologyRoutingOperation(); |
| | | routingOperation.setTechnologyRoutingId(technologyRouting.getId()); |
| | | routingOperation.setProductModelId(technologyRouting.getProductModelId()); |
| | | routingOperation.setProductModelId(resolveOutputProductModelId(bomStructure, structureById, technologyRouting.getProductModelId())); |
| | | routingOperation.setTechnologyOperationId(bomStructure.getOperationId()); |
| | | routingOperation.setDragSort(dragSort++); |
| | | routingOperation.setIsQuality(getOperationQuality(bomStructure.getOperationId())); |
| | |
| | | } |
| | | } |
| | | |
| | | private String buildBomOperationDedupKey(TechnologyBomStructure bomStructure, Long outputProductModelId) { |
| | | Long operationId = bomStructure == null ? null : bomStructure.getOperationId(); |
| | | Long parentId = bomStructure == null ? null : bomStructure.getParentId(); |
| | | return operationId + "#" |
| | | + outputProductModelId + "#" |
| | | + parentId; |
| | | } |
| | | |
| | | private Long resolveOutputProductModelId(TechnologyBomStructure bomStructure, |
| | | Map<Long, TechnologyBomStructure> structureById, |
| | | Long routingProductModelId) { |
| | | if (bomStructure == null) { |
| | | return routingProductModelId; |
| | | } |
| | | Long parentId = bomStructure.getParentId(); |
| | | if (parentId == null) { |
| | | return routingProductModelId != null ? routingProductModelId : bomStructure.getProductModelId(); |
| | | } |
| | | TechnologyBomStructure parent = structureById.get(parentId); |
| | | if (parent != null && parent.getProductModelId() != null) { |
| | | return parent.getProductModelId(); |
| | | } |
| | | return routingProductModelId != null ? routingProductModelId : bomStructure.getProductModelId(); |
| | | } |
| | | |
| | | private void syncRoutingOperationParams(Long technologyRoutingOperationId, Long technologyOperationId) { |
| | | List<TechnologyOperationParam> operationParamList = technologyOperationParamMapper.selectList( |
| | | Wrappers.<TechnologyOperationParam>lambdaQuery() |
| | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductionOperationTask"> |
| | | <id column="id" property="id" /> |
| | | <result column="technology_routing_operation_id" property="technologyRoutingOperationId" /> |
| | | <result column="production_order_routing_operation_id" property="productionOrderRoutingOperationId" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="work_order_no" property="workOrderNo" /> |
| | |
| | | <result column="dept_id" property="deptId" /> |
| | | </resultMap> |
| | | |
| | | <select id="pageProductionOperationTask" resultType="com.ruoyi.production.bean.vo.ProductionOperationTaskVo"> |
| | | select pot.*, |
| | | po.nps_no as npsNo, |
| | | p.product_name as productName, |
| | | pm.model as model, |
| | | pm.unit as unit, |
| | | poro.operation_name as operationName, |
| | | ROUND(pot.complete_quantity / pot.plan_quantity * 100, 2) AS completionStatus, |
| | | CASE |
| | | WHEN pot.work_order_no LIKE 'FG%' THEN '返工返修' |
| | | ELSE '正常' |
| | | END AS work_order_type |
| | | from production_operation_task pot |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id |
| | | left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) |
| | | left join product p on pm.product_id = p.id |
| | | <where> |
| | | <if test="c != null and c.id != null"> |
| | | and pot.id = #{c.id} |
| | | </if> |
| | | <if test="c != null and c.productionOrderId != null"> |
| | | and pot.production_order_id = #{c.productionOrderId} |
| | | </if> |
| | | <if test="c != null and c.productionOrderRoutingOperationId != null"> |
| | | and pot.production_order_routing_operation_id = #{c.productionOrderRoutingOperationId} |
| | | </if> |
| | | <if test="c != null and c.status != null"> |
| | | and pot.status = #{c.status} |
| | | </if> |
| | | <if test="c != null and c.workOrderNo != null and c.workOrderNo != ''"> |
| | | and pot.work_order_no like concat('%', #{c.workOrderNo}, '%') |
| | | </if> |
| | | </where> |
| | | order by pot.id desc |
| | | </select> |
| | | |
| | | <select id="selectTaskStatisticsByDate" resultType="com.ruoyi.home.dto.ProductionTaskStatisticsDto"> |
| | | select pot.id, |
| | | pot.work_order_no, |
| | |
| | | pot.actual_end_time as actualEndTime, |
| | | pot.plan_quantity as planQuantity, |
| | | ifnull(pot.complete_quantity, 0) as completeQuantity, |
| | | top2.name as processName, |
| | | poro.operation_name as processName, |
| | | p.product_name as productName, |
| | | pm.model, |
| | | pm.unit, |
| | | po.nps_no as productOrderNpsNo |
| | | from production_operation_task pot |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join product_model pm on po.product_model_id = pm.id |
| | | left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id |
| | | left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) |
| | | left join product p on pm.product_id = p.id |
| | | left join technology_routing_operation tro on pot.technology_routing_operation_id = tro.id |
| | | left join technology_operation top2 on tro.technology_operation_id = top2.id |
| | | where date(pot.create_time) between #{startDate} and #{endDate} |
| | | order by pot.create_time desc |
| | | </select> |
| | |
| | | </select> |
| | | |
| | | <select id="calculateProductionStatistics" resultType="com.ruoyi.home.dto.processDataProductionStatisticsDto"> |
| | | select top2.name as processName, |
| | | select poro.operation_name as processName, |
| | | sum(ifnull(ppi.input_quantity, 0)) as totalInput, |
| | | sum(ifnull(ppo.scrap_qty, 0)) as totalScrap, |
| | | sum(ifnull(ppo.quantity, 0) - ifnull(ppo.scrap_qty, 0)) as totalOutput |
| | | from production_product_output ppo |
| | | inner join production_product_main ppm on ppo.production_product_main_id = ppm.id |
| | | inner join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | inner join technology_routing_operation tro on pot.technology_routing_operation_id = tro.id |
| | | inner join technology_operation top2 on tro.technology_operation_id = top2.id |
| | | left join production_product_input ppi on ppi.production_product_main_id = ppm.id |
| | | left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id |
| | | left join production_product_input ppi on ppi.production_product_main_id = ppm.id |
| | | <where> |
| | | <if test="startDateTime != null"> |
| | | and ppo.create_time >= #{startDateTime} |
| | |
| | | and ppm.create_user = #{userId} |
| | | </if> |
| | | <if test="processIds != null and processIds.size() > 0"> |
| | | and top2.id in |
| | | and poro.technology_operation_id in |
| | | <foreach collection="processIds" item="id" open="(" separator="," close=")"> |
| | | #{id} |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | group by top2.id, top2.name |
| | | group by poro.technology_operation_id, poro.operation_name |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | po.dept_id, |
| | | po.plan_complete_time, |
| | | po.status, |
| | | po_sales.salesContractNo, |
| | | po_sales.customerName, |
| | | p.product_name as productName, |
| | | pm.model as model, |
| | | tr.process_route_code as processRouteCode, |
| | |
| | | |
| | | <sql id="ProductionOrderVoFrom"> |
| | | from production_order po |
| | | left join ( |
| | | select po2.id as orderId, |
| | | group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as salesContractNo, |
| | | group_concat(distinct sl2.customer_name order by sl2.customer_name separator ',') as customerName, |
| | | group_concat(distinct sl2.project_name order by sl2.project_name separator ',') as projectName, |
| | | min(sl2.delivery_date) as deliveryDate |
| | | from production_order po2 |
| | | left join production_plan pp2 |
| | | on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 |
| | | left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id |
| | | group by po2.id |
| | | ) po_sales on po_sales.orderId = po.id |
| | | 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 |
| | |
| | | |
| | | <select id="selectProgressOrders" resultType="com.ruoyi.home.dto.ProductionProgressOrderDto"> |
| | | select po.nps_no, |
| | | sl.sales_contract_no, |
| | | sl.project_name, |
| | | sl.customer_name, |
| | | po_sales.salesContractNo, |
| | | po_sales.projectName, |
| | | po_sales.customerName, |
| | | p.product_name as productCategory, |
| | | pm.model as specificationModel, |
| | | tr.process_route_code as processRouteCode, |
| | |
| | | ifnull(po.complete_quantity, 0) as completeQuantity, |
| | | round(ifnull(po.complete_quantity, 0) / nullif(po.quantity, 0) * 100, 2) as completionStatus, |
| | | tb.bom_no, |
| | | datediff(sl.delivery_date, curdate()) as deliveryDaysDiff, |
| | | sl.delivery_date, |
| | | datediff(po_sales.deliveryDate, curdate()) as deliveryDaysDiff, |
| | | po_sales.deliveryDate as deliveryDate, |
| | | false as isFh |
| | | from production_order po |
| | | left join sales_ledger sl on po.sales_ledger_id = sl.id |
| | | left join ( |
| | | select po2.id as orderId, |
| | | group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as salesContractNo, |
| | | group_concat(distinct sl2.customer_name order by sl2.customer_name separator ',') as customerName, |
| | | group_concat(distinct sl2.project_name order by sl2.project_name separator ',') as projectName, |
| | | min(sl2.delivery_date) as deliveryDate |
| | | from production_order po2 |
| | | left join production_plan pp2 |
| | | on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 |
| | | left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id |
| | | group by po2.id |
| | | ) po_sales on po_sales.orderId = po.id |
| | | 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 |
| | |
| | | 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 production_order_routing_operation poro on pot.production_order_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} |
| | |
| | | popr.create_time as supplementTime |
| | | 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 production_order_routing_operation poro on pot.production_order_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 |
| | | left join sys_user su on popr.create_user = su.user_id |
| | |
| | | left join production_product_main ppm on ppi.production_product_main_id = ppm.id |
| | | left join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join product_model pm on po.product_model_id = pm.id |
| | | left join product_model pm on ppi.product_model_id = pm.id |
| | | left join product p on pm.product_id = p.id |
| | | <where> |
| | | <if test="c.productNo != null and c.productNo != ''"> |
| | |
| | | <if test="c.productName != null and c.productName != ''"> |
| | | and p.product_name like concat('%', #{c.productName}, '%') |
| | | </if> |
| | | <if test="c.productMainId != null and c.productMainId != ''"> |
| | | and ppm.id = #{c.productMainId} |
| | | </if> |
| | | </where> |
| | | order by ppi.create_time desc |
| | | </select> |
| | |
| | | p.product_name as productName, |
| | | pm.model as productModelName, |
| | | pm.unit, |
| | | sl.sales_contract_no as salesContractNo, |
| | | po_sales.salesContractNo, |
| | | date(ppm.create_time) as schedulingDate, |
| | | su.nick_name as schedulingUserName, |
| | | sl.customer_name as customerName, |
| | | top2.name as process |
| | | po_sales.customerName, |
| | | poro.operation_name as process |
| | | from production_product_main ppm |
| | | left join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join sales_ledger sl on po.sales_ledger_id = sl.id |
| | | left join product_model pm on po.product_model_id = pm.id |
| | | left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id |
| | | left join ( |
| | | select po2.id as orderId, |
| | | group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as salesContractNo, |
| | | group_concat(distinct sl2.customer_name order by sl2.customer_name separator ',') as customerName |
| | | from production_order po2 |
| | | left join production_plan pp2 |
| | | on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 |
| | | left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id |
| | | group by po2.id |
| | | ) po_sales on po_sales.orderId = po.id |
| | | left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) |
| | | left join product p on pm.product_id = p.id |
| | | left join technology_routing_operation tro on pot.technology_routing_operation_id = tro.id |
| | | left join technology_operation top2 on tro.technology_operation_id = top2.id |
| | | left join sys_user su on ppm.create_user = su.user_id |
| | | left join production_product_output ppo on ppo.production_product_main_id = ppm.id |
| | | <where> |
| | |
| | | and pot.work_order_no like concat('%', #{c.workOrderNo}, '%') |
| | | </if> |
| | | <if test="c.salesContractNo != null and c.salesContractNo != ''"> |
| | | and sl.sales_contract_no like concat('%', #{c.salesContractNo}, '%') |
| | | and po_sales.salesContractNo like concat('%', #{c.salesContractNo}, '%') |
| | | </if> |
| | | <if test="c.customerName != null and c.customerName != ''"> |
| | | and sl.customer_name like concat('%', #{c.customerName}, '%') |
| | | and po_sales.customerName like concat('%', #{c.customerName}, '%') |
| | | </if> |
| | | <if test="c.productName != null and c.productName != ''"> |
| | | and p.product_name like concat('%', #{c.productName}, '%') |
| | |
| | | and pm.model like concat('%', #{c.productModelName}, '%') |
| | | </if> |
| | | <if test="c.process != null and c.process != ''"> |
| | | and top2.name like concat('%', #{c.process}, '%') |
| | | and poro.operation_name like concat('%', #{c.process}, '%') |
| | | </if> |
| | | <if test="c.schedulingDate != null"> |
| | | and date(ppm.create_time) = #{c.schedulingDate} |
| | | </if> |
| | | <if test="c.productMainId != null"> |
| | | and ppm.id = #{c.productMainId} |
| | | </if> |
| | | </where> |
| | | order by ppm.create_time desc |
| | |
| | | p.product_name as productName, |
| | | pm.model as productModelName, |
| | | pm.unit, |
| | | top2.name as process, |
| | | poro.operation_name as process, |
| | | ifnull(ppo.quantity, 0) as quantity, |
| | | ifnull(ppo.scrap_qty, 0) as scrapQty |
| | | from production_product_main ppm |
| | | left join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join product_model pm on po.product_model_id = pm.id |
| | | left join production_order_routing_operation poro on pot.production_order_routing_operation_id = poro.id |
| | | left join product_model pm on pm.id = ifnull(poro.product_model_id, po.product_model_id) |
| | | left join product p on pm.product_id = p.id |
| | | left join technology_routing_operation tro on pot.technology_routing_operation_id = tro.id |
| | | left join technology_operation top2 on tro.technology_operation_id = top2.id |
| | | left join production_product_output ppo on ppo.production_product_main_id = ppm.id |
| | | order by ppm.create_time desc |
| | | </select> |
| | |
| | | left join production_product_main ppm on ppo.production_product_main_id = ppm.id |
| | | left join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join product_model pm on po.product_model_id = pm.id |
| | | left join product_model pm on ppo.product_model_id = pm.id |
| | | <where> |
| | | <if test="c.productNo != null and c.productNo != ''"> |
| | | and ppm.product_no like concat('%', #{c.productNo}, '%') |
| | |
| | | pl.purchase_contract_number as purchase_contract_no |
| | | </when> |
| | | <otherwise> |
| | | pwo.work_order_no, |
| | | sl.sales_contract_no |
| | | pot.work_order_no, |
| | | po_sales.sales_contract_no |
| | | </otherwise> |
| | | </choose> |
| | | FROM |
| | |
| | | </when> |
| | | <otherwise> |
| | | 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 po.id = pwo.product_order_id |
| | | left join sales_ledger sl ON sl.id = po.sales_ledger_id |
| | | LEFT JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id |
| | | left join production_order po ON po.id = pot.production_order_id |
| | | left join ( |
| | | select po2.id as order_id, |
| | | group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no |
| | | from production_order po2 |
| | | left join production_plan pp2 |
| | | on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 |
| | | left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id |
| | | group by po2.id |
| | | ) po_sales ON po_sales.order_id = po.id |
| | | </otherwise> |
| | | </choose> |
| | | WHERE |
| | |
| | | SELECT qts.* |
| | | FROM quality_test_standard qts |
| | | left join quality_test_standard_binding qtsb on qtsb.test_standard_id = qts.id |
| | | left join product_process pp on qts.process_id = pp.id |
| | | left join technology_operation toper on qts.process_id = toper.id |
| | | WHERE qtsb.product_id = #{productId} |
| | | AND qts.inspect_type = #{inspectType} |
| | | <if test="process!='' and process!=null"> |
| | | and pp.name = #{process} |
| | | and toper.name = #{process} |
| | | </if> |
| | | order by qts.id desc |
| | | </select> |
| | |
| | | select slp.* |
| | | from quality_inspect qi |
| | | 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.sales_ledger_product_id = slp.id and slp.type = 1 |
| | | left join production_operation_task pot on ppm.production_operation_task_id = pot.id |
| | | left join production_order po on pot.production_order_id = po.id |
| | | left join production_plan pp_main |
| | | on find_in_set(pp_main.id, replace(replace(replace(po.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 |
| | | left join sales_ledger_product slp on slp.sales_ledger_id = pp_main.sales_ledger_id |
| | | and slp.product_model_id = po.product_model_id |
| | | and slp.type = 1 |
| | | where qi.product_main_id = #{productMainId} |
| | | and slp.id is not null |
| | | order by slp.id desc |
| | | limit 1 |
| | | |
| | | |
| | | </select> |