liu
6 天以前 8ad99e5f72085d14fd56e8faa7aa36701823c8b5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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;
    }
}