package cn.iocoder.yudao.module.aftersales.service.collaboration;
|
|
import cn.iocoder.yudao.module.aftersales.dal.dataobject.collaboration.AfterSaleCollaborationDO;
|
import cn.iocoder.yudao.module.aftersales.dal.mysql.collaboration.AfterSaleCollaborationMapper;
|
import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO;
|
import cn.iocoder.yudao.module.aftersales.service.ticket.AfterSaleTicketService;
|
import cn.iocoder.yudao.module.aftersales.service.permission.AfterSalePermissionService;
|
import cn.iocoder.yudao.framework.common.biz.system.permission.PermissionCommonApi;
|
import cn.iocoder.yudao.module.erp.api.finance.AfterSaleFinanceDraftApi;
|
import cn.iocoder.yudao.module.erp.api.finance.dto.AfterSaleFinanceDraftCreateDTO;
|
import cn.iocoder.yudao.module.erp.api.finance.dto.AfterSaleFinanceReviewDTO;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
|
import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
|
import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
|
import java.math.BigDecimal;
|
import java.util.Map;
|
import java.util.List;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.test.util.ReflectionTestUtils;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.mockito.Mockito.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import org.mockito.ArgumentCaptor;
|
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
|
class AfterSaleCollaborationServiceTest {
|
@Test
|
void warrantyUsesTicketCustomerInsteadOfSubmittedName() {
|
var tickets = mock(AfterSaleTicketService.class);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L); ticket.setStatus(10); ticket.setCustomerId(99L);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
var customers = mock(CrmCustomerApi.class);
|
var customer = new CrmCustomerRespDTO(); customer.setId(99L); customer.setName("工单客户");
|
when(customers.getCustomer(99L)).thenReturn(customer);
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "ticketService", tickets);
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
ReflectionTestUtils.setField(service, "customerApi", customers);
|
ReflectionTestUtils.setField(service, "userApi", mock(AdminUserApi.class));
|
var input = new AfterSaleCollaborationService.CreateRequest();
|
input.setTicketId(8L); input.setAssigneeUserId(20L); input.setCategory("WARRANTY");
|
input.setTitle("三包"); input.setContent("核查"); input.setAmount(BigDecimal.TEN);
|
input.setDirection("PAYABLE"); input.setPartyName("伪造名称");
|
service.create(input, 10L);
|
var created = ArgumentCaptor.forClass(AfterSaleCollaborationDO.class);
|
verify(mapper).insert(created.capture());
|
assertEquals("工单客户", created.getValue().getPartyName());
|
assertEquals("CUSTOMER", created.getValue().getPartyType());
|
assertEquals(99L, created.getValue().getPartyId());
|
}
|
@Test
|
void supplierClaimRequiresMasterSupplier() {
|
var tickets = mock(AfterSaleTicketService.class);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L); ticket.setStatus(10);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "ticketService", tickets);
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
ReflectionTestUtils.setField(service, "userApi", mock(AdminUserApi.class));
|
var input = new AfterSaleCollaborationService.CreateRequest();
|
input.setTicketId(8L); input.setAssigneeUserId(20L); input.setCategory("SUPPLIER");
|
input.setTitle("索赔"); input.setContent("核查"); input.setAmount(BigDecimal.TEN);
|
input.setDirection("RECEIVABLE"); input.setPartyName("任意填写的供应商");
|
assertThrows(RuntimeException.class, () -> service.create(input, 10L));
|
verifyNoInteractions(mapper);
|
}
|
@Test
|
void rejectedFinanceDraftCanBeRetriedWithTraceableNewTask() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var tickets = mock(AfterSaleTicketService.class);
|
var finance = mock(AfterSaleFinanceDraftApi.class);
|
var previous = new AfterSaleCollaborationDO(); previous.setId(1L); previous.setTicketId(8L);
|
previous.setRequestedBy(10L); previous.setCategory("SUPPLIER"); previous.setStatus(3); previous.setFinanceDraftId(50L);
|
when(mapper.selectById(1L)).thenReturn(previous);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L); ticket.setStatus(10);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
var review = new AfterSaleFinanceReviewDTO(); review.setStatus(2);
|
when(finance.getReviewResults(List.of(50L))).thenReturn(Map.of(50L, review));
|
when(mapper.insert(any(AfterSaleCollaborationDO.class))).thenAnswer(call -> {
|
AfterSaleCollaborationDO created = call.getArgument(0); created.setId(2L); return 1;
|
});
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper); ReflectionTestUtils.setField(service, "ticketService", tickets);
|
ReflectionTestUtils.setField(service, "financeDraftApi", finance); ReflectionTestUtils.setField(service, "userApi", mock(AdminUserApi.class));
|
var suppliers = mock(SrmSupplierApi.class);
|
var supplier = new SrmSupplierRespDTO(); supplier.setId(600L); supplier.setName("主数据供应商"); supplier.setStatus(0);
|
when(suppliers.getSupplier(600L)).thenReturn(CommonResult.success(supplier));
|
ReflectionTestUtils.setField(service, "supplierApi", suppliers);
|
var input = new AfterSaleCollaborationService.CreateRequest(); input.setPreviousId(1L); input.setTicketId(8L);
|
input.setAssigneeUserId(20L); input.setCategory("SUPPLIER"); input.setTitle("重办"); input.setContent("补充材料");
|
input.setAmount(new BigDecimal("100.00")); input.setDirection("RECEIVABLE"); input.setPartyName("伪造名称"); input.setPartyId(600L);
|
assertEquals(2L, service.create(input, 10L));
|
verify(mapper).insert((AfterSaleCollaborationDO) argThat(value -> Long.valueOf(1L).equals(((AfterSaleCollaborationDO) value).getPreviousId())));
|
var created = ArgumentCaptor.forClass(AfterSaleCollaborationDO.class);
|
verify(mapper).insert(created.capture());
|
assertEquals("主数据供应商", created.getValue().getPartyName());
|
assertEquals("SUPPLIER", created.getValue().getPartyType());
|
assertEquals(600L, created.getValue().getPartyId());
|
}
|
|
@Test
|
void businessApprovalCreatesOneFinanceDraftFromSubmittedAmount() {
|
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), AfterSaleCollaborationDO.class);
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var tickets = mock(AfterSaleTicketService.class);
|
var finance = mock(AfterSaleFinanceDraftApi.class);
|
var task = new AfterSaleCollaborationDO(); task.setId(1L); task.setTicketId(8L); task.setStatus(1);
|
task.setAmount(new BigDecimal("123.45")); task.setCategory("SUPPLIER"); task.setDirection("RECEIVABLE");
|
task.setPartyName("供应商"); task.setResult("核查完成");
|
task.setPartyType("SUPPLIER"); task.setPartyId(600L);
|
when(mapper.selectById(1L)).thenReturn(task);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
when(mapper.update(any(), any())).thenReturn(1);
|
when(mapper.updateById(any(AfterSaleCollaborationDO.class))).thenReturn(1);
|
when(finance.createDraft(any())).thenReturn(50L);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper); ReflectionTestUtils.setField(service, "ticketService", tickets);
|
ReflectionTestUtils.setField(service, "financeDraftApi", finance);
|
service.reviewFinancial(1L, 10L, true, "同意");
|
var capture = ArgumentCaptor.forClass(AfterSaleFinanceDraftCreateDTO.class);
|
verify(finance).createDraft(capture.capture());
|
assertEquals(new BigDecimal("123.45"), capture.getValue().getAmount());
|
assertEquals(10L, capture.getValue().getBusinessApproverId());
|
assertEquals(600L, capture.getValue().getPartyId());
|
verify(mapper).updateById((AfterSaleCollaborationDO) argThat(value -> Long.valueOf(50L).equals(((AfterSaleCollaborationDO) value).getFinanceDraftId())));
|
}
|
|
@Test
|
void onlyRequesterCanCancelPendingTask() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var task = new AfterSaleCollaborationDO(); task.setId(2L); task.setRequestedBy(10L); task.setStatus(0);
|
when(mapper.selectById(2L)).thenReturn(task);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
assertThrows(RuntimeException.class, () -> service.cancel(2L, 20L));
|
verify(mapper, never()).update(any(), any());
|
}
|
|
@Test
|
void unrelatedUserCannotCreateTasksForSomeoneElsesTicket() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var tickets = mock(AfterSaleTicketService.class);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L); ticket.setStatus(10);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
ReflectionTestUtils.setField(service, "ticketService", tickets);
|
ReflectionTestUtils.setField(service, "permissionService", mock(AfterSalePermissionService.class));
|
ReflectionTestUtils.setField(service, "permissionApi", mock(PermissionCommonApi.class));
|
var input = new AfterSaleCollaborationService.CreateRequest();
|
input.setTicketId(8L); input.setAssigneeUserId(20L); input.setCategory("FINANCE");
|
input.setAmount(new BigDecimal("100.00")); input.setDirection("INTERNAL");
|
input.setTitle("核查"); input.setContent("核查处理情况");
|
assertThrows(RuntimeException.class, () -> service.create(input, 30L));
|
verifyNoInteractions(mapper);
|
}
|
|
@Test
|
void unauthorizedBusinessReviewerCannotGenerateFinanceDraft() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var tickets = mock(AfterSaleTicketService.class);
|
var finance = mock(AfterSaleFinanceDraftApi.class);
|
var task = new AfterSaleCollaborationDO(); task.setId(1L); task.setTicketId(8L); task.setStatus(1); task.setAmount(BigDecimal.TEN);
|
when(mapper.selectById(1L)).thenReturn(task);
|
var ticket = new AfterSaleTicketDO(); ticket.setId(8L); ticket.setOwnerUserId(10L);
|
when(tickets.getTicket(8L)).thenReturn(ticket);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper); ReflectionTestUtils.setField(service, "ticketService", tickets);
|
ReflectionTestUtils.setField(service, "financeDraftApi", finance);
|
ReflectionTestUtils.setField(service, "permissionService", mock(AfterSalePermissionService.class));
|
ReflectionTestUtils.setField(service, "permissionApi", mock(PermissionCommonApi.class));
|
assertThrows(RuntimeException.class, () -> service.reviewFinancial(1L, 30L, true, null));
|
verifyNoInteractions(finance);
|
verify(mapper, never()).update(any(), any());
|
}
|
|
@Test
|
void onlyAssigneeCanCompleteTask() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var task = new AfterSaleCollaborationDO(); task.setId(1L); task.setAssigneeUserId(10L); task.setStatus(0);
|
when(mapper.selectById(1L)).thenReturn(task);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
assertThrows(RuntimeException.class, () -> service.complete(1L, 20L, "已处理"));
|
verify(mapper, never()).update(any(), any());
|
}
|
|
@Test
|
void completionRequiresResult() {
|
var mapper = mock(AfterSaleCollaborationMapper.class);
|
var service = new AfterSaleCollaborationService();
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
assertThrows(RuntimeException.class, () -> service.complete(1L, 10L, " "));
|
verifyNoInteractions(mapper);
|
}
|
}
|