1
This commit is contained in:
@@ -33,6 +33,7 @@ public class CustomerAddressService {
|
||||
|
||||
@Transactional
|
||||
public Long create(long tenantId, long userId, CustomerAddressDtos.SaveRequest request) {
|
||||
ensureNoDuplicate(tenantId, request, null);
|
||||
CustomerAddressEntity value = new CustomerAddressEntity();
|
||||
value.setId(IdWorker.getId());
|
||||
value.setTenantId(tenantId);
|
||||
@@ -51,6 +52,7 @@ public class CustomerAddressService {
|
||||
if (!value.getAddressType().equals(request.addressType())) {
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED, "地址类型创建后不可修改");
|
||||
}
|
||||
ensureNoDuplicate(tenantId, request, id);
|
||||
if (request.defaultAddress()) clearDefault(tenantId, request.addressType(), id);
|
||||
apply(value, request);
|
||||
value.setUpdatedBy(userId);
|
||||
@@ -99,6 +101,25 @@ public class CustomerAddressService {
|
||||
.set(CustomerAddressEntity::getDefaultAddress, false));
|
||||
}
|
||||
|
||||
private void ensureNoDuplicate(long tenantId, CustomerAddressDtos.SaveRequest request, Long excludedId) {
|
||||
boolean duplicate = mapper.selectList(new LambdaQueryWrapper<CustomerAddressEntity>()
|
||||
.eq(CustomerAddressEntity::getTenantId, tenantId)
|
||||
.eq(CustomerAddressEntity::getActive, true)
|
||||
.eq(CustomerAddressEntity::getAddressType, request.addressType())
|
||||
.eq(CustomerAddressEntity::getCompanyName, request.companyName().trim())
|
||||
.eq(CustomerAddressEntity::getContactName, request.contactName().trim())
|
||||
.eq(CustomerAddressEntity::getPhone, request.phone().trim())
|
||||
.eq(CustomerAddressEntity::getCountryCode, request.countryCode().trim().toUpperCase())
|
||||
.eq(CustomerAddressEntity::getCity, request.city().trim())
|
||||
.eq(CustomerAddressEntity::getAddressLine, request.addressLine().trim())
|
||||
.ne(excludedId != null, CustomerAddressEntity::getId, excludedId))
|
||||
.stream().findAny().isPresent();
|
||||
if (duplicate) {
|
||||
throw new BizException(ResultCode.CONFLICT, "PICKUP".equals(request.addressType())
|
||||
? "相同的企业提货地址已存在" : "相同的企业私人仓地址已存在");
|
||||
}
|
||||
}
|
||||
|
||||
private static void apply(CustomerAddressEntity value, CustomerAddressDtos.SaveRequest source) {
|
||||
value.setAddressType(source.addressType()); value.setAddressName(source.addressName().trim());
|
||||
value.setCompanyName(source.companyName().trim()); value.setContactName(source.contactName().trim());
|
||||
|
||||
@@ -324,11 +324,11 @@ public class UnifiedOrderQueryService {
|
||||
order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), null, null,
|
||||
order.getInboundCode(),
|
||||
order.getExpectedShipDate(), null, null, totalPackageCount(cargo), null, null,
|
||||
order.getEstimatedVolumeCbm(), volumeCbm(cargo), null, null,
|
||||
order.getEstimatedVolumeCbm(), volumeCbm(cargo), grossWeightKg(cargo), volumeCbm(cargo),
|
||||
order.getExpectedArrivalAt(), null, null, null, order.getFulfillmentType(), order.getLxCode(),
|
||||
order.getPickupMethod(), order.getTaxMode(), order.getContainerMode(),
|
||||
order.getCustomsInspection(), order.getDestinationType(), order.getAmazonWarehouseCode(),
|
||||
null, null, null, null, null, null, null, order.getExpressCompany(), order.getExpressTrackingNo(),
|
||||
null, null, null, null, netWeightKg(cargo), null, null, order.getExpressCompany(), order.getExpressTrackingNo(),
|
||||
StringUtils.hasText(creatorName) ? creatorName : string(order.getCreatedBy()), skuNos(cargo), totalQuantity(cargo), shipmentId(order, cargo), referenceId(order, cargo),
|
||||
null, null, null, null, null, coLoadGroup,
|
||||
order.getCustomerRemark(), latestInternalNote, order.getWarehouseRemark(), order.getCustomerServiceRemark(),
|
||||
@@ -348,13 +348,14 @@ public class UnifiedOrderQueryService {
|
||||
displayedPackageCount(order, cargo, inbound), null,
|
||||
distinctLocationCodes(inbound.locationCodes()),
|
||||
order.getEstimatedVolumeCbm(), volumeCbm(cargo),
|
||||
inbound.actualGrossWeightKg(), inbound.actualVolumeCbm(),
|
||||
measuredOrDeclared(inbound.actualGrossWeightKg(), grossWeightKg(cargo)),
|
||||
measuredOrDeclared(inbound.actualVolumeCbm(), volumeCbm(cargo)),
|
||||
order.getExpectedArrivalAt() != null ? order.getExpectedArrivalAt() : inbound.expectedArrivalAt(), inbound.feeReviewStatus(),
|
||||
inbound.companyName(), inbound.businessType(), inbound.fulfillmentType(), inbound.lxCode(),
|
||||
order.getPickupMethod(), inbound.taxMode(), inbound.containerMode(),
|
||||
inbound.customsInspection(), inbound.destinationType(), inbound.destinationCode(), inbound.palletCount(),
|
||||
inbound.chargeableWeightKg(), inbound.chargeableVolumeCbm(), inbound.volumeWeightKg(),
|
||||
inbound.actualNetWeightKg(),
|
||||
measuredOrDeclared(inbound.actualNetWeightKg(), netWeightKg(cargo)),
|
||||
inbound.measureCompletedAt(), inbound.inboundedAt(), inbound.expressCompanyName(), inbound.expressTrackingNo(),
|
||||
StringUtils.hasText(creatorName) ? creatorName : inbound.createdByName(), skuNos(cargo), totalQuantity(cargo), shipmentId(order, cargo), referenceId(order, cargo), measurement(inbound),
|
||||
preload(summary.preload()), loading(summary.loading()),
|
||||
@@ -378,13 +379,14 @@ public class UnifiedOrderQueryService {
|
||||
inbound.id(), inbound.version(), inbound.inboundCode(), null, inbound.holdFlag(), inbound.currentHoldReason(),
|
||||
displayedPackageCount(order, cargo, inbound), null, distinctLocationCodes(inbound.locationCodes()),
|
||||
order == null ? null : order.getEstimatedVolumeCbm(), volumeCbm(cargo),
|
||||
inbound.actualGrossWeightKg(), inbound.actualVolumeCbm(),
|
||||
measuredOrDeclared(inbound.actualGrossWeightKg(), grossWeightKg(cargo)),
|
||||
measuredOrDeclared(inbound.actualVolumeCbm(), volumeCbm(cargo)),
|
||||
order != null && order.getExpectedArrivalAt() != null ? order.getExpectedArrivalAt() : inbound.expectedArrivalAt(), inbound.feeReviewStatus(), inbound.companyName(),
|
||||
inbound.businessType(), inbound.fulfillmentType(), inbound.lxCode(),
|
||||
order == null ? null : order.getPickupMethod(), inbound.taxMode(), inbound.containerMode(),
|
||||
inbound.customsInspection(), inbound.destinationType(), inbound.destinationCode(), inbound.palletCount(),
|
||||
inbound.chargeableWeightKg(), inbound.chargeableVolumeCbm(), inbound.volumeWeightKg(),
|
||||
inbound.actualNetWeightKg(),
|
||||
measuredOrDeclared(inbound.actualNetWeightKg(), netWeightKg(cargo)),
|
||||
inbound.measureCompletedAt(), inbound.inboundedAt(), inbound.expressCompanyName(), inbound.expressTrackingNo(),
|
||||
inbound.createdByName(), skuNos(cargo), totalQuantity(cargo), shipmentId(order, cargo), referenceId(order, cargo),
|
||||
measurement(inbound), preload(summary.preload()), loading(summary.loading()),
|
||||
@@ -490,6 +492,10 @@ public class UnifiedOrderQueryService {
|
||||
return cargo == null ? null : cargo.volumeCbm();
|
||||
}
|
||||
|
||||
private BigDecimal measuredOrDeclared(BigDecimal measured, BigDecimal declared) {
|
||||
return measured == null ? declared : measured;
|
||||
}
|
||||
|
||||
private record CargoSummary(List<String> skuNos, List<String> shipmentIds, List<String> referenceIds,
|
||||
Integer totalQuantity, Integer totalPackageCount, BigDecimal grossWeightKg,
|
||||
BigDecimal netWeightKg, BigDecimal volumeCbm) {
|
||||
|
||||
@@ -7,9 +7,12 @@ import com.baiyue.order.mapper.CustomerAddressMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -38,4 +41,21 @@ class CustomerAddressServiceTest {
|
||||
assertThatThrownBy(() -> service.required(10001L, 90001L, "PICKUP"))
|
||||
.isInstanceOf(BizException.class).hasMessage("客户地址不存在或已停用");
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsDuplicatePickupAddressBeforeCreatingAnotherRecord() {
|
||||
CustomerAddressMapper mapper = mock(CustomerAddressMapper.class);
|
||||
CustomerAddressEntity duplicate = new CustomerAddressEntity();
|
||||
duplicate.setId(90001L);
|
||||
when(mapper.selectList(any())).thenReturn(List.of(duplicate));
|
||||
CustomerAddressService service = new CustomerAddressService();
|
||||
ReflectionTestUtils.setField(service, "mapper", mapper);
|
||||
var request = new CustomerAddressDtos.SaveRequest("PICKUP", "深圳工厂", "柏悦物流",
|
||||
"惠万昌", "13229608341", null, "CN", "江西省", "抚州市", null,
|
||||
"崇仁县三山乡长仁大队廉家村", null, false);
|
||||
|
||||
assertThatThrownBy(() -> service.create(10001L, 20001L, request))
|
||||
.isInstanceOf(BizException.class).hasMessage("相同的企业提货地址已存在");
|
||||
verify(mapper, never()).insert(any(CustomerAddressEntity.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class UnifiedOrderQueryServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void newlyCreatedOrderUsesItsOwnCargoPackageCountBeforeInboundExists() {
|
||||
void newlyCreatedOrderUsesItsOwnCargoTotalsBeforeInboundExists() {
|
||||
UnifiedOrderQuery query = query(null);
|
||||
OrderEntity order = order(OrderStatus.APPROVED);
|
||||
OrderCargoEntity cargo = new OrderCargoEntity();
|
||||
@@ -144,13 +144,39 @@ class UnifiedOrderQueryServiceTest {
|
||||
assertThat(service.page(10001L, query).records()).singleElement().satisfies(row -> {
|
||||
assertThat(row.totalPackageCount()).isEqualTo(100);
|
||||
assertThat(row.expectedVolumeCbm()).isEqualByComparingTo("0.375");
|
||||
assertThat(row.actualGrossWeightKg()).isNull();
|
||||
assertThat(row.totalNetWeightKg()).isNull();
|
||||
assertThat(row.actualVolumeCbm()).isNull();
|
||||
assertThat(row.actualGrossWeightKg()).isEqualByComparingTo("12.5");
|
||||
assertThat(row.totalNetWeightKg()).isEqualByComparingTo("11.2");
|
||||
assertThat(row.actualVolumeCbm()).isEqualByComparingTo("0.375");
|
||||
});
|
||||
verify(orders).findCargoByOrderIds(10001L, List.of(77L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unmeasuredInboundFallsBackToDeclaredCargoTotals() {
|
||||
UnifiedOrderQuery query = query(null);
|
||||
OrderEntity order = order(OrderStatus.APPROVED);
|
||||
OrderCargoEntity cargo = new OrderCargoEntity();
|
||||
cargo.setOrderId(77L);
|
||||
cargo.setPackageCount(50);
|
||||
cargo.setGrossWeightKg(new BigDecimal("1500"));
|
||||
cargo.setNetWeightKg(new BigDecimal("25"));
|
||||
cargo.setVolumeCbm(new BigDecimal("7.5"));
|
||||
var summary = summary("WAIT_MEASURE", null);
|
||||
when(summary.inbound().actualGrossWeightKg()).thenReturn(null);
|
||||
when(summary.inbound().actualNetWeightKg()).thenReturn(null);
|
||||
when(summary.inbound().actualVolumeCbm()).thenReturn(null);
|
||||
when(orders.unifiedPage(eq(10001L), eq(query), any()))
|
||||
.thenReturn(new PageResult<>(List.of(order), 1, 20, 1, 1));
|
||||
when(firstleg.summaries(eq("internal-token"), any())).thenReturn(ApiResponse.success(List.of(summary)));
|
||||
when(orders.findCargoByOrderIds(10001L, List.of(77L))).thenReturn(List.of(cargo));
|
||||
|
||||
assertThat(service.page(10001L, query).records()).singleElement().satisfies(row -> {
|
||||
assertThat(row.actualGrossWeightKg()).isEqualByComparingTo("1500");
|
||||
assertThat(row.totalNetWeightKg()).isEqualByComparingTo("25");
|
||||
assertThat(row.actualVolumeCbm()).isEqualByComparingTo("7.5");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dropshipMixedSkuRowsCountSharedCartonVolumeOnlyOnce() {
|
||||
UnifiedOrderQuery query = query(null);
|
||||
|
||||
Reference in New Issue
Block a user