feat: complete finance and overseas receiving workflow

This commit is contained in:
2026-09-10 22:43:11 +08:00
parent e531ae9407
commit 56635ad4e4
66 changed files with 1601 additions and 417 deletions
@@ -86,6 +86,26 @@ class WarehousePalletBatchServiceTest {
.containsExactly("container:plan-a:1", "container:plan-b:2");
}
@Test
void oneDropshipPalletSharedByMultipleCustomersUsesOnePhysicalResourceAndLock() {
when(batches.insertIgnore(any())).thenReturn(1);
when(resources.createPallet(anyLong(), anyLong(), any())).thenReturn(301L);
when(resources.pallet(0L, WAREHOUSE, 301L)).thenReturn(pallet(301L, 401L, "DP-260910-0001"));
when(locks.reserve(any())).thenReturn(lockResponse(CUSTOMER_A, 501L));
var request = new WarehousePalletBatchRequests.EnsureReserved(WAREHOUSE, "dropship-container", List.of(
new WarehousePalletBatchRequests.Item(CUSTOMER_A, "container:dropship-a:1", "PLAN-A", 1,
"STANDARD", null, "DP-260910-0001"),
new WarehousePalletBatchRequests.Item(CUSTOMER_B, "container:dropship-b:2", "PLAN-B", 2,
"STANDARD", null, "DP-260910-0001")));
var response = service.ensureReserved(request);
assertThat(response.items()).extracting(value -> value.palletId()).containsOnly(301L);
assertThat(response.items()).extracting(value -> value.resourceLockId()).containsOnly(501L);
verify(resources, times(1)).createPallet(anyLong(), anyLong(), any());
verify(locks, times(1)).reserve(any());
}
@Test
void missingSourcePalletCodeUsesWarehouseGeneratedPhysicalCode() {
when(batches.insertIgnore(any())).thenReturn(1);
@@ -219,6 +219,29 @@ class WarehouseResourceLockServiceTest {
verify(repository).scrapPalletAtVirtualLocation(lock);
}
@Test
void sharedDropshipPalletIsScrappedThroughItsActualLockOwner() {
WarehousePalletEntity pallet = pallet("OCCUPIED");
pallet.setPalletCode("DP-260910-0001");
pallet.setWarehouseId(WAREHOUSE);
pallet.setLocationId(LOCATION);
WarehouseResourceLockEntity lock = activeLock();
lock.setCustomerId(TENANT + 1);
when(repository.findPallet(TENANT, PALLET)).thenReturn(pallet);
when(repository.findAnyActiveByPallet(PALLET)).thenReturn(lock);
when(repository.find(TENANT + 1, lock.getId())).thenReturn(lock);
WarehouseLocationEntity virtual = location("ACTIVE");
virtual.setLocationType("VIRTUAL");
when(repository.findLocation(TENANT + 1, WAREHOUSE, LOCATION)).thenReturn(virtual);
when(repository.scrapPalletAtVirtualLocation(lock)).thenReturn(1);
when(repository.close(lock, "SCRAPPED")).thenReturn(1);
assertThat(service.scrapByPallet(TENANT, PALLET).status()).isEqualTo("SCRAPPED");
verify(repository).findAnyActiveByPallet(PALLET);
verify(repository).find(TENANT + 1, lock.getId());
}
@Test
void scrapByPalletIsIdempotentWhenAlreadyScrapped() {
WarehousePalletEntity pallet = pallet("SCRAPPED");