优化
This commit is contained in:
@@ -143,9 +143,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
||||
SELECT current_group.id groupId,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.accountId END accountId,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.inboundId END inboundId,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.palletId END palletId,
|
||||
MIN(eligible.expectedArrivalAt) sortArrivalAt,MIN(eligible.inboundId) sortInboundId
|
||||
FROM (
|
||||
SELECT o.tenant_id accountId,o.id inboundId,o.inbound_code inboundCode,
|
||||
available_pallet.palletId palletId,
|
||||
o.expected_arrival_at expectedArrivalAt,o.created_at createdAt,
|
||||
CASE WHEN o.process_status='WAIT_SPLIT' THEN 'WAIT_SPLIT'
|
||||
WHEN o.process_status='LOADING' THEN 'LOADING' ELSE 'WAIT_MEASURE' END candidateStatus,
|
||||
@@ -165,6 +167,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
||||
WHERE o.inbound_role='MASTER' AND split_item.tenant_id=o.tenant_id
|
||||
AND split_item.parent_inbound_id=o.id),0) availablePackageCount
|
||||
FROM fl_inbound_order o
|
||||
LEFT JOIN (
|
||||
SELECT DISTINCT carton.tenant_id accountId,carton.inbound_id inboundId,pallet.id palletId
|
||||
FROM fl_dropship_pallet pallet
|
||||
JOIN fl_dropship_pallet_carton carton ON carton.pallet_id=pallet.id
|
||||
WHERE pallet.pallet_status='SEALED'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM fl_loading_plan_item pallet_item
|
||||
WHERE pallet_item.pallet_id=pallet.id AND pallet_item.deleted=0
|
||||
)
|
||||
) available_pallet
|
||||
ON available_pallet.accountId=o.tenant_id AND available_pallet.inboundId=o.id
|
||||
AND o.fulfillment_type='ONE_CLICK_DROPSHIP'
|
||||
WHERE (#{query.warehouseId} IS NULL OR o.warehouse_id=#{query.warehouseId})
|
||||
AND COALESCE(o.hold_flag,0)=0
|
||||
AND o.channel_code IN
|
||||
@@ -174,11 +188,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
||||
o.process_status IN ('WAIT_MEASURE','MEASURING','MEASURE_PENDING','MEASURE_REJECTED',
|
||||
'WAIT_PRICING','FEE_CONFIRMING','INBOUNDING','WAIT_SPLIT','LOADING')
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM fl_loading_plan_item active_item
|
||||
WHERE active_item.account_id=o.tenant_id AND active_item.inbound_id=o.id
|
||||
AND active_item.deleted=0
|
||||
)
|
||||
AND ((COALESCE(o.fulfillment_type,'STANDARD')<>'ONE_CLICK_DROPSHIP' AND NOT EXISTS (
|
||||
SELECT 1 FROM fl_loading_plan_item active_item
|
||||
WHERE active_item.account_id=o.tenant_id AND active_item.inbound_id=o.id
|
||||
AND active_item.deleted=0
|
||||
)) OR (o.fulfillment_type='ONE_CLICK_DROPSHIP' AND available_pallet.palletId IS NOT NULL))
|
||||
) eligible
|
||||
LEFT JOIN fl_coload_group_member current_member
|
||||
ON current_member.tenant_id=eligible.accountId AND current_member.inbound_id=eligible.inboundId
|
||||
@@ -188,9 +202,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
||||
WHERE eligible.candidateStatus<>'WAIT_SPLIT' OR eligible.availablePackageCount>0
|
||||
GROUP BY current_group.id,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.accountId END,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.inboundId END
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.inboundId END,
|
||||
CASE WHEN current_group.id IS NULL THEN eligible.palletId END
|
||||
HAVING (current_group.id IS NULL OR (
|
||||
COUNT(*)=(SELECT COUNT(*) FROM fl_coload_group_member group_member_count
|
||||
COUNT(DISTINCT eligible.accountId,eligible.inboundId)=(SELECT COUNT(*) FROM fl_coload_group_member group_member_count
|
||||
WHERE group_member_count.group_id=current_group.id AND group_member_count.active_flag=1)
|
||||
))
|
||||
<if test="query.orderStatuses != null and !query.orderStatuses.isEmpty()">
|
||||
@@ -444,8 +459,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ba
|
||||
private String channelCode;
|
||||
private Long availableContainerCount;
|
||||
}
|
||||
record CandidateUnit(Long groupId,Long accountId,Long inboundId,
|
||||
LocalDateTime sortArrivalAt,Long sortInboundId) {}
|
||||
record CandidateUnit(Long groupId,Long accountId,Long inboundId,Long palletId,
|
||||
LocalDateTime sortArrivalAt,Long sortInboundId) {
|
||||
public CandidateUnit(Long groupId,Long accountId,Long inboundId,
|
||||
LocalDateTime sortArrivalAt,Long sortInboundId) {
|
||||
this(groupId,accountId,inboundId,null,sortArrivalAt,sortInboundId);
|
||||
}
|
||||
}
|
||||
record PlanColoadMemberRow(Long groupId,String groupNo,Long lockedPlanId,
|
||||
Long orderId,Long inboundId,Integer fullPackageCount) {}
|
||||
}
|
||||
|
||||
@@ -175,15 +175,15 @@ public class SmartLoadingService {
|
||||
LinkedHashMap::new, java.util.stream.Collectors.toList()));
|
||||
for (InboundCandidate candidate : all) {
|
||||
if (candidate.coLoadGroupId() == null) {
|
||||
units.put(unitKey(null, candidate.accountId(), candidate.inboundId()), candidate);
|
||||
units.put(unitKey(null, candidate.accountId(), candidate.inboundId(), candidate.palletId()), candidate);
|
||||
}
|
||||
}
|
||||
for (var entry : grouped.entrySet()) {
|
||||
InboundCandidate aggregate = globalGroupCandidate(entry.getValue());
|
||||
if (aggregate != null) units.put(unitKey(entry.getKey(), null, null), aggregate);
|
||||
if (aggregate != null) units.put(unitKey(entry.getKey(), null, null, null), aggregate);
|
||||
}
|
||||
List<InboundCandidate> records = unitPage.records().stream()
|
||||
.map(unit -> units.get(unitKey(unit.groupId(), unit.accountId(), unit.inboundId())))
|
||||
.map(unit -> units.get(unitKey(unit.groupId(), unit.accountId(), unit.inboundId(), unit.palletId())))
|
||||
.filter(Objects::nonNull).toList();
|
||||
return new PageResult<>(records, unitPage.page(), unitPage.size(), unitPage.total(), unitPage.pages());
|
||||
}
|
||||
@@ -357,8 +357,8 @@ public class SmartLoadingService {
|
||||
};
|
||||
}
|
||||
|
||||
private static String unitKey(Long groupId, Long accountId, Long inboundId) {
|
||||
return groupId == null ? "I|" + accountId + '|' + inboundId : "G|" + groupId;
|
||||
private static String unitKey(Long groupId, Long accountId, Long inboundId, Long palletId) {
|
||||
return groupId == null ? "I|" + accountId + '|' + inboundId + '|' + palletId : "G|" + groupId;
|
||||
}
|
||||
|
||||
private static BigDecimal weightedAverage(List<InboundCandidate> members,
|
||||
|
||||
+5
@@ -91,6 +91,11 @@ class SmartLoadingCandidateMapperContractTest {
|
||||
.contains("status.name() == 'WAIT_SPLIT'")
|
||||
.contains("status.name() == 'LOADING'")
|
||||
.contains("NOT EXISTS (", "active_item.inbound_id=o.id", "active_item.deleted=0")
|
||||
.contains("available_pallet.palletId palletId")
|
||||
.contains("pallet.pallet_status='SEALED'")
|
||||
.contains("pallet_item.pallet_id=pallet.id", "pallet_item.deleted=0")
|
||||
.contains("o.fulfillment_type='ONE_CLICK_DROPSHIP' AND available_pallet.palletId IS NOT NULL")
|
||||
.contains("CASE WHEN current_group.id IS NULL THEN eligible.palletId END palletId")
|
||||
.contains("current_group.id groupId")
|
||||
.contains("group_member_count.group_id=current_group.id")
|
||||
.doesNotContain("fl_container_booking")
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.DeleteRequest;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.GroupMemberCandidate;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.InboundCandidateQuery;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.InboundCandidate;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.PalletCandidate;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.WorkbenchContainer;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.WorkbenchContainerQuery;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.Plan;
|
||||
@@ -224,6 +225,39 @@ class SmartLoadingServiceTest {
|
||||
verify(repository, never()).booking(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void pagesEachAvailableDropshipPalletAsAnIndependentCandidate() {
|
||||
Candidate dropship = withChannel(candidate(9L, 10L, 20L, 30L, 12),
|
||||
"EXX_TRUCK", "EXX海卡");
|
||||
InboundCandidateQuery query = new InboundCandidateQuery(
|
||||
List.of("EXX"), null, null, "EXXHWK2609140003", null, null,
|
||||
null, null, List.of(CandidateOrderStatus.WAIT_SPLIT), 1, 20);
|
||||
List<CandidateUnit> units = List.of(
|
||||
new CandidateUnit(null, 9L, 10L, 801L, null, 10L),
|
||||
new CandidateUnit(null, 9L, 10L, 802L, null, 10L));
|
||||
when(repository.globalCandidateUnits(eq(query), anySet()))
|
||||
.thenReturn(new PageResult<>(units, 1, 20, 2, 1));
|
||||
when(repository.globalCandidatesByUnits(units)).thenReturn(List.of(dropship));
|
||||
when(dropshipPallets.palletCandidates(10L)).thenReturn(List.of(
|
||||
new PalletCandidate(801L, "DP-260914-0004", "SEALED_PALLET", true,
|
||||
8, 1, new BigDecimal("79.2"), new BigDecimal("4.4")),
|
||||
new PalletCandidate(802L, "DP-260914-0005", "SEALED_PALLET", true,
|
||||
4, 1, new BigDecimal("39.6"), new BigDecimal("2.2"))));
|
||||
|
||||
var result = service.inboundCandidates(query);
|
||||
|
||||
assertThat(result.total()).isEqualTo(2);
|
||||
assertThat(result.records()).extracting(InboundCandidate::palletId,
|
||||
InboundCandidate::palletNo, InboundCandidate::availablePackageCount)
|
||||
.containsExactly(
|
||||
org.assertj.core.groups.Tuple.tuple(801L, "DP-260914-0004", 8),
|
||||
org.assertj.core.groups.Tuple.tuple(802L, "DP-260914-0005", 4));
|
||||
assertThat(result.records()).allSatisfy(candidate -> {
|
||||
assertThat(candidate.unitType()).isEqualTo("SEALED_PALLET");
|
||||
assertThat(candidate.indivisible()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void combinesAllUnfinishedStatusesBeforeReturningTheRequestedPage() {
|
||||
InboundCandidateQuery query = new InboundCandidateQuery(
|
||||
|
||||
Reference in New Issue
Block a user