package com.zy.common.service;
|
|
import com.baomidou.mybatisplus.mapper.Wrapper;
|
import com.zy.asrs.entity.BasCrnp;
|
import com.zy.asrs.entity.LocMast;
|
import com.zy.asrs.entity.RowLastno;
|
import com.zy.asrs.entity.RowLastnoType;
|
import com.zy.asrs.service.BasCrnDepthRuleService;
|
import com.zy.asrs.service.BasCrnpService;
|
import com.zy.asrs.service.BasDevpService;
|
import com.zy.asrs.service.LocMastService;
|
import com.zy.asrs.service.RowLastnoService;
|
import com.zy.asrs.service.StaDescService;
|
import com.zy.common.model.CrnDepthRuleProfile;
|
import com.zy.common.model.LocTypeDto;
|
import com.zy.common.model.StartupDto;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.ArgumentCaptor;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.lang.reflect.Constructor;
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.List;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
@ExtendWith(MockitoExtension.class)
|
class CommonServiceRun2AllocationTest {
|
|
@Mock
|
private BasCrnpService basCrnpService;
|
@Mock
|
private StaDescService staDescService;
|
@Mock
|
private BasDevpService basDevpService;
|
@Mock
|
private LocMastService locMastService;
|
@Mock
|
private BasCrnDepthRuleService basCrnDepthRuleService;
|
@Mock
|
private RowLastnoService rowLastnoService;
|
|
private CommonService commonService;
|
|
@BeforeEach
|
void setUp() {
|
commonService = new CommonService();
|
ReflectionTestUtils.setField(commonService, "basCrnpService", basCrnpService);
|
ReflectionTestUtils.setField(commonService, "staDescService", staDescService);
|
ReflectionTestUtils.setField(commonService, "basDevpService", basDevpService);
|
ReflectionTestUtils.setField(commonService, "locMastService", locMastService);
|
ReflectionTestUtils.setField(commonService, "basCrnDepthRuleService", basCrnDepthRuleService);
|
ReflectionTestUtils.setField(commonService, "rowLastnoService", rowLastnoService);
|
}
|
|
@Test
|
void findRun2EmptyLocByCrnNos_shouldStopAtFirstMatchingCraneInOrder() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 2, 1, 4);
|
RowLastnoType rowLastnoType = standardRowLastnoType();
|
StartupDto startupDto = new StartupDto();
|
LocTypeDto locTypeDto = fullLocType((short) 1);
|
LocMast firstCraneLoc = openLoc("0200101", 2, 2, 1, 1);
|
|
when(basCrnpService.selectById(2)).thenReturn(activeCrn(2));
|
when(basCrnDepthRuleService.resolveProfile(eq(rowLastno), eq(2), any()))
|
.thenReturn(singleExtensionProfile(1, 2));
|
when(locMastService.selectList(any())).thenReturn(Collections.singletonList(firstCraneLoc));
|
|
LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findRun2EmptyLocByCrnNos",
|
rowLastno, rowLastnoType, Arrays.asList(2, 1), locTypeDto,
|
1, 100, startupDto, 1, "run2-order", false);
|
|
assertEquals("0200101", result.getLocNo());
|
assertEquals(Integer.valueOf(2), result.getCrnNo());
|
verify(locMastService, times(1)).selectList(any());
|
}
|
|
@Test
|
void findRun2EmptyLocByCrnNos_shouldSkipInactiveCrane() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 2, 1, 4);
|
RowLastnoType rowLastnoType = standardRowLastnoType();
|
StartupDto startupDto = new StartupDto();
|
LocTypeDto locTypeDto = fullLocType((short) 1);
|
LocMast secondCraneLoc = openLoc("0400101", 1, 4, 1, 1);
|
|
when(basCrnpService.selectById(2)).thenReturn(inactiveCrn(2));
|
when(basCrnpService.selectById(1)).thenReturn(activeCrn(1));
|
when(basCrnDepthRuleService.resolveProfile(eq(rowLastno), eq(1), any()))
|
.thenReturn(singleExtensionProfile(1, 4));
|
when(locMastService.selectList(any())).thenReturn(Collections.singletonList(secondCraneLoc));
|
|
LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findRun2EmptyLocByCrnNos",
|
rowLastno, rowLastnoType, Arrays.asList(2, 1), locTypeDto,
|
1, 100, startupDto, 1, "run2-skip-offline", false);
|
|
assertEquals("0400101", result.getLocNo());
|
assertEquals(Integer.valueOf(1), result.getCrnNo());
|
verify(locMastService, times(1)).selectList(any());
|
}
|
|
@Test
|
void findOpenLocsByRow_forSingleExtension_shouldOrderByLevThenBay() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 1, 1, 2);
|
RowLastnoType rowLastnoType = standardRowLastnoType();
|
|
when(locMastService.selectList(any())).thenReturn(Collections.emptyList());
|
|
ReflectionTestUtils.invokeMethod(commonService, "findOpenLocsByRow",
|
rowLastno, rowLastnoType, 1, 1, fullLocType((short) 1), true);
|
|
@SuppressWarnings("rawtypes")
|
ArgumentCaptor<Wrapper> wrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
|
verify(locMastService).selectList(wrapperCaptor.capture());
|
String sqlSegment = wrapperCaptor.getValue().getSqlSegment().toLowerCase();
|
|
assertTrue(sqlSegment.contains("order by"));
|
assertTrue(sqlSegment.indexOf("lev1") < sqlSegment.indexOf("bay1"));
|
}
|
|
@Test
|
void findConfiguredEmptyLocForCrn_forDoubleExtension_shouldPreferDeepOpenLoc() {
|
RowLastno rowLastno = doubleExtensionRowLastno();
|
RowLastnoType rowLastnoType = standardRowLastnoType();
|
LocMast shallowLoc = openLoc("0100101", 1, 1, 1, 1);
|
LocMast deepOpenLoc = openLoc("0200101", 1, 2, 1, 1);
|
|
when(basCrnDepthRuleService.resolveProfile(eq(rowLastno), eq(1), any()))
|
.thenReturn(doubleExtensionProfile());
|
when(locMastService.selectList(any())).thenReturn(Collections.singletonList(shallowLoc));
|
when(locMastService.selectOne(any())).thenReturn(deepOpenLoc);
|
|
LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn",
|
rowLastno, rowLastnoType, 1, 1, fullLocType((short) 1));
|
|
assertEquals("0200101", result.getLocNo());
|
}
|
|
@Test
|
void findConfiguredEmptyLocForCrn_forDoubleExtension_shouldFallbackToShallowWhenDeepBlocked() {
|
RowLastno rowLastno = doubleExtensionRowLastno();
|
RowLastnoType rowLastnoType = standardRowLastnoType();
|
LocMast shallowLoc = openLoc("0100101", 1, 1, 1, 1);
|
LocMast deepBlockedLoc = blockedLoc("0200101", 1, 2, 1, 1, "F");
|
|
when(basCrnDepthRuleService.resolveProfile(eq(rowLastno), eq(1), any()))
|
.thenReturn(doubleExtensionProfile());
|
when(locMastService.selectList(any())).thenReturn(Collections.singletonList(shallowLoc));
|
when(locMastService.selectOne(any())).thenReturn(null, deepBlockedLoc);
|
|
LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn",
|
rowLastno, rowLastnoType, 1, 1, fullLocType((short) 1));
|
|
assertEquals("0100101", result.getLocNo());
|
}
|
|
@Test
|
void getNextRun2CurrentRow_shouldAdvanceWithinRunnableCrnsOnly() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 4, 1, 8);
|
|
Integer nextRow = ReflectionTestUtils.invokeMethod(commonService, "getNextRun2CurrentRow",
|
rowLastno, Arrays.asList(2, 4), 2, 3);
|
|
assertEquals(Integer.valueOf(7), nextRow);
|
}
|
|
@Test
|
void resolveRun2CrnNo_shouldPreferCurrentCrnNoOverCurrentRow() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 4, 1, 8);
|
rowLastno.setCurrentRow(7);
|
rowLastno.setCurrentCrnNo(2);
|
|
Integer currentCrnNo = ReflectionTestUtils.invokeMethod(commonService, "resolveRun2CrnNo", rowLastno);
|
|
assertEquals(Integer.valueOf(2), currentCrnNo);
|
}
|
|
@Test
|
void resolveRun2CrnNo_shouldFallbackToStartCrnNoWhenCurrentCrnNoIsInvalid() {
|
RowLastno rowLastno = singleExtensionRowLastno(2, 4, 3, 8);
|
|
rowLastno.setCurrentCrnNo(null);
|
assertEquals(Integer.valueOf(2),
|
ReflectionTestUtils.invokeMethod(commonService, "resolveRun2CrnNo", rowLastno));
|
|
rowLastno.setCurrentCrnNo(0);
|
assertEquals(Integer.valueOf(2),
|
ReflectionTestUtils.invokeMethod(commonService, "resolveRun2CrnNo", rowLastno));
|
|
rowLastno.setCurrentCrnNo(5);
|
assertEquals(Integer.valueOf(2),
|
ReflectionTestUtils.invokeMethod(commonService, "resolveRun2CrnNo", rowLastno));
|
}
|
|
@Test
|
void advanceNormalRun2Cursor_shouldUpdateCurrentRowAndCurrentCrnNoTogether() {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 4, 1, 8);
|
rowLastno.setCurrentRow(1);
|
rowLastno.setCurrentCrnNo(1);
|
|
ReflectionTestUtils.invokeMethod(commonService, "advanceNormalRun2Cursor",
|
rowLastno, 1, Arrays.asList(1, 3), 1);
|
|
assertEquals(Integer.valueOf(5), rowLastno.getCurrentRow());
|
assertEquals(Integer.valueOf(3), rowLastno.getCurrentCrnNo());
|
verify(rowLastnoService).updateById(rowLastno);
|
}
|
|
@Test
|
void advanceEmptyPalletRun2Cursor_shouldUpdateCurrentRowAndCurrentCrnNoTogether() throws Exception {
|
RowLastno rowLastno = singleExtensionRowLastno(1, 4, 1, 8);
|
rowLastno.setCurrentRow(5);
|
rowLastno.setCurrentCrnNo(3);
|
LocMast locMast = openLoc("0500101", 3, 5, 1, 1);
|
Object searchResult = run2AreaSearchResult(locMast, rowLastno, Arrays.asList(1, 3));
|
|
ReflectionTestUtils.invokeMethod(commonService, "advanceEmptyPalletRun2Cursor", searchResult, locMast);
|
|
assertEquals(Integer.valueOf(1), rowLastno.getCurrentRow());
|
assertEquals(Integer.valueOf(1), rowLastno.getCurrentCrnNo());
|
verify(rowLastnoService).updateById(rowLastno);
|
}
|
|
private RowLastno singleExtensionRowLastno(int startCrnNo, int endCrnNo, int startRow, int endRow) {
|
RowLastno rowLastno = new RowLastno();
|
rowLastno.setWhsType(1);
|
rowLastno.setsCrnNo(startCrnNo);
|
rowLastno.seteCrnNo(endCrnNo);
|
rowLastno.setsRow(startRow);
|
rowLastno.seteRow(endRow);
|
rowLastno.setTypeId(2);
|
return rowLastno;
|
}
|
|
private RowLastno doubleExtensionRowLastno() {
|
RowLastno rowLastno = new RowLastno();
|
rowLastno.setWhsType(1);
|
rowLastno.setsCrnNo(1);
|
rowLastno.seteCrnNo(1);
|
rowLastno.setsRow(1);
|
rowLastno.seteRow(2);
|
rowLastno.setTypeId(1);
|
return rowLastno;
|
}
|
|
private RowLastnoType standardRowLastnoType() {
|
RowLastnoType rowLastnoType = new RowLastnoType();
|
rowLastnoType.setType(1);
|
return rowLastnoType;
|
}
|
|
private Object run2AreaSearchResult(LocMast locMast, RowLastno rowLastno, List<Integer> runnableCrnNos) throws Exception {
|
Class<?> clazz = Class.forName("com.zy.common.service.CommonService$Run2AreaSearchResult");
|
Constructor<?> constructor = clazz.getDeclaredConstructor(LocMast.class, RowLastno.class, List.class);
|
constructor.setAccessible(true);
|
return constructor.newInstance(locMast, rowLastno, runnableCrnNos);
|
}
|
|
private CrnDepthRuleProfile singleExtensionProfile(int shallowRow, int searchRow) {
|
CrnDepthRuleProfile profile = new CrnDepthRuleProfile();
|
profile.setLayoutType(1);
|
profile.setSearchRows(Collections.singletonList(searchRow));
|
profile.setShallowRows(Collections.singletonList(shallowRow));
|
return profile;
|
}
|
|
private CrnDepthRuleProfile doubleExtensionProfile() {
|
CrnDepthRuleProfile profile = new CrnDepthRuleProfile();
|
profile.setLayoutType(2);
|
profile.setSearchRows(Arrays.asList(1, 2));
|
profile.setShallowRows(Collections.singletonList(1));
|
profile.setDeepRows(Collections.singletonList(2));
|
profile.getShallowToDeepRow().put(1, 2);
|
profile.getDeepToShallowRow().put(2, 1);
|
return profile;
|
}
|
|
private BasCrnp activeCrn(int crnNo) {
|
BasCrnp basCrnp = new BasCrnp();
|
basCrnp.setCrnNo(crnNo);
|
basCrnp.setInEnable("Y");
|
basCrnp.setOutEnable("Y");
|
basCrnp.setCrnSts(3);
|
basCrnp.setCrnErr(0L);
|
return basCrnp;
|
}
|
|
private BasCrnp inactiveCrn(int crnNo) {
|
BasCrnp basCrnp = activeCrn(crnNo);
|
basCrnp.setInEnable("N");
|
return basCrnp;
|
}
|
|
private LocTypeDto fullLocType(short locType1) {
|
LocTypeDto locTypeDto = new LocTypeDto();
|
locTypeDto.setLocType1(locType1);
|
return locTypeDto;
|
}
|
|
private LocMast openLoc(String locNo, int crnNo, int row, int bay, int lev) {
|
LocMast locMast = new LocMast();
|
locMast.setLocNo(locNo);
|
locMast.setCrnNo(crnNo);
|
locMast.setWhsType(1L);
|
locMast.setRow1(row);
|
locMast.setBay1(bay);
|
locMast.setLev1(lev);
|
locMast.setLocSts("O");
|
locMast.setLocType1((short) 1);
|
locMast.setLocType2((short) 2);
|
return locMast;
|
}
|
|
private LocMast blockedLoc(String locNo, int crnNo, int row, int bay, int lev, String locSts) {
|
LocMast locMast = openLoc(locNo, crnNo, row, bay, lev);
|
locMast.setLocSts(locSts);
|
return locMast;
|
}
|
}
|