package cn.iocoder.yudao.module.mes.service.pro.feedback;
|
|
import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
|
import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO;
|
import cn.iocoder.yudao.module.mes.api.event.ProductionFinishedEvent;
|
import cn.iocoder.yudao.module.mes.enums.pro.MesProMpsStatusEnum;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
|
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
|
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
|
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.test.util.ReflectionTestUtils;
|
import org.mockito.ArgumentCaptor;
|
|
import java.math.BigDecimal;
|
import java.util.List;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
import static org.mockito.Mockito.*;
|
import static org.mockito.ArgumentMatchers.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
class MesProFeedbackMpsAllocationTest {
|
|
@Test
|
void mergedWorkOrderKeepsSurplusOutOfSaleOrders() {
|
MesProMpsApi mpsApi = mock(MesProMpsApi.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "mpsApi", mpsApi);
|
when(mpsApi.getMpsListByWorkOrderId(28L)).thenReturn(List.of(
|
mps(1716L, 38, 0, MesProMpsStatusEnum.ISSUED),
|
mps(1737L, 1, 0, MesProMpsStatusEnum.ISSUED)));
|
|
service.allocateMpsProducedQuantity(28L, new BigDecimal("40"));
|
|
verify(mpsApi).updateMpsProducedQuantity(1716L, new BigDecimal("38"));
|
verify(mpsApi).updateMpsProducedQuantity(1737L, BigDecimal.ONE);
|
verify(mpsApi, times(2)).updateMpsProducedQuantity(anyLong(), any(BigDecimal.class));
|
}
|
|
@Test
|
void onlyRemainingDemandIsAssignedAndCanceledMpsIsSkipped() {
|
MesProMpsApi mpsApi = mock(MesProMpsApi.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "mpsApi", mpsApi);
|
when(mpsApi.getMpsListByWorkOrderId(29L)).thenReturn(List.of(
|
mps(1L, 5, 0, MesProMpsStatusEnum.CANCELED),
|
mps(2L, 3, 2, MesProMpsStatusEnum.ISSUED)));
|
|
service.allocateMpsProducedQuantity(29L, new BigDecimal("4"));
|
|
verify(mpsApi).updateMpsProducedQuantity(2L, BigDecimal.ONE);
|
verify(mpsApi, never()).updateMpsProducedQuantity(eq(1L), any(BigDecimal.class));
|
verify(mpsApi, times(1)).updateMpsProducedQuantity(anyLong(), any(BigDecimal.class));
|
}
|
|
@Test
|
void mergedWorkOrderChecksBothSaleOrdersExactlyOnce() {
|
MesProMpsApi mpsApi = mock(MesProMpsApi.class);
|
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "mpsApi", mpsApi);
|
ReflectionTestUtils.setField(service, "eventPublisher", publisher);
|
MesProMpsRespDTO first = mps(1716L, 38, 38, MesProMpsStatusEnum.ISSUED);
|
first.setSaleOrderId(512L);
|
MesProMpsRespDTO second = mps(1737L, 1, 1, MesProMpsStatusEnum.ISSUED);
|
second.setSaleOrderId(513L);
|
when(mpsApi.getMpsListByWorkOrderId(28L)).thenReturn(List.of(first, second));
|
when(mpsApi.checkAndFinishMps(1716L)).thenReturn(true);
|
when(mpsApi.checkAndFinishMps(1737L)).thenReturn(true);
|
when(mpsApi.checkSaleOrderProductionFinished(512L)).thenReturn(true);
|
when(mpsApi.checkSaleOrderProductionFinished(513L)).thenReturn(true);
|
|
service.checkAndPublishProductionFinished(28L);
|
|
verify(mpsApi).checkAndFinishMps(1716L);
|
verify(mpsApi).checkAndFinishMps(1737L);
|
ArgumentCaptor<ProductionFinishedEvent> events = ArgumentCaptor.forClass(ProductionFinishedEvent.class);
|
verify(publisher, times(2)).publishEvent(events.capture());
|
assertEquals(Set.of(512L, 513L), events.getAllValues().stream()
|
.map(ProductionFinishedEvent::getSaleOrderId).collect(Collectors.toSet()));
|
}
|
|
@Test
|
void lastProcessUpdatesWorkOrderEvenWhenItIsNotKeyProcess() {
|
MesProMpsApi mpsApi = mock(MesProMpsApi.class);
|
MesProTaskService taskService = mock(MesProTaskService.class);
|
MesProWorkOrderService workOrderService = mock(MesProWorkOrderService.class);
|
MesProWorkOrderProcessService processService = mock(MesProWorkOrderProcessService.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "mpsApi", mpsApi);
|
ReflectionTestUtils.setField(service, "taskService", taskService);
|
ReflectionTestUtils.setField(service, "workOrderService", workOrderService);
|
ReflectionTestUtils.setField(service, "workOrderProcessService", processService);
|
when(processService.getLastWorkOrderProcessByWorkOrderId(28L))
|
.thenReturn(new MesProWorkOrderProcessDO().setProcessId(13L).setKeyFlag(false));
|
when(mpsApi.getMpsListByWorkOrderId(28L)).thenReturn(List.of(
|
mps(1716L, 38, 0, MesProMpsStatusEnum.ISSUED),
|
mps(1737L, 1, 0, MesProMpsStatusEnum.ISSUED)));
|
MesProFeedbackDO feedback = new MesProFeedbackDO().setWorkOrderId(28L)
|
.setTaskId(362L).setProcessId(13L).setFeedbackQuantity(new BigDecimal("40"));
|
|
service.updateTaskAndWorkOrderByFeedback(feedback);
|
|
verify(taskService).updateProducedQuantity(362L, new BigDecimal("40"), BigDecimal.ZERO, BigDecimal.ZERO);
|
verify(workOrderService).updateProducedQuantity(28L, new BigDecimal("40"));
|
verify(mpsApi).updateMpsProducedQuantity(1716L, new BigDecimal("38"));
|
verify(mpsApi).updateMpsProducedQuantity(1737L, BigDecimal.ONE);
|
}
|
|
@Test
|
void keyProcessBeforeLastOnlyUpdatesItsTask() {
|
MesProMpsApi mpsApi = mock(MesProMpsApi.class);
|
MesProTaskService taskService = mock(MesProTaskService.class);
|
MesProWorkOrderService workOrderService = mock(MesProWorkOrderService.class);
|
MesProWorkOrderProcessService processService = mock(MesProWorkOrderProcessService.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "mpsApi", mpsApi);
|
ReflectionTestUtils.setField(service, "taskService", taskService);
|
ReflectionTestUtils.setField(service, "workOrderService", workOrderService);
|
ReflectionTestUtils.setField(service, "workOrderProcessService", processService);
|
when(processService.getLastWorkOrderProcessByWorkOrderId(28L))
|
.thenReturn(new MesProWorkOrderProcessDO().setProcessId(13L).setKeyFlag(false));
|
when(mpsApi.getMpsListByWorkOrderId(28L)).thenReturn(List.of());
|
MesProFeedbackDO feedback = new MesProFeedbackDO().setWorkOrderId(28L)
|
.setTaskId(360L).setProcessId(11L).setFeedbackQuantity(new BigDecimal("40"));
|
|
service.updateTaskAndWorkOrderByFeedback(feedback);
|
|
verify(taskService).updateProducedQuantity(360L, new BigDecimal("40"), BigDecimal.ZERO, BigDecimal.ZERO);
|
verify(workOrderService, never()).updateProducedQuantity(anyLong(), any(BigDecimal.class));
|
verify(mpsApi, never()).updateMpsProducedQuantity(anyLong(), any(BigDecimal.class));
|
}
|
|
@Test
|
void lastQcAutoFinishesOnlyAfterAllLastProcessFeedbacksAreFinished() {
|
MesProFeedbackMapper feedbackMapper = mock(MesProFeedbackMapper.class);
|
MesProWorkOrderService workOrderService = mock(MesProWorkOrderService.class);
|
MesProWorkOrderProcessService processService = mock(MesProWorkOrderProcessService.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "feedbackMapper", feedbackMapper);
|
ReflectionTestUtils.setField(service, "workOrderService", workOrderService);
|
ReflectionTestUtils.setField(service, "workOrderProcessService", processService);
|
when(processService.getLastWorkOrderProcessByWorkOrderId(28L))
|
.thenReturn(new MesProWorkOrderProcessDO().setProcessId(13L));
|
MesProFeedbackDO lastFeedback = new MesProFeedbackDO().setWorkOrderId(28L).setProcessId(13L);
|
when(feedbackMapper.selectCount(any(com.baomidou.mybatisplus.core.conditions.Wrapper.class)))
|
.thenReturn(1L, 0L);
|
|
service.checkAndAutoFinishAfterLastQc(lastFeedback);
|
verify(workOrderService, never()).checkAndAutoFinishWorkOrder(28L);
|
|
service.checkAndAutoFinishAfterLastQc(lastFeedback);
|
verify(workOrderService).checkAndAutoFinishWorkOrder(28L);
|
}
|
|
@Test
|
void nonLastQcDoesNotAutoFinishWorkOrder() {
|
MesProWorkOrderService workOrderService = mock(MesProWorkOrderService.class);
|
MesProWorkOrderProcessService processService = mock(MesProWorkOrderProcessService.class);
|
MesProFeedbackServiceImpl service = new MesProFeedbackServiceImpl();
|
ReflectionTestUtils.setField(service, "workOrderService", workOrderService);
|
ReflectionTestUtils.setField(service, "workOrderProcessService", processService);
|
when(processService.getLastWorkOrderProcessByWorkOrderId(28L))
|
.thenReturn(new MesProWorkOrderProcessDO().setProcessId(13L));
|
|
service.checkAndAutoFinishAfterLastQc(new MesProFeedbackDO().setWorkOrderId(28L).setProcessId(11L));
|
|
verifyNoInteractions(workOrderService);
|
}
|
|
private static MesProMpsRespDTO mps(Long id, int planned, int produced, MesProMpsStatusEnum status) {
|
MesProMpsRespDTO mps = new MesProMpsRespDTO();
|
mps.setId(id);
|
mps.setQuantity(BigDecimal.valueOf(planned));
|
mps.setQuantityProduced(BigDecimal.valueOf(produced));
|
mps.setStatus(status.getStatus());
|
return mps;
|
}
|
}
|