package cn.iocoder.yudao.module.crm.service.quotation; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.crm.dal.dataobject.bidbond.CrmBidBondDO; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationDO; import cn.iocoder.yudao.module.crm.dal.mysql.bidbond.CrmBidBondMapper; import cn.iocoder.yudao.module.crm.dal.mysql.quotation.CrmSaleQuotationMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; import java.lang.reflect.Proxy; import java.util.concurrent.atomic.AtomicReference; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.SALE_QUOTATION_VOID_FAIL_STATUS; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.SALE_QUOTATION_VOID_FAIL_WON; 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 CrmSaleQuotationVoidTest { private final CrmSaleQuotationServiceImpl service = new CrmSaleQuotationServiceImpl(); @BeforeEach void setUp() { ReflectionTestUtils.setField(service, "expiryHelper", new CrmSaleQuotationExpiryHelper()); } @Test void voidDraftQuotation() { CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setStatus(0); AtomicReference updated = new AtomicReference<>(); ReflectionTestUtils.setField(service, "saleQuotationMapper", quoteMapper(quote, updated)); service.voidSaleQuotation(1L, " 客户取消本次采购 "); assertNotNull(updated.get()); assertEquals(5, updated.get().getStatus()); assertEquals(1, updated.get().getVoidType()); assertEquals("客户取消本次采购", updated.get().getVoidReason()); assertNotNull(updated.get().getVoidTime()); } @Test void voidWonQuotationRejected() { CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setStatus(2).setBidBondId(9L); ReflectionTestUtils.setField(service, "saleQuotationMapper", quoteMapper(quote, new AtomicReference<>())); ReflectionTestUtils.setField(service, "bidBondMapper", bondMapper(new CrmBidBondDO().setId(9L).setBidResult(1))); ServiceException ex = assertThrows(ServiceException.class, () -> service.voidSaleQuotation(1L, "不再参与")); assertEquals(SALE_QUOTATION_VOID_FAIL_WON.getCode(), ex.getCode()); } @Test void voidConvertedQuotationRejected() { CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setStatus(10); ReflectionTestUtils.setField(service, "saleQuotationMapper", quoteMapper(quote, new AtomicReference<>())); ServiceException ex = assertThrows(ServiceException.class, () -> service.voidSaleQuotation(1L, "不再参与")); assertEquals(SALE_QUOTATION_VOID_FAIL_STATUS.getCode(), ex.getCode()); } @Test void voidProcessingQuotationCancelsProcess() { CrmSaleQuotationDO quote = new CrmSaleQuotationDO().setId(1L).setNo("BJ1").setStatus(1) .setProcessInstanceId("proc-1"); AtomicReference updated = new AtomicReference<>(); ReflectionTestUtils.setField(service, "saleQuotationMapper", quoteMapper(quote, updated)); AtomicReference cancelled = new AtomicReference<>(); ReflectionTestUtils.setField(service, "bpmProcessInstanceApi", stub(BpmProcessInstanceApi.class, (proxy, method, args) -> { if ("cancelProcessInstanceByAdmin".equals(method.getName())) { cancelled.set(new String[]{(String) args[1], (String) args[2]}); return null; } throw new AssertionError(method.getName()); })); service.voidSaleQuotation(1L, "项目取消"); assertEquals(5, updated.get().getStatus()); assertNotNull(cancelled.get()); assertEquals("proc-1", cancelled.get()[0]); assertEquals("项目取消", cancelled.get()[1]); } private CrmSaleQuotationMapper quoteMapper(CrmSaleQuotationDO quote, AtomicReference updated) { return stub(CrmSaleQuotationMapper.class, (proxy, method, args) -> switch (method.getName()) { case "selectById" -> quote; case "updateById" -> { updated.set((CrmSaleQuotationDO) args[0]); yield 1; } default -> throw new AssertionError(method.getName()); }); } private CrmBidBondMapper bondMapper(CrmBidBondDO bond) { return stub(CrmBidBondMapper.class, (proxy, method, args) -> { if ("selectById".equals(method.getName())) { return bond; } throw new AssertionError(method.getName()); }); } private static T stub(Class type, java.lang.reflect.InvocationHandler handler) { return type.cast(Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, handler)); } }