| | |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.PlatformTransactionManager; |
| | | import org.springframework.transaction.TransactionStatus; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.support.DefaultTransactionDefinition; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.InputStream; |
| | |
| | | private final QualityInspectParamMapper qualityInspectParamMapper; |
| | | private final ApproveProcessServiceImpl approveProcessService; |
| | | private final ProcurementRecordMapper procurementRecordStorageMapper; |
| | | private final PlatformTransactionManager transactionManager; |
| | | private final FileUtil fileUtil; |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult importData(MultipartFile file) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | int successCount = 0; |
| | | int skipCount = 0; |
| | | int failCount = 0; |
| | | List<String> failList = new ArrayList<>(); |
| | | List<String> skipList = new ArrayList<>(); |
| | | |
| | | try { |
| | | InputStream inputStream = file.getInputStream(); |
| | | ExcelUtil<PurchaseLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(PurchaseLedgerImportDto.class); |
| | | Map<String, List<PurchaseLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("采购台账数据", "采购产品数据"), inputStream, 0); |
| | | Map<String, List<PurchaseLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet( |
| | | Arrays.asList("采购台账数据", "采购产品数据"), inputStream, 0); |
| | | if (CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("采购表格为空!"); |
| | | // 业务层合并 |
| | | List<PurchaseLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("采购台账数据"); |
| | | if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("采购台账数据为空!"); |
| | | List<PurchaseLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("采购产品数据"); |
| | | if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("采购产品数据为空!"); |
| | | // 供应商数据 |
| | | List<SupplierManage> customers = supplierManageMapper.selectList(new LambdaQueryWrapper<SupplierManage>().in(SupplierManage::getSupplierName, |
| | | salesLedgerImportDtoList.stream().map(PurchaseLedgerImportDto::getSupplierName).collect(Collectors.toList()))); |
| | | List<Map<String,Object>> list = productModelMapper.getProductAndModelList(); |
| | | // 录入人数据 |
| | | List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName, |
| | | salesLedgerImportDtoList.stream().map(PurchaseLedgerImportDto::getRecorderName).collect(Collectors.toList()))); |
| | | for (PurchaseLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) { |
| | | PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>() |
| | | .eq(PurchaseLedger::getPurchaseContractNumber, salesLedgerImportDto.getPurchaseContractNumber()) |
| | | |
| | | List<PurchaseLedgerImportDto> ledgerList = stringListMap.get("采购台账数据"); |
| | | if (CollectionUtils.isEmpty(ledgerList)) return AjaxResult.error("采购台账数据为空!"); |
| | | List<PurchaseLedgerImportDto> productList = stringListMap.get("采购产品数据"); |
| | | if (CollectionUtils.isEmpty(productList)) return AjaxResult.error("采购产品数据为空!"); |
| | | |
| | | // 预加载供应商、产品、录入人数据(全量,避免每条都查) |
| | | List<SupplierManage> customers = supplierManageMapper.selectList(Wrappers.lambdaQuery()); |
| | | List<Map<String, Object>> productModelList = productModelMapper.getProductAndModelList(); |
| | | List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.lambdaQuery()); |
| | | |
| | | int rowNum = 0; |
| | | for (PurchaseLedgerImportDto dto : ledgerList) { |
| | | rowNum++; |
| | | String contractNo = dto.getPurchaseContractNumber(); |
| | | String rowLabel = "第" + rowNum + "行[" + (contractNo != null ? contractNo : "无采购单号") + "]"; |
| | | |
| | | // 已存在则跳过 |
| | | PurchaseLedger exist = purchaseLedgerMapper.selectOne(Wrappers.<PurchaseLedger>lambdaQuery() |
| | | .eq(PurchaseLedger::getPurchaseContractNumber, contractNo) |
| | | .last("limit 1")); |
| | | if(purchaseLedger != null){ |
| | | if (exist != null) { |
| | | skipCount++; |
| | | skipList.add(rowLabel + " 采购单号已存在,跳过"); |
| | | continue; |
| | | } |
| | | PurchaseLedger salesLedger = new PurchaseLedger(); |
| | | BeanUtils.copyProperties(salesLedgerImportDto, salesLedger); |
| | | // 通过供应商名称查询ID |
| | | salesLedger.setSupplierId(customers.stream() |
| | | .filter(customer -> customer.getSupplierName().equals(salesLedger.getSupplierName())) |
| | | .findFirst() |
| | | .map(SupplierManage::getId) |
| | | .orElse(null)); |
| | | Long aLong = sysUsers.stream() |
| | | .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getRecorderName())) |
| | | .findFirst() |
| | | .map(SysUser::getUserId) |
| | | .orElse(null); |
| | | if (aLong == null) |
| | | throw new RuntimeException("录入人:" + salesLedger.getRecorderName() + ",无对应用户!"); |
| | | salesLedger.setRecorderId(aLong); |
| | | // 采购产品数据绑定,通过采购单号获取对应采购产品数据 |
| | | List<PurchaseLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream() |
| | | .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getPurchaseContractNumber().equals(salesLedger.getPurchaseContractNumber())) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(salesLedgerProductImportDtos)) |
| | | throw new RuntimeException("采购单号:" + salesLedgerImportDto.getPurchaseContractNumber() + ",无对应产品数据!"); |
| | | salesLedger.setContractAmount(salesLedgerProductImportDtos.stream() |
| | | .map(PurchaseLedgerProductImportDto::getTaxInclusiveTotalPrice) |
| | | .reduce(BigDecimal.ZERO,BigDecimal::add)); |
| | | // 通过销售单号绑定销售 |
| | | SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>() |
| | | .eq(SalesLedger::getSalesContractNo, salesLedger.getSalesContractNo()) |
| | | .last("LIMIT 1")); |
| | | if(salesLedger1 != null){ |
| | | salesLedger.setSalesLedgerId(salesLedger1.getId()); |
| | | } |
| | | if (StringUtils.hasText(salesLedger.getApproveUserIds())) { |
| | | // 采购审核:历史导入模板传审批人姓名时,继续兼容转换为用户ID。 |
| | | String[] split = salesLedger.getApproveUserIds().split(","); |
| | | List<Long> ids = new ArrayList<>(); |
| | | for (int i = 0; i < split.length; i++) { |
| | | SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getNickName, split[i]) |
| | | .last("LIMIT 1")); |
| | | if (sysUser != null) { |
| | | ids.add(sysUser.getUserId()); |
| | | } |
| | | } |
| | | // 将集合转为字符串,隔开 |
| | | String collect = ids.stream().map(Object::toString).collect(Collectors.joining(",")); |
| | | salesLedger.setApproveUserIds(collect); |
| | | } |
| | | purchaseLedgerMapper.insert(salesLedger); |
| | | |
| | | for (PurchaseLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) { |
| | | SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct(); |
| | | BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct); |
| | | salesLedgerProduct.setSalesLedgerId(salesLedger.getId()); |
| | | salesLedgerProduct.setType(2); |
| | | AmountUtils.normalizeSalesLedgerProduct(salesLedgerProduct); |
| | | // 计算不含税总价 |
| | | salesLedgerProduct.setTaxExclusiveTotalPrice( |
| | | AmountUtils.calcTaxExclusiveTotalPrice( |
| | | salesLedgerProduct.getTaxInclusiveTotalPrice(), |
| | | salesLedgerProduct.getTaxRate() |
| | | ) |
| | | ); |
| | | list.stream() |
| | | .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel())) |
| | | .findFirst() |
| | | .ifPresent(map -> { |
| | | salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString())); |
| | | salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString())); |
| | | }); |
| | | salesLedgerProduct.setRegister(loginUser.getNickName()); |
| | | salesLedgerProduct.setRegisterDate(LocalDateTime.now()); |
| | | salesLedgerProduct.setApproveStatus(0); |
| | | // 是否质检判断 |
| | | salesLedgerProduct.setIsChecked(salesLedgerProductImportDto.getIsChecked() == 1); |
| | | if(salesLedgerProductImportDto.getIsChecked() == 1){ |
| | | addQualityInspect(salesLedger, salesLedgerProduct); |
| | | } |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | // 每条一个独立事务,失败只回滚当前条 |
| | | TransactionStatus txStatus = transactionManager.getTransaction(new DefaultTransactionDefinition()); |
| | | try { |
| | | importOneLedger(dto, productList, customers, productModelList, sysUsers, loginUser); |
| | | transactionManager.commit(txStatus); |
| | | successCount++; |
| | | } catch (Exception e) { |
| | | transactionManager.rollback(txStatus); |
| | | failCount++; |
| | | failList.add(rowLabel + " " + e.getMessage()); |
| | | log.error("导入失败 - {}", rowLabel, e); |
| | | } |
| | | // 采购审核 |
| | | addApproveByPurchase(loginUser,salesLedger); |
| | | } |
| | | |
| | | return AjaxResult.success("导入成功"); |
| | | // 构建返回结果 |
| | | StringBuilder msg = new StringBuilder(); |
| | | msg.append("导入完成:成功").append(successCount).append("条"); |
| | | if (skipCount > 0) msg.append(",跳过").append(skipCount).append("条"); |
| | | if (failCount > 0) msg.append(",失败").append(failCount).append("条"); |
| | | |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("successCount", successCount); |
| | | result.put("skipCount", skipCount); |
| | | result.put("failCount", failCount); |
| | | result.put("failList", failList); |
| | | result.put("skipList", skipList); |
| | | result.put("msg", msg.toString()); |
| | | |
| | | AjaxResult ajaxResult = AjaxResult.success(msg.toString()); |
| | | ajaxResult.putAll(result); |
| | | return ajaxResult; |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("采购台账导入异常", e); |
| | | return AjaxResult.error("导入异常:" + e.getMessage()); |
| | | } |
| | | return AjaxResult.success("导入失败"); |
| | | } |
| | | |
| | | /** |
| | | * 导入单条采购台账(含产品明细+审批流程) |
| | | */ |
| | | private void importOneLedger(PurchaseLedgerImportDto dto, |
| | | List<PurchaseLedgerImportDto> productList, |
| | | List<SupplierManage> customers, |
| | | List<Map<String, Object>> productModelList, |
| | | List<SysUser> sysUsers, |
| | | LoginUser loginUser) throws Exception { |
| | | PurchaseLedger ledger = new PurchaseLedger(); |
| | | BeanUtils.copyProperties(dto, ledger); |
| | | |
| | | // 供应商 |
| | | ledger.setSupplierId(customers.stream() |
| | | .filter(c -> c.getSupplierName() != null && c.getSupplierName().equals(dto.getSupplierName())) |
| | | .findFirst() |
| | | .map(SupplierManage::getId) |
| | | .orElse(null)); |
| | | if (ledger.getSupplierId() == null) { |
| | | throw new RuntimeException("供应商不存在:" + dto.getSupplierName()); |
| | | } |
| | | |
| | | // 录入人 |
| | | Long recorderId = sysUsers.stream() |
| | | .filter(u -> u.getNickName() != null && u.getNickName().equals(dto.getRecorderName())) |
| | | .findFirst() |
| | | .map(SysUser::getUserId) |
| | | .orElse(null); |
| | | if (recorderId == null) { |
| | | throw new RuntimeException("录入人不存在:" + dto.getRecorderName()); |
| | | } |
| | | ledger.setRecorderId(recorderId); |
| | | |
| | | // 产品明细 |
| | | List<PurchaseLedgerProductImportDto> productDtos = productList.stream() |
| | | .filter(p -> p.getPurchaseContractNumber() != null |
| | | && p.getPurchaseContractNumber().equals(dto.getPurchaseContractNumber())) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(productDtos)) { |
| | | throw new RuntimeException("无对应产品数据"); |
| | | } |
| | | ledger.setContractAmount(productDtos.stream() |
| | | .map(PurchaseLedgerProductImportDto::getTaxInclusiveTotalPrice) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add)); |
| | | |
| | | // 关联销售单号 |
| | | SalesLedger salesLedger = salesLedgerMapper.selectOne(Wrappers.<SalesLedger>lambdaQuery() |
| | | .eq(SalesLedger::getSalesContractNo, dto.getSalesContractNo()) |
| | | .last("LIMIT 1")); |
| | | if (salesLedger != null) { |
| | | ledger.setSalesLedgerId(salesLedger.getId()); |
| | | } |
| | | |
| | | // 审核人(中文逗号分隔的姓名转ID) |
| | | if (StringUtils.hasText(ledger.getApproveUserIds())) { |
| | | String[] split = ledger.getApproveUserIds().split(","); |
| | | List<Long> ids = new ArrayList<>(); |
| | | for (String name : split) { |
| | | String trimmed = name.trim(); |
| | | if (trimmed.isEmpty()) continue; |
| | | sysUsers.stream() |
| | | .filter(u -> trimmed.equals(u.getNickName())) |
| | | .findFirst() |
| | | .ifPresent(u -> ids.add(u.getUserId())); |
| | | } |
| | | ledger.setApproveUserIds(ids.stream().map(String::valueOf).collect(Collectors.joining(","))); |
| | | } |
| | | |
| | | purchaseLedgerMapper.insert(ledger); |
| | | |
| | | // 产品明细入库 |
| | | for (PurchaseLedgerProductImportDto prodDto : productDtos) { |
| | | SalesLedgerProduct product = new SalesLedgerProduct(); |
| | | BeanUtils.copyProperties(prodDto, product); |
| | | product.setSalesLedgerId(ledger.getId()); |
| | | product.setType(2); |
| | | AmountUtils.normalizeSalesLedgerProduct(product); |
| | | product.setTaxExclusiveTotalPrice( |
| | | AmountUtils.calcTaxExclusiveTotalPrice( |
| | | product.getTaxInclusiveTotalPrice(), |
| | | product.getTaxRate() |
| | | ) |
| | | ); |
| | | productModelList.stream() |
| | | .filter(map -> prodDto.getProductCategory() != null |
| | | && prodDto.getSpecificationModel() != null |
| | | && prodDto.getProductCategory().equals(map.get("productName")) |
| | | && prodDto.getSpecificationModel().equals(map.get("model"))) |
| | | .findFirst() |
| | | .ifPresent(map -> { |
| | | product.setProductModelId(Long.parseLong(map.get("modelId").toString())); |
| | | product.setProductId(Long.parseLong(map.get("id").toString())); |
| | | }); |
| | | product.setRegister(loginUser.getNickName()); |
| | | product.setRegisterDate(LocalDateTime.now()); |
| | | product.setApproveStatus(0); |
| | | product.setIsChecked(prodDto.getIsChecked() != null && prodDto.getIsChecked() == 1); |
| | | if (prodDto.getIsChecked() != null && prodDto.getIsChecked() == 1) { |
| | | addQualityInspect(ledger, product); |
| | | } |
| | | salesLedgerProductMapper.insert(product); |
| | | } |
| | | |
| | | // 采购审核 |
| | | addApproveByPurchase(loginUser, ledger); |
| | | } |
| | | |
| | | @Override |