| | |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.URLEncoder; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | |
| | | QualityInspect qualityInspect = new QualityInspect(); |
| | | BeanUtils.copyProperties(qualityInspectDto, qualityInspect); |
| | | qualityInspect.setInspectState(0);//默认未提交 |
| | | ensureQualifiedSplitDefaults(qualityInspect); |
| | | // 前端若已传合格/不合格数量,defaults 不会写 pass_rate,这里补算列表展示用合格率 |
| | | refreshPassRateFromQuantities(qualityInspect); |
| | | qualityInspectMapper.insert(qualityInspect); |
| | | for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) { |
| | | qualityInspectParam.setInspectId(qualityInspect.getId()); |
| | |
| | | @Override |
| | | public int submit(QualityInspect inspect) { |
| | | QualityInspect qualityInspect = qualityInspectMapper.selectById(inspect.getId()); |
| | | //提交前必须判断是否合格 |
| | | if (ObjectUtils.isNull(qualityInspect.getCheckResult())) { |
| | | throw new RuntimeException("请先判断是否合格"); |
| | | if (qualityInspect == null) { |
| | | throw new RuntimeException("质检单不存在"); |
| | | } |
| | | /*判断不合格*/ |
| | | if (qualityInspect.getCheckResult().equals("不合格")) { |
| | | if (Objects.equals(qualityInspect.getInspectState(), 1)) { |
| | | throw new RuntimeException("该质检单已提交,不能重复提交"); |
| | | } |
| | | if (inspect != null) { |
| | | if (inspect.getQualifiedQuantity() != null) { |
| | | qualityInspect.setQualifiedQuantity(inspect.getQualifiedQuantity()); |
| | | } |
| | | if (inspect.getUnqualifiedQuantity() != null) { |
| | | qualityInspect.setUnqualifiedQuantity(inspect.getUnqualifiedQuantity()); |
| | | } |
| | | } |
| | | validateAndCalculateQuantities(qualityInspect); |
| | | |
| | | BigDecimal qualifiedQty = qualityInspect.getQualifiedQuantity(); |
| | | BigDecimal unqualifiedQty = qualityInspect.getUnqualifiedQuantity(); |
| | | |
| | | if (unqualifiedQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | QualityUnqualified qualityUnqualified = new QualityUnqualified(); |
| | | BeanUtils.copyProperties(qualityInspect, qualityUnqualified); |
| | | qualityUnqualified.setInspectState(0);//待处理 |
| | | List<QualityInspectParam> inspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId())); |
| | | String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(",")); |
| | | qualityUnqualified.setDefectivePhenomena(text + "这些指标中存在不合格");//不合格现象 |
| | | qualityUnqualified.setId(null); |
| | | qualityUnqualified.setQuantity(unqualifiedQty); |
| | | qualityUnqualified.setInspectState(0); |
| | | qualityUnqualified.setDefectivePhenomena(buildDefectivePhenomena(qualityInspect)); |
| | | qualityUnqualified.setInspectId(qualityInspect.getId()); |
| | | qualityUnqualifiedMapper.insert(qualityUnqualified); |
| | | } else { |
| | | // 原材料检验合格后,先发起“入库审批”,审批通过后再入库 |
| | | } |
| | | |
| | | if (qualifiedQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | if (Objects.equals(qualityInspect.getInspectType(), 0)) { |
| | | Long ledgerId = qualityInspect.getPurchaseLedgerId(); |
| | | PurchaseLedger purchaseLedger = ledgerId == null ? null : purchaseLedgerMapper.selectById(ledgerId); |
| | | if (purchaseLedger != null) { |
| | | submitQualifiedInboundApprove(qualityInspect); |
| | | } else { |
| | | // 直接入库 |
| | | // 手动新增的原材料检验:无采购台账,不走采购入库审批,直接入合格库存(与过程/出厂检验一致) |
| | | stockUtils.addStock( |
| | | qualityInspect.getPurchaseLedgerId() == null ? null : qualityInspect.getPurchaseLedgerId().longValue(), |
| | | null, |
| | | null, |
| | | qualityInspect.getProductModelId(), |
| | | qualityInspect.getQuantity(), |
| | | qualifiedQty, |
| | | StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), |
| | | qualityInspect.getId() |
| | | ); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect, qualifiedQty); |
| | | } |
| | | } else { |
| | | stockUtils.addStock( |
| | | qualityInspect.getPurchaseLedgerId() == null ? null : qualityInspect.getPurchaseLedgerId(), |
| | | null, |
| | | qualityInspect.getProductModelId(), |
| | | qualifiedQty, |
| | | StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), |
| | | qualityInspect.getId() |
| | | ); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect, qualifiedQty); |
| | | } |
| | | } |
| | | qualityInspect.setInspectState(1);//已提交 |
| | | |
| | | qualityInspect.setCheckResult(resolveCheckResult(qualifiedQty, unqualifiedQty)); |
| | | qualityInspect.setInspectState(1); |
| | | int updated = qualityInspectMapper.updateById(qualityInspect); |
| | | refreshPurchaseLedgerStockStatusByInspect(qualityInspect.getPurchaseLedgerId()); |
| | | return updated; |
| | | } |
| | | |
| | | private void validateAndCalculateQuantities(QualityInspect qualityInspect) { |
| | | if (qualityInspect.getQualifiedQuantity() == null || qualityInspect.getUnqualifiedQuantity() == null) { |
| | | throw new RuntimeException("请填写合格数量和不合格数量"); |
| | | } |
| | | if (qualityInspect.getQualifiedQuantity().compareTo(BigDecimal.ZERO) < 0 |
| | | || qualityInspect.getUnqualifiedQuantity().compareTo(BigDecimal.ZERO) < 0) { |
| | | throw new RuntimeException("合格数量和不合格数量不能为负数"); |
| | | } |
| | | if (qualityInspect.getQuantity() == null) { |
| | | throw new RuntimeException("质检单总数量异常"); |
| | | } |
| | | BigDecimal total = qualityInspect.getQualifiedQuantity().add(qualityInspect.getUnqualifiedQuantity()); |
| | | BigDecimal qtyScaled = qualityInspect.getQuantity().setScale(4, RoundingMode.HALF_UP); |
| | | BigDecimal sumScaled = total.setScale(4, RoundingMode.HALF_UP); |
| | | if (sumScaled.compareTo(qtyScaled) > 0) { |
| | | throw new RuntimeException("合格数量与不合格数量之和不能超过总数量"); |
| | | } |
| | | qualityInspect.setPassRate(calculatePassRate(qualityInspect.getQualifiedQuantity(), qualityInspect.getQuantity())); |
| | | } |
| | | |
| | | /** |
| | | * 新增时若未拆分合格/不合格,默认全部为待检合格数 |
| | | */ |
| | | private void ensureQualifiedSplitDefaults(QualityInspect q) { |
| | | if (q.getQuantity() == null) { |
| | | return; |
| | | } |
| | | if (q.getQualifiedQuantity() == null && q.getUnqualifiedQuantity() == null) { |
| | | q.setQualifiedQuantity(q.getQuantity()); |
| | | q.setUnqualifiedQuantity(BigDecimal.ZERO); |
| | | q.setPassRate(calculatePassRate(q.getQualifiedQuantity(), q.getQuantity())); |
| | | if (q.getCheckResult() == null || q.getCheckResult().isEmpty()) { |
| | | q.setCheckResult("合格"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private BigDecimal calculatePassRate(BigDecimal qualifiedQty, BigDecimal totalQty) { |
| | | if (totalQty == null || totalQty.compareTo(BigDecimal.ZERO) <= 0 || qualifiedQty == null) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | return qualifiedQty.multiply(BigDecimal.valueOf(100)) |
| | | .divide(totalQty, 2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | private void refreshPassRateFromQuantities(QualityInspect q) { |
| | | if (q.getQuantity() == null || q.getQualifiedQuantity() == null) { |
| | | return; |
| | | } |
| | | q.setPassRate(calculatePassRate(q.getQualifiedQuantity(), q.getQuantity())); |
| | | } |
| | | |
| | | private String resolveCheckResult(BigDecimal qualifiedQty, BigDecimal unqualifiedQty) { |
| | | if (unqualifiedQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return "合格"; |
| | | } |
| | | if (qualifiedQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return "不合格"; |
| | | } |
| | | return "部分合格"; |
| | | } |
| | | |
| | | private String buildDefectivePhenomena(QualityInspect qualityInspect) { |
| | | if (ObjectUtils.isNotEmpty(qualityInspect.getDefectivePhenomena())) { |
| | | return qualityInspect.getDefectivePhenomena(); |
| | | } |
| | | List<QualityInspectParam> inspectParams = qualityInspectParamService.list( |
| | | Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, qualityInspect.getId())); |
| | | if (inspectParams.isEmpty()) { |
| | | return "质检不合格数量:" + qualityInspect.getUnqualifiedQuantity(); |
| | | } |
| | | String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(",")); |
| | | return text + "等指标检验不合格,不合格数量:" + qualityInspect.getUnqualifiedQuantity(); |
| | | } |
| | | |
| | | private void submitQualifiedInboundApprove(QualityInspect qualityInspect) { |
| | |
| | | if (!Objects.equals(qualityInspect.getInspectType(), 0)) { |
| | | throw new RuntimeException("审批失败,仅原材料检验支持入库审批"); |
| | | } |
| | | if (!Objects.equals(qualityInspect.getInspectState(), 1) || !"合格".equals(qualityInspect.getCheckResult())) { |
| | | if (!Objects.equals(qualityInspect.getInspectState(), 1)) { |
| | | throw new RuntimeException("审批失败,当前质检单状态不允许入库"); |
| | | } |
| | | BigDecimal qualifiedQty = qualityInspect.getQualifiedQuantity(); |
| | | if (qualifiedQty == null || qualifiedQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new RuntimeException("审批失败,无合格数量可入库"); |
| | | } |
| | | stockUtils.addStock( |
| | | qualityInspect.getPurchaseLedgerId() == null ? null : qualityInspect.getPurchaseLedgerId().longValue(), |
| | | null, |
| | | qualityInspect.getProductModelId(), |
| | | qualityInspect.getQuantity(), |
| | | qualifiedQty, |
| | | StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), |
| | | qualityInspect.getId() |
| | | ); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect, qualifiedQty); |
| | | refreshPurchaseLedgerStockStatusByInspect(qualityInspect.getPurchaseLedgerId()); |
| | | qualityInspect.setApprovalStatus(3); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | |
| | | |
| | | @Override |
| | | public int updateQualityInspect(QualityInspectDto qualityInspectDto) { |
| | | QualityInspect existing = qualityInspectMapper.selectById(qualityInspectDto.getId()); |
| | | if (existing == null) { |
| | | throw new RuntimeException("质检单不存在"); |
| | | } |
| | | if (Objects.equals(existing.getInspectState(), 1)) { |
| | | throw new RuntimeException("已提交的数据不允许修改"); |
| | | } |
| | | if (ObjectUtils.isNotNull(qualityInspectDto.getQualityInspectParams())) { |
| | | qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, qualityInspectDto.getId())); |
| | | for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) { |
| | |
| | | } |
| | | QualityInspect qualityInspect = new QualityInspect(); |
| | | BeanUtils.copyProperties(qualityInspectDto, qualityInspect); |
| | | qualityInspect.setQuantity(existing.getQuantity()); |
| | | |
| | | BigDecimal qf = qualityInspect.getQualifiedQuantity() != null ? qualityInspect.getQualifiedQuantity() : existing.getQualifiedQuantity(); |
| | | BigDecimal uqf = qualityInspect.getUnqualifiedQuantity() != null ? qualityInspect.getUnqualifiedQuantity() : existing.getUnqualifiedQuantity(); |
| | | if (qf == null || uqf == null) { |
| | | BigDecimal qty = existing.getQuantity() != null ? existing.getQuantity() : BigDecimal.ZERO; |
| | | if ("不合格".equals(existing.getCheckResult())) { |
| | | qf = BigDecimal.ZERO; |
| | | uqf = qty; |
| | | } else { |
| | | qf = qty; |
| | | uqf = BigDecimal.ZERO; |
| | | } |
| | | } |
| | | qualityInspect.setQualifiedQuantity(qf); |
| | | qualityInspect.setUnqualifiedQuantity(uqf); |
| | | validateAndCalculateQuantities(qualityInspect); |
| | | qualityInspect.setCheckResult(resolveCheckResult(qf, uqf)); |
| | | return qualityInspectMapper.updateById(qualityInspect); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private void syncQualifiedInboundToPurchaseProducts(QualityInspect qualityInspect) { |
| | | private void syncQualifiedInboundToPurchaseProducts(QualityInspect qualityInspect, BigDecimal inboundQty) { |
| | | if (qualityInspect == null) { |
| | | return; |
| | | } |
| | | if (!Objects.equals(qualityInspect.getInspectType(), 0) || qualityInspect.getPurchaseLedgerId() == null) { |
| | | return; |
| | | } |
| | | if (qualityInspect.getProductModelId() == null || qualityInspect.getQuantity() == null) { |
| | | if (qualityInspect.getProductModelId() == null || inboundQty == null) { |
| | | return; |
| | | } |
| | | BigDecimal inboundQty = qualityInspect.getQuantity(); |
| | | if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return; |
| | | } |