fix(finance): key container finance by booking
This commit is contained in:
+3
-1
@@ -22,6 +22,8 @@ class FinanceContainerSettlementOpenApiContractTest {
|
||||
.contains("platform:finance:settlement-ar:list")
|
||||
.contains("platform:finance:settlement-ap:list")
|
||||
.contains("x-query-count: 3 fixed set-based SQL statements")
|
||||
.contains("settledSourceFeeIds:", "costs:", "allocations:");
|
||||
.contains("containerBookingId:", "不是装柜计划 loadingPlanId",
|
||||
"settledSourceFeeIds:", "costs:", "allocations:")
|
||||
.doesNotContain("- name: containerId");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ class FinanceContainerSettlementQueryMapperContractTest {
|
||||
.reduce("", (left, right) -> left + "\n" + right);
|
||||
assertThat(sql).contains("JOIN fin_settlement_line", "JOIN fin_fee_source",
|
||||
"LEFT JOIN fin_cost_allocation", "c.tenant_id = #{customerId}",
|
||||
"c.container_id = #{containerId}");
|
||||
"f.container_booking_id = #{containerBookingId}",
|
||||
"c.container_id = #{containerBookingId}");
|
||||
assertThat(sql).doesNotContain("${");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -33,7 +33,7 @@ class FinanceContainerSettlementQueryServiceTest {
|
||||
var result = new FinanceContainerSettlementQueryService(mapper).details(101L, 301L);
|
||||
|
||||
assertThat(result.customerId()).isEqualTo(101L);
|
||||
assertThat(result.containerId()).isEqualTo(301L);
|
||||
assertThat(result.containerBookingId()).isEqualTo(301L);
|
||||
assertThat(result.settledSourceFeeIds()).containsExactly(901L, 902L);
|
||||
assertThat(result.costs()).hasSize(2);
|
||||
assertThat(result.costs().get(0).costId()).isEqualTo(501L);
|
||||
@@ -79,14 +79,14 @@ class FinanceContainerSettlementQueryServiceTest {
|
||||
return row;
|
||||
}
|
||||
|
||||
private static CostAllocationRow row(long costId, long containerId, Long allocationId,
|
||||
private static CostAllocationRow row(long costId, long containerBookingId, Long allocationId,
|
||||
Long orderId, boolean roundingAdjustment) {
|
||||
var row = new CostAllocationRow();
|
||||
row.setCostId(costId);
|
||||
row.setCostNo("COST-" + costId);
|
||||
row.setCostType("CONTAINER_SHARED");
|
||||
row.setCostOrigin("MANUAL");
|
||||
row.setContainerId(containerId);
|
||||
row.setContainerBookingId(containerBookingId);
|
||||
row.setSupplierName("供应商");
|
||||
row.setFeeItemName("柜费");
|
||||
row.setAmount(new BigDecimal("100.00"));
|
||||
|
||||
@@ -62,6 +62,31 @@ class FinanceFeeSourceEventServiceTest {
|
||||
assertThat(service.consume(event)).isEqualTo(101L);
|
||||
verify(firstleg).container("test-token", 41, 31, 1);
|
||||
verify(jdbc).update(contains("status='SUPERSEDED'"), eq("CONTAINER_FEE"), eq(31L));
|
||||
ArgumentCaptor<Object[]> values = ArgumentCaptor.forClass(Object[].class);
|
||||
verify(jdbc).update(startsWith("INSERT INTO fin_fee_source"), values.capture());
|
||||
assertThat(values.getValue()[8]).as("fin_fee_source.container_id keeps loadingPlanId")
|
||||
.isEqualTo(41L);
|
||||
assertThat(values.getValue()[9]).as("fin_fee_source.container_booking_id stores physical container")
|
||||
.isEqualTo(61L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsContainerFeeSnapshotWithoutPhysicalContainerBookingId() {
|
||||
FinanceFeeSourceEvent event = containerEvent("container-missing-booking", "FIRSTLEG_FEE_PUBLISHED", 1, 7);
|
||||
when(jdbc.queryForList(startsWith("SELECT payload_hash,status"), eq("FIRSTLEG"),
|
||||
eq("container-missing-booking"))).thenReturn(List.of());
|
||||
var snapshot = new FirstlegFeeSourceClient.Snapshot(7, "CONTAINER_FEE", 31, 1,
|
||||
null, null, null, 41L, null, "C-41", 7, "客户", null, null,
|
||||
null, null, null, null, null, List.of(), 61L, "CUSTOMS", "清关费",
|
||||
"RECEIVABLE", LocalDate.of(2026, 8, 11), "CNY", new BigDecimal("100.00"),
|
||||
"APPROVED", "PUBLISHED", LocalDateTime.of(2026, 8, 11, 1, 0),
|
||||
BigDecimal.ONE, "SHIPMENT", BigDecimal.TEN, BigDecimal.ONE, "source-hash", 1);
|
||||
when(firstleg.container("test-token", 41, 31, 1)).thenReturn(ApiResponse.success(snapshot));
|
||||
|
||||
assertThatThrownBy(() -> service.consume(event))
|
||||
.isInstanceOf(FinanceEventException.class)
|
||||
.extracting(error -> ((FinanceEventException) error).code()).isEqualTo("FIN-EVT-014");
|
||||
verify(jdbc, never()).update(startsWith("INSERT INTO fin_fee_source"), any(Object[].class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,7 +108,7 @@ class FinanceFeeSourceEventServiceTest {
|
||||
verify(jdbc, never()).update(startsWith("INSERT INTO fin_cost"), any(Object[].class));
|
||||
ArgumentCaptor<Object[]> values = ArgumentCaptor.forClass(Object[].class);
|
||||
verify(jdbc).update(startsWith("INSERT INTO fin_fee_source"), values.capture());
|
||||
assertThat(values.getValue()[19].toString())
|
||||
assertThat(values.getValue()[20].toString())
|
||||
.contains("\"supplierId\":71", "\"supplierName\":\"现有供应商\"", "\"supplierCategory\":\"TRUCKING\"");
|
||||
}
|
||||
|
||||
@@ -121,9 +146,9 @@ class FinanceFeeSourceEventServiceTest {
|
||||
|
||||
ArgumentCaptor<Object[]> values = ArgumentCaptor.forClass(Object[].class);
|
||||
verify(jdbc).update(startsWith("INSERT INTO fin_fee_source"), values.capture());
|
||||
assertThat(values.getValue()[13]).isEqualTo("DIRECT_PAID");
|
||||
assertThat(values.getValue()[15]).isEqualTo("BANK_TRANSFER");
|
||||
assertThat(values.getValue()[17]).isEqualTo("[901]");
|
||||
assertThat(values.getValue()[14]).isEqualTo("DIRECT_PAID");
|
||||
assertThat(values.getValue()[16]).isEqualTo("BANK_TRANSFER");
|
||||
assertThat(values.getValue()[18]).isEqualTo("[901]");
|
||||
ArgumentCaptor<Object[]> costValues = ArgumentCaptor.forClass(Object[].class);
|
||||
verify(jdbc).update(startsWith("INSERT INTO fin_cost"), costValues.capture());
|
||||
assertThat(costValues.getValue()[0]).isEqualTo(7L);
|
||||
@@ -131,6 +156,8 @@ class FinanceFeeSourceEventServiceTest {
|
||||
assertThat(costValues.getValue()[2]).isEqualTo("CONTAINER_FEE");
|
||||
assertThat(costValues.getValue()[3]).isEqualTo(31L);
|
||||
assertThat(costValues.getValue()[4]).isEqualTo(1);
|
||||
assertThat(costValues.getValue()[8]).as("fin_cost.container_id stores containerBookingId")
|
||||
.isEqualTo(61L);
|
||||
assertThat(costValues.getValue()[15]).isEqualTo("[901]");
|
||||
assertThat(costValues.getValue()[17]).isEqualTo("BANK_TRANSFER");
|
||||
assertThat(costValues.getValue()[18]).isEqualTo("BANK-001");
|
||||
@@ -284,7 +311,7 @@ class FinanceFeeSourceEventServiceTest {
|
||||
Long inboundId, Long containerId,
|
||||
String publicationStatus, BigDecimal amount) {
|
||||
return new FirstlegFeeSourceClient.Snapshot(customerId, sourceType, 31, version, inboundId,
|
||||
inboundId == null ? null : "IB-21", 51L, containerId, null,
|
||||
inboundId == null ? null : "IB-21", 51L, containerId, containerId == null ? null : 61L,
|
||||
containerId == null ? null : "C-41", customerId, "客户", null, null, null,
|
||||
null, null, null, null, List.of(), 61L, "CUSTOMS",
|
||||
"清关费", "RECEIVABLE", LocalDate.of(2026, 8, 11), "CNY", amount,
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.eq;
|
||||
@@ -55,9 +56,13 @@ class PlatformFinanceControllerBehaviorTest {
|
||||
controller.cost(user, "cost-key", request);
|
||||
|
||||
verify(snapshotClient).loadingPlan("internal-token", 10L, 88L);
|
||||
verify(service).createCost(eq(10L), eq(7L), any(), eq(List.of(
|
||||
new FinanceService.ContainerOrderVolume(101L, 1001L, 88L, 10L, new BigDecimal("1.25")),
|
||||
new FinanceService.ContainerOrderVolume(102L, 1002L, 88L, 10L, new BigDecimal("2.75")))), eq("cost-key"));
|
||||
org.mockito.ArgumentCaptor<FinanceService.CostRequest> cost =
|
||||
org.mockito.ArgumentCaptor.forClass(FinanceService.CostRequest.class);
|
||||
verify(service).createCost(eq(10L), eq(7L), cost.capture(), eq(List.of(
|
||||
new FinanceService.ContainerOrderVolume(101L, 1001L, 99L, 10L, new BigDecimal("1.25")),
|
||||
new FinanceService.ContainerOrderVolume(102L, 1002L, 99L, 10L, new BigDecimal("2.75")))), eq("cost-key"));
|
||||
assertThat(cost.getValue().containerId()).as("Finance persists the physical containerBookingId")
|
||||
.isEqualTo(99L);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user