fix: stabilize smart loading plan reads
This commit is contained in:
@@ -359,6 +359,21 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
|||||||
Candidate candidate(@Param("planId") long planId,@Param("warehouseId") long warehouseId,
|
Candidate candidate(@Param("planId") long planId,@Param("warehouseId") long warehouseId,
|
||||||
@Param("inboundId") long inboundId,@Param("detailId") long detailId);
|
@Param("inboundId") long inboundId,@Param("detailId") long detailId);
|
||||||
|
|
||||||
|
@Select("""
|
||||||
|
SELECT SUM(i.package_count)
|
||||||
|
FROM fl_inbound_measurement m
|
||||||
|
JOIN fl_inbound_measurement_item i
|
||||||
|
ON i.tenant_id=m.tenant_id AND i.measurement_id=m.id
|
||||||
|
WHERE m.tenant_id=#{accountId} AND m.inbound_id=#{inboundId} AND m.status='APPROVED'
|
||||||
|
AND m.id=(SELECT MAX(m2.id) FROM fl_inbound_measurement m2
|
||||||
|
WHERE m2.tenant_id=m.tenant_id AND m2.inbound_id=m.inbound_id
|
||||||
|
AND m2.status='APPROVED')
|
||||||
|
AND i.inbound_detail_id=#{detailId} AND i.package_count>0
|
||||||
|
""")
|
||||||
|
Integer measuredPackageCount(@Param("accountId") long accountId,
|
||||||
|
@Param("inboundId") long inboundId,
|
||||||
|
@Param("detailId") long detailId);
|
||||||
|
|
||||||
@lombok.Getter @lombok.Setter class ChannelContainerCountRow {
|
@lombok.Getter @lombok.Setter class ChannelContainerCountRow {
|
||||||
private String channelCode;
|
private String channelCode;
|
||||||
private Long availableContainerCount;
|
private Long availableContainerCount;
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ public class SmartLoadingRepository {
|
|||||||
public Candidate candidate(long planId, long warehouseId, long inboundId, long detailId) {
|
public Candidate candidate(long planId, long warehouseId, long inboundId, long detailId) {
|
||||||
return candidates.candidate(planId, warehouseId, inboundId, detailId);
|
return candidates.candidate(planId, warehouseId, inboundId, detailId);
|
||||||
}
|
}
|
||||||
|
public Integer measuredPackageCount(long accountId, long inboundId, long detailId) {
|
||||||
|
return candidates.measuredPackageCount(accountId, inboundId, detailId);
|
||||||
|
}
|
||||||
public InboundOrderEntity inbound(long accountId, long inboundId) {
|
public InboundOrderEntity inbound(long accountId, long inboundId) {
|
||||||
return inbounds.selectOne(new LambdaQueryWrapper<InboundOrderEntity>()
|
return inbounds.selectOne(new LambdaQueryWrapper<InboundOrderEntity>()
|
||||||
.eq(InboundOrderEntity::getTenantId, accountId)
|
.eq(InboundOrderEntity::getTenantId, accountId)
|
||||||
|
|||||||
@@ -1429,7 +1429,7 @@ public class SmartLoadingService {
|
|||||||
int picked = task.pickedByPlanItem().getOrDefault(item.getId(), 0);
|
int picked = task.pickedByPlanItem().getOrDefault(item.getId(), 0);
|
||||||
item.setPickedPackageCount(picked);
|
item.setPickedPackageCount(picked);
|
||||||
item.setMinPackageCount(Math.max(1, picked));
|
item.setMinPackageCount(Math.max(1, picked));
|
||||||
int total = adjustmentTotal(p.getId(), b.getWarehouseId(), item);
|
int total = adjustmentTotal(item);
|
||||||
item.setTotalPackageCount(total);
|
item.setTotalPackageCount(total);
|
||||||
item.setRemainingPackageCount(Math.max(0, total - item.getPackageCount()));
|
item.setRemainingPackageCount(Math.max(0, total - item.getPackageCount()));
|
||||||
item.setCanAdjust(mutable);
|
item.setCanAdjust(mutable);
|
||||||
@@ -1441,18 +1441,21 @@ public class SmartLoadingService {
|
|||||||
b.getContainerNo(),b.getVoyageNo(),p.getVersion(),mutable,mutable,blockedReason,finalStatus,
|
b.getContainerNo(),b.getVoyageNo(),p.getVersion(),mutable,mutable,blockedReason,finalStatus,
|
||||||
task.taskId(),task.taskStatus(),task.taskVersion(),planCoLoadGroups(p.getId()),items);
|
task.taskId(),task.taskStatus(),task.taskVersion(),planCoLoadGroups(p.getId()),items);
|
||||||
}
|
}
|
||||||
private int adjustmentTotal(long planId, long warehouseId, LoadingPlanItemEntity item) {
|
private int adjustmentTotal(LoadingPlanItemEntity item) {
|
||||||
int current = item.getPackageCount() == null ? 0 : item.getPackageCount();
|
int current = item.getPackageCount() == null ? 0 : item.getPackageCount();
|
||||||
Candidate measured = repository.candidate(planId, warehouseId, item.getInboundId(), item.getInboundDetailId());
|
|
||||||
if (measured != null) {
|
|
||||||
return current + Math.max(0, measured.availablePackageCount() == null
|
|
||||||
? 0 : measured.availablePackageCount());
|
|
||||||
}
|
|
||||||
InboundOrderEntity inbound = repository.inbound(item.getAccountId(), item.getInboundId());
|
|
||||||
if (inbound == null || !Set.of("PREPARING", "WAIT_MEASURE", "MEASURING", "MEASURE_PENDING",
|
|
||||||
"MEASURE_REJECTED", "WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING")
|
|
||||||
.contains(inbound.getProcessStatus())) return current;
|
|
||||||
try {
|
try {
|
||||||
|
if (item.getAccountId() == null || item.getInboundId() == null
|
||||||
|
|| item.getInboundDetailId() == null) return current;
|
||||||
|
InboundOrderEntity inbound = repository.inbound(item.getAccountId(), item.getInboundId());
|
||||||
|
if (inbound == null) return current;
|
||||||
|
if (Set.of("WAIT_SPLIT", "LOADING").contains(inbound.getProcessStatus())) {
|
||||||
|
Integer measured = repository.measuredPackageCount(item.getAccountId(), item.getInboundId(),
|
||||||
|
item.getInboundDetailId());
|
||||||
|
return Math.max(current, measured == null ? 0 : measured);
|
||||||
|
}
|
||||||
|
if (!Set.of("PREPARING", "WAIT_MEASURE", "MEASURING", "MEASURE_PENDING",
|
||||||
|
"MEASURE_REJECTED", "WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING")
|
||||||
|
.contains(inbound.getProcessStatus()) || item.getOrderId() == null) return current;
|
||||||
OrderCargoClient.CargoBinding cargo = loadCargo(item.getAccountId(), item.getOrderId(), item.getInboundDetailId());
|
OrderCargoClient.CargoBinding cargo = loadCargo(item.getAccountId(), item.getOrderId(), item.getInboundDetailId());
|
||||||
return Math.max(current, cargo.originalPackageCount() == null ? 0 : cargo.originalPackageCount());
|
return Math.max(current, cargo.originalPackageCount() == null ? 0 : cargo.originalPackageCount());
|
||||||
} catch (RuntimeException ignored) {
|
} catch (RuntimeException ignored) {
|
||||||
|
|||||||
+35
@@ -23,6 +23,7 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -107,6 +108,40 @@ class SmartLoadingProvisionalAdjustmentTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void planReadFallsBackToAssignedCountWhenQuantityEnrichmentFails() {
|
||||||
|
LoadingPlanEntity plan = plan(103);
|
||||||
|
when(repository.planByBooking(99L)).thenReturn(plan);
|
||||||
|
when(repository.booking(99L)).thenReturn(booking());
|
||||||
|
when(repository.items(1L)).thenReturn(List.of(item));
|
||||||
|
when(repository.inbound(9L, 10L))
|
||||||
|
.thenThrow(new DataAccessResourceFailureException("read query failed"));
|
||||||
|
|
||||||
|
Plan result = service.draftByBooking(99L);
|
||||||
|
|
||||||
|
assertThat(result.items()).singleElement().satisfies(updated -> {
|
||||||
|
assertThat(updated.getTotalPackageCount()).isEqualTo(20);
|
||||||
|
assertThat(updated.getRemainingPackageCount()).isZero();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void planReadUsesApprovedMeasurementWithoutCallingTheLockedAdjustmentQuery() {
|
||||||
|
inbound.setProcessStatus("WAIT_SPLIT");
|
||||||
|
when(repository.planByBooking(99L)).thenReturn(plan(103));
|
||||||
|
when(repository.booking(99L)).thenReturn(booking());
|
||||||
|
when(repository.items(1L)).thenReturn(List.of(item));
|
||||||
|
when(repository.inbound(9L, 10L)).thenReturn(inbound);
|
||||||
|
when(repository.measuredPackageCount(9L, 10L, 20L)).thenReturn(100);
|
||||||
|
|
||||||
|
Plan result = service.draftByBooking(99L);
|
||||||
|
|
||||||
|
assertThat(result.items()).singleElement().satisfies(updated -> {
|
||||||
|
assertThat(updated.getTotalPackageCount()).isEqualTo(100);
|
||||||
|
assertThat(updated.getRemainingPackageCount()).isEqualTo(80);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static LoadingPlanEntity plan(int version) {
|
private static LoadingPlanEntity plan(int version) {
|
||||||
LoadingPlanEntity value = new LoadingPlanEntity();
|
LoadingPlanEntity value = new LoadingPlanEntity();
|
||||||
value.setId(1L);
|
value.setId(1L);
|
||||||
|
|||||||
Reference in New Issue
Block a user