xiaoyi
4 天以前 8782476e9cb4480be5da588888d08022b7942d0c
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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);
    }
}