diff --git a/firstleg/src/main/java/com/baiyue/firstleg/mapper/SmartLoadingCandidateMapper.java b/firstleg/src/main/java/com/baiyue/firstleg/mapper/SmartLoadingCandidateMapper.java index e876d46d2..955715c40 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/mapper/SmartLoadingCandidateMapper.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/mapper/SmartLoadingCandidateMapper.java @@ -15,7 +15,7 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.Candidate; import org.apache.iba WHERE o.inbound_role='MASTER' AND split_item.tenant_id=o.tenant_id AND split_item.parent_inbound_id=o.id - AND split_item.source_measurement_item_id=i.id),0) availablePackageCount, + AND split_item.source_inbound_detail_id=i.inbound_detail_id),0) availablePackageCount, COALESCE(o.actual_gross_weight_kg / NULLIF(o.total_package_count, 0), 0) unitGrossWeightKg, COALESCE(o.actual_net_weight_kg / NULLIF(o.total_package_count, 0), 0) unitNetWeightKg, COALESCE(i.unit_volume_cbm,0) unitVolumeCbm @@ -24,11 +24,17 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.Candidate; import org.apache.iba AND m.status='APPROVED' AND m.id=(SELECT MAX(m2.id) FROM fl_inbound_measurement m2 WHERE m2.tenant_id=o.tenant_id AND m2.inbound_id=o.id AND m2.status='APPROVED') - JOIN fl_inbound_measurement_item i ON i.tenant_id=o.tenant_id AND i.measurement_id=m.id + JOIN ( + SELECT tenant_id,measurement_id,inbound_detail_id,SUM(package_count) package_count, + COALESCE(SUM(COALESCE(total_volume_cbm,COALESCE(unit_volume_cbm,0)*package_count)) + / NULLIF(SUM(package_count),0),0) unit_volume_cbm + FROM fl_inbound_measurement_item + WHERE inbound_detail_id IS NOT NULL AND package_count>0 + GROUP BY tenant_id,measurement_id,inbound_detail_id + ) i ON i.tenant_id=o.tenant_id AND i.measurement_id=m.id WHERE o.warehouse_id=#{warehouseId} AND o.process_status='WAIT_SPLIT' AND o.actual_gross_weight_kg IS NOT NULL AND o.actual_net_weight_kg IS NOT NULL AND (o.inbound_role='MASTER' OR (o.split_purpose='REMAINDER' AND o.split_status='NOT_SPLIT')) - AND i.inbound_detail_id IS NOT NULL AND i.package_count>COALESCE((SELECT SUM(li.package_count) FROM fl_loading_plan_item li WHERE li.account_id=o.tenant_id AND li.inbound_id=o.id AND li.inbound_detail_id=i.inbound_detail_id AND li.deleted=0),0) @@ -37,8 +43,8 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.Candidate; import org.apache.iba WHERE o.inbound_role='MASTER' AND split_item.tenant_id=o.tenant_id AND split_item.parent_inbound_id=o.id - AND split_item.source_measurement_item_id=i.id),0) - ORDER BY o.inbounded_at ASC, o.id ASC, i.id ASC + AND split_item.source_inbound_detail_id=i.inbound_detail_id),0) + ORDER BY o.inbounded_at ASC, o.id ASC, i.inbound_detail_id ASC """) List candidates(@Param("warehouseId") long warehouseId); @@ -56,7 +62,7 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.Candidate; import org.apache.iba WHERE o.inbound_role='MASTER' AND split_item.tenant_id=o.tenant_id AND split_item.parent_inbound_id=o.id - AND split_item.source_measurement_item_id=i.id),0) availablePackageCount, + AND split_item.source_inbound_detail_id=i.inbound_detail_id),0) availablePackageCount, COALESCE(o.actual_gross_weight_kg / NULLIF(o.total_package_count, 0), 0) unitGrossWeightKg, COALESCE(o.actual_net_weight_kg / NULLIF(o.total_package_count, 0), 0) unitNetWeightKg, COALESCE(i.unit_volume_cbm,0) unitVolumeCbm @@ -65,7 +71,14 @@ import com.baiyue.firstleg.dto.SmartLoadingDtos.Candidate; import org.apache.iba AND m.status='APPROVED' AND m.id=(SELECT MAX(m2.id) FROM fl_inbound_measurement m2 WHERE m2.tenant_id=o.tenant_id AND m2.inbound_id=o.id AND m2.status='APPROVED') - JOIN fl_inbound_measurement_item i ON i.tenant_id=o.tenant_id AND i.measurement_id=m.id + JOIN ( + SELECT tenant_id,measurement_id,inbound_detail_id,SUM(package_count) package_count, + COALESCE(SUM(COALESCE(total_volume_cbm,COALESCE(unit_volume_cbm,0)*package_count)) + / NULLIF(SUM(package_count),0),0) unit_volume_cbm + FROM fl_inbound_measurement_item + WHERE inbound_detail_id IS NOT NULL AND package_count>0 + GROUP BY tenant_id,measurement_id,inbound_detail_id + ) i ON i.tenant_id=o.tenant_id AND i.measurement_id=m.id WHERE o.warehouse_id=#{warehouseId} AND o.id=#{inboundId} AND o.process_status='WAIT_SPLIT' AND o.actual_gross_weight_kg IS NOT NULL AND o.actual_net_weight_kg IS NOT NULL AND (o.inbound_role='MASTER' OR (o.split_purpose='REMAINDER' AND o.split_status='NOT_SPLIT')) diff --git a/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingCandidateMapperContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingCandidateMapperContractTest.java index b74c68455..fbeb77491 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingCandidateMapperContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingCandidateMapperContractTest.java @@ -19,7 +19,9 @@ class SmartLoadingCandidateMapperContractTest { .contains("m.status='APPROVED'") .contains("SELECT MAX(m2.id)") .contains("m2.status='APPROVED'") - .contains("i.inbound_detail_id IS NOT NULL") + .contains("WHERE inbound_detail_id IS NOT NULL AND package_count>0") + .contains("SUM(package_count) package_count") + .contains("GROUP BY tenant_id,measurement_id,inbound_detail_id") .contains("o.warehouse_id=#{warehouseId}") .contains("o.process_status='WAIT_SPLIT'") .contains("unitGrossWeightKg") @@ -29,7 +31,7 @@ class SmartLoadingCandidateMapperContractTest { .doesNotContain("i.unit_weight_kg") .contains("SELECT SUM(li.package_count)") .contains("li.deleted=0") - .contains("ORDER BY o.inbounded_at ASC, o.id ASC, i.id ASC"); + .contains("ORDER BY o.inbounded_at ASC, o.id ASC, i.inbound_detail_id ASC"); } @Test @@ -48,6 +50,8 @@ class SmartLoadingCandidateMapperContractTest { .contains("unitNetWeightKg") .doesNotContain("i.unit_weight_kg") .contains("SELECT SUM(li.package_count)") + .contains("SUM(package_count) package_count") + .contains("GROUP BY tenant_id,measurement_id,inbound_detail_id") .contains("FOR UPDATE"); } } diff --git a/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingSqlContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingSqlContractTest.java index d784cf5f6..8f4302c98 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingSqlContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/repository/SmartLoadingSqlContractTest.java @@ -76,6 +76,18 @@ class SmartLoadingSqlContractTest { .contains("version INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '乐观锁版本号'"); } + @Test + @DisplayName("同一入库明细的多条单箱测量记录只生成一个候选") + void shouldAggregateCartonMeasurementRowsByInboundDetail() throws Exception { + String mapper = Files.readString(Path.of( + "src/main/java/com/baiyue/firstleg/mapper/SmartLoadingCandidateMapper.java"), StandardCharsets.UTF_8); + assertThat(mapper) + .contains("SUM(package_count) package_count") + .contains("GROUP BY tenant_id,measurement_id,inbound_detail_id") + .contains("split_item.source_inbound_detail_id=i.inbound_detail_id") + .doesNotContain("split_item.source_measurement_item_id=i.id"); + } + @Test @DisplayName("仓库备注使用计划先行与明细单表CAS并允许已拣明细仅改备注") void shouldUpdateWarehouseRemarkWithoutMultiTableTriggerConflict() throws Exception {