package com.zy.common.service; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.RowLastno; import com.zy.asrs.entity.RowLastnoType; import com.zy.asrs.entity.result.FindLocNoAttributeVo; import com.zy.asrs.service.BasCrnDepthRuleService; import com.zy.asrs.service.LocDetlService; import com.zy.asrs.service.LocMastService; import com.zy.common.model.CrnDepthRuleProfile; import com.zy.common.entity.Parameter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; 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.LinkedHashMap; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class CommonServiceDoubleExtensionSameGoodsTest { @Mock private BasCrnDepthRuleService basCrnDepthRuleService; @Mock private LocMastService locMastService; @Mock private LocDetlService locDetlService; private CommonService commonService; private Parameter originalParameter; @BeforeEach void setUp() { commonService = new CommonService(); ReflectionTestUtils.setField(commonService, "basCrnDepthRuleService", basCrnDepthRuleService); ReflectionTestUtils.setField(commonService, "locMastService", locMastService); ReflectionTestUtils.setField(commonService, "locDetlService", locDetlService); originalParameter = (Parameter) ReflectionTestUtils.getField(Parameter.class, "instance"); ReflectionTestUtils.setField(Parameter.class, "instance", buildParameter()); } @org.junit.jupiter.api.AfterEach void tearDown() { ReflectionTestUtils.setField(Parameter.class, "instance", originalParameter); } @Test void doubleExtension_shouldReturnShallowLocWhenSameStandby1DeepLocHasEmptyPartner() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); LocMast deepLoc = buildLoc("D-001", 1, 1, 1, "F", 1); LocMast shallowLoc = buildLoc("S-001", 2, 1, 1, "O", 1); LocDetl deepDetl = buildDetl("D-001", "PO-001"); when(locMastService.selectList(any())).thenReturn(Arrays.asList(deepLoc)); when(locDetlService.selectList(any())).thenReturn(Arrays.asList(deepDetl)); when(locMastService.selectOne(any())).thenReturn(shallowLoc); LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, buildAttributeVo("PO-001"), false); assertEquals("S-001", result.getLocNo()); assertEquals(Integer.valueOf(2), result.getRow1()); assertEquals("O", result.getLocSts()); } @Test void doubleExtension_shouldReturnShallowLocWhenDeepLocContainsEmptyPallet() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); LocMast deepLoc = buildLoc("D-002", 1, 1, 1, "F", 1); LocMast shallowLoc = buildLoc("S-002", 2, 1, 1, "O", 1); LocDetl deepDetl = buildDetl("D-002", "PO-002"); deepDetl.setMatnr("emptyPallet"); when(locMastService.selectList(any())).thenReturn(Arrays.asList(deepLoc)); when(locDetlService.selectList(any())).thenReturn(Arrays.asList(deepDetl)); when(locMastService.selectOne(any())).thenReturn(shallowLoc); FindLocNoAttributeVo attributeVo = buildAttributeVo("PO-002"); attributeVo.setMatnr("emptyPallet"); LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, attributeVo, false); assertEquals("S-002", result.getLocNo()); assertEquals(Integer.valueOf(2), result.getRow1()); assertEquals("O", result.getLocSts()); } @Test void orderDoubleExtensionShallowRows_shouldPreferLessLoadedPair() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionTwoPairProfile(); when(locMastService.selectCount(any())).thenReturn(2, 2, 0, 0); @SuppressWarnings("unchecked") List orderedRows = ReflectionTestUtils.invokeMethod(commonService, "orderDoubleExtensionShallowRows", rowLastno, buildRowLastnoType(), 1, profile); assertEquals(Arrays.asList(3, 2), orderedRows); } @Test void orderDoubleExtensionShallowRows_shouldRotateEqualLoadPairByCurrentRow() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionTwoPairProfile(); when(locMastService.selectCount(any())).thenReturn(1, 1, 1, 1); @SuppressWarnings("unchecked") List orderedRows = ReflectionTestUtils.invokeMethod(commonService, "orderDoubleExtensionShallowRows", rowLastno, buildRowLastnoType(), 1, profile); assertEquals(Arrays.asList(3, 2), orderedRows); } @Test void doubleExtension_shouldSwitchPairAfterReservationLoadIncreases() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionTwoPairProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); when(locMastService.selectCount(any())).thenReturn( 1, 1, 1, 1, 1, 1, 1, 2); LocMast firstPairShallowLoc = buildLoc("S-003", 3, 1, 1, "O", 1); LocMast firstPairDeepLoc = buildLoc("D-004", 4, 1, 1, "O", 1); LocMast secondPairShallowLoc = buildLoc("S-002", 2, 1, 1, "O", 1); LocMast secondPairDeepLoc = buildLoc("D-001", 1, 1, 1, "O", 1); when(locMastService.selectList(any())).thenReturn( Arrays.asList(firstPairShallowLoc), Arrays.asList(secondPairShallowLoc)); when(locMastService.selectOne(any())).thenReturn(firstPairDeepLoc, secondPairDeepLoc); FindLocNoAttributeVo attributeVo = new FindLocNoAttributeVo(); LocMast firstResult = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, attributeVo, false); LocMast secondResult = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, attributeVo, false); assertEquals("D-004", firstResult.getLocNo()); assertEquals(Integer.valueOf(4), firstResult.getRow1()); assertEquals("D-001", secondResult.getLocNo()); assertEquals(Integer.valueOf(1), secondResult.getRow1()); } @Test void doubleExtension_shouldUseLessLoadedPairFirstWhenBothSidesAreOpen() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionTwoPairProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); when(locMastService.selectCount(any())).thenReturn(2, 2, 0, 0); LocMast openShallowLoc = buildLoc("S-003", 3, 1, 1, "O", 1); LocMast openDeepLoc = buildLoc("D-004", 4, 1, 1, "O", 1); when(locMastService.selectList(any())).thenReturn( Collections.emptyList(), Collections.emptyList(), Arrays.asList(openShallowLoc)); when(locMastService.selectOne(any())).thenReturn(openDeepLoc); FindLocNoAttributeVo attributeVo = buildAttributeVo("PO-003"); LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, attributeVo, false); assertEquals("D-004", result.getLocNo()); assertEquals(Integer.valueOf(4), result.getRow1()); assertEquals("O", result.getLocSts()); } @Test void doubleExtension_shouldFallBackWhenSameStandby1DeepLocHasNoEmptyShallowPartner() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildDoubleExtensionTwoPairProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); LocMast sameGoodsDeepLoc = buildLoc("D-001", 1, 1, 1, "F", 1); LocMast genericShallowLoc = buildLoc("S-003", 3, 1, 1, "O", 1); LocMast genericDeepFallbackLoc = buildLoc("D-004", 4, 1, 1, "O", 1); LocDetl deepDetl = buildDetl("D-001", "PO-001"); when(locMastService.selectList(any())).thenReturn( Collections.emptyList(), Arrays.asList(sameGoodsDeepLoc), Arrays.asList(genericShallowLoc)); when(locDetlService.selectList(any())).thenReturn(Arrays.asList(deepDetl)); when(locMastService.selectOne(any())).thenReturn(null, genericDeepFallbackLoc); LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, buildAttributeVo("PO-001"), false); assertEquals("D-004", result.getLocNo()); assertEquals(Integer.valueOf(4), result.getRow1()); assertEquals("O", result.getLocSts()); } @Test void singleExtension_shouldNotApplySameGoodsPrecheck() { RowLastno rowLastno = buildRowLastno(); CrnDepthRuleProfile profile = buildSingleExtensionProfile(); when(basCrnDepthRuleService.resolveProfile(rowLastno, 1, 2)).thenReturn(profile); LocMast openLoc = buildLoc("S-010", 2, 1, 1, "O", 1); when(locMastService.selectList(any())).thenReturn(Arrays.asList(openLoc)); LocMast result = ReflectionTestUtils.invokeMethod(commonService, "findConfiguredEmptyLocForCrn", rowLastno, buildRowLastnoType(), 1, 2, null, buildAttributeVo("PO-001"), false); assertEquals("S-010", result.getLocNo()); verifyNoInteractions(locDetlService); } private RowLastno buildRowLastno() { RowLastno rowLastno = new RowLastno(); rowLastno.setWhsType(1); rowLastno.setCurrentRow(2); return rowLastno; } private RowLastnoType buildRowLastnoType() { RowLastnoType rowLastnoType = new RowLastnoType(); rowLastnoType.setType(1); return rowLastnoType; } private FindLocNoAttributeVo buildAttributeVo(String standby1) { FindLocNoAttributeVo attributeVo = new FindLocNoAttributeVo(); attributeVo.setStandby1(standby1); return attributeVo; } private CrnDepthRuleProfile buildDoubleExtensionProfile() { CrnDepthRuleProfile profile = new CrnDepthRuleProfile(); profile.setLayoutType(2); profile.setSearchRows(Arrays.asList(2, 1)); profile.setShallowRows(Arrays.asList(2)); profile.setDeepRows(Arrays.asList(1)); LinkedHashMap shallowToDeep = new LinkedHashMap(); shallowToDeep.put(2, 1); LinkedHashMap deepToShallow = new LinkedHashMap(); deepToShallow.put(1, 2); profile.setShallowToDeepRow(shallowToDeep); profile.setDeepToShallowRow(deepToShallow); return profile; } private CrnDepthRuleProfile buildDoubleExtensionTwoPairProfile() { CrnDepthRuleProfile profile = new CrnDepthRuleProfile(); profile.setLayoutType(2); profile.setSearchRows(Arrays.asList(2, 3, 1, 4)); profile.setShallowRows(Arrays.asList(2, 3)); profile.setDeepRows(Arrays.asList(1, 4)); LinkedHashMap shallowToDeep = new LinkedHashMap(); shallowToDeep.put(2, 1); shallowToDeep.put(3, 4); LinkedHashMap deepToShallow = new LinkedHashMap(); deepToShallow.put(1, 2); deepToShallow.put(4, 3); profile.setShallowToDeepRow(shallowToDeep); profile.setDeepToShallowRow(deepToShallow); return profile; } private CrnDepthRuleProfile buildSingleExtensionProfile() { CrnDepthRuleProfile profile = new CrnDepthRuleProfile(); profile.setLayoutType(1); profile.setSearchRows(Arrays.asList(2)); profile.setShallowRows(Arrays.asList(2)); profile.setDeepRows(null); profile.setShallowToDeepRow(new LinkedHashMap()); profile.setDeepToShallowRow(new LinkedHashMap()); return profile; } private LocMast buildLoc(String locNo, Integer row, Integer bay, Integer lev, String status, Integer crnNo) { LocMast locMast = new LocMast(); locMast.setLocNo(locNo); locMast.setRow1(row); locMast.setBay1(bay); locMast.setLev1(lev); locMast.setLocSts(status); locMast.setCrnNo(crnNo); return locMast; } private LocDetl buildDetl(String locNo, String standby1) { LocDetl locDetl = new LocDetl(); locDetl.setLocNo(locNo); locDetl.setStandby1(standby1); return locDetl; } private Parameter buildParameter() { try { Constructor constructor = Parameter.class.getDeclaredConstructor(); constructor.setAccessible(true); Parameter parameter = constructor.newInstance(); parameter.setHighFreqFrontBayCount("0"); return parameter; } catch (Exception e) { throw new IllegalStateException("Failed to initialize Parameter test instance", e); } } }