This commit is contained in:
wuweihua
2026-11-11 13:52:35 +08:00
5 changed files with 127 additions and 8 deletions
@@ -1,9 +1,11 @@
package com.bms.report;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
@@ -11,18 +13,93 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Test;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import com.bms.common.core.domain.entity.SysUser;
import com.bms.common.core.domain.model.LoginUser;
import com.bms.receivable.domain.ArBalanceWriteoff;
import com.bms.receivable.domain.ArBill;
import com.bms.receivable.mapper.ArBillMapper;
import com.bms.receivable.mapper.ArCommissionMapper;
import com.bms.receivable.profit.ArCommissionRate;
import com.bms.receivable.profit.ArCommissionResult;
import com.bms.receivable.profit.ArCommissionService;
import com.bms.receivable.profit.ArProfitScope;
import com.bms.receivable.profit.ArProfitScopeResolver;
import com.bms.receivable.profit.ArWriteoffRate;
import com.bms.common.exception.ServiceException;
class ArCommissionServiceTest
{
@Test
void rateConfirmationRequiresCompleteProfitDataBeforeAnyWrite()
{
List<String> calls = new ArrayList<>();
AtomicReference<Integer> complete = new AtomicReference<>(0);
ArCommissionMapper mapper = (ArCommissionMapper) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<?>[] { ArCommissionMapper.class }, (proxy, method, args) -> {
calls.add(method.getName());
return switch (method.getName()) {
case "selectBillIdByWriteoffId" -> 25L;
case "isBillProfitDataComplete" -> complete.get();
case "confirmMissingRate", "reverseResults" -> 1;
case "countMissingRates" -> 0;
case "selectSettlementInputs" -> List.of();
default -> throw new AssertionError(method.getName());
};
});
ArBill bill = new ArBill();
bill.setProfitSalesUserId(7L);
bill.setGenerationStatus("READY");
ArBillMapper billMapper = (ArBillMapper) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<?>[] { ArBillMapper.class }, (proxy, method, args) -> {
if ("selectArBillByIdForUpdate".equals(method.getName())) return bill;
throw new AssertionError(method.getName());
});
ArProfitScopeResolver resolver = new ArProfitScopeResolver() {
@Override public ArProfitScope resolve() { return new ArProfitScope(true, false, false, 1L, 1L); }
};
ArCommissionService service = new ArCommissionService(mapper, resolver, null, billMapper);
ArWriteoffRate input = new ArWriteoffRate();
input.setWriteoffId(18L);
input.setRate(new BigDecimal("5"));
input.setRemark("已核对");
for (String status : List.of("CONFIRMED", "PARTIAL_WRITTEN_OFF", "WRITTEN_OFF"))
{
bill.setStatus(status);
calls.clear();
ServiceException error = assertThrows(ServiceException.class, () -> service.confirmMissingRate(input));
assertTrue(error.getMessage().contains("请先处理后再确认比例"));
assertFalse(calls.contains("confirmMissingRate"));
assertFalse(calls.contains("reverseResults"));
}
complete.set(null);
assertThrows(ServiceException.class, () -> service.confirmMissingRate(input));
complete.set(1);
SysUser user = new SysUser();
user.setUserName("finance");
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(new LoginUser(user, java.util.Set.of()), null));
try
{
bill.setStatus("PARTIAL_WRITTEN_OFF");
calls.clear();
service.confirmMissingRate(input);
assertTrue(calls.contains("confirmMissingRate"));
assertFalse(calls.contains("reverseResults"));
bill.setStatus("WRITTEN_OFF");
calls.clear();
service.confirmMissingRate(input);
assertTrue(calls.indexOf("isBillProfitDataComplete") < calls.indexOf("confirmMissingRate"));
assertTrue(calls.contains("reverseResults"));
assertTrue(calls.contains("selectSettlementInputs"));
}
finally
{
SecurityContextHolder.clearContext();
}
}
@Test
void commissionReadsUseServerResolvedScopeAndManagementRemainsRestricted()
{
@@ -158,6 +158,17 @@ class ArProfitMapperSqlTest
.getBoundSql(Map.of("billId", 1L)).getSql();
assertTrue(settlement.contains("w.status = 'EFFECTIVE'"));
assertTrue(settlement.contains("b.status = 'WRITTEN_OFF'"));
String validation = configuration.getMappedStatement("com.bms.receivable.mapper.ArCommissionMapper.isBillProfitDataComplete")
.getBoundSql(Map.of("billId", 1L)).getSql();
assertTrue(validation.contains("detail.ar_bill_id = ?"));
assertTrue(validation.contains("d.ar_bill_id = ?"));
assertTrue(validation.contains("a.detail_total = b.total_amount"));
assertTrue(validation.contains("f.sales_amount = d.total_amount"));
assertTrue(validation.contains("f.fee_currency = d.currency"));
assertTrue(validation.contains("f.product_complete = 1"));
assertTrue(validation.contains("f.redline_complete = 1"));
assertFalse(validation.contains("b.status = 'WRITTEN_OFF'"));
assertFalse(validation.contains("profit_calc_status"));
var insert = configuration.getMappedStatement("com.bms.receivable.mapper.ArCommissionMapper.insertResults")
.getBoundSql(Map.of("items", java.util.List.of(new ArCommissionResult(), new ArCommissionResult()), "operator", "test"));
assertTrue(insert.getSql().contains("ar_profit_commission_result"));