fix(phase4): enforce customer and pallet versions
This commit is contained in:
+10
-2
@@ -23,11 +23,19 @@ public final class PalletRequests {
|
||||
@NotBlank String status,
|
||||
Long locationId,
|
||||
@Size(max = 500) String remark,
|
||||
@Size(max = 128) String fbaWarehouseCode
|
||||
@Size(max = 128) String fbaWarehouseCode,
|
||||
@Min(0) Integer version
|
||||
) {
|
||||
public SaveRequest(String palletCode, String palletType, BigDecimal capacityCbm,
|
||||
BigDecimal unitPrice, String status, Long locationId, String remark) {
|
||||
this(palletCode, palletType, capacityCbm, unitPrice, status, locationId, remark, null);
|
||||
this(palletCode, palletType, capacityCbm, unitPrice, status, locationId, remark, null, null);
|
||||
}
|
||||
|
||||
public SaveRequest(String palletCode, String palletType, BigDecimal capacityCbm,
|
||||
BigDecimal unitPrice, String status, Long locationId, String remark,
|
||||
String fbaWarehouseCode) {
|
||||
this(palletCode, palletType, capacityCbm, unitPrice, status, locationId, remark,
|
||||
fbaWarehouseCode, null);
|
||||
}
|
||||
|
||||
public SaveRequest {
|
||||
|
||||
+2
-2
@@ -124,8 +124,8 @@ public class WarehouseResourceRepository {
|
||||
pallets.insert(entity);
|
||||
}
|
||||
|
||||
public void updatePallet(WarehousePalletEntity entity) {
|
||||
pallets.updateById(entity);
|
||||
public int updatePallet(WarehousePalletEntity entity) {
|
||||
return pallets.updateById(entity);
|
||||
}
|
||||
|
||||
public WarehousePalletEntity findPallet(long customerId, long warehouseId, long id) {
|
||||
|
||||
+7
-1
@@ -152,6 +152,9 @@ public class WarehouseResourceService {
|
||||
@Transactional
|
||||
public void updatePallet(long customerId, long warehouseId, long id, PalletRequests.SaveRequest request) {
|
||||
WarehousePalletEntity existing = requirePallet(customerId, warehouseId, id);
|
||||
if (request.version() == null || !request.version().equals(existing.getVersion())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "托盘版本已变化,请刷新后重试");
|
||||
}
|
||||
if ("SCRAPPED".equals(existing.getStatus()) && !"SCRAPPED".equals(request.status())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "SCRAPPED pallet cannot be reused");
|
||||
}
|
||||
@@ -161,7 +164,10 @@ public class WarehouseResourceService {
|
||||
validatePallet(request, palletCode, locationId, customerId, warehouseId, id);
|
||||
WarehousePalletEntity entity = palletEntity(customerId, warehouseId, request, palletCode, locationId);
|
||||
entity.setId(existing.getId());
|
||||
repository.updatePallet(entity);
|
||||
entity.setVersion(request.version());
|
||||
if (repository.updatePallet(entity) != 1) {
|
||||
throw new BizException(ResultCode.CONFLICT, "托盘版本已变化,请刷新后重试");
|
||||
}
|
||||
}
|
||||
|
||||
public WarehousePalletEntity pallet(long customerId, long warehouseId, long id) {
|
||||
|
||||
+29
-3
@@ -259,10 +259,11 @@ class WarehouseResourceServiceTest {
|
||||
existing.setId(40002L);
|
||||
existing.setPalletCode("PLT-OLD");
|
||||
existing.setStatus("SCRAPPED");
|
||||
existing.setVersion(0);
|
||||
when(repository.findPallet(TENANT, WAREHOUSE, 40002L)).thenReturn(existing);
|
||||
|
||||
assertThatThrownBy(() -> service.updatePallet(TENANT, WAREHOUSE, 40002L,
|
||||
new PalletRequests.SaveRequest(null, "STANDARD", null, BigDecimal.ONE, "IDLE", null, null)))
|
||||
new PalletRequests.SaveRequest(null, "STANDARD", null, BigDecimal.ONE, "IDLE", null, null, null, 0)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("cannot be reused");
|
||||
}
|
||||
@@ -274,17 +275,20 @@ class WarehouseResourceServiceTest {
|
||||
existing.setId(40003L);
|
||||
existing.setPalletCode("PLT-OLD");
|
||||
existing.setStatus("IDLE");
|
||||
existing.setVersion(2);
|
||||
when(repository.findPallet(TENANT, WAREHOUSE, 40003L)).thenReturn(existing);
|
||||
when(repository.updatePallet(org.mockito.ArgumentMatchers.any())).thenReturn(1);
|
||||
|
||||
service.updatePallet(TENANT, WAREHOUSE, 40003L,
|
||||
new PalletRequests.SaveRequest("PLT-NEW", "WOOD", new BigDecimal("2.5000"),
|
||||
new BigDecimal("25.00"), "IDLE", null, "updated", "ONT8"));
|
||||
new BigDecimal("25.00"), "IDLE", null, "updated", "ONT8", 2));
|
||||
|
||||
ArgumentCaptor<WarehousePalletEntity> captor = ArgumentCaptor.forClass(WarehousePalletEntity.class);
|
||||
verify(repository).palletCodeExists(TENANT, WAREHOUSE, "PLT-NEW", 40003L);
|
||||
verify(repository).updatePallet(captor.capture());
|
||||
assertThat(captor.getValue().getPalletCode()).isEqualTo("PLT-NEW");
|
||||
assertThat(captor.getValue().getFbaWarehouseCode()).isEqualTo("ONT8");
|
||||
assertThat(captor.getValue().getVersion()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -294,17 +298,39 @@ class WarehouseResourceServiceTest {
|
||||
existing.setId(40004L);
|
||||
existing.setPalletCode("PLT-OLD");
|
||||
existing.setStatus("IDLE");
|
||||
existing.setVersion(0);
|
||||
when(repository.findPallet(TENANT, WAREHOUSE, 40004L)).thenReturn(existing);
|
||||
when(repository.palletCodeExists(TENANT, WAREHOUSE, "PLT-DUP", 40004L)).thenReturn(true);
|
||||
|
||||
assertThatThrownBy(() -> service.updatePallet(TENANT, WAREHOUSE, 40004L,
|
||||
new PalletRequests.SaveRequest("PLT-DUP", "WOOD", BigDecimal.ONE,
|
||||
BigDecimal.ONE, "IDLE", null, null, "ONT8")))
|
||||
BigDecimal.ONE, "IDLE", null, null, "ONT8", 0)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("托盘编码已存在");
|
||||
verify(repository, never()).updatePallet(org.mockito.ArgumentMatchers.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updatePalletRejectsStaleVersionBeforeMutation() {
|
||||
when(repository.warehouseOwned(TENANT, WAREHOUSE)).thenReturn(true);
|
||||
WarehousePalletEntity existing = new WarehousePalletEntity();
|
||||
existing.setId(40005L);
|
||||
existing.setPalletCode("PLT-OLD");
|
||||
existing.setStatus("IDLE");
|
||||
existing.setVersion(3);
|
||||
when(repository.findPallet(TENANT, WAREHOUSE, 40005L)).thenReturn(existing);
|
||||
|
||||
assertThatThrownBy(() -> service.updatePallet(TENANT, WAREHOUSE, 40005L,
|
||||
new PalletRequests.SaveRequest("PLT-STALE", "WOOD", BigDecimal.ONE,
|
||||
BigDecimal.ONE, "IDLE", null, null, "ONT8", 2)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("版本已变化");
|
||||
verify(repository, never()).palletCodeExists(org.mockito.ArgumentMatchers.anyLong(),
|
||||
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString(),
|
||||
org.mockito.ArgumentMatchers.any());
|
||||
verify(repository, never()).updatePallet(org.mockito.ArgumentMatchers.any());
|
||||
}
|
||||
|
||||
private static WarehouseEntity warehouse() {
|
||||
WarehouseEntity warehouse = new WarehouseEntity();
|
||||
warehouse.setId(WAREHOUSE);
|
||||
|
||||
Reference in New Issue
Block a user