88 lines
4.5 KiB
Java
88 lines
4.5 KiB
Java
package com.baiyue.finance;
|
|
|
|
import com.baiyue.finance.dto.ReceivableStatisticsDtos.ReceivableStatisticsRow;
|
|
import com.baiyue.finance.service.FinanceEventException;
|
|
import com.baiyue.finance.service.ReceivableStatisticsService;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.jdbc.core.RowMapper;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.time.YearMonth;
|
|
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.anyString;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
class ReceivableStatisticsServiceTest {
|
|
@Test
|
|
@SuppressWarnings("unchecked")
|
|
void aggregatesOnlyTheApprovedFormalCnyDimensionsAndPaginatesCustomers() {
|
|
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
|
List<ReceivableStatisticsRow> rows = List.of(
|
|
row(10001, "客户A", "300.00", "100.00", "200.00"),
|
|
row(10002, "客户B", "80.00", "80.00", "0.00"));
|
|
when(jdbc.query(anyString(), any(RowMapper.class), any(Object[].class))).thenReturn(rows);
|
|
ReceivableStatisticsService service = new ReceivableStatisticsService(jdbc, FinanceCustomerNamesTestSupport.names());
|
|
|
|
var result = service.query(YearMonth.of(2026, 7), null, 1, 1);
|
|
|
|
assertThat(result.currency()).isEqualTo("CNY");
|
|
assertThat(result.totalReceivable()).isEqualByComparingTo("380.00");
|
|
assertThat(result.totalReceived()).isEqualByComparingTo("180.00");
|
|
assertThat(result.totalOutstanding()).isEqualByComparingTo("200.00");
|
|
assertThat(result.totalCustomers()).isEqualTo(2);
|
|
assertThat(result.records()).containsExactly(rows.get(0));
|
|
var sql = org.mockito.ArgumentCaptor.forClass(String.class);
|
|
verify(jdbc).query(sql.capture(), any(RowMapper.class), any(Object[].class));
|
|
assertThat(sql.getValue()).contains("s.direction='RECEIVABLE'", "s.status<>'VOIDED'", "s.currency_code='CNY'",
|
|
"s.generated_date>=?", "s.generated_date<?", "fin_customer_settlement_profile", "GROUP BY s.tenant_id,p.customer_name_snapshot");
|
|
}
|
|
|
|
@Test
|
|
@SuppressWarnings("unchecked")
|
|
void failsClosedWhenPersistedTotalsDoNotReconcile() {
|
|
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
|
when(jdbc.query(anyString(), any(RowMapper.class), any(Object[].class)))
|
|
.thenReturn(List.of(row(10001, "客户A", "300.00", "100.00", "199.99")));
|
|
|
|
assertThatThrownBy(() -> new ReceivableStatisticsService(jdbc, FinanceCustomerNamesTestSupport.names())
|
|
.query(YearMonth.of(2026, 7), null, 1, 20))
|
|
.isInstanceOf(FinanceEventException.class)
|
|
.hasMessageContaining("勾稽异常");
|
|
}
|
|
|
|
@Test
|
|
@SuppressWarnings("unchecked")
|
|
void queryAndExportResolveTheSameCustomerNameWithoutChangingAmounts() throws Exception {
|
|
var jdbc = mock(JdbcTemplate.class);
|
|
when(jdbc.query(anyString(), any(RowMapper.class), any(Object[].class))).thenAnswer(invocation -> {
|
|
RowMapper<ReceivableStatisticsRow> mapper = invocation.getArgument(1);
|
|
var rs = mock(java.sql.ResultSet.class);
|
|
when(rs.getLong("tenant_id")).thenReturn(9L);
|
|
when(rs.getString("customer_name_snapshot")).thenReturn("客户9");
|
|
when(rs.getBigDecimal("total_receivable")).thenReturn(new BigDecimal("300.00"));
|
|
when(rs.getBigDecimal("total_received")).thenReturn(new BigDecimal("100.00"));
|
|
when(rs.getBigDecimal("total_outstanding")).thenReturn(new BigDecimal("200.00"));
|
|
return List.of(mapper.mapRow(rs, 0));
|
|
});
|
|
var service = new ReceivableStatisticsService(jdbc, FinanceCustomerNamesTestSupport.names());
|
|
var query = service.query(YearMonth.of(2026, 10), 9L, 1, 20);
|
|
assertThat(query.records()).singleElement().satisfies(row -> {
|
|
assertThat(row.customerName()).isEqualTo("测试客户公司");
|
|
assertThat(row.totalReceivable()).isEqualByComparingTo("300.00");
|
|
});
|
|
assertThat(service.exportRows(YearMonth.of(2026, 10), 9L)).isEqualTo(query.records());
|
|
}
|
|
|
|
private static ReceivableStatisticsRow row(long id, String name, String total, String received, String outstanding) {
|
|
return new ReceivableStatisticsRow(id, name, "CNY", new BigDecimal(total),
|
|
new BigDecimal(received), new BigDecimal(outstanding));
|
|
}
|
|
}
|