一件代发拣货
This commit is contained in:
+6
@@ -58,5 +58,11 @@ class CustomerDimensionConfigControllerContractTest {
|
||||
long.class, com.baiyue.firstleg.dto.CustomerDimensionConfigDtos.UpdateRequest.class)
|
||||
.getAnnotation(PreAuthorize.class).value())
|
||||
.isEqualTo("hasAuthority('firstleg:dimension-config:edit')");
|
||||
assertThat(PlatformCustomerDimensionConfigController.class
|
||||
.getDeclaredMethod("updateDefaultCalculationMode",
|
||||
com.baiyue.common.security.AuthenticatedUser.class, long.class,
|
||||
com.baiyue.firstleg.dto.CustomerDimensionConfigDtos.DefaultCalculationModeUpdateRequest.class)
|
||||
.getAnnotation(PreAuthorize.class).value())
|
||||
.isEqualTo("hasAuthority('firstleg:dimension-config:edit')");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.baiyue.firstleg.controller;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
@@ -15,6 +16,15 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("FBA计费OpenAPI契约")
|
||||
class FbaPricingContractTest {
|
||||
@Test
|
||||
@DisplayName("确认和发送费用兼容新的组合权限与原有权限")
|
||||
void allowsCombinedConfirmSendPermissionAndLegacyPermissions() {
|
||||
assertPricingAuthority("confirm", "hasAnyAuthority('firstleg:inbound:confirm-send-fee',"
|
||||
+ " 'firstleg:fba-pricing:confirm')");
|
||||
assertPricingAuthority("send", "hasAnyAuthority('firstleg:inbound:confirm-send-fee',"
|
||||
+ " 'firstleg:inbound:send-fee')");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("客户规则保留客户参数,船司价格使用平台公共作用域")
|
||||
void keepsCustomerRuleScopeAndRemovesCarrierRateTenantScope() {
|
||||
@@ -25,7 +35,7 @@ class FbaPricingContractTest {
|
||||
Method rates = method("rates");
|
||||
assertThat(rates.getParameterTypes()).doesNotContain(Long.class);
|
||||
|
||||
for (String scopedMethod : new String[] {"rule", "createRule", "retireRule"}) {
|
||||
for (String scopedMethod : new String[] {"rule", "createRule", "retireRule", "setDefaultRule"}) {
|
||||
Method method = method(scopedMethod);
|
||||
assertThat(method.getParameterTypes()[1]).isEqualTo(long.class);
|
||||
assertThat(method.getParameters()[1].getAnnotation(RequestParam.class).required()).isTrue();
|
||||
@@ -45,6 +55,7 @@ class FbaPricingContractTest {
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
assertThat(openapi)
|
||||
.contains("/api/platform/v1/fba-pricing/customer-rules/versions:")
|
||||
.contains("/api/platform/v1/fba-pricing/customer-rules/{id}/default:")
|
||||
.contains("/api/platform/v1/fba-pricing/carrier-rates/versions:")
|
||||
.contains("/api/platform/v1/inbounds/{inboundId}/fees/calculate:")
|
||||
.contains("/api/platform/v1/inbounds/{inboundId}/fees/confirm:")
|
||||
@@ -146,6 +157,13 @@ class FbaPricingContractTest {
|
||||
.findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
private static void assertPricingAuthority(String name, String expected) {
|
||||
Method method = java.util.Arrays.stream(PlatformFbaPricingController.class.getDeclaredMethods())
|
||||
.filter(candidate -> candidate.getName().equals(name))
|
||||
.findFirst().orElseThrow();
|
||||
assertThat(method.getAnnotation(PreAuthorize.class).value()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String, Object> map(Object value) {
|
||||
return (Map<String, Object>) value;
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ class PlatformInboundMeasurementControllerContractTest {
|
||||
"hasAnyAuthority('platform:firstleg:inbound:measure:view',"
|
||||
+ " 'platform:firstleg:inbound:weight:edit')",
|
||||
AuthenticatedUser.class, long.class, long.class, long.class, long.class, String.class);
|
||||
assertAuthority("saveDraft", "hasAuthority('platform:firstleg:inbound:measure:edit')",
|
||||
assertAuthority("saveDraft", "hasAnyAuthority('platform:firstleg:inbound:warehouse-suggestion:edit',"
|
||||
+ " 'platform:firstleg:inbound:measure:edit')",
|
||||
AuthenticatedUser.class, long.class, long.class,
|
||||
InboundMeasurementRequests.SaveDraftRequest.class);
|
||||
assertAuthority("submit", "hasAuthority('platform:firstleg:inbound:measure:submit')",
|
||||
|
||||
+15
@@ -5,6 +5,7 @@ import com.baiyue.firstleg.mapper.CustomerDimensionConfigMapper;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
@@ -34,6 +35,7 @@ class CustomerDimensionConfigSqlContractTest {
|
||||
.contains("inner_width_cm DECIMAL(9,3) NOT NULL")
|
||||
.contains("inner_height_cm DECIMAL(9,3) NOT NULL")
|
||||
.contains("edge_addition_cm DECIMAL(6,3) NOT NULL DEFAULT 2.000")
|
||||
.contains("default_calculation_mode VARCHAR(16) NOT NULL DEFAULT 'ADD'")
|
||||
.contains("initialization_key VARCHAR(128) NOT NULL")
|
||||
.contains("created_by BIGINT UNSIGNED NOT NULL")
|
||||
.contains("updated_by BIGINT UNSIGNED NOT NULL")
|
||||
@@ -88,6 +90,19 @@ class CustomerDimensionConfigSqlContractTest {
|
||||
.contains("remark = CASE box_type");
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultCalculationModeUpdateCoversTheWholeCustomerRuleSet() throws Exception {
|
||||
Update annotation = CustomerDimensionConfigMapper.class
|
||||
.getDeclaredMethod("updateDefaultCalculationMode", long.class, String.class, long.class)
|
||||
.getAnnotation(Update.class);
|
||||
String sql = String.join(" ", annotation.value());
|
||||
|
||||
assertThat(sql)
|
||||
.contains("default_calculation_mode = #{mode}")
|
||||
.contains("tenant_id = #{tenantId}")
|
||||
.contains("version = version + 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void unifiedMigrationKeepsPermissionGuardsAndAssertsFinalFourRowSchema() throws Exception {
|
||||
String sql = Files.readString(Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql"),
|
||||
|
||||
+15
@@ -140,6 +140,20 @@ class CustomerDimensionConfigServiceTest {
|
||||
verify(repository, times(2)).update(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void savesAndReturnsTheCustomerDefaultCalculationMode() {
|
||||
List<CustomerDimensionConfigEntity> existing = defaultConfigs("registration-1");
|
||||
List<CustomerDimensionConfigEntity> saved = defaultConfigs("registration-1");
|
||||
saved.forEach(value -> value.setDefaultCalculationMode("MULTIPLY"));
|
||||
when(repository.findAll(8L)).thenReturn(existing, saved);
|
||||
when(repository.updateDefaultCalculationMode(8L, "MULTIPLY", 100L)).thenReturn(4);
|
||||
|
||||
GroupResponse result = service.updateDefaultCalculationMode(8L, 100L, "MULTIPLY");
|
||||
|
||||
assertThat(result.defaultCalculationMode()).isEqualTo("MULTIPLY");
|
||||
verify(repository).updateDefaultCalculationMode(8L, "MULTIPLY", 100L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compensationLocksAndDeletesExactlyFourUnchangedDefaults() {
|
||||
when(repository.findDefaultsForCompensation(8L, "registration-1"))
|
||||
@@ -192,6 +206,7 @@ class CustomerDimensionConfigServiceTest {
|
||||
value.setInnerWidthCm(type.defaultWidthCm());
|
||||
value.setInnerHeightCm(type.defaultHeightCm());
|
||||
value.setEdgeAdditionCm(new BigDecimal("2.000"));
|
||||
value.setDefaultCalculationMode("ADD");
|
||||
value.setRemark(type.defaultRemark());
|
||||
value.setVersion(0);
|
||||
value.setInitializationKey(initializationKey);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.baiyue.firstleg.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.CustomerRuleVersionRequest;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.CarrierRateVersionRequest;
|
||||
import com.baiyue.firstleg.entity.CarrierFbaRateEntity;
|
||||
@@ -17,10 +16,10 @@ import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -47,10 +46,9 @@ class FbaMasterDataServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("半开有效期首尾相接不视为重叠")
|
||||
void acceptsAdjacentHalfOpenPeriods() {
|
||||
@DisplayName("有效期合法时创建客户规则")
|
||||
void createsRuleWithValidPeriod() {
|
||||
CustomerChargeRuleEntity old = activeRule(AUGUST.minusMonths(1), AUGUST);
|
||||
when(repository.listRules(1L, null)).thenReturn(List.of(old));
|
||||
when(repository.listRules(1L, "CR-1")).thenReturn(List.of(old));
|
||||
when(repository.nextRuleVersion(1L, "CR-1")).thenReturn(2);
|
||||
doAnswer(invocation -> { ((CustomerChargeRuleEntity) invocation.getArgument(0)).setId(10L); return null; })
|
||||
@@ -61,18 +59,25 @@ class FbaMasterDataServiceTest {
|
||||
|
||||
assertThat(created.getId()).isEqualTo(10L);
|
||||
assertThat(created.getRuleVersion()).isEqualTo(2);
|
||||
assertThat(created.getEffectiveFrom()).isEqualTo(AUGUST);
|
||||
assertThat(created.getEffectiveTo()).isEqualTo(AUGUST.plusMonths(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("任意重叠有效期在保存阶段拒绝避免多规则匹配")
|
||||
void rejectsOverlappingPeriods() {
|
||||
when(repository.listRules(1L, null)).thenReturn(List.of(
|
||||
activeRule(AUGUST, AUGUST.plusMonths(1))));
|
||||
@DisplayName("重叠配置允许新增且新增时固定不启用")
|
||||
void createsOverlappingRuleAsNonDefault() {
|
||||
when(repository.nextRuleVersion(1L, "CR-1")).thenReturn(2);
|
||||
doAnswer(invocation -> { ((CustomerChargeRuleEntity) invocation.getArgument(0)).setId(11L); return null; })
|
||||
.when(repository).insertRule(any());
|
||||
|
||||
assertThatThrownBy(() -> service.createRuleVersion(
|
||||
1L, 2L, request(AUGUST.plusDays(1), AUGUST.plusMonths(2))))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("有效期重叠");
|
||||
CustomerChargeRuleEntity created = service.createRuleVersion(
|
||||
1L, 2L, request(AUGUST.plusDays(1), AUGUST.plusMonths(2), true));
|
||||
|
||||
assertThat(created.getId()).isEqualTo(11L);
|
||||
assertThat(created.getDefaultRule()).isFalse();
|
||||
verify(repository, never()).clearDefaultRule(anyLong(), anyLong(), anyLong());
|
||||
verify(repository, never()).setDefaultRule(anyLong(), anyLong(), anyLong());
|
||||
verify(repository, never()).listRules(1L, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,8 +97,13 @@ class FbaMasterDataServiceTest {
|
||||
}
|
||||
|
||||
private CustomerRuleVersionRequest request(LocalDateTime from, LocalDateTime to) {
|
||||
return request(from, to, null);
|
||||
}
|
||||
|
||||
private CustomerRuleVersionRequest request(LocalDateTime from, LocalDateTime to, Boolean defaultRule) {
|
||||
return new CustomerRuleVersionRequest("CR-1", 100L, "客户A", "FBA_SEA", "KG",
|
||||
"TAX_INCLUDED", new BigDecimal("167"), 3, "CEILING", "USD", from, to, null);
|
||||
"TAX_INCLUDED", new BigDecimal("167"), 3, "CEILING", "USD", from, to, null,
|
||||
BigDecimal.ONE, BigDecimal.ONE, BigDecimal.ONE, defaultRule);
|
||||
}
|
||||
|
||||
private CarrierRateVersionRequest carrierRateRequest() {
|
||||
|
||||
+165
-9
@@ -7,6 +7,8 @@ import com.baiyue.firstleg.entity.CustomerDimensionConfigEntity;
|
||||
import com.baiyue.firstleg.entity.InboundMeasurementEntity;
|
||||
import com.baiyue.firstleg.entity.InboundMeasurementItemEntity;
|
||||
import com.baiyue.firstleg.entity.InboundOrderEntity;
|
||||
import com.baiyue.firstleg.entity.CustomerChargeRuleEntity;
|
||||
import com.baiyue.firstleg.repository.FbaPricingRepository;
|
||||
import com.baiyue.firstleg.repository.InboundMeasurementRepository;
|
||||
import com.baiyue.firstleg.repository.CustomerDimensionConfigRepository;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -34,6 +36,7 @@ import static org.mockito.Mockito.when;
|
||||
class MeasurementBatchServiceTest {
|
||||
@MockBean private InboundMeasurementRepository repository;
|
||||
@MockBean private CustomerDimensionConfigRepository dimensionConfigs;
|
||||
@MockBean private FbaPricingRepository pricingRepository;
|
||||
@Resource private MeasurementBatchService service;
|
||||
|
||||
@BeforeEach
|
||||
@@ -62,14 +65,17 @@ class MeasurementBatchServiceTest {
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
assertThat(items.getValue().get(0).getUnitVolumeCbm()).isEqualByComparingTo("0.0510");
|
||||
assertThat(items.getValue().get(0).getTotalVolumeCbm()).isEqualByComparingTo("0.1020");
|
||||
assertThat(items.getValue().get(0).getOuterLengthCm()).isEqualByComparingTo("44.000");
|
||||
assertThat(items.getValue().get(0).getOuterWidthCm()).isEqualByComparingTo("34.000");
|
||||
assertThat(items.getValue().get(0).getOuterHeightCm()).isEqualByComparingTo("34.000");
|
||||
assertThat(items.getValue().get(0).getUnitVolumeCbm()).isEqualByComparingTo("0.0267");
|
||||
assertThat(items.getValue().get(0).getTotalVolumeCbm()).isEqualByComparingTo("0.0534");
|
||||
assertThat(items.getValue().get(0).getOuterLengthCm()).isEqualByComparingTo("41.000");
|
||||
assertThat(items.getValue().get(0).getOuterWidthCm()).isEqualByComparingTo("31.000");
|
||||
assertThat(items.getValue().get(0).getOuterHeightCm()).isEqualByComparingTo("21.000");
|
||||
assertThat(items.getValue().get(0).getCalculationRuleVersion())
|
||||
.isEqualTo("CUSTOMER_DIMENSION_MEDIUM_V0");
|
||||
assertThat(items.getValue().get(0).getGirthCm()).isEqualByComparingTo("140.000");
|
||||
.isEqualTo("WAREHOUSE_OUTER_OVERRIDE_V1");
|
||||
assertThat(items.getValue().get(0).getCoefficientMode()).isNull();
|
||||
assertThat(items.getValue().get(0).getChargeRuleId()).isNull();
|
||||
assertThat(items.getValue().get(0).getGirthCm()).isEqualByComparingTo("145.000");
|
||||
verify(pricingRepository).findDefaultRule(1L, 1L);
|
||||
verify(repository, never()).updateInbound(any());
|
||||
}
|
||||
|
||||
@@ -83,14 +89,163 @@ class MeasurementBatchServiceTest {
|
||||
InboundMeasurementEntity saved = service.saveBatch(command);
|
||||
|
||||
assertThat(saved.getStatus()).isEqualTo("DRAFT");
|
||||
assertThat(saved.getTotalVolumeCbm()).isEqualByComparingTo("0.1020");
|
||||
assertThat(saved.getVolumeWeightKg()).isEqualByComparingTo("17.034");
|
||||
assertThat(saved.getTotalVolumeCbm()).isEqualByComparingTo("0.0534");
|
||||
assertThat(saved.getVolumeWeightKg()).isEqualByComparingTo("8.918");
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
assertThat(items.getValue().get(0).getInboundDetailId()).isEqualTo(80001L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void automaticallyAppliesCustomerDefaultRuleToActualMeasurement() {
|
||||
CustomerChargeRuleEntity rule = new CustomerChargeRuleEntity();
|
||||
rule.setId(77L);
|
||||
rule.setTenantId(1L);
|
||||
rule.setCustomerId(1L);
|
||||
rule.setRuleCode("DEFAULT");
|
||||
rule.setRuleVersion(2);
|
||||
rule.setStatus("ACTIVE");
|
||||
rule.setDefaultRule(true);
|
||||
rule.setLengthFactor(new BigDecimal("1.1"));
|
||||
rule.setWidthFactor(new BigDecimal("1.1"));
|
||||
rule.setHeightFactor(new BigDecimal("1.1"));
|
||||
when(pricingRepository.findDefaultRule(1L, 1L)).thenReturn(rule);
|
||||
MeasurementBatchCommand.Item source = new MeasurementBatchCommand.Item(
|
||||
80001L, "001", "A", 2, new BigDecimal("40"), new BigDecimal("30"),
|
||||
new BigDecimal("20"), 500L, null, null, null, null, null,
|
||||
null, "备注");
|
||||
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
||||
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
||||
LocalDateTime.now(), null, null, null, null, null, 9L, List.of(source));
|
||||
|
||||
service.saveBatch(command);
|
||||
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
InboundMeasurementItemEntity calculated = items.getValue().get(0);
|
||||
assertThat(calculated.getChargeRuleId()).isEqualTo(77L);
|
||||
assertThat(calculated.getCoefficientMode()).isEqualTo("MULTIPLY");
|
||||
assertThat(calculated.getOuterLengthCm()).isEqualByComparingTo("44.000");
|
||||
assertThat(calculated.getOuterWidthCm()).isEqualByComparingTo("33.000");
|
||||
assertThat(calculated.getOuterHeightCm()).isEqualByComparingTo("22.000");
|
||||
assertThat(calculated.getGirthCm()).isEqualByComparingTo("154.000");
|
||||
assertThat(calculated.getUnitVolumeCbm()).isEqualByComparingTo("0.0320");
|
||||
assertThat(calculated.getTotalVolumeCbm()).isEqualByComparingTo("0.0640");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usesOneMatchedTierCoefficientForAllDimensionsOfEachSpecification() {
|
||||
CustomerChargeRuleEntity rule = new CustomerChargeRuleEntity();
|
||||
rule.setId(78L);
|
||||
rule.setTenantId(1L);
|
||||
rule.setCustomerId(1L);
|
||||
rule.setRuleCode("TIERED");
|
||||
rule.setRuleVersion(3);
|
||||
rule.setStatus("ACTIVE");
|
||||
rule.setDefaultRule(true);
|
||||
rule.setLengthFactor(new BigDecimal("1.05"));
|
||||
rule.setWidthFactor(new BigDecimal("1.25"));
|
||||
rule.setHeightFactor(new BigDecimal("1.35"));
|
||||
rule.setRemark("SMALL:30,20,20;系数:1.1;小箱:—;MEDIUM:40,30,30;系数:1.2;中箱:—;"
|
||||
+ "LARGE:50,40,40;系数:1.3;大箱:—;EXTRA_LARGE:60,50,50;系数:1.4;特大箱:—");
|
||||
when(pricingRepository.findDefaultRule(1L, 1L)).thenReturn(rule);
|
||||
MeasurementBatchCommand.Item small = new MeasurementBatchCommand.Item(
|
||||
80001L, "001", "A", 1, new BigDecimal("30"), new BigDecimal("20"),
|
||||
new BigDecimal("20"), 500L, null, null, null, null, null, null, "小箱");
|
||||
MeasurementBatchCommand.Item medium = new MeasurementBatchCommand.Item(
|
||||
80002L, "002", "B", 1, new BigDecimal("31"), new BigDecimal("20"),
|
||||
new BigDecimal("20"), 501L, null, null, null, null, null, null, "中箱");
|
||||
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
||||
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
||||
LocalDateTime.now(), null, null, null, null, null, 9L, List.of(small, medium));
|
||||
|
||||
service.saveBatch(command);
|
||||
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
assertThat(items.getValue().get(0).getOuterLengthCm()).isEqualByComparingTo("33.000");
|
||||
assertThat(items.getValue().get(0).getOuterWidthCm()).isEqualByComparingTo("22.000");
|
||||
assertThat(items.getValue().get(0).getOuterHeightCm()).isEqualByComparingTo("22.000");
|
||||
assertThat(items.getValue().get(1).getOuterLengthCm()).isEqualByComparingTo("37.200");
|
||||
assertThat(items.getValue().get(1).getOuterWidthCm()).isEqualByComparingTo("24.000");
|
||||
assertThat(items.getValue().get(1).getOuterHeightCm()).isEqualByComparingTo("24.000");
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsActualMeasurementUnchangedWhenCustomerHasNoDefaultRule() {
|
||||
MeasurementBatchCommand.Item source = new MeasurementBatchCommand.Item(
|
||||
80001L, "001", "A", 2, new BigDecimal("40"), new BigDecimal("30"),
|
||||
new BigDecimal("20"), 500L, null, null, null, null, null, null, "备注");
|
||||
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
||||
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
||||
LocalDateTime.now(), null, null, null, null, null, 9L, List.of(source));
|
||||
|
||||
service.saveBatch(command);
|
||||
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
InboundMeasurementItemEntity calculated = items.getValue().get(0);
|
||||
assertThat(calculated.getOuterLengthCm()).isEqualByComparingTo("40.000");
|
||||
assertThat(calculated.getOuterWidthCm()).isEqualByComparingTo("30.000");
|
||||
assertThat(calculated.getOuterHeightCm()).isEqualByComparingTo("20.000");
|
||||
assertThat(calculated.getChargeRuleId()).isNull();
|
||||
assertThat(calculated.getCoefficientMode()).isNull();
|
||||
assertThat(calculated.getCalculationRuleVersion()).isEqualTo("ACTUAL_DIMENSION_V1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void addsMatchedEdgeValueToMeasuredDimensionsInsteadOfRuleBoundary() {
|
||||
MeasurementBatchCommand.Item source = new MeasurementBatchCommand.Item(
|
||||
80001L, "001", "A", 2, new BigDecimal("59.5"), new BigDecimal("41.2"),
|
||||
new BigDecimal("31.3"), 500L, null, null, null, null, null, "ADD", "备注");
|
||||
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
||||
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
||||
LocalDateTime.now(), null, null, null, null, null, 9L, List.of(source));
|
||||
|
||||
service.saveBatch(command);
|
||||
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
InboundMeasurementItemEntity calculated = items.getValue().get(0);
|
||||
assertThat(calculated.getOuterLengthCm()).isEqualByComparingTo("61.500");
|
||||
assertThat(calculated.getOuterWidthCm()).isEqualByComparingTo("43.200");
|
||||
assertThat(calculated.getOuterHeightCm()).isEqualByComparingTo("33.300");
|
||||
assertThat(calculated.getGirthCm()).isEqualByComparingTo("214.500");
|
||||
assertThat(calculated.getUnitVolumeCbm()).isEqualByComparingTo("0.088");
|
||||
assertThat(calculated.getTotalVolumeCbm()).isEqualByComparingTo("0.1760");
|
||||
}
|
||||
|
||||
@Test
|
||||
void warehouseOuterDimensionsOverrideCalculatedCartonAndAllDerivedValues() {
|
||||
MeasurementBatchCommand.Item source = new MeasurementBatchCommand.Item(
|
||||
80001L, "001", "A", 2, new BigDecimal("40"), new BigDecimal("30"),
|
||||
new BigDecimal("20"), 500L, null, new BigDecimal("50"),
|
||||
new BigDecimal("40"), new BigDecimal("30"), null, "ADD", "仓库修正");
|
||||
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
||||
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
||||
LocalDateTime.now(), null, null, null, null, null, 9L, List.of(source));
|
||||
|
||||
service.saveBatch(command);
|
||||
|
||||
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
||||
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
||||
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
||||
InboundMeasurementItemEntity calculated = items.getValue().get(0);
|
||||
assertThat(calculated.getOuterLengthCm()).isEqualByComparingTo("50.000");
|
||||
assertThat(calculated.getOuterWidthCm()).isEqualByComparingTo("40.000");
|
||||
assertThat(calculated.getOuterHeightCm()).isEqualByComparingTo("30.000");
|
||||
assertThat(calculated.getGirthCm()).isEqualByComparingTo("190.000");
|
||||
assertThat(calculated.getUnitVolumeCbm()).isEqualByComparingTo("0.0600");
|
||||
assertThat(calculated.getTotalVolumeCbm()).isEqualByComparingTo("0.1200");
|
||||
assertThat(calculated.getVolumeWeightKg()).isEqualByComparingTo("20.040");
|
||||
assertThat(calculated.getCalculationRuleVersion()).isEqualTo("WAREHOUSE_OUTER_OVERRIDE_V1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void staleDraftVersionIsRejectedBeforeReplacingItems() {
|
||||
InboundMeasurementEntity existing = new InboundMeasurementEntity();
|
||||
@@ -149,6 +304,7 @@ class MeasurementBatchServiceTest {
|
||||
InboundOrderEntity inbound = new InboundOrderEntity();
|
||||
inbound.setId(10L);
|
||||
inbound.setTenantId(1L);
|
||||
inbound.setCustomerId(1L);
|
||||
inbound.setProcessStatus("WAIT_MEASURE");
|
||||
inbound.setVersion(0);
|
||||
return inbound;
|
||||
|
||||
Reference in New Issue
Block a user