diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java index 718ca63..7038437 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java @@ -6,6 +6,8 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.ruoyi.algorithm.shadow.InboundShadowObservation; +import com.ruoyi.algorithm.shadow.ShadowObservationGateway; import com.ruoyi.api.domain.*; import com.ruoyi.api.service.IToErpService; import com.ruoyi.api.service.IToWmsService; @@ -90,6 +92,8 @@ public class ToWmsServiceImpl implements IToWmsService { private IBasStockService stockService; @Autowired private MydoJobMapper mydoJobMapper; + @Autowired + private ShadowObservationGateway shadowObservationGateway; @Override @@ -412,11 +416,22 @@ public class ToWmsServiceImpl implements IToWmsService { map.put("v_tray_code", inJob.getTrayCode()); map.put("v_code", deviceCode); + InboundShadowObservation shadowObservation = InboundShadowObservation.empty(); + try { + shadowObservation = shadowObservationGateway.planInbound(taskNo, inJob.getTrayCode()); + } catch (RuntimeException exception) { + log.warn("Inbound shadow observation failed open for task {}: {}", + taskNo, exception.getMessage()); + } mydoJobMapper.allotInJobSpace(map); - if (!"10".equals(map.get("v_result").toString())) { + String legacyResultCode = map.get("v_result").toString(); + if (!"10".equals(legacyResultCode)) { + compareInboundShadow(shadowObservation, legacyResultCode, null); return AjaxResult.error(map.get("v_resultmsg").toString()); }else{ MydoJob inJob2 = mydoJobMapper.selectInJobByTaskNo(taskNo); + compareInboundShadow(shadowObservation, legacyResultCode, + inJob2 == null ? null : inJob2.getCargoSpaceId()); return AjaxResult.success(inJob2); } } @@ -425,5 +440,15 @@ public class ToWmsServiceImpl implements IToWmsService { } } + private void compareInboundShadow(InboundShadowObservation observation, + String legacyResultCode, String legacySpaceId) { + try { + shadowObservationGateway.compareInbound(observation, legacyResultCode, legacySpaceId); + } catch (RuntimeException exception) { + log.warn("Inbound shadow comparison failed open for request {}: {}", + observation == null ? null : observation.requestId(), exception.getMessage()); + } + } + } diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java new file mode 100644 index 0000000..a5a46b7 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java @@ -0,0 +1,95 @@ +package com.ruoyi.api.service.impl; + +import com.ruoyi.algorithm.shadow.InboundShadowObservation; +import com.ruoyi.algorithm.shadow.ShadowObservationGateway; +import com.ruoyi.api.domain.RequestEnter; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InOrder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ToWmsServiceImplShadowTest { + @Mock + private MydoJobMapper mydoJobMapper; + @Mock + private ShadowObservationGateway shadowObservationGateway; + @InjectMocks + private ToWmsServiceImpl service; + + private RequestEnter request; + private MydoJob beforeLegacy; + private MydoJob legacyResult; + + @BeforeEach + void setUp() { + request = new RequestEnter(); + request.setTaskNo("TASK-1"); + request.setDeviceCode("ENTRY-1"); + beforeLegacy = inboundJob("TRAY-1", null); + legacyResult = inboundJob("TRAY-1", "SPACE-LEGACY"); + when(mydoJobMapper.selectInJobByTaskNo("TASK-1")).thenReturn(beforeLegacy, legacyResult); + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + HashMap parameters = invocation.getArgument(0); + parameters.put("v_result", "10"); + parameters.put("v_resultmsg", "ok"); + return null; + }).when(mydoJobMapper).allotInJobSpace(any()); + } + + @Test + void observesBeforeLegacyAndReturnsTheReloadedLegacyJob() { + InboundShadowObservation observation = new InboundShadowObservation( + true, "W01", "JOB-1", "READY", "SPACE-SHADOW", "proposal"); + when(shadowObservationGateway.planInbound("TASK-1", "TRAY-1")).thenReturn(observation); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.get(AjaxResult.DATA_TAG)).isSameAs(legacyResult); + InOrder order = inOrder(mydoJobMapper, shadowObservationGateway); + order.verify(mydoJobMapper).selectInJobByTaskNo("TASK-1"); + order.verify(shadowObservationGateway).planInbound("TASK-1", "TRAY-1"); + order.verify(mydoJobMapper).allotInJobSpace(any()); + order.verify(mydoJobMapper).selectInJobByTaskNo("TASK-1"); + order.verify(shadowObservationGateway) + .compareInbound(observation, "10", "SPACE-LEGACY"); + verify(mydoJobMapper, times(1)).allotInJobSpace(any()); + } + + @Test + void shadowExceptionCannotSkipOrReplaceLegacyAllocation() { + when(shadowObservationGateway.planInbound("TASK-1", "TRAY-1")) + .thenThrow(new IllegalStateException("shadow unavailable")); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.get(AjaxResult.DATA_TAG)).isSameAs(legacyResult); + verify(shadowObservationGateway).planInbound("TASK-1", "TRAY-1"); + verify(mydoJobMapper, times(1)).allotInJobSpace(any()); + } + + private MydoJob inboundJob(String trayNo, String cargoSpaceId) { + MydoJob job = new MydoJob(); + job.setInOrOut("10"); + job.setTrayCode(trayNo); + job.setCargoSpaceId(cargoSpaceId); + return job; + } +}