优化
This commit is contained in:
@ -103,10 +103,11 @@
|
||||
<el-form-item v-if="form.level > 1" label="编码" prop="itemCode">
|
||||
<el-input style="width: 300px" v-model="form.itemCode" placeholder="请输入编码"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.level === 2" label="合计规则" prop="symbol">
|
||||
<el-form-item v-if="form.level === 2" label="计算" prop="symbol">
|
||||
<el-radio-group v-model="form.symbol">
|
||||
<el-radio-button label="加" value="+"/>
|
||||
<el-radio-button label="减" value="-"/>
|
||||
<el-radio-button label="函数" value="f"/>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.level > 1" label="取数规则" prop="rule">
|
||||
|
||||
@ -71,11 +71,11 @@
|
||||
<el-input style="width: 300px" v-model="form.itemName" placeholder="请输入名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="计算" prop="symbol">
|
||||
<el-select v-model="form.symbol" placeholder="选择" style="width: 300px">
|
||||
<el-option label="加" value="+"></el-option>
|
||||
<el-option label="减" value="-"></el-option>
|
||||
<el-option label="f" value="f"></el-option>
|
||||
</el-select>
|
||||
<el-radio-group v-model="form.symbol">
|
||||
<el-radio-button label="加" value="+"/>
|
||||
<el-radio-button label="减" value="-"/>
|
||||
<el-radio-button label="函数" value="f"/>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="行号" prop="sortIndex">
|
||||
<el-input-number :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>
|
||||
|
||||
@ -179,19 +179,25 @@
|
||||
<!-- <el-form-item label="编码" prop="itemCode">-->
|
||||
<!-- <el-input disabled style="width: 300px" v-model="form.itemCode" placeholder="请输入编码"/>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="编码" prop="itemCode">
|
||||
<el-input style="width: 300px" v-model="form.itemCode" placeholder="请输入编码" disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="itemName">
|
||||
<el-input style="width: 300px" v-model="form.itemName" placeholder="请输入名称"/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="行号" prop="sortIndex">-->
|
||||
<!-- <el-input-number disabled :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item v-if="form.level === 2" label="合计规则" prop="symbol">
|
||||
<el-form-item v-if="form.level === 2" label="计算" prop="symbol">
|
||||
<el-radio-group v-model="form.symbol">
|
||||
<el-radio-button label="加" value="+"/>
|
||||
<el-radio-button label="减" value="-"/>
|
||||
<el-radio-button label="函数" value="f"/>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="行号" prop="sortIndex">
|
||||
<el-input-number :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>
|
||||
</el-form-item>
|
||||
<el-table v-if="form.level !== 1" v-loading="loading" :data="form.rules" border size="small"
|
||||
:cell-class-name="tableCellClassName"
|
||||
@cell-click="cellMouseEnter"
|
||||
|
||||
@ -145,6 +145,13 @@
|
||||
<el-form-item label="名称" prop="itemName">
|
||||
<el-input style="width: 300px" v-model="form.itemName" placeholder="请输入名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="计算" prop="symbol">
|
||||
<el-radio-group v-model="form.symbol">
|
||||
<el-radio-button label="加" value="+"/>
|
||||
<el-radio-button label="减" value="-"/>
|
||||
<el-radio-button label="函数" value="f"/>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="行号" prop="sortIndex">
|
||||
<el-input-number :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>
|
||||
</el-form-item>
|
||||
|
||||
@ -49,12 +49,5 @@ public interface StatementBalanceSheetConfigService {
|
||||
|
||||
Message<Boolean> delete(String id);
|
||||
|
||||
Message<StatementSubjectBalance> getSubjectBalance(StatementSubjectBalance params);
|
||||
|
||||
void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules);
|
||||
|
||||
void refreshItemsBalance(List<StatementBalanceSheetItem> items,
|
||||
String bookId, String yearPeriod);
|
||||
|
||||
StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items);
|
||||
}
|
||||
|
||||
@ -22,7 +22,12 @@ import com.jinbooks.entity.Message;
|
||||
import com.jinbooks.entity.book.Settlement;
|
||||
import com.jinbooks.entity.book.dto.BookChangeDto;
|
||||
import com.jinbooks.entity.statement.StatementBalanceSheet;
|
||||
import com.jinbooks.entity.statement.StatementBalanceSheetItem;
|
||||
import com.jinbooks.entity.statement.StatementRules;
|
||||
import com.jinbooks.entity.statement.StatementSubjectBalance;
|
||||
import com.jinbooks.entity.statement.dto.StatementParamsDto;
|
||||
import com.jinbooks.entity.statement.vo.StatementBalanceSheetItemListVo;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -51,4 +56,12 @@ public interface StatementBalanceSheetService {
|
||||
boolean checkout(Settlement dto) ;
|
||||
|
||||
void export(StatementParamsDto dto, HttpServletResponse response) throws IOException;
|
||||
|
||||
void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules);
|
||||
|
||||
void refreshItemsBalance(List<StatementBalanceSheetItem> items,
|
||||
String bookId, String yearPeriod);
|
||||
|
||||
StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items);
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
package com.jinbooks.persistence.service;
|
||||
|
||||
import com.jinbooks.entity.Message;
|
||||
import com.jinbooks.entity.book.BookSubject;
|
||||
import com.jinbooks.entity.book.Settlement;
|
||||
import com.jinbooks.entity.statement.StatementSubjectBalance;
|
||||
@ -33,6 +34,8 @@ import java.util.List;
|
||||
*/
|
||||
public interface StatementSubjectBalanceService {
|
||||
StatementSubjectBalance getSubjectBalance(String bookId, String subjectCode);
|
||||
|
||||
public Message<StatementSubjectBalance> getSubjectBalance(StatementSubjectBalance params);
|
||||
|
||||
boolean hasVoucher(String bookId, List<String> codes);
|
||||
|
||||
|
||||
@ -22,44 +22,37 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.jinbooks.constants.ConstsSysConfig;
|
||||
import com.jinbooks.entity.Message;
|
||||
import com.jinbooks.entity.statement.StatementBalanceSheet;
|
||||
import com.jinbooks.entity.statement.StatementBalanceSheetItem;
|
||||
import com.jinbooks.entity.statement.StatementRules;
|
||||
import com.jinbooks.entity.statement.StatementSubjectBalance;
|
||||
import com.jinbooks.entity.statement.vo.StatementBalanceSheetItemListVo;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.jinbooks.enums.AssetOrLiabilityEnum;
|
||||
import com.jinbooks.enums.StatementPeriodTypeEnum;
|
||||
import com.jinbooks.enums.StatementSymbolEnum;
|
||||
import com.jinbooks.enums.StatementTypeEnum;
|
||||
import com.jinbooks.persistence.mapper.StatementBalanceSheetItemMapper;
|
||||
import com.jinbooks.persistence.mapper.StatementBalanceSheetMapper;
|
||||
import com.jinbooks.persistence.mapper.StatementRulesMapper;
|
||||
import com.jinbooks.persistence.mapper.StatementSubjectBalanceMapper;
|
||||
import com.jinbooks.persistence.service.ConfigSysService;
|
||||
import com.jinbooks.persistence.service.StatementBalanceSheetConfigService;
|
||||
import com.jinbooks.persistence.service.StatementBalanceSheetService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceSheetConfigService {
|
||||
private final StatementBalanceSheetMapper balanceSheetMapper;
|
||||
private final StatementBalanceSheetItemMapper statementBalanceSheetItemMapper;
|
||||
private final StatementRulesMapper rulesMapper;
|
||||
private final StatementSubjectBalanceMapper subjectBalanceMapper;
|
||||
private final ConfigSysService configSysService;
|
||||
private final StatementBalanceSheetService statementBalanceSheetService;
|
||||
|
||||
/**
|
||||
* 获取资产负载配置明细
|
||||
@ -92,7 +85,7 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
|
||||
List<StatementSubjectBalance> subjectBalances = subjectBalanceMapper.selectList(lqwSubject);
|
||||
for (StatementSubjectBalance subjectBalance : subjectBalances) {
|
||||
StatementRules statementRules = rulesMap.get(subjectBalance.getSubjectCode());
|
||||
updateRuleBalance(subjectBalance, statementRules);
|
||||
statementBalanceSheetService.updateRuleBalance(subjectBalance, statementRules);
|
||||
}
|
||||
}
|
||||
balanceSheetItem.setRules(rules);
|
||||
@ -112,8 +105,8 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
|
||||
lqw.eq(StatementBalanceSheetItem::getBookId, bookId);
|
||||
lqw.eq(StatementBalanceSheetItem::getBalanceSheetId, ConstsSysConfig.SYS_CONFIG_TEMPLATE_ID);
|
||||
List<StatementBalanceSheetItem> balanceSheets = statementBalanceSheetItemMapper.selectList(lqw);
|
||||
refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId));
|
||||
StatementBalanceSheetItemListVo itemListVo = insertSubtotals(balanceSheets);
|
||||
statementBalanceSheetService.refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId));
|
||||
StatementBalanceSheetItemListVo itemListVo = statementBalanceSheetService.insertSubtotals(balanceSheets);
|
||||
itemListVo.getAssets().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
|
||||
itemListVo.getLiability().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
|
||||
return Message.ok(itemListVo);
|
||||
@ -173,16 +166,6 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
|
||||
return Message.ok(statementBalanceSheetItemMapper.deleteById(id) > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message<StatementSubjectBalance> getSubjectBalance(StatementSubjectBalance params) {
|
||||
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StatementSubjectBalance::getBookId, params.getBookId());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getSubjectCode()), StatementSubjectBalance::getSubjectCode, params.getSubjectCode());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getSourceId()), StatementSubjectBalance::getSourceId, params.getSourceId());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getYearPeriod()), StatementSubjectBalance::getYearPeriod, params.getYearPeriod());
|
||||
return Message.ok(subjectBalanceMapper.selectOne(lqw));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*
|
||||
@ -198,212 +181,8 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
|
||||
return Message.ok(rules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules) {
|
||||
if (subjectBalance != null) {
|
||||
statementRules.setOpeningYearBalance(subjectBalance.getOpeningYearBalanceDebit()
|
||||
.subtract(subjectBalance.getOpeningYearBalanceCredit()));
|
||||
statementRules.setClosingBalance(subjectBalance.getBalance());
|
||||
} else {
|
||||
statementRules.setOpeningYearBalance(BigDecimal.ZERO);
|
||||
statementRules.setClosingBalance(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新信息项对应的余额数据
|
||||
*
|
||||
* @param items 信息项组
|
||||
* @param bookId 所属账簿
|
||||
* @param yearPeriod 账期
|
||||
*/
|
||||
@Override
|
||||
public void refreshItemsBalance(List<StatementBalanceSheetItem> items,
|
||||
String bookId, String yearPeriod) {
|
||||
// 方便更新参数
|
||||
Map<String, StatementBalanceSheetItem> mapSheet = items.stream()
|
||||
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item));
|
||||
List<String> itemCodes = items.stream().map(StatementBalanceSheetItem::getItemCode).toList();
|
||||
// 规则查询
|
||||
LambdaQueryWrapper<StatementRules> lqwRule = Wrappers.lambdaQuery();
|
||||
lqwRule.in(StatementRules::getItemCode, itemCodes);
|
||||
lqwRule.eq(StatementRules::getBookId, bookId);
|
||||
lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name());
|
||||
List<StatementRules> rules = rulesMapper.selectList(lqwRule);
|
||||
List<String> subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList();
|
||||
if (CollectionUtils.isNotEmpty(subjectCodes)) {
|
||||
// 查询科目余额
|
||||
LambdaQueryWrapper<StatementSubjectBalance> lqwSubject = Wrappers.lambdaQuery();
|
||||
lqwSubject.in(StatementSubjectBalance::getSubjectCode, subjectCodes);
|
||||
lqwSubject.eq(StatementSubjectBalance::getBookId, bookId);
|
||||
lqwSubject.eq(StatementSubjectBalance::getYearPeriod, yearPeriod);
|
||||
List<StatementSubjectBalance> subjectBalances = subjectBalanceMapper.selectList(lqwSubject);
|
||||
Map<String, StatementSubjectBalance> subjectMap = subjectBalances.stream()
|
||||
.collect(Collectors.toMap(StatementSubjectBalance::getSubjectCode, item -> item));
|
||||
// 更新对应规则的余额和报表余额
|
||||
for (StatementRules statementRules : rules) {
|
||||
StatementSubjectBalance subjectBalance = subjectMap.get(statementRules.getSubjectCode());
|
||||
updateRuleBalance(subjectBalance, statementRules);
|
||||
StatementBalanceSheetItem balanceSheet = mapSheet.get(statementRules.getItemCode());
|
||||
if (StatementSymbolEnum.PLUS.getValue().equals(statementRules.getSymbol())) {
|
||||
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
|
||||
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
|
||||
} else {
|
||||
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
|
||||
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对资产/负债中的合计类节点(如:1199、1299、1399)进行数据聚合,并更新这些节点的余额。
|
||||
*
|
||||
* @param items 数据组
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items) {
|
||||
if (items == null || items.isEmpty()) return null;
|
||||
|
||||
// 分组(资产和负债)
|
||||
Map<String, List<StatementBalanceSheetItem>> grouped = items.stream()
|
||||
.collect(Collectors.groupingBy(StatementBalanceSheetItem::getAssetOrLiability));
|
||||
|
||||
StatementBalanceSheetItemListVo result = new StatementBalanceSheetItemListVo();
|
||||
|
||||
// 资产
|
||||
List<StatementBalanceSheetItem> assetList = grouped.getOrDefault(AssetOrLiabilityEnum.asset.name(), new ArrayList<>());
|
||||
buildTreeAndSum(assetList);
|
||||
result.setAssets(assetList);
|
||||
|
||||
// 负债 + 所有者权益
|
||||
List<StatementBalanceSheetItem> liabilityList = grouped.getOrDefault(AssetOrLiabilityEnum.liability.name(), new ArrayList<>());
|
||||
buildTreeAndSum(liabilityList);
|
||||
result.setLiability(liabilityList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树 + 递归合计
|
||||
*
|
||||
* @param flatList 扁平化数据
|
||||
*/
|
||||
private void buildTreeAndSum(List<StatementBalanceSheetItem> flatList) {
|
||||
if (flatList == null || flatList.isEmpty()) return;
|
||||
|
||||
// 构建子列表引用(临时构建树结构)
|
||||
Map<String, List<StatementBalanceSheetItem>> childMap = new HashMap<>();
|
||||
for (StatementBalanceSheetItem item : flatList) {
|
||||
String parentCode = item.getParentItemCode();
|
||||
if (parentCode != null && !parentCode.isBlank()) {
|
||||
childMap.computeIfAbsent(parentCode, k -> new ArrayList<>()).add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// 递归聚合所有合计节点(自底向上)
|
||||
Set<String> visited = new HashSet<>();
|
||||
for (StatementBalanceSheetItem item : flatList) {
|
||||
if (!visited.contains(item.getItemCode())) {
|
||||
sumRecursively(item, childMap, visited);
|
||||
}
|
||||
}
|
||||
|
||||
// 聚合所有合计节点余额,
|
||||
// 递归时已经将子节点余额聚合到父节点上,这里只需要将父节点余额聚合到根节点上即可。
|
||||
final StatementBalanceSheetItem[] maxNode = {null};
|
||||
final BigDecimal[] currentAllSum = {BigDecimal.ZERO};
|
||||
final BigDecimal[] initialAllSum = {BigDecimal.ZERO};
|
||||
// 构建映射关系
|
||||
Map<String, StatementBalanceSheetItem> itemMap = flatList.stream()
|
||||
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, Function.identity()));
|
||||
|
||||
flatList.stream().filter(item -> item.getLevel() == 1).forEach(node -> {
|
||||
// 默认定义尾号99为合计项。如:1199、1299、1399、1199_1299
|
||||
if (node.getItemCode().endsWith("99")) {
|
||||
BigDecimal currentSum = node.getCurrentBalance() != null ? node.getCurrentBalance() : BigDecimal.ZERO;
|
||||
BigDecimal initialSum = node.getInitialBalance() != null ? node.getInitialBalance() : BigDecimal.ZERO;
|
||||
|
||||
// 分割拼接节点,叠加余额
|
||||
String[] codes = node.getItemCode().split("_");
|
||||
for (String code : codes) {
|
||||
code = code.substring(0, 2) + "00";
|
||||
StatementBalanceSheetItem parent = itemMap.get(code);
|
||||
if (parent != null) {
|
||||
currentSum = currentSum.add(parent.getCurrentBalance());
|
||||
initialSum = initialSum.add(parent.getInitialBalance());
|
||||
}
|
||||
}
|
||||
node.setCurrentBalance(currentSum);
|
||||
node.setInitialBalance(initialSum);
|
||||
// 避免重复叠加总额,因为节点可能被多次引用,如1199_1299
|
||||
if (codes.length == 1) {
|
||||
initialAllSum[0] = initialAllSum[0].add(initialSum);
|
||||
currentAllSum[0] = currentAllSum[0].add(currentSum);
|
||||
}
|
||||
|
||||
// 获取最大节点,一般为总计项
|
||||
if (maxNode[0] == null || node.getItemCode().compareTo(maxNode[0].getItemCode()) > 0) {
|
||||
maxNode[0] = node;
|
||||
}
|
||||
}
|
||||
});
|
||||
flatList.forEach(node -> {
|
||||
// 顶级节点不允许出现余额,统计项除外
|
||||
if (node.getItemCode().endsWith("00")) {
|
||||
node.setCurrentBalance(BigDecimal.ZERO);
|
||||
node.setInitialBalance(BigDecimal.ZERO);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置总计项余额
|
||||
if (maxNode[0] != null) {
|
||||
maxNode[0].setCurrentBalance(currentAllSum[0]);
|
||||
maxNode[0].setInitialBalance(initialAllSum[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归合计
|
||||
*
|
||||
* @param node 当前节点
|
||||
* @param childMap 子列表引用
|
||||
* @param visited 访问过的节点
|
||||
*/
|
||||
private void sumRecursively(StatementBalanceSheetItem node,
|
||||
Map<String, List<StatementBalanceSheetItem>> childMap,
|
||||
Set<String> visited) {
|
||||
if (visited.contains(node.getItemCode())) return;
|
||||
visited.add(node.getItemCode());
|
||||
List<StatementBalanceSheetItem> children = childMap.getOrDefault(node.getItemCode(), Collections.emptyList());
|
||||
|
||||
BigDecimal currentSum = node.getCurrentBalance() != null ? node.getCurrentBalance() : BigDecimal.ZERO;
|
||||
BigDecimal initialSum = node.getInitialBalance() != null ? node.getInitialBalance() : BigDecimal.ZERO;
|
||||
|
||||
for (StatementBalanceSheetItem child : children) {
|
||||
sumRecursively(child, childMap, visited);
|
||||
if (StatementSymbolEnum.PLUS.getValue().equals(child.getSymbol())) {
|
||||
currentSum = currentSum.add(
|
||||
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
|
||||
);
|
||||
initialSum = initialSum.add(
|
||||
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
|
||||
);
|
||||
} else {
|
||||
currentSum = currentSum.subtract(
|
||||
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
|
||||
);
|
||||
initialSum = initialSum.subtract(
|
||||
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
node.setCurrentBalance(currentSum);
|
||||
node.setInitialBalance(initialSum);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新行号,保证插入的行号,不影响到原有布局。
|
||||
@ -440,19 +219,4 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前账期报表ID
|
||||
*
|
||||
* @param bookId 账簿
|
||||
* @return StatementBalanceSheet
|
||||
*/
|
||||
private StatementBalanceSheet getBalanceSheetCurrentPeriod(String bookId) {
|
||||
String currentTerm = configSysService.getCurrentTerm(bookId);
|
||||
LambdaQueryWrapper<StatementBalanceSheet> lqwBalanceSheet = Wrappers.lambdaQuery();
|
||||
lqwBalanceSheet.eq(StatementBalanceSheet::getBookId, bookId);
|
||||
lqwBalanceSheet.eq(StatementBalanceSheet::getYearPeriod, currentTerm);
|
||||
lqwBalanceSheet.eq(StatementBalanceSheet::getPeriodType, StatementPeriodTypeEnum.MONTH.getValue());
|
||||
return balanceSheetMapper.selectOne(lqwBalanceSheet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -32,18 +32,20 @@ import com.jinbooks.entity.statement.*;
|
||||
import com.jinbooks.entity.statement.dto.StatementParamsDto;
|
||||
import com.jinbooks.entity.statement.vo.StatementBalanceSheetExport;
|
||||
import com.jinbooks.entity.statement.vo.StatementBalanceSheetItemListVo;
|
||||
import com.jinbooks.enums.AssetOrLiabilityEnum;
|
||||
import com.jinbooks.enums.StatementPeriodTypeEnum;
|
||||
import com.jinbooks.enums.StatementSymbolEnum;
|
||||
import com.jinbooks.enums.StatementTypeEnum;
|
||||
import com.jinbooks.persistence.mapper.*;
|
||||
import com.jinbooks.persistence.service.ConfigSysService;
|
||||
import com.jinbooks.persistence.service.StatementBalanceSheetConfigService;
|
||||
import com.jinbooks.persistence.service.StatementBalanceSheetService;
|
||||
import com.jinbooks.util.excel.ExcelDataModeEnum;
|
||||
import com.jinbooks.util.excel.ExcelExporter;
|
||||
import com.jinbooks.util.excel.ExcelParams;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
@ -54,6 +56,8 @@ import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@ -61,12 +65,13 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
|
||||
private final ConfigSysService configSysService;
|
||||
private final StatementBalanceSheetMapper balanceSheetMapper;
|
||||
private final StatementBalanceSheetItemMapper balanceSheetItemMapper;
|
||||
private final StatementBalanceSheetConfigService balanceSheetConfigService;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private final StatementRulesMapper statementRulesMapper;
|
||||
private final StandardStatementBalanceSheetMapper standardStatementBalanceSheetMapper;
|
||||
private final StandardStatementRulesMapper standardStatementRulesMapper;
|
||||
private final BookMapper bookMapper;
|
||||
private final StatementRulesMapper rulesMapper;
|
||||
private final StatementSubjectBalanceMapper subjectBalanceMapper;
|
||||
|
||||
/**
|
||||
* 报表-资产负债表
|
||||
@ -123,7 +128,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
|
||||
|
||||
// 遍历月份,统计总金额
|
||||
for (String month : allMonths) {
|
||||
balanceSheetConfigService.refreshItemsBalance(items, dto.getBookId(), month);
|
||||
refreshItemsBalance(items, dto.getBookId(), month);
|
||||
}
|
||||
}
|
||||
}else {// 拉取历史数据
|
||||
@ -134,7 +139,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
|
||||
items = balanceSheetItemMapper.selectList(itemLqw);
|
||||
}
|
||||
|
||||
StatementBalanceSheetItemListVo itemListVo = balanceSheetConfigService.insertSubtotals(items);
|
||||
StatementBalanceSheetItemListVo itemListVo = insertSubtotals(items);
|
||||
itemListVo.getAssets().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
|
||||
itemListVo.getLiability().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
|
||||
balanceSheet.setItems(itemListVo);
|
||||
@ -358,4 +363,213 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新信息项对应的余额数据
|
||||
*
|
||||
* @param items 信息项组
|
||||
* @param bookId 所属账簿
|
||||
* @param yearPeriod 账期
|
||||
*/
|
||||
@Override
|
||||
public void refreshItemsBalance(List<StatementBalanceSheetItem> items,
|
||||
String bookId, String yearPeriod) {
|
||||
// 方便更新参数
|
||||
Map<String, StatementBalanceSheetItem> mapSheet = items.stream()
|
||||
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item));
|
||||
List<String> itemCodes = items.stream().map(StatementBalanceSheetItem::getItemCode).toList();
|
||||
// 规则查询
|
||||
LambdaQueryWrapper<StatementRules> lqwRule = Wrappers.lambdaQuery();
|
||||
lqwRule.in(StatementRules::getItemCode, itemCodes);
|
||||
lqwRule.eq(StatementRules::getBookId, bookId);
|
||||
lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name());
|
||||
List<StatementRules> rules = rulesMapper.selectList(lqwRule);
|
||||
List<String> subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList();
|
||||
if (CollectionUtils.isNotEmpty(subjectCodes)) {
|
||||
// 查询科目余额
|
||||
LambdaQueryWrapper<StatementSubjectBalance> lqwSubject = Wrappers.lambdaQuery();
|
||||
lqwSubject.in(StatementSubjectBalance::getSubjectCode, subjectCodes);
|
||||
lqwSubject.eq(StatementSubjectBalance::getBookId, bookId);
|
||||
lqwSubject.eq(StatementSubjectBalance::getYearPeriod, yearPeriod);
|
||||
List<StatementSubjectBalance> subjectBalances = subjectBalanceMapper.selectList(lqwSubject);
|
||||
Map<String, StatementSubjectBalance> subjectMap = subjectBalances.stream()
|
||||
.collect(Collectors.toMap(StatementSubjectBalance::getSubjectCode, item -> item));
|
||||
// 更新对应规则的余额和报表余额
|
||||
for (StatementRules statementRules : rules) {
|
||||
StatementSubjectBalance subjectBalance = subjectMap.get(statementRules.getSubjectCode());
|
||||
updateRuleBalance(subjectBalance, statementRules);
|
||||
StatementBalanceSheetItem balanceSheet = mapSheet.get(statementRules.getItemCode());
|
||||
if (StatementSymbolEnum.PLUS.getValue().equals(statementRules.getSymbol())) {
|
||||
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
|
||||
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
|
||||
} else {
|
||||
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
|
||||
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对资产/负债中的合计类节点(如:1199、1299、1399)进行数据聚合,并更新这些节点的余额。
|
||||
*
|
||||
* @param items 数据组
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items) {
|
||||
if (items == null || items.isEmpty()) return null;
|
||||
|
||||
// 分组(资产和负债)
|
||||
Map<String, List<StatementBalanceSheetItem>> grouped = items.stream()
|
||||
.collect(Collectors.groupingBy(StatementBalanceSheetItem::getAssetOrLiability));
|
||||
|
||||
StatementBalanceSheetItemListVo result = new StatementBalanceSheetItemListVo();
|
||||
|
||||
// 资产
|
||||
List<StatementBalanceSheetItem> assetList = grouped.getOrDefault(AssetOrLiabilityEnum.asset.name(), new ArrayList<>());
|
||||
buildTreeAndSum(assetList);
|
||||
result.setAssets(assetList);
|
||||
|
||||
// 负债 + 所有者权益
|
||||
List<StatementBalanceSheetItem> liabilityList = grouped.getOrDefault(AssetOrLiabilityEnum.liability.name(), new ArrayList<>());
|
||||
buildTreeAndSum(liabilityList);
|
||||
result.setLiability(liabilityList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树 + 递归合计
|
||||
*
|
||||
* @param flatList 扁平化数据
|
||||
*/
|
||||
private void buildTreeAndSum(List<StatementBalanceSheetItem> flatList) {
|
||||
if (flatList == null || flatList.isEmpty()) return;
|
||||
|
||||
// 构建子列表引用(临时构建树结构)
|
||||
Map<String, List<StatementBalanceSheetItem>> childMap = new HashMap<>();
|
||||
for (StatementBalanceSheetItem item : flatList) {
|
||||
String parentCode = item.getParentItemCode();
|
||||
if (parentCode != null && !parentCode.isBlank()) {
|
||||
childMap.computeIfAbsent(parentCode, k -> new ArrayList<>()).add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// 递归聚合所有合计节点(自底向上)
|
||||
Set<String> visited = new HashSet<>();
|
||||
for (StatementBalanceSheetItem item : flatList) {
|
||||
if (!visited.contains(item.getItemCode())) {
|
||||
sumRecursively(item, childMap, visited);
|
||||
}
|
||||
}
|
||||
|
||||
// 聚合所有合计节点余额,
|
||||
// 递归时已经将子节点余额聚合到父节点上,这里只需要将父节点余额聚合到根节点上即可。
|
||||
final StatementBalanceSheetItem[] maxNode = {null};
|
||||
final BigDecimal[] currentAllSum = {BigDecimal.ZERO};
|
||||
final BigDecimal[] initialAllSum = {BigDecimal.ZERO};
|
||||
// 构建映射关系
|
||||
Map<String, StatementBalanceSheetItem> itemMap = flatList.stream()
|
||||
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, Function.identity()));
|
||||
|
||||
flatList.stream().filter(item -> item.getLevel() == 1).forEach(node -> {
|
||||
// 默认定义尾号99为合计项。如:1199、1299、1399、1199_1299
|
||||
if (node.getItemCode().endsWith("99")) {
|
||||
BigDecimal currentSum = node.getCurrentBalance() != null ? node.getCurrentBalance() : BigDecimal.ZERO;
|
||||
BigDecimal initialSum = node.getInitialBalance() != null ? node.getInitialBalance() : BigDecimal.ZERO;
|
||||
|
||||
// 分割拼接节点,叠加余额
|
||||
String[] codes = node.getItemCode().split("_");
|
||||
for (String code : codes) {
|
||||
code = code.substring(0, 2) + "00";
|
||||
StatementBalanceSheetItem parent = itemMap.get(code);
|
||||
if (parent != null) {
|
||||
currentSum = currentSum.add(parent.getCurrentBalance());
|
||||
initialSum = initialSum.add(parent.getInitialBalance());
|
||||
}
|
||||
}
|
||||
node.setCurrentBalance(currentSum);
|
||||
node.setInitialBalance(initialSum);
|
||||
// 避免重复叠加总额,因为节点可能被多次引用,如1199_1299
|
||||
if (codes.length == 1) {
|
||||
initialAllSum[0] = initialAllSum[0].add(initialSum);
|
||||
currentAllSum[0] = currentAllSum[0].add(currentSum);
|
||||
}
|
||||
|
||||
// 获取最大节点,一般为总计项
|
||||
if (maxNode[0] == null || node.getItemCode().compareTo(maxNode[0].getItemCode()) > 0) {
|
||||
maxNode[0] = node;
|
||||
}
|
||||
}
|
||||
});
|
||||
flatList.forEach(node -> {
|
||||
// 顶级节点不允许出现余额,统计项除外
|
||||
if (node.getItemCode().endsWith("00")) {
|
||||
node.setCurrentBalance(BigDecimal.ZERO);
|
||||
node.setInitialBalance(BigDecimal.ZERO);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置总计项余额
|
||||
if (maxNode[0] != null) {
|
||||
maxNode[0].setCurrentBalance(currentAllSum[0]);
|
||||
maxNode[0].setInitialBalance(initialAllSum[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归合计
|
||||
*
|
||||
* @param node 当前节点
|
||||
* @param childMap 子列表引用
|
||||
* @param visited 访问过的节点
|
||||
*/
|
||||
private void sumRecursively(StatementBalanceSheetItem node,
|
||||
Map<String, List<StatementBalanceSheetItem>> childMap,
|
||||
Set<String> visited) {
|
||||
if (visited.contains(node.getItemCode())) return;
|
||||
visited.add(node.getItemCode());
|
||||
List<StatementBalanceSheetItem> children = childMap.getOrDefault(node.getItemCode(), Collections.emptyList());
|
||||
|
||||
BigDecimal currentSum = node.getCurrentBalance() != null ? node.getCurrentBalance() : BigDecimal.ZERO;
|
||||
BigDecimal initialSum = node.getInitialBalance() != null ? node.getInitialBalance() : BigDecimal.ZERO;
|
||||
|
||||
for (StatementBalanceSheetItem child : children) {
|
||||
sumRecursively(child, childMap, visited);
|
||||
if (StatementSymbolEnum.PLUS.getValue().equals(child.getSymbol())) {
|
||||
currentSum = currentSum.add(
|
||||
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
|
||||
);
|
||||
initialSum = initialSum.add(
|
||||
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
|
||||
);
|
||||
} else if (StatementSymbolEnum.MINUS.getValue().equals(child.getSymbol())){
|
||||
currentSum = currentSum.subtract(
|
||||
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
|
||||
);
|
||||
initialSum = initialSum.subtract(
|
||||
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
node.setCurrentBalance(currentSum);
|
||||
node.setInitialBalance(initialSum);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules) {
|
||||
if (subjectBalance != null) {
|
||||
statementRules.setOpeningYearBalance(subjectBalance.getOpeningYearBalanceDebit()
|
||||
.subtract(subjectBalance.getOpeningYearBalanceCredit()));
|
||||
statementRules.setClosingBalance(subjectBalance.getBalance());
|
||||
} else {
|
||||
statementRules.setOpeningYearBalance(BigDecimal.ZERO);
|
||||
statementRules.setClosingBalance(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jinbooks.entity.Message;
|
||||
import com.jinbooks.entity.SubjectAuxiliary;
|
||||
import com.jinbooks.entity.base.AssistAcc;
|
||||
import com.jinbooks.entity.book.BookSubject;
|
||||
@ -73,6 +74,16 @@ public class StatementSubjectBalanceServiceImpl implements StatementSubjectBalan
|
||||
queryWrapper.eq(StatementSubjectBalance::getSubjectCode, subjectCode);
|
||||
return subjectBalanceMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message<StatementSubjectBalance> getSubjectBalance(StatementSubjectBalance params) {
|
||||
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StatementSubjectBalance::getBookId, params.getBookId());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getSubjectCode()), StatementSubjectBalance::getSubjectCode, params.getSubjectCode());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getSourceId()), StatementSubjectBalance::getSourceId, params.getSourceId());
|
||||
lqw.eq(StringUtils.isNotBlank(params.getYearPeriod()), StatementSubjectBalance::getYearPeriod, params.getYearPeriod());
|
||||
return Message.ok(subjectBalanceMapper.selectOne(lqw));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断科目是否有凭证
|
||||
|
||||
@ -22,7 +22,8 @@ import com.jinbooks.authn.annotation.CurrentUser;
|
||||
import com.jinbooks.entity.Message;
|
||||
import com.jinbooks.entity.idm.UserInfo;
|
||||
import com.jinbooks.entity.statement.StatementSubjectBalance;
|
||||
import com.jinbooks.persistence.service.StatementBalanceSheetConfigService;
|
||||
import com.jinbooks.persistence.service.StatementSubjectBalanceService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -36,7 +37,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class StatementSubjectBalanceController {
|
||||
private final StatementBalanceSheetConfigService configService;
|
||||
private final StatementSubjectBalanceService statementSubjectBalanceService;
|
||||
|
||||
/**
|
||||
* 获取单个
|
||||
@ -45,7 +46,7 @@ public class StatementSubjectBalanceController {
|
||||
public Message<StatementSubjectBalance> getSubjectBalance(StatementSubjectBalance params,
|
||||
@CurrentUser UserInfo userInfo) {
|
||||
params.setBookId(userInfo.getBookId());
|
||||
return configService.getSubjectBalance(params);
|
||||
return statementSubjectBalanceService.getSubjectBalance(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user