test: expand domestic container acceptance coverage

This commit is contained in:
2026-09-04 12:02:38 +08:00
parent 55cad93be3
commit b971ca2f7c
6 changed files with 142 additions and 4 deletions
@@ -81,7 +81,8 @@ public class DomesticContainerService {
DomesticContainerInventoryEntity inventory = repository.lockInventory(warehouse.getId(), normalize(request.containerNo()));
if (inventory == null) throw new BizException(ResultCode.NOT_FOUND, "整柜库存不存在");
if ("COMPLETED".equals(request.status())) {
if (request.inventoryVersion() != null && !request.inventoryVersion().equals(inventory.getVersion())) throw new BizException(ResultCode.CONFLICT, "库存已被修改,请刷新后重试");
if (request.inventoryVersion() == null) throw new BizException(ResultCode.VALIDATION_FAILED, "完成出库必须提供库存版本");
if (!request.inventoryVersion().equals(inventory.getVersion())) throw new BizException(ResultCode.CONFLICT, "库存已被修改,请刷新后重试");
if (request.boxCount() > inventory.getAvailableBoxes()) throw new BizException(ResultCode.CONFLICT, "出库箱数超过可用库存");
}
DomesticContainerOrderEntity order = new DomesticContainerOrderEntity(); order.setId(IdWorker.getId()); order.setTenantId(PLATFORM_TENANT); order.setBusinessType("OUTBOUND");
@@ -74,7 +74,7 @@ components:
status: { type: string, enum: [PENDING, COMPLETED] }
remark: { type: string, maxLength: 500 }
idempotencyKey: { type: string, maxLength: 128 }
inventoryVersion: { type: integer, minimum: 0 }
inventoryVersion: { type: integer, minimum: 0, description: 完成出库时必填;待出库不扣减库存时可不传 }
ApiEnvelope:
type: object
required: [code, message, timestamp]
@@ -1,6 +1,7 @@
package com.baiyue.warehouse.domesticcontainer.service;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.warehouse.domesticcontainer.dto.DomesticContainerDtos;
import com.baiyue.warehouse.domesticcontainer.entity.DomesticContainerIdempotencyEntity;
import com.baiyue.warehouse.domesticcontainer.entity.DomesticContainerInventoryEntity;
@@ -76,6 +77,24 @@ class DomesticContainerServiceTest {
verify(repository, never()).insertOrder(any());
}
@Test
void completedOutboundRequiresInventoryVersionBeforeWriting() {
when(warehouses.findActiveOwned(0L, 10L)).thenReturn(warehouse());
when(repository.claim(anyLong(), eq("OUTBOUND"), eq("out-no-version"), any())).thenReturn(1);
DomesticContainerInventoryEntity inventory = inventory(120, 0, 120, 3);
when(repository.lockInventory(10L, "MSCU1234567")).thenReturn(inventory);
assertThatThrownBy(() -> service.createOutbound(new DomesticContainerDtos.CreateOutboundRequest(10L,
"MSCU1234567", 1, LocalDateTime.now(), "COMPLETED", null, "out-no-version", null)))
.isInstanceOf(BizException.class)
.extracting(error -> ((BizException) error).getResultCode())
.isEqualTo(ResultCode.VALIDATION_FAILED);
assertThat(inventory.getAvailableBoxes()).isEqualTo(120);
verify(repository, never()).insertOrder(any());
verify(repository, never()).updateInventory(any());
verify(repository, never()).insertTransaction(any());
}
@Test
void replaysCompletedIdempotentRequestWithoutWriting() {
DomesticContainerIdempotencyEntity replay = new DomesticContainerIdempotencyEntity();