| | |
| | | @Override |
| | | public ErpPurchaseRequestImportRespVO importPurchaseRequestList(List<ErpPurchaseRequestImportExcelVO> importRequests, |
| | | ErpPurchaseRequestImportReqVO importReqVO) { |
| | | if (Boolean.TRUE.equals(importReqVO.getUpdateSupport())) throw exception(PURCHASE_REQUEST_IMPORT_INVALID, "仅支持新增,不支持覆盖"); |
| | | if (CollUtil.isEmpty(importRequests)) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_LIST_IS_EMPTY); |
| | | } |
| | |
| | | if (isBlankRow(row)) { |
| | | continue; |
| | | } |
| | | // 1.2 物料编码为空:业务上无法定位物料,跳过并明确告知用户 |
| | | if (StrUtil.isBlank(row.getProductCode())) { |
| | | respVO.getSkippedRows().put(rowLabel, "物料编码为空,该行未导入"); |
| | | continue; |
| | | } |
| | | validRows.add(new ImportRow(excelRowNo, row)); |
| | | } |
| | | respVO.setTotalRows(validRows.size() + respVO.getSkippedRows().size()); |
| | |
| | | Map<String, Integer> groupIndexMap = new LinkedHashMap<>(); |
| | | for (ImportRow row : validRows) { |
| | | String no = row.data.getNo(); |
| | | String groupKey = StrUtil.isNotBlank(no) ? no : ("__row_" + row.excelRowNo); |
| | | if (StrUtil.isBlank(no)) { groups.add(new ArrayList<>(Collections.singletonList(row))); continue; } |
| | | String groupKey = no.trim(); |
| | | Integer index = groupIndexMap.get(groupKey); |
| | | if (index == null) { |
| | | index = groups.size(); |
| | |
| | | String groupKey = StrUtil.isNotBlank(firstRow.data.getNo()) |
| | | ? firstRow.data.getNo() : "第" + firstRow.excelRowNo + "行"; |
| | | try { |
| | | ErpPurchaseRequestSaveReqVO createReqVO = buildPurchaseRequestImportSaveReqVO( |
| | | convertList(group, ImportRow::getData)); |
| | | Long requestId = createPurchaseRequest(createReqVO); |
| | | Long requestId = cn.hutool.extra.spring.SpringUtil.getBean(ErpPurchaseRequestServiceImpl.class) |
| | | .createImportedPurchaseRequest(convertList(group, ImportRow::getData)); |
| | | respVO.getCreatePurchaseRequestNos().add(purchaseRequestMapper.selectById(requestId).getNo()); |
| | | respVO.setSuccessRows(respVO.getSuccessRows() == null |
| | | ? group.size() : respVO.getSuccessRows() + group.size()); |
| | |
| | | // 记录为失败并继续,保证其它能导的行正常入库 |
| | | log.error("[importPurchaseRequestList] 导入行({}) 发生非业务异常", groupKey, ex); |
| | | respVO.getFailurePurchaseRequestNos().put(groupKey, |
| | | "导入失败:" + (ex instanceof NullPointerException ? "数据解析异常,请检查物料/单位编码" : ex.getMessage())); |
| | | "导入失败,请检查基础资料和申请明细"); |
| | | } |
| | | } |
| | | return respVO; |
| | |
| | | * 判断一行是否完全空白(所有业务列都没有值) |
| | | */ |
| | | private boolean isBlankRow(ErpPurchaseRequestImportExcelVO row) { |
| | | return StrUtil.isBlank(row.getNo()) |
| | | return row == null || StrUtil.isBlank(row.getNo()) |
| | | && StrUtil.isBlank(row.getProductCode()) |
| | | && StrUtil.isBlank(row.getProductUnitCode()) |
| | | && row.getRequestTime() == null |
| | | && row.getCount() == null |
| | | && row.getProductPrice() == null |
| | | && row.getDiscountPercent() == null && row.getDepositPrice() == null && row.getTaxPercent() == null |
| | | && row.getDemandTime() == null && row.getQcCheckFlag() == null |
| | | && StrUtil.isBlank(row.getSupplierName()) |
| | | && StrUtil.isBlank(row.getRequestReason()) |
| | | && StrUtil.isBlank(row.getRemark()) |
| | |
| | | /** |
| | | * 将同一张采购申请的多行明细转换成创建 Request VO |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createImportedPurchaseRequest(List<ErpPurchaseRequestImportExcelVO> group) { |
| | | return createPurchaseRequest(buildPurchaseRequestImportSaveReqVO(group)); |
| | | } |
| | | private ErpPurchaseRequestSaveReqVO buildPurchaseRequestImportSaveReqVO(List<ErpPurchaseRequestImportExcelVO> group) { |
| | | ErpPurchaseRequestImportExcelVO first = group.get(0); |
| | | // 1. 校验申请时间 |
| | | if (first.getRequestTime() == null) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_REQUEST_TIME_REQUIRED); |
| | | } |
| | | if (first.getDiscountPercent() != null && (first.getDiscountPercent().signum() < 0 || first.getDiscountPercent().compareTo(new BigDecimal("100")) > 0) |
| | | || first.getDepositPrice() != null && first.getDepositPrice().signum() < 0) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_INVALID, "优惠率须在 0 至 100 之间,定金不能为负数"); |
| | | } |
| | | for (ErpPurchaseRequestImportExcelVO row : group) { |
| | | if (row.getRequestTime() != null && !row.getRequestTime().equals(first.getRequestTime()) |
| | | || StrUtil.isNotBlank(row.getSupplierName()) && !StrUtil.equals(first.getSupplierName(), row.getSupplierName()) |
| | | || StrUtil.isNotBlank(row.getRequestReason()) && !StrUtil.equals(first.getRequestReason(), row.getRequestReason()) |
| | | || row.getDiscountPercent() != null && (first.getDiscountPercent() == null || row.getDiscountPercent().compareTo(first.getDiscountPercent()) != 0) |
| | | || row.getDepositPrice() != null && (first.getDepositPrice() == null || row.getDepositPrice().compareTo(first.getDepositPrice()) != 0) |
| | | || StrUtil.isNotBlank(row.getRemark()) && !StrUtil.equals(first.getRemark(), row.getRemark())) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_INVALID, "同一申请单的主表信息不一致"); |
| | | } |
| | | if (StrUtil.isBlank(row.getProductCode()) || StrUtil.isBlank(row.getProductUnitCode()) || row.getCount() == null || row.getCount().signum() <= 0 |
| | | || row.getProductPrice() == null || row.getProductPrice().signum() < 0 |
| | | || row.getTaxPercent() != null && (row.getTaxPercent().signum() < 0 || row.getTaxPercent().compareTo(new BigDecimal("100")) > 0)) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_INVALID, "每行须填写物料、单位、正数数量、非负单价;税率须在 0 至 100 之间"); |
| | | } |
| | | } |
| | | // 2. 解析供应商(可选) |
| | | Long supplierId = null; |
| | |
| | | // 3. 组装明细 |
| | | List<ErpPurchaseRequestSaveReqVO.Item> items = new ArrayList<>(); |
| | | for (ErpPurchaseRequestImportExcelVO row : group) { |
| | | MdmItemRespDTO product = mdmItemApi.getItemByCode(row.getProductCode()).getCheckedData(); |
| | | MdmItemRespDTO product = mdmItemApi.getItemByCode(row.getProductCode().trim()).getCheckedData(); |
| | | if (product == null) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_PRODUCT_NOT_EXISTS, row.getProductCode()); |
| | | } |
| | | MdmUnitMeasureRespDTO unit = mdmUnitMeasureApi.getUnitMeasureByCode(row.getProductUnitCode()).getCheckedData(); |
| | | MdmUnitMeasureRespDTO unit = mdmUnitMeasureApi.getUnitMeasureByCode(row.getProductUnitCode().trim()).getCheckedData(); |
| | | if (unit == null) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_UNIT_NOT_EXISTS, row.getProductUnitCode()); |
| | | } |
| | | if (product.getStatus() != null && product.getStatus() != 0 || unit.getStatus() != null && unit.getStatus() != 0) { |
| | | throw exception(PURCHASE_REQUEST_IMPORT_INVALID, "物料或计量单位已停用"); |
| | | } |
| | | ErpPurchaseRequestSaveReqVO.Item item = new ErpPurchaseRequestSaveReqVO.Item() |
| | | .setProductId(product.getId()) |
| | | .setProductUnitId(unit.getId()) |