doc/sql/Ìì½òçâÜßÀÖÆ÷.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ ALTER TABLE `production_product_main` ADD COLUMN `report_type` int NULL DEFAULT 0 COMMENT 'æ¥å·¥ç»æç±»åï¼0åæ ¼ï¼1轻微è¿å·¥ï¼2严éè¿å·¥ï¼3æ¥åº' AFTER `status`, ADD COLUMN `audit_status` int NULL DEFAULT 0 COMMENT 'å®¡æ ¸ç¶æï¼0å¾ å®¡æ ¸ï¼1å®¡æ ¸éè¿ï¼2å®¡æ ¸ä¸éè¿' AFTER `report_type`, ADD COLUMN `audit_remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'å®¡æ ¸æè§' AFTER `audit_status`; ALTER TABLE `production_account` ADD COLUMN `adjust_amount` decimal(18,2) NULL DEFAULT NULL COMMENT 'å·¥èµä¿®æ£éé¢' AFTER `technology_operation_name`, ADD COLUMN `adjust_remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'å·¥èµä¿®æ£è¯´æ' AFTER `adjust_amount`, ADD COLUMN `adjust_user` bigint NULL DEFAULT NULL COMMENT 'ä¿®æ£äºº' AFTER `adjust_remark`, ADD COLUMN `adjust_time` datetime NULL DEFAULT NULL COMMENT 'ä¿®æ£æ¶é´' AFTER `adjust_user`, ADD COLUMN `accounting_batch_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'æ ¸ç®æ¹æ¬¡å·' AFTER `adjust_time`; ALTER TABLE `quality_unqualified` ADD COLUMN `photo_urls` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT 'ä¸åæ ¼å¾ç' AFTER `deal_result`; src/main/java/com/ruoyi/approve/service/ApprovalTemplateService.java
@@ -31,4 +31,6 @@ ApprovalTemplateVo getApprovalTemplateVoById(Long id); ApprovalTemplateVo getEnabledTemplateByBusinessType(Long businessType); } src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
@@ -31,6 +31,8 @@ import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.domain.R; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.pojo.ProductionProductMain; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysDeptMapper; @@ -94,6 +96,7 @@ private final EnterpriseNewsMapper enterpriseNewsMapper; private final EnterpriseNewsScopeDeptMapper enterpriseNewsScopeDeptMapper; private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper; private final ProductionProductMainMapper productionProductMainMapper; @Override public R listPage(Page<ApprovalInstanceVo> page, ApprovalInstanceDto approvalInstanceDto) { @@ -550,6 +553,10 @@ } if (TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode().equals(businessType)) { handleNewsApprovalFinished(instance, status); return; } if (TypeEnums.PRODUCTION_REPORT_APPROVAL.getCode().equals(businessType)) { handleProductionReportApprovalFinished(instance, status); } } @@ -691,6 +698,27 @@ shippingInfoMapper.updateById(shippingInfo); } private void handleProductionReportApprovalFinished(ApprovalInstance instance, String status) { if (instance == null || instance.getBusinessId() == null) { return; } ProductionProductMain productionProductMain = productionProductMainMapper.selectById(instance.getBusinessId()); if (productionProductMain == null) { return; } if ("APPROVED".equals(status)) { productionProductMain.setAuditStatus(1); } else if ("REJECTED".equals(status)) { productionProductMain.setAuditStatus(2); } else if ("PENDING".equals(status)) { productionProductMain.setAuditStatus(0); } else { return; } productionProductMainMapper.updateById(productionProductMain); } private List<ApprovalTask> createNodeAndTasks(ApprovalInstance instance, ApprovalTemplateNode templateNode) { List<ApprovalTemplateNodeApprover> approvers = approvalTemplateNodeApproverMapper.selectList( new LambdaQueryWrapper<ApprovalTemplateNodeApprover>() src/main/java/com/ruoyi/approve/service/impl/ApprovalTemplateServiceImpl.java
@@ -183,6 +183,25 @@ return buildTemplateVo(template, nodeMap, approverMap); } @Override public ApprovalTemplateVo getEnabledTemplateByBusinessType(Long businessType) { if (businessType == null) { return null; } ApprovalTemplate template = this.getOne( new LambdaQueryWrapper<ApprovalTemplate>() .eq(ApprovalTemplate::getDeleted, 0) .eq(ApprovalTemplate::getEnabled, 1) .eq(ApprovalTemplate::getBusinessType, businessType) .orderByDesc(ApprovalTemplate::getId) .last("limit 1") ); if (template == null) { return null; } return getApprovalTemplateVoById(template.getId()); } /** * æ¹éå¡«å æ¨¡æ¿èç¹åèç¹å®¡æ¹äººï¼é¿å å¾ªç¯æ¥åºã */ src/main/java/com/ruoyi/common/enums/TypeEnums.java
@@ -24,7 +24,8 @@ OVERTIME_APPROVAL(15L, "å ç审æ¹"), TRAVEL_REIMBURSEMENT_APPROVAL(16L, "åºå·®æ¥é审æ¹"), EXPENSE_APPROVAL(17L, "è´¹ç¨å®¡æ¹"), ENTERPRISE_NEWS_APPROVAL(18L, "ä¼ä¸æ°é»å®¡æ¹"); ENTERPRISE_NEWS_APPROVAL(18L, "ä¼ä¸æ°é»å®¡æ¹"), PRODUCTION_REPORT_APPROVAL(19L, "æ¥å·¥å®¡æ¹"); src/main/java/com/ruoyi/production/bean/dto/ProductionAccountDto.java
@@ -6,6 +6,7 @@ import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDate; @Data @@ -39,6 +40,21 @@ @Schema(description = "å·¥åº") private String process; @Schema(description = "å·¥èµä¿®æ£éé¢") private BigDecimal adjustAmount; @Schema(description = "å·¥èµä¿®æ£è¯´æ") private String adjustRemark; @Schema(description = "ä¿®æ£äºº") private Long adjustUser; @Schema(description = "æ¥å·¥ç»æç±»åï¼0åæ ¼ï¼1轻微è¿å·¥ï¼2严éè¿å·¥ï¼3æ¥åº") private Integer reportType; @Schema(description = "å®¡æ ¸ç¶æï¼0å¾ å®¡æ ¸ï¼1å®¡æ ¸éè¿ï¼2å®¡æ ¸ä¸éè¿") private Integer auditStatus; @Schema(description = "æ¥æç±»åï¼æå¤©/ææï¼") private String dateType; src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java
@@ -21,6 +21,15 @@ @Schema(description = "æ¥å·¥ID") private Long productMainId; @Schema(description = "æ¥å·¥ç»æç±»åï¼0åæ ¼ï¼1轻微è¿å·¥ï¼2严éè¿å·¥ï¼3æ¥åº") private Integer reportType; @Schema(description = "å®¡æ ¸ç¶æï¼0å¾ å®¡æ ¸ï¼1å®¡æ ¸éè¿ï¼2å®¡æ ¸ä¸éè¿") private Integer auditStatus; @Schema(description = "å®¡æ ¸æè§") private String auditRemark; @Schema(description = "ç§æ·ID") private Long tenantId; src/main/java/com/ruoyi/production/bean/vo/ProductionAccountVo.java
@@ -11,6 +11,15 @@ @Schema(name = "ProductionAccountVo", description = "çäº§æ ¸ç®åé¡µç»æ") public class ProductionAccountVo { @Schema(description = "æ¥å·¥åå·") private String reportNo; @Schema(description = "å®¡æ ¸ç¶æ") private String auditStatusName; @Schema(description = "æ¥å·¥ç±»å") private String reportTypeName; @Schema(description = "客æ·ååå·") private String customerContractNo; @@ -35,6 +44,9 @@ @Schema(description = "æäº§äººååç§°") private String schedulingUserName; @Schema(description = "å·¥åç¼å·") private String workOrderNo; @Schema(description = "å·¥èµ") private BigDecimal wages; @@ -44,6 +56,12 @@ @Schema(description = "å·¥èµå®é¢") private BigDecimal workHours; @Schema(description = "å·¥èµä¿®æ£éé¢") private BigDecimal adjustAmount; @Schema(description = "å·¥èµä¿®æ£è¯´æ") private String adjustRemark; @Schema(description = "å·¥æ¶") private BigDecimal workHour; src/main/java/com/ruoyi/production/controller/ProductionAccountController.java
@@ -10,9 +10,11 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestBody; /** * <p> @@ -38,4 +40,16 @@ public R<IPage<ProductionProductMainDto>> listProductionDetails(ProductionAccountDto productionAccountDto, Page page) { return R.ok(productionAccountService.listProductionDetails(productionAccountDto,page)); } @PostMapping("/batchAccounting") @Operation(summary = "æ¹éæ ¸ç®") public R<Boolean> batchAccounting(@RequestBody ProductionAccountDto dto) { return R.ok(productionAccountService.batchAccounting(dto)); } @PostMapping("/singleAdjust") @Operation(summary = "å个修æ£") public R<Boolean> singleAdjust(@RequestBody ProductionAccountDto dto) { return R.ok(productionAccountService.singleAdjust(dto)); } } src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -80,6 +80,13 @@ return R.ok(productionProductMainService.removeProductMain(id)); } @PostMapping("/audit") @Operation(summary = "å®¡æ ¸ç产æ¥å·¥") @PreAuthorize("@ss.hasPermi('productionProductMain:audit')") public R audit(@RequestBody ProductionProductMainDto productionProductMainDto) { return R.ok(productionProductMainService.auditProductMain(productionProductMainDto)); } /** * å¯¼åº src/main/java/com/ruoyi/production/pojo/ProductionAccount.java
@@ -45,6 +45,21 @@ @Schema(description = "å·¥åºåç§°") private String technologyOperationName; @Schema(description = "å·¥èµä¿®æ£éé¢") private BigDecimal adjustAmount; @Schema(description = "å·¥èµä¿®æ£è¯´æ") private String adjustRemark; @Schema(description = "ä¿®æ£äºº") private Long adjustUser; @Schema(description = "ä¿®æ£æ¶é´") private LocalDateTime adjustTime; @Schema(description = "æ ¸ç®æ¹æ¬¡å·") private String accountingBatchNo; @Schema(description = "çäº§æ¥æ") private LocalDateTime schedulingDate; src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -33,6 +33,18 @@ @Schema(description = "æ¥å·¥ç¶æ") private Integer status; @Schema(description = "æ¥å·¥ç»æç±»åï¼0åæ ¼ï¼1轻微è¿å·¥ï¼2严éè¿å·¥ï¼3æ¥åº") @TableField("report_type") private Integer reportType; @Schema(description = "å®¡æ ¸ç¶æï¼0å¾ å®¡æ ¸ï¼1å®¡æ ¸éè¿ï¼2å®¡æ ¸ä¸éè¿") @TableField("audit_status") private Integer auditStatus; @Schema(description = "å®¡æ ¸æè§") @TableField("audit_remark") private String auditRemark; @Schema(description = "å建æ¶é´") @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") src/main/java/com/ruoyi/production/service/ProductionAccountService.java
@@ -20,4 +20,8 @@ IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto); IPage<ProductionProductMainDto> listProductionDetails(ProductionAccountDto productionAccountDto, Page page); Boolean batchAccounting(ProductionAccountDto dto); Boolean singleAdjust(ProductionAccountDto dto); } src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -22,5 +22,7 @@ Boolean removeProductMain(Long id); Boolean auditProductMain(ProductionProductMainDto productionProductMainDto); ArrayList<Long> listMain(List<Long> idList); } src/main/java/com/ruoyi/production/service/impl/ProductionAccountServiceImpl.java
@@ -1,19 +1,39 @@ package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.production.bean.dto.ProductionAccountDto; import com.ruoyi.production.bean.dto.ProductionProductMainDto; import com.ruoyi.production.bean.vo.ProductionAccountVo; import com.ruoyi.production.mapper.ProductionAccountMapper; import com.ruoyi.production.mapper.ProductionOperationTaskMapper; import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.mapper.ProductionProductOutputMapper; import com.ruoyi.production.pojo.ProductionAccount; import com.ruoyi.production.pojo.ProductionOperationTask; import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; import com.ruoyi.production.pojo.ProductionProductMain; import com.ruoyi.production.pojo.ProductionProductOutput; import com.ruoyi.technology.mapper.TechnologyOperationMapper; import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper; import com.ruoyi.technology.pojo.TechnologyOperation; import com.ruoyi.technology.pojo.TechnologyRoutingOperation; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.production.service.ProductionAccountService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.exception.ServiceException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @Service @RequiredArgsConstructor @@ -21,6 +41,12 @@ private final ProductionProductMainMapper productionProductMainMapper; private final ProductionProductOutputMapper productionProductOutputMapper; private final ProductionOperationTaskMapper productionOperationTaskMapper; private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper; private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper; private final TechnologyOperationMapper technologyOperationMapper; private final SysUserMapper sysUserMapper; @Override public IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto) { @@ -32,7 +58,114 @@ @Override public IPage<ProductionProductMainDto> listProductionDetails(ProductionAccountDto dto, Page page) { // æ¥è¯¢çäº§æ ¸ç®æç» return productionProductMainMapper.listProductionDetails(normalizeDateQuery(dto), page); ProductionAccountDto queryDto = normalizeDateQuery(dto); if (queryDto.getAuditStatus() == null) { queryDto.setAuditStatus(1); } if (queryDto.getReportType() == null) { queryDto.setReportType(0); } return productionProductMainMapper.listProductionDetails(queryDto, page); } @Override @Transactional(rollbackFor = Exception.class) public Boolean batchAccounting(ProductionAccountDto dto) { ProductionAccountDto queryDto = normalizeDateQuery(dto); LambdaQueryWrapper<ProductionProductMain> queryWrapper = Wrappers.<ProductionProductMain>lambdaQuery() .eq(ProductionProductMain::getAuditStatus, 1) .eq(ProductionProductMain::getReportType, 0); if (queryDto.getSchedulingUserId() != null) { queryWrapper.eq(ProductionProductMain::getUserId, queryDto.getSchedulingUserId()); } if (queryDto.getSchedulingUserName() != null && !queryDto.getSchedulingUserName().isEmpty()) { queryWrapper.like(ProductionProductMain::getUserName, queryDto.getSchedulingUserName()); } if (queryDto.getEntryDate() != null) { queryWrapper.apply("date(create_time) = {0}", queryDto.getEntryDate()); } if (queryDto.getEntryDateStart() != null) { queryWrapper.ge(ProductionProductMain::getCreateTime, queryDto.getEntryDateStart().atStartOfDay()); } if (queryDto.getEntryDateEnd() != null) { queryWrapper.le(ProductionProductMain::getCreateTime, queryDto.getEntryDateEnd().atTime(23, 59, 59)); } List<ProductionProductMain> reportList = productionProductMainMapper.selectList(queryWrapper); for (ProductionProductMain report : reportList) { rebuildAccount(report); } return Boolean.TRUE; } @Override @Transactional(rollbackFor = Exception.class) public Boolean singleAdjust(ProductionAccountDto dto) { if (dto == null || dto.getSchedulingUserId() == null) { throw new ServiceException("è¯·éæ©éè¦ä¿®æ£ç人å"); } BigDecimal adjustAmount = dto.getAdjustAmount(); if (adjustAmount == null || adjustAmount.compareTo(BigDecimal.ZERO) == 0) { throw new ServiceException("ä¿®æ£éé¢ä¸è½ä¸ºç©º"); } ProductionAccount account = new ProductionAccount(); account.setSchedulingUserId(dto.getSchedulingUserId()); account.setSchedulingUserName(dto.getSchedulingUserName()); account.setTechnologyOperationName("å·¥èµä¿®æ£"); account.setAdjustAmount(adjustAmount); account.setAdjustRemark(dto.getAdjustRemark()); account.setAdjustUser(dto.getAdjustUser()); account.setAdjustTime(LocalDateTime.now()); account.setSchedulingDate(LocalDateTime.now()); account.setWorkHours(BigDecimal.ZERO); account.setFinishedNum(BigDecimal.ZERO); account.setAccountingBatchNo("ADJ-" + LocalDate.now()); baseMapper.insert(account); return Boolean.TRUE; } private void rebuildAccount(ProductionProductMain productionProductMain) { if (productionProductMain == null || productionProductMain.getId() == null) { return; } productionAccountDelete(productionProductMain.getId()); ProductionProductOutput output = productionProductOutputMapper.selectOne( Wrappers.<ProductionProductOutput>lambdaQuery() .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()) .last("limit 1")); if (output == null || output.getQuantity() == null || output.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { return; } ProductionOperationTask task = productionOperationTaskMapper.selectById(productionProductMain.getProductionOperationTaskId()); if (task == null) { return; } ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(task.getProductionOrderRoutingOperationId()); if (routingOperation == null) { return; } TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); SysUser user = sysUserMapper.selectUserById(productionProductMain.getUserId()); ProductionAccount account = new ProductionAccount(); account.setProductionProductMainId(productionProductMain.getId()); account.setSchedulingUserId(user == null ? productionProductMain.getUserId() : user.getUserId()); account.setSchedulingUserName(user == null ? productionProductMain.getUserName() : user.getNickName()); account.setFinishedNum(output.getQuantity()); account.setWorkHours(technologyOperation == null ? null : technologyOperation.getSalaryQuota()); account.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName()); account.setSchedulingDate(LocalDateTime.now()); account.setAccountingBatchNo("BATCH-" + LocalDate.now()); baseMapper.insert(account); } private void productionAccountDelete(Long productionProductMainId) { if (productionProductMainId == null) { return; } baseMapper.delete(new LambdaQueryWrapper<ProductionAccount>() .eq(ProductionAccount::getProductionProductMainId, productionProductMainId)); } private ProductionAccountDto normalizeDateQuery(ProductionAccountDto dto) { src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -7,10 +7,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.alibaba.fastjson2.JSON; import com.ruoyi.approve.bean.dto.ApprovalInstanceDto; import com.ruoyi.approve.bean.vo.ApprovalTemplateVo; import com.ruoyi.approve.service.ApprovalInstanceService; import com.ruoyi.approve.service.ApprovalTemplateService; import com.ruoyi.basic.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.common.enums.TypeEnums; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.exception.ServiceException; @@ -78,6 +84,8 @@ private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper; private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper; private final TechnologyOperationMapper technologyOperationMapper; private final ApprovalTemplateService approvalTemplateService; private final ApprovalInstanceService approvalInstanceService; private final StockUtils stockUtils; private final StockInRecordService stockInRecordService; private final StockInventoryService stockInventoryService; @@ -277,9 +285,13 @@ productionProductMain.setUserName(user == null ? dto.getUserName() : user.getNickName()); productionProductMain.setProductionOperationTaskId(taskId); productionProductMain.setStatus(0); productionProductMain.setReportType(dto.getReportType() == null ? 0 : dto.getReportType()); productionProductMain.setAuditStatus(dto.getAuditStatus() == null ? 0 : dto.getAuditStatus()); productionProductMain.setAuditRemark(dto.getAuditRemark()); productionProductMain.setWorkHour(dto.getWorkHour()); productionProductMainMapper.insert(productionProductMain); syncOperationParamInputValue(dto, routingOperation.getId(), productionProductMain.getId()); createReportApprovalInstance(productionProductMain); List<ProductStructureDto> productStructureDtos = resolveInputStructures( productionOrder.getId(), routingOperation, productModel.getId()); @@ -406,7 +418,6 @@ productionAccount.setWorkHours(technologyOperation != null ? technologyOperation.getSalaryQuota() : null); productionAccount.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName()); productionAccount.setSchedulingDate(LocalDateTime.now()); productionAccountMapper.insert(productionAccount); } if (scrapQty.compareTo(BigDecimal.ZERO) > 0) { stockUtils.addUnStockWithBatchNo( @@ -417,6 +428,120 @@ qualifiedBatchNo); } return true; } private void createReportApprovalInstance(ProductionProductMain productionProductMain) { if (productionProductMain == null || productionProductMain.getId() == null) { return; } ApprovalTemplateVo templateVo = approvalTemplateService.getEnabledTemplateByBusinessType( TypeEnums.PRODUCTION_REPORT_APPROVAL.getCode() ); if (templateVo == null) { throw new ServiceException("请å é ç½®æ¥å·¥å®¡æ¹æ¨¡æ¿"); } ApprovalInstanceDto approvalInstanceDto = new ApprovalInstanceDto(); approvalInstanceDto.setTemplateId(templateVo.getId()); approvalInstanceDto.setTemplateName(templateVo.getTemplateName()); approvalInstanceDto.setBusinessId(productionProductMain.getId()); approvalInstanceDto.setBusinessType(TypeEnums.PRODUCTION_REPORT_APPROVAL.getCode()); approvalInstanceDto.setTitle(productionProductMain.getProductNo()); approvalInstanceDto.setApplicantId(productionProductMain.getUserId()); approvalInstanceDto.setApplicantName(productionProductMain.getUserName()); approvalInstanceDto.setApplyTime(LocalDateTime.now()); approvalInstanceDto.setStatus("PENDING"); approvalInstanceDto.setFormConfig(JSON.toJSONString(buildReportApprovalFormConfig(productionProductMain))); approvalInstanceService.add(approvalInstanceDto); } private Map<String, Object> buildReportApprovalFormConfig(ProductionProductMain productionProductMain) { Map<String, Object> formConfig = new LinkedHashMap<>(); formConfig.put("summaryPlaceholder", "æ¥å·¥å®¡æ¹"); formConfig.put("approvalType", "production_report"); List<Map<String, Object>> fields = new ArrayList<>(); fields.add(buildReportField("productNo", "æ¥å·¥åå·", "text", productionProductMain.getProductNo())); fields.add(buildReportField("userName", "æ¥å·¥äººå", "text", productionProductMain.getUserName())); fields.add(buildReportField("workOrderNo", "å·¥åç¼å·", "text", resolveWorkOrderNo(productionProductMain.getProductionOperationTaskId()))); fields.add(buildReportField("reportType", "æ¥å·¥ç»æ", "select", resolveReportTypeLabel(productionProductMain.getReportType()))); fields.add(buildReportField("workHour", "å·¥æ¶", "number", productionProductMain.getWorkHour())); fields.add(buildReportField("auditStatus", "å®¡æ ¸ç¶æ", "select", resolveAuditStatusLabel(productionProductMain.getAuditStatus()))); fields.add(buildReportField("auditRemark", "å®¡æ ¸æè§", "textarea", productionProductMain.getAuditRemark())); formConfig.put("fields", fields); Map<String, Object> formPayload = new LinkedHashMap<>(); formPayload.put("productNo", productionProductMain.getProductNo()); formPayload.put("userName", productionProductMain.getUserName()); formPayload.put("workOrderNo", resolveWorkOrderNo(productionProductMain.getProductionOperationTaskId())); formPayload.put("reportType", resolveReportTypeLabel(productionProductMain.getReportType())); formPayload.put("workHour", productionProductMain.getWorkHour()); formPayload.put("auditStatus", resolveAuditStatusLabel(productionProductMain.getAuditStatus())); formPayload.put("auditRemark", productionProductMain.getAuditRemark()); formConfig.put("formPayload", formPayload); return formConfig; } private Map<String, Object> buildReportField(String key, String label, String type, Object defaultValue) { Map<String, Object> field = new LinkedHashMap<>(); field.put("key", key); field.put("label", label); field.put("type", type); field.put("required", Boolean.FALSE); field.put("defaultValue", defaultValue); return field; } private String resolveWorkOrderNo(Long productionOperationTaskId) { if (productionOperationTaskId == null) { return null; } ProductionOperationTask task = productionOperationTaskMapper.selectById(productionOperationTaskId); if (task != null && task.getWorkOrderNo() != null) { return task.getWorkOrderNo(); } if (task == null || task.getProductionOrderRoutingOperationId() == null) { return null; } ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(task.getProductionOrderRoutingOperationId()); if (routingOperation == null || routingOperation.getProductionOrderId() == null) { return null; } ProductionOrder productionOrder = productionOrderMapper.selectById(routingOperation.getProductionOrderId()); return productionOrder == null ? null : productionOrder.getNpsNo(); } private String resolveReportTypeLabel(Integer reportType) { if (reportType == null) { return "â"; } switch (reportType) { case 0: return "åæ ¼"; case 1: return "轻微è¿å·¥"; case 2: return "严éè¿å·¥"; case 3: return "æ¥åº"; default: return "â"; } } private String resolveAuditStatusLabel(Integer auditStatus) { if (auditStatus == null) { return "å¾ å®¡æ ¸"; } switch (auditStatus) { case 0: return "å¾ å®¡æ ¸"; case 1: return "å®¡æ ¸éè¿"; case 2: return "å®¡æ ¸ä¸éè¿"; default: return "â"; } } private String resolveLatestStockInBatchNo(Long recordId, @@ -681,6 +806,86 @@ return dto.getProductionOperationTaskId(); } private boolean isCountingWageReport(ProductionProductMain productionProductMain) { return productionProductMain != null && productionProductMain.getAuditStatus() != null && productionProductMain.getAuditStatus() == 1 && productionProductMain.getReportType() != null && productionProductMain.getReportType() == 0; } private boolean isExcludedFromWage(ProductionProductMain productionProductMain) { return productionProductMain != null && productionProductMain.getReportType() != null && productionProductMain.getReportType() != 0; } @Override public Boolean auditProductMain(ProductionProductMainDto productionProductMainDto) { if (productionProductMainDto == null || productionProductMainDto.getId() == null) { throw new ServiceException("åæ°é误"); } ProductionProductMain productionProductMain = productionProductMainMapper.selectById(productionProductMainDto.getId()); if (productionProductMain == null) { throw new ServiceException("æ¥å·¥ä¸åå¨"); } Integer auditStatus = productionProductMainDto.getAuditStatus(); if (auditStatus == null) { throw new ServiceException("å®¡æ ¸ç¶æä¸è½ä¸ºç©º"); } productionProductMain.setAuditStatus(auditStatus); productionProductMain.setAuditRemark(productionProductMainDto.getAuditRemark()); productionProductMainMapper.updateById(productionProductMain); productionAccountMapper.delete(new LambdaQueryWrapper<ProductionAccount>() .eq(ProductionAccount::getProductionProductMainId, productionProductMain.getId())); if (auditStatus == 1 && !isExcludedFromWage(productionProductMain)) { rebuildProductionAccount(productionProductMain); } return true; } private void rebuildProductionAccount(ProductionProductMain productionProductMain) { if (productionProductMain == null || productionProductMain.getId() == null) { return; } ProductionProductOutput output = productionProductOutputMapper.selectOne( Wrappers.<ProductionProductOutput>lambdaQuery() .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()) .last("limit 1")); if (output == null) { return; } ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(productionProductMain.getProductionOperationTaskId()); if (productionOperationTask == null) { return; } ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId()); if (routingOperation == null) { return; } ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId()); if (productionOrder == null) { return; } TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); SysUser user = userMapper.selectUserById(productionProductMain.getUserId()); BigDecimal productQty = defaultDecimal(output.getQuantity()); if (productQty.compareTo(BigDecimal.ZERO) <= 0) { return; } ProductionAccount productionAccount = new ProductionAccount(); productionAccount.setProductionProductMainId(productionProductMain.getId()); productionAccount.setSchedulingUserId(user == null ? productionProductMain.getUserId() : user.getUserId()); productionAccount.setSchedulingUserName(user == null ? productionProductMain.getUserName() : user.getNickName()); productionAccount.setFinishedNum(productQty); productionAccount.setWorkHours(technologyOperation != null ? technologyOperation.getSalaryQuota() : null); productionAccount.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName()); productionAccount.setSchedulingDate(LocalDateTime.now()); productionAccountMapper.insert(productionAccount); } @Override public ArrayList<Long> listMain(List<Long> idList) { // æ¥è¯¢ä¸»è¡¨IDéå src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -4,6 +4,7 @@ import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.quality.pojo.QualityUnqualified; import com.ruoyi.quality.service.IQualityUnqualifiedService; import io.swagger.v3.oas.annotations.Operation; @@ -37,6 +38,10 @@ @Log(title = "æ°å¢ä¸åæ ¼ç®¡ç", businessType = BusinessType.INSERT) public R<?> add(@RequestBody QualityUnqualified qualityUnqualified) { qualityUnqualified.setInspectState(0); if (qualityUnqualified.getDealType() != null) { qualityUnqualified.setDealResult(resolveDealResult(qualityUnqualified.getDealType())); } normalizeRepairWorkHour(qualityUnqualified); return R.ok(qualityUnqualifiedService.save(qualityUnqualified)); } @@ -78,6 +83,10 @@ @Operation(summary = "ä¸åæ ¼ç®¡çä¿®æ¹") @Log(title = "ä¸åæ ¼ç®¡çä¿®æ¹", businessType = BusinessType.UPDATE) public R<?> update(@RequestBody QualityUnqualified qualityUnqualified) { if (qualityUnqualified.getDealType() != null) { qualityUnqualified.setDealResult(resolveDealResult(qualityUnqualified.getDealType())); } normalizeRepairWorkHour(qualityUnqualified); return R.ok(qualityUnqualifiedService.updateById(qualityUnqualified)); } @@ -115,8 +124,38 @@ @Operation(summary = "ä¸åæ ¼ç®¡çå¤ç") @Log(title = "ä¸åæ ¼ç®¡çå¤ç", businessType = BusinessType.OTHER) public R<?> deal(@RequestBody QualityUnqualified qualityUnqualified) { if (qualityUnqualified.getDealType() != null) { qualityUnqualified.setDealResult(resolveDealResult(qualityUnqualified.getDealType())); } normalizeRepairWorkHour(qualityUnqualified); return R.ok(qualityUnqualifiedService.deal(qualityUnqualified)); } private String resolveDealResult(Integer dealType) { if (dealType == null) { return null; } return switch (dealType) { case 0 -> "轻微è¿å·¥"; case 1 -> "严éè¿å·¥"; case 2 -> "æ¥åº"; default -> null; }; } private void normalizeRepairWorkHour(QualityUnqualified qualityUnqualified) { if (qualityUnqualified == null || qualityUnqualified.getDealType() == null) { return; } if (qualityUnqualified.getDealType() == 0) { if (qualityUnqualified.getRepairWorkHour() == null || qualityUnqualified.getRepairWorkHour().compareTo(java.math.BigDecimal.ZERO) <= 0) { throw new ServiceException("轻微è¿å·¥å¿ 须填å大äº0çä¿®çå·¥æ¶"); } } else { qualityUnqualified.setRepairWorkHour(java.math.BigDecimal.ZERO); } } } src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
@@ -99,6 +99,24 @@ private String dealResult; /** * ä¸åæ ¼å¾ç */ @Excel(name = "ä¸åæ ¼å¾ç") private String photoUrls; @Schema(description = "ä¸åæ ¼å¤çç±»åï¼0轻微è¿å·¥ï¼1严éè¿å·¥ï¼2æ¥åº") @Excel(name = "ä¸åæ ¼å¤çç±»å", readConverterExp = "0=轻微è¿å·¥,1=严éè¿å·¥,2=æ¥åº") private Integer dealType; @Schema(description = "ä¿®çå·¥æ¶") @Excel(name = "ä¿®çå·¥æ¶") private BigDecimal repairWorkHour; @Schema(description = "æ¯å¦éæ°çææ°åï¼0å¦ï¼1æ¯") @Excel(name = "æ¯å¦éæ°çææ°å", readConverterExp = "0=å¦,1=æ¯") private Integer regenerateNewOrder; /** * å¤ç人 */ @Excel(name = "å¤ç人") src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -73,14 +73,29 @@ QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId()); String batchNo = qualityInspect == null ? null : resolveProductionBatchNo(qualityInspect.getProductMainId(), qualityInspect.getId(), qualityInspect.getProductModelId()); if (qualityUnqualified.getDealType() != null) { switch (qualityUnqualified.getDealType()) { case 0: qualityUnqualified.setDealResult("轻微è¿å·¥"); break; case 1: qualityUnqualified.setDealResult("严éè¿å·¥"); break; case 2: qualityUnqualified.setDealResult("æ¥åº"); break; default: break; } } if (ObjectUtils.isNotNull(qualityInspect) && qualityInspect.getInspectType() != 0) { switch (qualityUnqualified.getDealResult()) { case "è¿ä¿®": case "è¿å·¥": case "严éè¿å·¥": case "轻微è¿å·¥": if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())) { ProductionProductMain sourceMain = productionProductMainMapper.selectById(qualityInspect.getProductMainId()); if (sourceMain == null || sourceMain.getProductionOperationTaskId() == null) { throw new ServiceException("å岿¥å·¥æªç»å®ç产工åï¼æ æ³ææ°æ¨¡åè¿ä¿®/è¿å·¥"); throw new ServiceException("å岿¥å·¥æªç»å®ç产工åï¼æ æ³ææ°æ¨¡åè¿å·¥"); } createReworkProductionByNewModel(sourceMain, unqualified.getQuantity()); } @@ -88,6 +103,7 @@ case "æ¥åº": stockUtils.addUnStockWithBatchNo(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId(), batchNo); qualityUnqualified.setRegenerateNewOrder(1); break; case "è®©æ¥æ¾è¡": stockUtils.addStockWithBatchNo(qualityInspect.getProductModelId(), unqualified.getQuantity(), src/main/resources/mapper/production/ProductionAccountMapper.xml
@@ -13,6 +13,11 @@ <result column="finished_num" property="finishedNum" /> <result column="work_hours" property="workHours" /> <result column="technology_operation_name" property="technologyOperationName" /> <result column="adjust_amount" property="adjustAmount" /> <result column="adjust_remark" property="adjustRemark" /> <result column="adjust_user" property="adjustUser" /> <result column="adjust_time" property="adjustTime" /> <result column="accounting_batch_no" property="accountingBatchNo" /> <result column="scheduling_date" property="schedulingDate" /> <result column="create_user" property="createUser" /> <result column="create_time" property="createTime" /> @@ -23,13 +28,27 @@ <select id="listPage" resultType="com.ruoyi.production.bean.vo.ProductionAccountVo"> select group_concat(distinct ppm.product_no order by ppm.product_no separator ',') as reportNo, case when sum(case when ppm.audit_status = 0 then 1 else 0 end) > 0 then 'å¾ å®¡æ ¸' when sum(case when ppm.audit_status = 2 then 1 else 0 end) > 0 then 'å®¡æ ¸ä¸éè¿' else 'å®¡æ ¸éè¿' end as auditStatusName, case when sum(case when ppm.report_type = 1 then 1 else 0 end) > 0 then '轻微è¿å·¥' when sum(case when ppm.report_type = 2 then 1 else 0 end) > 0 then '严éè¿å·¥' when sum(case when ppm.report_type = 3 then 1 else 0 end) > 0 then 'æ¥åº' else 'åæ ¼' end as reportTypeName, group_concat(distinct p_parent.product_name order by p_parent.product_name separator ',') as productCategory, group_concat(distinct pm.model order by pm.model separator ',') as specificationModel, group_concat(distinct pm.unit order by pm.unit separator ',') as unit, pa.scheduling_user_id as schedulingUserId, pa.scheduling_user_name as schedulingUserName, group_concat(distinct pot.work_order_no order by pot.work_order_no separator ',') as workOrderNo, cast(sum( case when pa.adjust_amount is not null then ifnull(pa.adjust_amount, 0) when poro.type = 0 then ifnull(pa.work_hours, 0) * ifnull(ppm.work_hour, 0) else ifnull(pa.work_hours, 0) * ifnull(pa.finished_num, 0) * case @@ -41,6 +60,7 @@ ) as decimal(18,4)) as wages, cast(sum(ifnull(pa.finished_num, 0)) as decimal(18,4)) as finishedNum, cast(sum(ifnull(pa.work_hours, 0)) as decimal(18,4)) as workHours, cast(sum(ifnull(pa.adjust_amount, 0)) as decimal(18,4)) as adjustAmount, cast(sum(ifnull(ppm.work_hour, 0)) as decimal(18,4)) as workHour, case when sum(ifnull(ppo.quantity, 0) + ifnull(ppo.scrapQty, 0)) = 0 then '0%' @@ -55,6 +75,7 @@ ) end as outputRate, group_concat(distinct pa.technology_operation_name order by pa.technology_operation_name separator ',') as process, group_concat(distinct pa.adjust_remark order by pa.adjust_time desc separator ',') as adjustRemark, case when count(distinct date(pa.scheduling_date)) = 1 then min(date(pa.scheduling_date)) else null @@ -79,6 +100,8 @@ group by production_product_main_id ) ppo on ppo.production_product_main_id = ppm.id <where> and ppm.audit_status = 1 and ppm.report_type = 0 <if test="c != null"> <if test="c.productCategory != null and c.productCategory != ''"> and p_parent.product_name like concat('%', #{c.productCategory}, '%') @@ -115,9 +138,12 @@ <select id="selectUserAccount" resultType="com.ruoyi.production.bean.dto.UserAccountDto"> select ifnull(sum(finished_num), 0) as accountBalance, ifnull(sum(work_hours), 0) as account from production_account where scheduling_user_id = #{userId} and date_format(scheduling_date, '%Y-%m') = #{date} from production_account pa inner join production_product_main ppm on ppm.id = pa.production_product_main_id where pa.scheduling_user_id = #{userId} and date_format(pa.scheduling_date, '%Y-%m') = #{date} and ppm.audit_status = 1 and ppm.report_type = 0 </select> <select id="selectDailyWagesStats" resultType="java.util.Map"> @@ -125,9 +151,12 @@ cast(ifnull(sum(finished_num), 0) as decimal(18,2)) as numberOfCompleted, cast(ifnull(sum(work_hours), 0) as decimal(18,2)) as amount, cast(0 as decimal(18,2)) as passRate from production_account where scheduling_date >= #{startDate} and scheduling_date <= #{endDate} from production_account pa inner join production_product_main ppm on ppm.id = pa.production_product_main_id where pa.scheduling_date >= #{startDate} and pa.scheduling_date <= #{endDate} and ppm.audit_status = 1 and ppm.report_type = 0 group by date_format(scheduling_date, '%m-%d') order by date_format(scheduling_date, '%m-%d') </select> src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -7,6 +7,9 @@ <id column="id" property="id" /> <result column="product_no" property="productNo" /> <result column="production_operation_task_id" property="productionOperationTaskId" /> <result column="report_type" property="reportType" /> <result column="audit_status" property="auditStatus" /> <result column="audit_remark" property="auditRemark" /> <result column="dept_id" property="deptId" /> <result column="update_time" property="updateTime" /> <result column="create_user" property="createUser" /> @@ -16,6 +19,20 @@ <select id="listPageProductionProductMainDto" resultType="com.ruoyi.production.bean.dto.ProductionProductMainDto"> select ppm.*, ppm.product_no as reportNo, case ppm.report_type when 0 then 'åæ ¼' when 1 then '轻微è¿å·¥' when 2 then '严éè¿å·¥' when 3 then 'æ¥åº' else 'æªç¥' end as reportTypeName, case ppm.audit_status when 0 then 'å¾ å®¡æ ¸' when 1 then 'å®¡æ ¸éè¿' when 2 then 'å®¡æ ¸ä¸éè¿' else 'æªç¥' end as auditStatusName, pot.work_order_no as workOrderNo, case pot.status when 1 then 'å¾ ç¡®è®¤' @@ -57,6 +74,12 @@ <if test="c.productNo != null and c.productNo != ''"> and ppm.product_no like concat('%', #{c.productNo}, '%') </if> <if test="c.auditStatus != null"> and ppm.audit_status = #{c.auditStatus} </if> <if test="c.reportType != null"> and ppm.report_type = #{c.reportType} </if> <if test="c.workOrderNo != null and c.workOrderNo != ''"> and pot.work_order_no like concat('%', #{c.workOrderNo}, '%') </if> @@ -91,6 +114,20 @@ <select id="listProductionDetails" resultType="com.ruoyi.production.bean.dto.ProductionProductMainDto"> select ppm.*, ppm.product_no as reportNo, case ppm.report_type when 0 then 'åæ ¼' when 1 then '轻微è¿å·¥' when 2 then '严éè¿å·¥' when 3 then 'æ¥åº' else 'æªç¥' end as reportTypeName, case ppm.audit_status when 0 then 'å¾ å®¡æ ¸' when 1 then 'å®¡æ ¸éè¿' when 2 then 'å®¡æ ¸ä¸éè¿' else 'æªç¥' end as auditStatusName, pot.work_order_no as workOrderNo, p.product_name as productName, pm.model as productModelName, @@ -125,6 +162,12 @@ left join production_product_output ppo on ppo.production_product_main_id = ppm.id <where> <if test="c != null"> <if test="c.auditStatus != null"> and ppm.audit_status = #{c.auditStatus} </if> <if test="c.reportType != null"> and ppm.report_type = #{c.reportType} </if> <if test="c.productCategory != null and c.productCategory != ''"> and p_parent.product_name like concat('%', #{c.productCategory}, '%') </if> src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml
@@ -14,6 +14,7 @@ qu.quantity, qu.defective_phenomena, qu.deal_result, qu.photo_urls, qu.deal_name, qu.deal_time, CASE @@ -72,9 +73,10 @@ qu.product_name, qu.unit, qu.quantity, qu.defective_phenomena, qu.deal_result, qu.deal_name, qu.defective_phenomena, qu.deal_result, qu.photo_urls, qu.deal_name, qu.deal_time, CASE WHEN qu.model = pm.id THEN pm.model src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -222,7 +222,7 @@ unit, product_name, product_id order by combined.create_time desc order by MAX(create_time) desc </select> <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">