package cn.iocoder.yudao.module.crm.service.quotation;
|
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.module.crm.controller.admin.quotation.vo.CrmSaleQuotationImportExcelVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.quotation.vo.CrmSaleQuotationSaveReqVO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationDO;
|
import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
|
import cn.iocoder.yudao.module.crm.dal.mysql.quotation.CrmSaleQuotationMapper;
|
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
|
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import java.math.BigDecimal;
|
import java.util.*;
|
|
@Service
|
public class CrmSaleQuotationImportService {
|
@Resource private CrmCustomerMapper customerMapper;
|
@Resource private CrmSaleQuotationMapper quotationMapper;
|
@Resource private MdmItemApi itemApi;
|
@Resource private CrmSaleQuotationService quotationService;
|
|
public Map<String, Object> importRows(List<CrmSaleQuotationImportExcelVO> rows, Long userId) {
|
Map<String, List<CrmSaleQuotationImportExcelVO>> groups = new LinkedHashMap<>();
|
int rowNumber = 1;
|
for (CrmSaleQuotationImportExcelVO row : rows) {
|
rowNumber++;
|
if (row == null) continue;
|
if (StrUtil.isBlank(row.getName()) && StrUtil.isBlank(row.getCustomerName()) && StrUtil.isBlank(row.getItemCode())) continue;
|
if (StrUtil.isBlank(row.getName()) || StrUtil.isBlank(row.getCustomerName())) {
|
throw new IllegalArgumentException("第" + rowNumber + "行报价名称和客户名称不能为空");
|
}
|
String key = row.getCustomerName().trim() + " / " + row.getName().trim();
|
groups.computeIfAbsent(key, ignored -> new ArrayList<>()).add(row);
|
}
|
if (groups.isEmpty()) throw new IllegalArgumentException("导入数据不能为空");
|
List<String> created = new ArrayList<>();
|
Map<String, String> failures = new LinkedHashMap<>();
|
groups.forEach((key, group) -> {
|
try {
|
CrmSaleQuotationImportExcelVO first = group.get(0);
|
CrmCustomerDO customer = customerMapper.selectByCustomerName(first.getCustomerName().trim());
|
if (customer == null) throw new IllegalArgumentException("客户不存在:" + first.getCustomerName());
|
if (quotationMapper.selectCount(new LambdaQueryWrapper<CrmSaleQuotationDO>()
|
.eq(CrmSaleQuotationDO::getCustomerId, customer.getId()).eq(CrmSaleQuotationDO::getName, first.getName().trim())) > 0) {
|
throw new IllegalArgumentException("该客户已有同名报价单,请勿重复导入");
|
}
|
CrmSaleQuotationSaveReqVO req = new CrmSaleQuotationSaveReqVO();
|
req.setName(first.getName().trim()); req.setCustomerId(customer.getId()); req.setOwnerUserId(userId);
|
req.setQuotationTime(first.getQuotationTime()); req.setValidUntil(first.getValidUntil());
|
req.setDiscountPercent(first.getDiscountPercent() == null ? BigDecimal.ZERO : first.getDiscountPercent());
|
if (req.getDiscountPercent().signum() < 0 || req.getDiscountPercent().compareTo(new BigDecimal("100")) > 0) throw new IllegalArgumentException("折扣须在 0 到 100 之间");
|
if (req.getQuotationTime() != null && req.getValidUntil() != null && req.getValidUntil().isBefore(req.getQuotationTime())) throw new IllegalArgumentException("有效期不能早于报价日期");
|
List<CrmSaleQuotationSaveReqVO.Item> items = new ArrayList<>();
|
for (CrmSaleQuotationImportExcelVO row : group) {
|
if (row.getQuotationTime() != null && !row.getQuotationTime().equals(first.getQuotationTime()) || row.getValidUntil() != null && !row.getValidUntil().equals(first.getValidUntil()) || row.getDiscountPercent() != null && (first.getDiscountPercent() == null || row.getDiscountPercent().compareTo(first.getDiscountPercent()) != 0)) throw new IllegalArgumentException("同一报价单的日期和折扣必须一致");
|
if (StrUtil.isBlank(row.getItemCode()) || row.getPrice() == null || row.getPrice().signum() < 0 || row.getCount() == null || row.getCount().signum() <= 0) throw new IllegalArgumentException("物料编码、非负单价和大于零的数量不能为空");
|
if (row.getTaxPercent() != null && (row.getTaxPercent().signum() < 0 || row.getTaxPercent().compareTo(new BigDecimal("100")) > 0)) throw new IllegalArgumentException("税率须在 0 到 100 之间");
|
MdmItemRespDTO item = itemApi.getItemByCode(row.getItemCode().trim()).getCheckedData();
|
if (item == null) throw new IllegalArgumentException("物料不存在:" + row.getItemCode());
|
CrmSaleQuotationSaveReqVO.Item detail = new CrmSaleQuotationSaveReqVO.Item();
|
detail.setItemId(item.getId()); detail.setQuotationPrice(row.getPrice()); detail.setCount(row.getCount()); detail.setTaxPercent(row.getTaxPercent()); detail.setRemark(row.getRemark()); items.add(detail);
|
}
|
req.setItems(items);
|
quotationService.createSaleQuotation(req, userId);
|
created.add(key);
|
} catch (ServiceException | IllegalArgumentException ex) {
|
failures.put(key, ex.getMessage());
|
}
|
});
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("createQuotationNames", created); result.put("failureQuotationNames", failures);
|
return result;
|
}
|
}
|