This commit is contained in:
2026-09-09 15:27:10 +08:00
parent 5f671e164f
commit 2980308f4d
17 changed files with 292 additions and 17 deletions
@@ -4,6 +4,7 @@ import com.baiyue.lastleg.financefee.dto.OverseasFeeSourceDtos.SaveRequest;
import com.baiyue.lastleg.financefee.entity.OverseasFeeSource;
import com.baiyue.lastleg.financefee.mapper.OverseasFeeCommandMapper;
import com.baiyue.lastleg.financefee.mapper.OverseasFeeSourceMapper;
import com.baiyue.lastleg.masterdata.exchange.mapper.MonthlyExchangeRateMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -22,7 +23,9 @@ class OverseasContainerFeeSourceServiceTest {
private final OverseasFeeBusinessGuard guard = mock(OverseasFeeBusinessGuard.class);
private final OverseasFeeOutboxService outbox = mock(OverseasFeeOutboxService.class);
private final OverseasFeeSourceService service = new OverseasFeeSourceService(
mapper, commands, guard, outbox, new ObjectMapper().findAndRegisterModules());
mapper, commands, guard, outbox,
new OverseasFeeCurrencyConverter(mock(MonthlyExchangeRateMapper.class)),
new ObjectMapper().findAndRegisterModules());
@Test
void createsContainerFeeUsingTheRealContainerAsItsStableBusinessReference() {
@@ -50,7 +53,8 @@ class OverseasContainerFeeSourceServiceTest {
source.warehouseId(), "CUSTOM_FEE", "自定义费", source.direction(), source.supplierId(),
source.supplierName(), source.supplierCategory(), source.settlementMode(), source.paidAt(),
source.paymentMethod(), source.paymentReferenceNo(), source.paymentVoucherFileIds(),
source.businessDate(), source.currency(), source.amount());
source.businessDate(), source.currency(), source.amount(), source.chargeableQuantity(),
source.quantityUnit(), source.unitPrice(), source.periodStart(), source.periodEnd());
when(commands.find("operator-a", "CREATE", "bad-container-fee")).thenReturn(null);
assertThatThrownBy(() -> service.create("operator-a", "bad-container-fee", request))
@@ -57,7 +57,8 @@ class OverseasFeeBusinessGuardTest {
source.warehouseId(), source.feeItemCode(), source.feeItemName(), source.direction(), source.supplierId(),
source.supplierName(), source.supplierCategory(), source.settlementMode(), source.paidAt(),
source.paymentMethod(), source.paymentReferenceNo(), source.paymentVoucherFileIds(),
source.businessDate(), source.currency(), source.amount());
source.businessDate(), source.currency(), source.amount(), source.chargeableQuantity(),
source.quantityUnit(), source.unitPrice(), source.periodStart(), source.periodEnd());
StubJdbc jdbc = new StubJdbc();
assertThatThrownBy(() -> new OverseasFeeBusinessGuard(jdbc).requireOwned(inconsistent))
@@ -83,7 +84,8 @@ class OverseasFeeBusinessGuardTest {
return new SaveRequest(customerId, "客户A", "OVERSEAS_CONTAINER_FEE", "OVERSEAS_CONTAINER",
bookingId, containerNo, null, null, null, null, bookingId, containerNo, 91L,
"PORT_FEE", "港口费", "RECEIVABLE", null, null, null, null, null, null, null,
List.of(), LocalDate.of(2026, 9, 8), "CNY", new BigDecimal("88.00"));
List.of(), LocalDate.of(2026, 9, 8), "CNY", new BigDecimal("88.00"),
null, null, null, null, null);
}
private static final class StubJdbc extends JdbcTemplate {
@@ -0,0 +1,37 @@
package com.baiyue.lastleg.financefee.service;
import com.baiyue.lastleg.masterdata.exchange.entity.MonthlyExchangeRate;
import com.baiyue.lastleg.masterdata.exchange.mapper.MonthlyExchangeRateMapper;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.time.LocalDate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class OverseasFeeCurrencyConverterTest {
private final MonthlyExchangeRateMapper rates = mock(MonthlyExchangeRateMapper.class);
private final OverseasFeeCurrencyConverter converter = new OverseasFeeCurrencyConverter(rates);
@Test
void convertsUsdUsingTheActiveRateForTheBusinessMonth() {
MonthlyExchangeRate rate = new MonthlyExchangeRate();
rate.setStatus("ACTIVE"); rate.setUsdToCnyAverage(new BigDecimal("7.120000"));
when(rates.findMonth("2026-09")).thenReturn(rate);
var result = converter.convert("USD", new BigDecimal("12.34"), LocalDate.of(2026, 9, 9));
assertThat(result.originalAmount()).isEqualByComparingTo("12.34");
assertThat(result.exchangeRate()).isEqualByComparingTo("7.120000");
assertThat(result.settlementAmount()).isEqualByComparingTo("87.86");
}
@Test
void refusesUsdWhenTheBusinessMonthHasNoActiveRate() {
assertThatThrownBy(() -> converter.convert("USD", BigDecimal.TEN, LocalDate.of(2026, 9, 9)))
.hasMessageContaining("缺少有效USD兑CNY汇率");
}
}
@@ -38,6 +38,8 @@ class OverseasFeeOutboxServiceTest {
source.setFeeItemCode("PROCUREMENT_SERVICE"); source.setFeeItemName("采购服务费");
source.setDirection("RECEIVABLE"); source.setBusinessDate(LocalDate.of(2026, 9, 2));
source.setCurrency("CNY"); source.setAmount(new BigDecimal("120.00"));
source.setOriginalCurrency("USD"); source.setOriginalAmount(new BigDecimal("16.85"));
source.setExchangeRate(new BigDecimal("7.122000")); source.setExchangeRateMonth("2026-09");
source.setReviewStatus("APPROVED"); source.setPublicationStatus("PUBLISHED");
source.setSourceStatus("ACTIVE"); source.setPaymentVoucherFileIds(List.of());
@@ -52,5 +54,7 @@ class OverseasFeeOutboxServiceTest {
assertThat(payload.inboundId()).isNull();
assertThat(payload.inboundCode()).isNull();
assertThat(payload.sourceHash()).startsWith("sha256:").hasSize(71);
assertThat(payload.originalCurrency()).isEqualTo("USD");
assertThat(payload.exchangeRateMonth()).isEqualTo("2026-09");
}
}