fix(lastleg): keep inventory warehouse snapshots canonical
This commit is contained in:
+18
@@ -9,6 +9,8 @@ import com.baiyue.lastleg.inventory.query.mapper.InventoryQueryMapper;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -82,6 +84,22 @@ class InventorySchemaContractTest {
|
||||
assertFalse(sql.contains("sku_code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void balanceQueriesHideZeroRowsAndMutationsKeepWarehouseDimensionCanonical() throws Exception {
|
||||
assertTrue(InventoryQueryMapper.BALANCE_FILTER.contains("procurement_packages)>0"));
|
||||
assertTrue(InventoryQueryMapper.JOINED_BALANCE_FILTER.contains("b.procurement_packages)>0"));
|
||||
String bindSql = String.join(" ", com.baiyue.lastleg.inventory.mapper.InventoryBalanceMapper.class
|
||||
.getMethod("bindInboundPlan", String.class, String.class, Long.class, String.class,
|
||||
String.class, java.time.LocalDateTime.class)
|
||||
.getAnnotation(Update.class).value());
|
||||
assertTrue(bindSql.contains("overseas_warehouse_id=#{overseasWarehouseId}"));
|
||||
String deleteSql = String.join(" ", com.baiyue.lastleg.inventory.command.mapper.InventoryCommandMapper.class
|
||||
.getMethod("deleteEmptyBalance", String.class, Long.class)
|
||||
.getAnnotation(Delete.class).value());
|
||||
assertTrue(deleteSql.contains("in_transit_packages=0"));
|
||||
assertTrue(deleteSql.contains("NOT EXISTS"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void incrementalMigrationIsAdditiveAndRerunnable() throws IOException {
|
||||
String migration = Files.readString(Path.of("..", "scripts", "db", "incremental.sql"), StandardCharsets.UTF_8)
|
||||
|
||||
+36
@@ -140,6 +140,7 @@ class InventoryCommandServiceTest {
|
||||
source.setInTransitPackages(12L);
|
||||
when(balances.lockDimension("100", "WH-1", "ONT8", 101L, "IN-CODE-1")).thenReturn(target);
|
||||
when(commands.lockInboundTransitBalances("100", 101L, "IN-CODE-1")).thenReturn(List.of(source));
|
||||
when(commands.deleteEmptyBalance("100", 201L)).thenReturn(1);
|
||||
|
||||
InventoryCommandResponse result = service.stockIn("100", "7",
|
||||
stockIn("IN-1", "stock-in-cross-warehouse", 12, 24));
|
||||
@@ -152,6 +153,40 @@ class InventoryCommandServiceTest {
|
||||
assertEquals(-12L, written.getAllValues().get(0).getDeltaPackages());
|
||||
assertEquals("STOCK_IN", written.getAllValues().get(1).getBusinessType());
|
||||
assertEquals("IN_TRANSIT", written.getAllValues().get(1).getStatusFrom());
|
||||
verify(commands).deleteEmptyBalance("100", 201L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receivingWarehouseChangeRebindsOnlyInTransitBalanceAndWritesZeroDeltaAudit() {
|
||||
InventoryBalance balance = balance(200L, 0);
|
||||
balance.setInTransitPackages(12L);
|
||||
when(commands.lockInboundBalances("100", 101L)).thenReturn(List.of(balance));
|
||||
when(balances.lockDimension("100", "900", "ONT8", 101L, "IN-CODE-1")).thenReturn(null);
|
||||
|
||||
service.rebindReceivingWarehouse("100", 101L, 900L, "US-NYC-01", "纽约仓",
|
||||
"admin", "change-1");
|
||||
|
||||
assertEquals("900", balance.getOverseasWarehouseId());
|
||||
assertEquals("US-NYC-01", balance.getOverseasWarehouseCode());
|
||||
assertEquals("纽约仓", balance.getOverseasWarehouseName());
|
||||
ArgumentCaptor<InventoryLedger> audit = ArgumentCaptor.forClass(InventoryLedger.class);
|
||||
verify(ledgers).insert(audit.capture());
|
||||
assertEquals("RECEIVING_WAREHOUSE_CHANGED", audit.getValue().getBusinessType());
|
||||
assertEquals(0L, audit.getValue().getDeltaPackages());
|
||||
assertEquals(12L, audit.getValue().getBeforePackages());
|
||||
assertEquals(12L, audit.getValue().getAfterPackages());
|
||||
}
|
||||
|
||||
@Test
|
||||
void receivingWarehouseChangeRejectsPhysicalInventoryBeforeAnySnapshotMutation() {
|
||||
InventoryBalance balance = balance(200L, 1);
|
||||
when(commands.lockInboundBalances("100", 101L)).thenReturn(List.of(balance));
|
||||
|
||||
assertThrows(ResponseStatusException.class, () -> service.rebindReceivingWarehouse(
|
||||
"100", 101L, 900L, "US-NYC-01", "纽约仓", "admin", "change-physical"));
|
||||
|
||||
verify(balances, never()).updateById(any(InventoryBalance.class));
|
||||
verify(ledgers, never()).insert(any(InventoryLedger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -311,6 +346,7 @@ class InventoryCommandServiceTest {
|
||||
InventoryBalance value = new InventoryBalance();
|
||||
value.setId(id); value.setCustomerId("100"); value.setCustomerName("Customer 100");
|
||||
value.setOverseasWarehouseId("WH-1");
|
||||
value.setOverseasWarehouseCode("WH1"); value.setOverseasWarehouseName("Warehouse 1");
|
||||
value.setDestinationWarehouseCode("ONT8"); value.setInboundOrderId(101L);
|
||||
value.setInboundOrderNo("IN-1"); value.setInboundCode("IN-CODE-1");
|
||||
value.setAvailablePackages(available);
|
||||
|
||||
Reference in New Issue
Block a user