package cn.iocoder.yudao.module.crm.service.quotation; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationDO; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationRevisionDO; import cn.iocoder.yudao.module.crm.dal.mysql.quotation.CrmSaleQuotationMapper; import cn.iocoder.yudao.module.crm.dal.mysql.quotation.CrmSaleQuotationProductMapper; import cn.iocoder.yudao.module.crm.dal.mysql.quotation.CrmSaleQuotationRevisionMapper; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; import java.lang.reflect.Proxy; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.SALE_QUOTATION_REVISION_EXISTS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; class CrmSaleQuotationRevisionTest { private final CrmSaleQuotationServiceImpl service = new CrmSaleQuotationServiceImpl(); private final List inserted = new ArrayList<>(); private void prepare(long existingRevisionCount) { CrmSaleQuotationRevisionMapper revisionMapper = stub(CrmSaleQuotationRevisionMapper.class, (proxy, method, args) -> switch (method.getName()) { case "selectByQuotationIdAndRevisionNo" -> (Integer) args[1] <= existingRevisionCount ? new CrmSaleQuotationRevisionDO() : null; case "insert" -> { inserted.add((CrmSaleQuotationRevisionDO) args[0]); yield 1; } default -> throw new AssertionError(method.getName()); }); CrmSaleQuotationProductMapper productMapper = stub(CrmSaleQuotationProductMapper.class, (proxy, method, args) -> { if ("selectListByQuotationId".equals(method.getName())) { return List.of(new CrmSaleQuotationProductDO().setItemId(1103L) .setCount(new BigDecimal("2")) .setQuotationPrice(new BigDecimal("100"))); } throw new AssertionError(method.getName()); }); CrmSaleQuotationMapper quoteMapper = stub(CrmSaleQuotationMapper.class, (proxy, method, args) -> 1); MdmItemApi itemApi = stub(MdmItemApi.class, (proxy, method, args) -> Map.of()); ReflectionTestUtils.setField(service, "revisionMapper", revisionMapper); ReflectionTestUtils.setField(service, "saleQuotationProductMapper", productMapper); ReflectionTestUtils.setField(service, "saleQuotationMapper", quoteMapper); ReflectionTestUtils.setField(service, "mdmItemApi", itemApi); } @Test void eachSubmitIncrementsRevision() { prepare(0); CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setRevisionNo(0); ReflectionTestUtils.invokeMethod(service, "recordRevision", quote, 291L); ReflectionTestUtils.invokeMethod(service, "recordRevision", quote, 291L); assertEquals(2, inserted.size()); assertEquals(1, inserted.get(0).getRevisionNo()); assertEquals(2, inserted.get(1).getRevisionNo()); assertEquals(2, quote.getRevisionNo()); assertNotNull(inserted.get(0).getItemsSnapshot()); assertEquals(1, inserted.get(0).getStatus()); } @Test void duplicateRevisionRejected() { prepare(1); CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setRevisionNo(0); ServiceException ex = assertThrows(ServiceException.class, () -> ReflectionTestUtils.invokeMethod(service, "recordRevision", quote, 291L)); assertEquals(SALE_QUOTATION_REVISION_EXISTS.getCode(), ex.getCode()); } private static T stub(Class type, java.lang.reflect.InvocationHandler handler) { return type.cast(Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, handler)); } }