| | |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | 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.ruoyi.common.exception.base.BaseException; |
| | | import com.deepoove.poi.XWPFTemplate; |
| | | import com.deepoove.poi.config.Configure; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.utils.HackLoopTableRenderPolicy; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.approve.pojo.ApproveProcess; |
| | | import com.ruoyi.approve.service.IApproveProcessService; |
| | | import com.ruoyi.approve.vo.ApproveProcessVO; |
| | | import com.ruoyi.common.enums.ApproveTypeEnum; |
| | | import com.ruoyi.procurementrecord.service.ProcurementRecordService; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.quality.dto.QualityInspectDto; |
| | | import com.ruoyi.quality.mapper.QualityInspectMapper; |
| | | import com.ruoyi.quality.mapper.QualityInspectParamMapper; |
| | | import com.ruoyi.quality.mapper.QualityTestStandardMapper; |
| | | import com.ruoyi.quality.mapper.QualityUnqualifiedMapper; |
| | | import com.ruoyi.quality.pojo.QualityInspect; |
| | | import com.ruoyi.quality.pojo.QualityInspectParam; |
| | | import com.ruoyi.quality.pojo.QualityTestStandard; |
| | | import com.ruoyi.quality.pojo.QualityUnqualified; |
| | | import com.ruoyi.quality.service.IQualityInspectParamService; |
| | | import com.ruoyi.quality.service.IQualityInspectService; |
| | | import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper; |
| | | import com.ruoyi.staff.mapper.StaffOnJobMapper; |
| | | import com.ruoyi.staff.pojo.StaffJoinLeaveRecord; |
| | | import com.ruoyi.staff.pojo.StaffOnJob; |
| | | import com.ruoyi.staff.service.IStaffOnJobService; |
| | | import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; |
| | | import com.ruoyi.purchase.pojo.PurchaseLedger; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | 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; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @AllArgsConstructor |
| | | @Service |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect> implements IQualityInspectService { |
| | | public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect> implements IQualityInspectService { |
| | | |
| | | private final StockUtils stockUtils; |
| | | private QualityInspectMapper qualityInspectMapper; |
| | | |
| | | private IQualityInspectParamService qualityInspectParamService; |
| | | |
| | | private QualityTestStandardMapper qualityTestStandardMapper; |
| | | |
| | | private QualityUnqualifiedMapper qualityUnqualifiedMapper; |
| | | |
| | | private SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | private PurchaseLedgerMapper purchaseLedgerMapper; |
| | | |
| | | private ProcurementRecordService procurementRecordService; |
| | | private IApproveProcessService approveProcessService; |
| | | |
| | | @Override |
| | | public int add(QualityInspect qualityInspect) { |
| | | String[] ignoreProperties = {"id"};//排除id属性 |
| | | //根据产品id查询指标维护对应新增检验参数 |
| | | List<QualityTestStandard> qualityTestStandards = qualityTestStandardMapper.selectList(Wrappers.<QualityTestStandard>lambdaQuery() |
| | | .eq(QualityTestStandard::getProductId, qualityInspect.getProductId())); |
| | | if (qualityTestStandards.size()>0){ |
| | | qualityInspectMapper.insert(qualityInspect); |
| | | List<QualityInspectParam> qualityInspectParams = qualityTestStandards.stream().map(qualityTestStandard -> { |
| | | QualityInspectParam qualityInspectParam = new QualityInspectParam(); |
| | | BeanUtils.copyProperties(qualityTestStandard, qualityInspectParam,ignoreProperties); |
| | | qualityInspectParam.setInspectId(qualityInspect.getId()); |
| | | return qualityInspectParam; |
| | | }).collect(Collectors.toList()); |
| | | qualityInspectParamService.saveBatch(qualityInspectParams); |
| | | }else{ |
| | | throw new BaseException("该产品没有维护检验指标,请检查!!!!!!!!"); |
| | | public int add(QualityInspectDto qualityInspectDto) { |
| | | 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()); |
| | | } |
| | | qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams()); |
| | | return 0; |
| | | } |
| | | |
| | | @Override |
| | | public int updateQualityInspect(QualityInspect qualityInspect) { |
| | | String[] ignoreProperties = {"id"};//排除id属性 |
| | | //先删除所有检验参数再新增 |
| | | qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery() |
| | | .eq(QualityInspectParam::getInspectId,qualityInspect.getId())); |
| | | //根据产品id查询指标维护对应新增检验参数 |
| | | List<QualityTestStandard> qualityTestStandards = qualityTestStandardMapper.selectList(Wrappers.<QualityTestStandard>lambdaQuery() |
| | | .eq(QualityTestStandard::getProductId, qualityInspect.getProductId())); |
| | | if (qualityTestStandards.size()>0){ |
| | | List<QualityInspectParam> qualityInspectParams = qualityTestStandards.stream().map(qualityTestStandard -> { |
| | | QualityInspectParam qualityInspectParam = new QualityInspectParam(); |
| | | BeanUtils.copyProperties(qualityTestStandard, qualityInspectParam,ignoreProperties); |
| | | qualityInspectParam.setInspectId(qualityInspect.getId()); |
| | | return qualityInspectParam; |
| | | }).collect(Collectors.toList()); |
| | | qualityInspectParamService.saveBatch(qualityInspectParams); |
| | | }else{ |
| | | throw new BaseException("该产品没有维护检验指标,请检查!!!!!!!!"); |
| | | public QualityInspectDto getDetailById(Integer id) { |
| | | QualityInspect qualityInspect = qualityInspectMapper.selectById(id); |
| | | List<QualityInspectParam> qualityInspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id)); |
| | | QualityInspectDto qualityInspectDto = new QualityInspectDto(); |
| | | BeanUtils.copyProperties(qualityInspect, qualityInspectDto); |
| | | qualityInspectDto.setQualityInspectParams(qualityInspectParams); |
| | | return qualityInspectDto; |
| | | } |
| | | |
| | | //提交 |
| | | @Override |
| | | public int submit(QualityInspect inspect) { |
| | | QualityInspect qualityInspect = qualityInspectMapper.selectById(inspect.getId()); |
| | | if (qualityInspect == null) { |
| | | throw new RuntimeException("质检单不存在"); |
| | | } |
| | | return qualityInspectMapper.updateById(qualityInspect); |
| | | 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.setId(null); |
| | | qualityUnqualified.setQuantity(unqualifiedQty); |
| | | qualityUnqualified.setInspectState(0); |
| | | qualityUnqualified.setDefectivePhenomena(buildDefectivePhenomena(qualityInspect)); |
| | | qualityUnqualified.setInspectId(qualityInspect.getId()); |
| | | qualityUnqualifiedMapper.insert(qualityUnqualified); |
| | | } |
| | | |
| | | 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( |
| | | null, |
| | | null, |
| | | qualityInspect.getProductModelId(), |
| | | qualifiedQty, |
| | | StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), |
| | | qualityInspect.getId() |
| | | ); |
| | | 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.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) { |
| | | PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(qualityInspect.getPurchaseLedgerId()); |
| | | if (purchaseLedger == null) { |
| | | throw new RuntimeException("提交失败,采购台账不存在"); |
| | | } |
| | | String approveUserIds = ObjectUtils.isNotEmpty(qualityInspect.getApproveUserIds()) |
| | | ? qualityInspect.getApproveUserIds() |
| | | : purchaseLedger.getApproveUserIds(); |
| | | if (ObjectUtils.isEmpty(approveUserIds)) { |
| | | throw new RuntimeException("提交失败,请先维护质检单审批人(或采购台账审批人)"); |
| | | } |
| | | |
| | | String approveReason = "原材料质检入库审批:" + purchaseLedger.getPurchaseContractNumber(); |
| | | String approveRemark = "qualityQualifiedInbound:" + qualityInspect.getId() + ":" + purchaseLedger.getId(); |
| | | ApproveProcess exist = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>() |
| | | .eq(ApproveProcess::getApproveType, ApproveTypeEnum.STOCK_IN.getCode()) |
| | | .eq(ApproveProcess::getApproveRemark, approveRemark) |
| | | .eq(ApproveProcess::getApproveDelete, 0) |
| | | .orderByDesc(ApproveProcess::getCreateTime) |
| | | .last("limit 1")); |
| | | if (exist != null && !Objects.equals(exist.getApproveStatus(), 3)) { |
| | | throw new RuntimeException("提交失败,该质检单已发起入库审批,审批完成前不能重复提交"); |
| | | } |
| | | |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | approveProcessVO.setApproveType(ApproveTypeEnum.STOCK_IN.getCode()); |
| | | approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |
| | | approveProcessVO.setApproveReason(approveReason); |
| | | approveProcessVO.setApproveRemark(approveRemark); |
| | | approveProcessVO.setApproveUserIds(approveUserIds); |
| | | approveProcessVO.setApproveUser(loginUser.getUserId()); |
| | | approveProcessVO.setApproveTime(java.time.LocalDate.now().toString()); |
| | | try { |
| | | approveProcessService.addApprove(approveProcessVO); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("提交失败,入库审批发起异常:" + e.getMessage()); |
| | | } |
| | | qualityInspect.setApprovalStatus(2); |
| | | qualityInspect.setApproveUserIds(approveUserIds); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<QualityInspect> qualityInspectListPage(Page page, QualityInspect qualityInspect) { |
| | | return qualityInspectMapper.qualityInspectListPage(page,qualityInspect); |
| | | public void executeQualifiedInboundApproval(Integer inspectId) { |
| | | if (inspectId == null) { |
| | | throw new RuntimeException("审批失败,质检单ID不能为空"); |
| | | } |
| | | QualityInspect qualityInspect = qualityInspectMapper.selectById(inspectId); |
| | | if (qualityInspect == null) { |
| | | throw new RuntimeException("审批失败,质检单不存在"); |
| | | } |
| | | if (!Objects.equals(qualityInspect.getInspectType(), 0)) { |
| | | throw new RuntimeException("审批失败,仅原材料检验支持入库审批"); |
| | | } |
| | | 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(), |
| | | qualifiedQty, |
| | | StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), |
| | | qualityInspect.getId() |
| | | ); |
| | | syncQualifiedInboundToPurchaseProducts(qualityInspect, qualifiedQty); |
| | | refreshPurchaseLedgerStockStatusByInspect(qualityInspect.getPurchaseLedgerId()); |
| | | qualityInspect.setApprovalStatus(3); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | | } |
| | | |
| | | @Override |
| | | public void markQualifiedInboundApprovalStatus(Integer inspectId, Integer approvalStatus) { |
| | | if (inspectId == null || approvalStatus == null) { |
| | | return; |
| | | } |
| | | QualityInspect qualityInspect = qualityInspectMapper.selectById(inspectId); |
| | | if (qualityInspect == null) { |
| | | return; |
| | | } |
| | | qualityInspect.setApprovalStatus(approvalStatus); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | | } |
| | | |
| | | /*生成检验报告*/ |
| | | @Override |
| | | public void down(HttpServletResponse response, QualityInspect qualityInspect) { |
| | | QualityInspect inspect = qualityInspectMapper.selectById(qualityInspect.getId()); |
| | | String inspectType = ""; |
| | | switch (inspect.getInspectType()) { |
| | | case 0: |
| | | inspectType = "原材料检验"; |
| | | break; |
| | | case 1: |
| | | inspectType = "过程检验"; |
| | | break; |
| | | case 2: |
| | | inspectType = "出厂检验"; |
| | | break; |
| | | } |
| | | List<QualityInspectParam> paramList = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId())); |
| | | int index = 1; |
| | | for (QualityInspectParam detail : paramList) { |
| | | detail.setIndex(index); |
| | | index++; |
| | | } |
| | | InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx"); |
| | | Configure configure = Configure.builder() |
| | | .bind("paramList", new HackLoopTableRenderPolicy()) |
| | | .build(); |
| | | String finalInspectType = inspectType; |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( |
| | | new HashMap<String, Object>() {{ |
| | | put("inspect", inspect); |
| | | put("inspectType", finalInspectType); |
| | | put("paramList", paramList); |
| | | }}); |
| | | |
| | | try { |
| | | response.setContentType("application/msword"); |
| | | String fileName = URLEncoder.encode( |
| | | "检验报告", "UTF-8"); |
| | | response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); |
| | | response.setHeader("Content-disposition", |
| | | "attachment;filename=" + fileName + ".docx"); |
| | | OutputStream os = response.getOutputStream(); |
| | | template.write(os); |
| | | os.flush(); |
| | | os.close(); |
| | | inputStream.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException("导出失败"); |
| | | } |
| | | } |
| | | |
| | | @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()) { |
| | | qualityInspectParam.setInspectId(qualityInspectDto.getId()); |
| | | } |
| | | qualityInspectParamService.saveBatch(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); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<QualityInspect> qualityInspectListPage(Page<?> page, QualityInspect qualityInspect) { |
| | | return qualityInspectMapper.qualityInspectListPage(page, qualityInspect); |
| | | } |
| | | |
| | | @Override |
| | | public void qualityInspectExport(HttpServletResponse response, QualityInspect qualityInspect) { |
| | | List<QualityInspect> qualityInspects =qualityInspectMapper.qualityInspectExport(qualityInspect); |
| | | List<QualityInspect> qualityInspects = qualityInspectMapper.qualityInspectExport(qualityInspect); |
| | | ExcelUtil<QualityInspect> util = new ExcelUtil<QualityInspect>(QualityInspect.class); |
| | | switch (qualityInspect.getInspectType()){ |
| | | switch (qualityInspect.getInspectType()) { |
| | | case 0: |
| | | util.exportExcel(response, qualityInspects, "原材料检验导出"); |
| | | break; |
| | | case 1: |
| | | case 1: |
| | | util.exportExcel(response, qualityInspects, "过程检验导出"); |
| | | break; |
| | | case 2: |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | private void refreshPurchaseLedgerStockStatusByInspect(Long purchaseLedgerId) { |
| | | if (purchaseLedgerId == null) { |
| | | return; |
| | | } |
| | | List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>() |
| | | .eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedgerId) |
| | | .eq(SalesLedgerProduct::getType, 2)); |
| | | if (products == null || products.isEmpty()) { |
| | | return; |
| | | } |
| | | boolean allInbound = true; |
| | | boolean anyInbound = false; |
| | | for (SalesLedgerProduct product : products) { |
| | | BigDecimal orderQty = product.getQuantity() == null ? BigDecimal.ZERO : product.getQuantity(); |
| | | BigDecimal totalInboundQty = product.getStockedQuantity() == null ? BigDecimal.ZERO : product.getStockedQuantity(); |
| | | if (totalInboundQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | anyInbound = true; |
| | | } |
| | | if (totalInboundQty.compareTo(orderQty) < 0) { |
| | | allInbound = false; |
| | | } |
| | | } |
| | | PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(purchaseLedgerId); |
| | | if (purchaseLedger == null) { |
| | | return; |
| | | } |
| | | int targetStockStatus = allInbound ? 2 : (anyInbound ? 1 : 0); |
| | | if (!Objects.equals(purchaseLedger.getStockStatus(), targetStockStatus)) { |
| | | purchaseLedger.setStockStatus(targetStockStatus); |
| | | purchaseLedgerMapper.updateById(purchaseLedger); |
| | | } |
| | | } |
| | | |
| | | 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 || inboundQty == null) { |
| | | return; |
| | | } |
| | | if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return; |
| | | } |
| | | |
| | | List<SalesLedgerProduct> lines = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>() |
| | | .eq(SalesLedgerProduct::getSalesLedgerId, qualityInspect.getPurchaseLedgerId()) |
| | | .eq(SalesLedgerProduct::getType, 2) |
| | | .eq(SalesLedgerProduct::getProductModelId, qualityInspect.getProductModelId()) |
| | | .eq(SalesLedgerProduct::getIsChecked, true) |
| | | .orderByAsc(SalesLedgerProduct::getId)); |
| | | if (lines == null || lines.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | BigDecimal remaining = inboundQty; |
| | | SalesLedgerProduct fallbackLine = null; |
| | | for (SalesLedgerProduct line : lines) { |
| | | if (remaining.compareTo(BigDecimal.ZERO) <= 0) { |
| | | break; |
| | | } |
| | | BigDecimal orderQty = line.getQuantity() == null ? BigDecimal.ZERO : line.getQuantity(); |
| | | BigDecimal stocked = line.getStockedQuantity() == null ? BigDecimal.ZERO : line.getStockedQuantity(); |
| | | BigDecimal canFill = orderQty.subtract(stocked); |
| | | if (canFill.compareTo(BigDecimal.ZERO) <= 0) { |
| | | fallbackLine = line; |
| | | continue; |
| | | } |
| | | BigDecimal add = canFill.min(remaining); |
| | | BigDecimal newStocked = stocked.add(add); |
| | | int status; |
| | | if (newStocked.compareTo(BigDecimal.ZERO) <= 0) { |
| | | status = 0; |
| | | } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) { |
| | | status = 1; |
| | | } else { |
| | | status = 2; |
| | | } |
| | | line.setStockedQuantity(newStocked); |
| | | line.setProductStockStatus(status); |
| | | line.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(line); |
| | | remaining = remaining.subtract(add); |
| | | fallbackLine = line; |
| | | } |
| | | |
| | | // 允许多入库:若仍有剩余,累计到最后一行,确保 remaining_shipped_quantity 能同步增长 |
| | | if (remaining.compareTo(BigDecimal.ZERO) > 0 && fallbackLine != null) { |
| | | BigDecimal orderQty = fallbackLine.getQuantity() == null ? BigDecimal.ZERO : fallbackLine.getQuantity(); |
| | | BigDecimal stocked = fallbackLine.getStockedQuantity() == null ? BigDecimal.ZERO : fallbackLine.getStockedQuantity(); |
| | | BigDecimal newStocked = stocked.add(remaining); |
| | | int status; |
| | | if (newStocked.compareTo(BigDecimal.ZERO) <= 0) { |
| | | status = 0; |
| | | } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) { |
| | | status = 1; |
| | | } else { |
| | | status = 2; |
| | | } |
| | | fallbackLine.setStockedQuantity(newStocked); |
| | | fallbackLine.setProductStockStatus(status); |
| | | fallbackLine.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(fallbackLine); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |