✨ 按客户区域计算毛利并完善汇总展示

This commit is contained in:
caojia
2026-11-05 15:41:20 +08:00
parent 891fdea7d3
commit 25801fe42f
9 changed files with 248 additions and 77 deletions
@@ -32,6 +32,7 @@ import com.bms.common.utils.uuid.IdUtils;
import com.bms.common.utils.poi.ExcelUtil;
// 提成功能暂停使用:import com.bms.price.domain.PrcProfitCommissionRate;
import com.bms.price.domain.PrcProfitReportExport;
import com.bms.price.enums.ProfitAreaRule;
import com.bms.price.domain.vo.PrcProfitReportOrderRow;
import com.bms.price.domain.vo.PrcProfitReportProductRow;
import com.bms.price.domain.vo.PrcProfitReportQuery;
@@ -58,6 +59,14 @@ public class PrcProfitReportController extends BaseController
return getDataTable(profitReportService.selectCustomerOptions(keywords));
}
/** 客户区域字典值与毛利规则的映射。 */
@PreAuthorize("@ss.hasPermi('report:profit:list')")
@GetMapping("/area-rules")
public AjaxResult areaRules()
{
return success(profitReportService.selectAreaRules());
}
@PreAuthorize("@ss.hasPermi('report:profit:list')")
@GetMapping("/summary")
public AjaxResult summary(PrcProfitReportQuery query)
@@ -118,7 +127,7 @@ public class PrcProfitReportController extends BaseController
try
{
List<PrcProfitReportOrderRow> rows = profitReportService.selectOrderRows(query);
return finishExport(export, rows, PrcProfitReportOrderRow.class, "订单毛利报表");
return finishExport(export, rows, PrcProfitReportOrderRow.class, "订单毛利报表", query.getProfitRule());
}
catch (RuntimeException e)
{
@@ -136,7 +145,7 @@ public class PrcProfitReportController extends BaseController
try
{
List<PrcProfitReportProductRow> rows = profitReportService.selectProductRows(query);
return finishExport(export, rows, PrcProfitReportProductRow.class, "产品毛利报表");
return finishExport(export, rows, PrcProfitReportProductRow.class, "产品毛利报表", query.getProfitRule());
}
catch (RuntimeException e)
{
@@ -200,7 +209,8 @@ public class PrcProfitReportController extends BaseController
return export;
}
private <T> AjaxResult finishExport(PrcProfitReportExport export, List<T> rows, Class<T> rowType, String sheetName)
private <T> AjaxResult finishExport(PrcProfitReportExport export, List<T> rows, Class<T> rowType, String sheetName,
String profitRule)
{
Path temp = null;
try
@@ -208,7 +218,12 @@ public class PrcProfitReportController extends BaseController
temp = Files.createTempFile("profit-report-", ".xlsx");
try (OutputStream output = Files.newOutputStream(temp))
{
new ExcelUtil<T>(rowType).exportExcelToStream(rows, sheetName, output);
ExcelUtil<T> excelUtil = new ExcelUtil<>(rowType);
if (ProfitAreaRule.GUANGZHOU.name().equals(profitRule))
{
excelUtil.hideColumn("costAmount", "redlineGrossProfit", "redlineGrossMarginRate");
}
excelUtil.exportExcelToStream(rows, sheetName, output);
}
String objectKey = "report/profit/" + DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + ".xlsx";
export.setStorageKey(ossStorage.upload(temp, objectKey,
@@ -0,0 +1,53 @@
package com.bms.report;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import com.bms.common.exception.ServiceException;
import com.bms.price.domain.vo.PrcProfitReportQuery;
import com.bms.price.mapper.PrcProfitReportMapper;
import com.bms.price.service.impl.PrcProfitReportServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
class ProfitAreaRuleTest
{
@Test
void reportQueriesResolveRuleOnServerAndRejectUnknownAreas()
{
AtomicInteger calls = new AtomicInteger();
PrcProfitReportMapper mapper = (PrcProfitReportMapper) Proxy.newProxyInstance(
getClass().getClassLoader(), new Class<?>[] { PrcProfitReportMapper.class },
(proxy, method, args) -> {
calls.incrementAndGet();
return Collections.emptyList();
});
PrcProfitReportServiceImpl service = new PrcProfitReportServiceImpl();
ReflectionTestUtils.setField(service, "profitReportMapper", mapper);
PrcProfitReportQuery query = new PrcProfitReportQuery();
query.setCustomerArea(" GZ ");
query.setProfitRule("SHENZHEN");
service.selectSummary(query);
assertEquals("GZ", query.getCustomerArea());
assertEquals("GUANGZHOU", query.getProfitRule());
query.setCustomerArea("C");
query.setProfitRule("GUANGZHOU");
service.selectOrderRows(query);
assertEquals("SHENZHEN", query.getProfitRule());
service.selectProductRows(query);
assertEquals(3, calls.get());
query.setCustomerArea("UNKNOWN");
assertThrows(ServiceException.class, () -> service.selectProductRows(query));
query.setCustomerArea("");
assertThrows(ServiceException.class, () -> service.selectSummary(query));
assertEquals(3, calls.get());
assertEquals("SHENZHEN", service.selectAreaRules().get("C"));
assertEquals("GUANGZHOU", service.selectAreaRules().get("GZ"));
}
}