This commit is contained in:
2026-08-11 11:41:41 +08:00
parent 9f455b6c0b
commit 9b3ff06a90
17 changed files with 429 additions and 76 deletions
@@ -18,6 +18,12 @@ class FinanceContractTest {
assertTrue(sql.contains("CREATE TABLE IF NOT EXISTS fin_bill"));
assertTrue(sql.contains("currency_code CHECK (currency_code = 'CNY')") || sql.contains("currency_code = 'CNY'"));
assertTrue(sql.contains("fin_fee_source") && sql.contains("fin_inbox_event"));
assertTrue(sql.contains("fin_bill_revision"));
assertTrue(sql.contains("PROCESSING/SUCCEEDED/FAILED"));
String service = Files.readString(Path.of("src/main/java/com/baiyue/finance/service/FinanceService.java"));
assertTrue(service.contains("status='PROCESSING'") && service.contains("stableNo"));
assertTrue(service.contains("request_hash") && service.contains("result_resource_id") && service.contains("Idempotency-Key已用于其他请求"));
assertTrue(service.contains("status IN ('ISSUED','PARTIALLY_PAID','PAID')"));
String unified = Files.readString(Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql"));
assertTrue(unified.contains("CREATE DATABASE IF NOT EXISTS baiyue_finance"));
assertTrue(unified.contains("assert_finance_permissions"));
@@ -9,12 +9,33 @@ import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
class FinanceServiceValidationTest {
@Test
void containerCostAllocatesByVolumeAndPutsRoundingOnLastOrder() {
var rows = List.of(
new FinanceService.ContainerOrderVolume(11L, 101L, 7L, 9L, new BigDecimal("1.00")),
new FinanceService.ContainerOrderVolume(12L, 102L, 7L, 9L, new BigDecimal("2.00")),
new FinanceService.ContainerOrderVolume(13L, 103L, 7L, 9L, new BigDecimal("3.00")));
var allocations = FinanceService.allocateContainerCost(new BigDecimal("100.00"), rows);
assertEquals(new BigDecimal("16.666667"), allocations.get(0).amount());
assertEquals(new BigDecimal("33.333333"), allocations.get(1).amount());
assertEquals(new BigDecimal("50.000000"), allocations.get(2).amount());
assertEquals(new BigDecimal("100.000000"), allocations.stream().map(FinanceService.CostAllocation::amount)
.reduce(BigDecimal.ZERO, BigDecimal::add));
assertEquals(true, allocations.get(2).roundingAdjustment());
}
@Test
void rejectsEmptyContainerVolumeSnapshot() {
assertThrows(RuntimeException.class, () -> FinanceService.allocateContainerCost(BigDecimal.TEN, List.of()));
}
@Test
void rejectsUnsupportedCostTypeBeforeWrite() {
JdbcTemplate jdbc = mock(JdbcTemplate.class);
@@ -32,4 +53,13 @@ class FinanceServiceValidationTest {
List.of(new FinanceService.ReceiptAllocation(10L, BigDecimal.ZERO)));
assertThrows(RuntimeException.class, () -> service.createReceipt(1L, 2L, request, "k2"));
}
@Test
void rejectsDuplicateBillAllocationInsteadOfMerging() {
JdbcTemplate jdbc = mock(JdbcTemplate.class);
FinanceService service = new FinanceService(jdbc, new ObjectMapper());
var request = new FinanceService.ReceiptRequest("R-2", 1L, null, "BANK_TRANSFER", null, List.of("f"), null,
List.of(new FinanceService.ReceiptAllocation(10L, BigDecimal.ONE), new FinanceService.ReceiptAllocation(10L, BigDecimal.ONE)));
assertThrows(RuntimeException.class, () -> service.createReceipt(1L, 2L, request, "k3"));
}
}