From 1fe9353f448048b2bf25218c7377e87caeb98654 Mon Sep 17 00:00:00 2001 From: jinbooks_dev Date: Thu, 12 Jun 2025 09:56:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/config/standard-balance-sheet.vue | 3 +- .../config/standard-income-statement.vue | 10 +- .../src/views/statement/balance-sheet.vue | 10 +- .../src/views/statement/income-statement.vue | 7 + .../StatementBalanceSheetConfigService.java | 7 - .../service/StatementBalanceSheetService.java | 13 + .../StatementSubjectBalanceService.java | 3 + ...tatementBalanceSheetConfigServiceImpl.java | 250 +----------------- .../StatementBalanceSheetServiceImpl.java | 222 +++++++++++++++- .../StatementSubjectBalanceServiceImpl.java | 11 + .../StatementSubjectBalanceController.java | 7 +- 11 files changed, 278 insertions(+), 265 deletions(-) diff --git a/jinbooks-ui/src/views/config/standard-balance-sheet.vue b/jinbooks-ui/src/views/config/standard-balance-sheet.vue index 050f7d2..6d314ae 100644 --- a/jinbooks-ui/src/views/config/standard-balance-sheet.vue +++ b/jinbooks-ui/src/views/config/standard-balance-sheet.vue @@ -103,10 +103,11 @@ - + + diff --git a/jinbooks-ui/src/views/config/standard-income-statement.vue b/jinbooks-ui/src/views/config/standard-income-statement.vue index f96e52c..d66a979 100644 --- a/jinbooks-ui/src/views/config/standard-income-statement.vue +++ b/jinbooks-ui/src/views/config/standard-income-statement.vue @@ -71,11 +71,11 @@ - - - - - + + + + + diff --git a/jinbooks-ui/src/views/statement/balance-sheet.vue b/jinbooks-ui/src/views/statement/balance-sheet.vue index ad7010e..c2fedac 100644 --- a/jinbooks-ui/src/views/statement/balance-sheet.vue +++ b/jinbooks-ui/src/views/statement/balance-sheet.vue @@ -179,19 +179,25 @@ + + + - + + - + + + + + + + + + + diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetConfigService.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetConfigService.java index c20e5cb..00d285c 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetConfigService.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetConfigService.java @@ -49,12 +49,5 @@ public interface StatementBalanceSheetConfigService { Message delete(String id); - Message getSubjectBalance(StatementSubjectBalance params); - void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules); - - void refreshItemsBalance(List items, - String bookId, String yearPeriod); - - StatementBalanceSheetItemListVo insertSubtotals(List items); } diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetService.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetService.java index fc94b44..cf9de44 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetService.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementBalanceSheetService.java @@ -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 items, + String bookId, String yearPeriod); + + StatementBalanceSheetItemListVo insertSubtotals(List items); + } diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementSubjectBalanceService.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementSubjectBalanceService.java index 99ff46f..e2244a3 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementSubjectBalanceService.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/StatementSubjectBalanceService.java @@ -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 getSubjectBalance(StatementSubjectBalance params); boolean hasVoucher(String bookId, List codes); diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetConfigServiceImpl.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetConfigServiceImpl.java index 2dfa861..e149a2b 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetConfigServiceImpl.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetConfigServiceImpl.java @@ -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 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 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 getSubjectBalance(StatementSubjectBalance params) { - LambdaQueryWrapper 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 items, - String bookId, String yearPeriod) { - // 方便更新参数 - Map mapSheet = items.stream() - .collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item)); - List itemCodes = items.stream().map(StatementBalanceSheetItem::getItemCode).toList(); - // 规则查询 - LambdaQueryWrapper lqwRule = Wrappers.lambdaQuery(); - lqwRule.in(StatementRules::getItemCode, itemCodes); - lqwRule.eq(StatementRules::getBookId, bookId); - lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name()); - List rules = rulesMapper.selectList(lqwRule); - List subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList(); - if (CollectionUtils.isNotEmpty(subjectCodes)) { - // 查询科目余额 - LambdaQueryWrapper lqwSubject = Wrappers.lambdaQuery(); - lqwSubject.in(StatementSubjectBalance::getSubjectCode, subjectCodes); - lqwSubject.eq(StatementSubjectBalance::getBookId, bookId); - lqwSubject.eq(StatementSubjectBalance::getYearPeriod, yearPeriod); - List subjectBalances = subjectBalanceMapper.selectList(lqwSubject); - Map 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 items) { - if (items == null || items.isEmpty()) return null; - - // 分组(资产和负债) - Map> grouped = items.stream() - .collect(Collectors.groupingBy(StatementBalanceSheetItem::getAssetOrLiability)); - - StatementBalanceSheetItemListVo result = new StatementBalanceSheetItemListVo(); - - // 资产 - List assetList = grouped.getOrDefault(AssetOrLiabilityEnum.asset.name(), new ArrayList<>()); - buildTreeAndSum(assetList); - result.setAssets(assetList); - - // 负债 + 所有者权益 - List liabilityList = grouped.getOrDefault(AssetOrLiabilityEnum.liability.name(), new ArrayList<>()); - buildTreeAndSum(liabilityList); - result.setLiability(liabilityList); - - return result; - } - - /** - * 构建树 + 递归合计 - * - * @param flatList 扁平化数据 - */ - private void buildTreeAndSum(List flatList) { - if (flatList == null || flatList.isEmpty()) return; - - // 构建子列表引用(临时构建树结构) - Map> 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 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 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> childMap, - Set visited) { - if (visited.contains(node.getItemCode())) return; - visited.add(node.getItemCode()); - List 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 lqwBalanceSheet = Wrappers.lambdaQuery(); - lqwBalanceSheet.eq(StatementBalanceSheet::getBookId, bookId); - lqwBalanceSheet.eq(StatementBalanceSheet::getYearPeriod, currentTerm); - lqwBalanceSheet.eq(StatementBalanceSheet::getPeriodType, StatementPeriodTypeEnum.MONTH.getValue()); - return balanceSheetMapper.selectOne(lqwBalanceSheet); - } - } diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetServiceImpl.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetServiceImpl.java index 6f6b521..5228935 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetServiceImpl.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementBalanceSheetServiceImpl.java @@ -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 items, + String bookId, String yearPeriod) { + // 方便更新参数 + Map mapSheet = items.stream() + .collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item)); + List itemCodes = items.stream().map(StatementBalanceSheetItem::getItemCode).toList(); + // 规则查询 + LambdaQueryWrapper lqwRule = Wrappers.lambdaQuery(); + lqwRule.in(StatementRules::getItemCode, itemCodes); + lqwRule.eq(StatementRules::getBookId, bookId); + lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name()); + List rules = rulesMapper.selectList(lqwRule); + List subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList(); + if (CollectionUtils.isNotEmpty(subjectCodes)) { + // 查询科目余额 + LambdaQueryWrapper lqwSubject = Wrappers.lambdaQuery(); + lqwSubject.in(StatementSubjectBalance::getSubjectCode, subjectCodes); + lqwSubject.eq(StatementSubjectBalance::getBookId, bookId); + lqwSubject.eq(StatementSubjectBalance::getYearPeriod, yearPeriod); + List subjectBalances = subjectBalanceMapper.selectList(lqwSubject); + Map 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 items) { + if (items == null || items.isEmpty()) return null; + + // 分组(资产和负债) + Map> grouped = items.stream() + .collect(Collectors.groupingBy(StatementBalanceSheetItem::getAssetOrLiability)); + + StatementBalanceSheetItemListVo result = new StatementBalanceSheetItemListVo(); + + // 资产 + List assetList = grouped.getOrDefault(AssetOrLiabilityEnum.asset.name(), new ArrayList<>()); + buildTreeAndSum(assetList); + result.setAssets(assetList); + + // 负债 + 所有者权益 + List liabilityList = grouped.getOrDefault(AssetOrLiabilityEnum.liability.name(), new ArrayList<>()); + buildTreeAndSum(liabilityList); + result.setLiability(liabilityList); + + return result; + } + + /** + * 构建树 + 递归合计 + * + * @param flatList 扁平化数据 + */ + private void buildTreeAndSum(List flatList) { + if (flatList == null || flatList.isEmpty()) return; + + // 构建子列表引用(临时构建树结构) + Map> 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 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 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> childMap, + Set visited) { + if (visited.contains(node.getItemCode())) return; + visited.add(node.getItemCode()); + List 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); + } + } + } diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementSubjectBalanceServiceImpl.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementSubjectBalanceServiceImpl.java index 5cf5bd9..3c4aa9b 100644 --- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementSubjectBalanceServiceImpl.java +++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/StatementSubjectBalanceServiceImpl.java @@ -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 getSubjectBalance(StatementSubjectBalance params) { + LambdaQueryWrapper 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)); + } /** * 判断科目是否有凭证 diff --git a/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/statement/controller/StatementSubjectBalanceController.java b/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/statement/controller/StatementSubjectBalanceController.java index ed4b3db..44cc23f 100644 --- a/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/statement/controller/StatementSubjectBalanceController.java +++ b/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/statement/controller/StatementSubjectBalanceController.java @@ -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 getSubjectBalance(StatementSubjectBalance params, @CurrentUser UserInfo userInfo) { params.setBookId(userInfo.getBookId()); - return configService.getSubjectBalance(params); + return statementSubjectBalanceService.getSubjectBalance(params); } }