fix(overseas): repair pallet transitions and transfer queries

This commit is contained in:
2026-09-29 14:18:20 +08:00
parent 875d2497f4
commit 8df0f4e823
11 changed files with 114 additions and 31 deletions
@@ -1,5 +1,7 @@
package com.baiyue.lastleg.palletops.gateway;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.lastleg.config.LastlegRestClientFactory;
import com.baiyue.lastleg.config.LastlegRestClientProperties;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -111,18 +113,28 @@ public class HttpPalletPhysicalGateway implements PalletPhysicalGateway {
.onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalStateException("Warehouse rejected pallet transition: HTTP " + result.getStatusCode());
}).body(TransitionEnvelope.class);
if (response == null || response.data() == null) throw new IllegalStateException("Warehouse returned no transition");
requireTransitionSuccess(response);
if (response.data() == null) throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "Warehouse returned no transition");
return response.data();
}
@Override
public void compensate(long warehouseId, Transition transition) {
client.post().uri("/internal/v1/pda-pallet-transitions/{id}/{key}/compensate",
TransitionEnvelope response = client.post().uri("/internal/v1/pda-pallet-transitions/{id}/{key}/compensate",
transition.palletId(), transition.operationKey())
.header("X-Internal-Service-Token", internalToken).body(Map.of("warehouseId", warehouseId))
.retrieve().onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalStateException("Warehouse rejected pallet compensation: HTTP " + result.getStatusCode());
}).toBodilessEntity();
}).body(TransitionEnvelope.class);
requireTransitionSuccess(response);
}
private void requireTransitionSuccess(TransitionEnvelope response) {
if (response != null && "200".equals(response.code())) return;
if (response != null && "A0409".equals(response.code())) {
throw new BizException(ResultCode.CONFLICT, response.message());
}
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "Warehouse pallet transition failed");
}
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -130,5 +142,5 @@ public class HttpPalletPhysicalGateway implements PalletPhysicalGateway {
@JsonIgnoreProperties(ignoreUnknown = true)
private record LocationEnvelope(LocationReference data) { }
@JsonIgnoreProperties(ignoreUnknown = true)
private record TransitionEnvelope(Transition data) { }
private record TransitionEnvelope(String code, String message, Transition data) { }
}
@@ -433,8 +433,10 @@ public class WarehouseTransferService {
value.getFbaWarehouseCode(), value.getDestinationType(), value.getDestinationWarehouseCode(),
value.getDestinationWarehouseName(), value.getPackageCount(), value.getDeliveryMethod(),
Boolean.TRUE.equals(value.getNeedRelabel()), value.getRelabelNo(),
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getStatus(),
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getFulfillmentStatus(),
value.getRelabelNo() == null || relabelApplicationsByNo.get(value.getRelabelNo()) == null
? null : relabelApplicationsByNo.get(value.getRelabelNo()).getStatus(),
value.getRelabelNo() == null || relabelApplicationsByNo.get(value.getRelabelNo()) == null
? null : relabelApplicationsByNo.get(value.getRelabelNo()).getFulfillmentStatus(),
value.getStatus(),
value.getEstimatedArrivalAt(), value.getCreatedAt())).toList();
return new PageResult<>(records, result.getCurrent(), result.getSize(), result.getTotal(), result.getPages());
@@ -26,6 +26,32 @@ class HttpPalletPhysicalGatewayTest {
ReflectionTestUtils.setField(gateway, "internalToken", "test-token");
}
@Test
void applyPreservesBusinessConflictInsteadOfReportingMissingTransition() {
server.expect(requestTo("http://warehouse/internal/v1/pda-pallet-transitions/30"))
.andRespond(withSuccess("""
{"code":"A0409","message":"Pallet version changed","data":null}
""", MediaType.APPLICATION_JSON));
var pallet = new PalletPhysicalGateway.PalletReference(30L, "PAL-1", 88L, 40L, "IDLE", "XLX1", 2);
assertThatThrownBy(() -> gateway.apply(88L, pallet, "OCCUPIED", 40L, "key", "swap"))
.isInstanceOf(com.baiyue.common.core.exception.BizException.class)
.hasMessageContaining("Pallet version changed");
server.verify();
}
@Test
void compensationBusinessFailureIsNotReportedAsSuccess() {
server.expect(requestTo("http://warehouse/internal/v1/pda-pallet-transitions/30/key/compensate"))
.andRespond(withSuccess("""
{"code":"A0409","message":"Pallet changed after operation","data":null}
""", MediaType.APPLICATION_JSON));
var transition = new PalletPhysicalGateway.Transition("key", 30L, "PAL-1", 88L,
"IDLE", "OCCUPIED", 40L, 40L, 2, 3, "APPLIED", false);
assertThatThrownBy(() -> gateway.compensate(88L, transition))
.isInstanceOf(com.baiyue.common.core.exception.BizException.class);
server.verify();
}
@Test
void resolveMapsBusinessNotFoundEnvelopeToStableNotFound() {
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/MISSING"))
@@ -127,6 +127,23 @@ class WarehouseTransferServiceTest {
assertEquals("READY_FOR_DISPATCH", result.records().get(0).relabelFulfillmentStatus());
}
@Test
void transferPageWithoutRelabelReturnsEmptyRelabelStatuses() {
WarehouseTransferOrder transfer = transfer(WarehouseTransferService.WAIT_PDA_RECEIVING);
transfer.setRelabelNo(null);
Page<WarehouseTransferOrder> resultPage = new Page<>(1, 20, 1);
resultPage.setRecords(List.of(transfer));
when(transfers.selectPage(any(), any())).thenReturn(resultPage);
var result = service.page("TENANT-A", new WarehouseTransferRequests.Query(
1, 20, null, null, null, null, null, null, null, null));
assertEquals(1, result.records().size());
assertNull(result.records().get(0).relabelApplicationStatus());
assertNull(result.records().get(0).relabelFulfillmentStatus());
verify(relabelApplications, never()).selectList(any());
}
@Mock WarehouseTransferOrderMapper transfers;
@Mock WarehouseTransferItemMapper transferItems;
@Mock WarehouseTransferCartonMapper transferCartons;