CostDepartmentProfitServiceImpl.java 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. package com.imed.costaccount.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import cn.hutool.poi.excel.ExcelWriter;
  7. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  9. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  10. import com.imed.costaccount.common.enums.DateStyleEnum;
  11. import com.imed.costaccount.common.exception.CostException;
  12. import com.imed.costaccount.common.util.BeanUtil;
  13. import com.imed.costaccount.common.util.DateUtils;
  14. import com.imed.costaccount.common.util.PageUtils;
  15. import com.imed.costaccount.common.util.UserContext;
  16. import com.imed.costaccount.constants.NumberConstant;
  17. import com.imed.costaccount.mapper.CostDepartmentProfitMapper;
  18. import com.imed.costaccount.model.*;
  19. import com.imed.costaccount.model.vo.AllocationQueryReportVO;
  20. import com.imed.costaccount.model.vo.CostDepartmentProfitVO;
  21. import com.imed.costaccount.service.*;
  22. import org.apache.poi.ss.usermodel.Sheet;
  23. import org.springframework.stereotype.Service;
  24. import org.springframework.transaction.annotation.Propagation;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import java.math.BigDecimal;
  27. import java.util.*;
  28. import java.util.concurrent.atomic.AtomicReference;
  29. import java.util.stream.Collectors;
  30. @Service("costDepartmentProfitService")
  31. public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentProfitMapper, CostDepartmentProfit> implements CostDepartmentProfitService {
  32. private final ReportFormService reportFormService;
  33. private final IncomeCollectionService incomeCollectionService;
  34. private final CostShareLevelService costShareLevelService;
  35. private final ResponsibilityService responsibilityService;
  36. private final ReportRelationService reportRelationService;
  37. private final AllocationService allocationService;
  38. private final AllocationQueryService allocationQueryService;
  39. public CostDepartmentProfitServiceImpl(ReportFormService reportFormService, IncomeCollectionService incomeCollectionService, CostShareLevelService costShareLevelService, ResponsibilityService responsibilityService, ReportRelationService reportRelationService, AllocationService allocationService, AllocationQueryService allocationQueryService) {
  40. this.reportFormService = reportFormService;
  41. this.incomeCollectionService = incomeCollectionService;
  42. this.costShareLevelService = costShareLevelService;
  43. this.responsibilityService = responsibilityService;
  44. this.reportRelationService = reportRelationService;
  45. this.allocationService = allocationService;
  46. this.allocationQueryService = allocationQueryService;
  47. }
  48. /**
  49. * 查询科室损益数据
  50. *
  51. * @param current
  52. * @param pageSize
  53. * @param responsibilityCode
  54. * @param date
  55. * @param hospId
  56. * @return
  57. */
  58. @Override
  59. public PageUtils queryList(Integer current, Integer pageSize, String responsibilityCode, String date, Long hospId) {
  60. int year = 0;
  61. int month = 0;
  62. if (StrUtil.isNotBlank(date)) {
  63. Date dateTime = DateUtils.StringToDate(date, DateStyleEnum.YYYY_MM_DD);
  64. year = DateUtil.year(dateTime);
  65. month = DateUtil.month(dateTime) + 1;
  66. }
  67. Page<CostDepartmentProfit> departmentProfitPage = new Page<>(current, pageSize);
  68. // 查询的时候过过滤那些计算方式是不设置的数据
  69. Page<CostDepartmentProfit> pages = this.page(departmentProfitPage, new QueryWrapper<CostDepartmentProfit>().lambda()
  70. .eq(CostDepartmentProfit::getHospId, hospId)
  71. .eq(StrUtil.isNotBlank(responsibilityCode), CostDepartmentProfit::getResponsibilityCode, responsibilityCode)
  72. .eq(StrUtil.isNotBlank(date), CostDepartmentProfit::getYear, year)
  73. .eq(StrUtil.isNotBlank(date), CostDepartmentProfit::getMonth, month)
  74. .ne(CostDepartmentProfit::getCalcType, NumberConstant.ZERO).orderByDesc(CostDepartmentProfit::getAmount));
  75. List<CostDepartmentProfit> records = pages.getRecords();
  76. List<CostDepartmentProfitVO> costDepartmentProfitVOList = BeanUtil.convertList(records, CostDepartmentProfitVO.class);
  77. PageUtils pageUtils = new PageUtils(pages);
  78. pageUtils.setList(costDepartmentProfitVOList);
  79. return pageUtils;
  80. }
  81. /**
  82. * 科室损益计算
  83. *
  84. * @param date
  85. * @param hospId
  86. */
  87. @Override
  88. @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
  89. public void setDepartmentProfit(String date, Long hospId) {
  90. DateTime parse = DateUtil.parse(date);
  91. int year = DateUtil.year(parse);
  92. int month = DateUtil.month(parse) + 1;
  93. // 先查询指定条件的报表数据 查询损益表的数据
  94. List<ReportForm> reportFormList = reportFormService.list(new QueryWrapper<ReportForm>().lambda()
  95. .eq(ReportForm::getHospId, hospId)
  96. .eq(ReportForm::getReportType, NumberConstant.ZERO));
  97. if (CollUtil.isEmpty(reportFormList)) {
  98. throw new CostException(500, "损益表未找到");
  99. }
  100. // 遍历报表数据根据报表数据计算方式进行计算
  101. // 查询最后一个层级的责任中心
  102. List<CostShareLevel> costShareLevelList = costShareLevelService.list(new QueryWrapper<CostShareLevel>().lambda()
  103. .eq(CostShareLevel::getHospId, hospId).orderByDesc(CostShareLevel::getLeverSort));
  104. if (CollUtil.isEmpty(costShareLevelList)) {
  105. throw new CostException(500, "分摊层级未设置");
  106. }
  107. // TODO 可能多个
  108. Long id = costShareLevelList.get(0).getId();
  109. // 查询责任中心里面是这个层级的所有的收益中心
  110. List<Responsibility> responsibilityList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
  111. .eq(Responsibility::getHospId, hospId).eq(Responsibility::getResponsibilityType, NumberConstant.ONE).eq(Responsibility::getShareId, id));
  112. // 归集后
  113. List<IncomeCollection> incomeList = incomeCollectionService.list(new QueryWrapper<IncomeCollection>().lambda()
  114. .eq(IncomeCollection::getHospId, hospId)
  115. .eq(year > 0, IncomeCollection::getYear, year).eq(month > 0, IncomeCollection::getMonth, month));
  116. if (CollUtil.isEmpty(incomeList)) {
  117. throw new CostException(500, "归集后数据不存在");
  118. }
  119. Map<Long, List<ReportRelation>> reportRelationMap = reportRelationService.list(new QueryWrapper<ReportRelation>().lambda().eq(ReportRelation::getHospId, hospId)).stream().collect(Collectors.groupingBy(ReportRelation::getReportId));
  120. // 分摊后的数据说明是分摊后的数据
  121. List<AllocationQuery> allocationQueryList = allocationQueryService.list(new QueryWrapper<AllocationQuery>().lambda().eq(AllocationQuery::getHospId, hospId)
  122. .eq(year > 0, AllocationQuery::getDateYear, year)
  123. .eq(month > 0, AllocationQuery::getDateMonth, month)
  124. );
  125. if (CollUtil.isEmpty(allocationQueryList)) {
  126. throw new CostException(500, "分摊后数据不存在");
  127. }
  128. // 封装数据
  129. List<AllocationQueryReportVO> allocationQueryReportVOList = BeanUtil.convertList(allocationQueryList, AllocationQueryReportVO.class);
  130. allocationQueryReportVOList.forEach(i -> {
  131. i.setAccountingCodes(Arrays.asList(i.getAccountingCode().split(StrUtil.COMMA)));
  132. i.setAccountingNames(Arrays.asList(i.getAccountingName().split(StrUtil.COMMA)));
  133. });
  134. // 查询分摊的报表数据 后面的计算方式需要使用 小计等需要使用
  135. List<Allocation> allocationList = allocationService.list(new QueryWrapper<Allocation>().lambda().eq(Allocation::getHospId, hospId)
  136. .eq(year > 0, Allocation::getDateYear, year).eq(month > 0, Allocation::getDateMonth, month));
  137. if (CollUtil.isEmpty(allocationList)) {
  138. throw new CostException(500, "分摊报表数据不存在");
  139. }
  140. // 查询所有指定类型的损益表
  141. // 每个责任中心对应报表都要生成记录
  142. // 封装需要设置的数据
  143. List<CostDepartmentProfitVO> list = new ArrayList<>();
  144. int finalYear = year;
  145. int finalMonth = month;
  146. responsibilityList.forEach(i -> {
  147. reportFormList.forEach(j -> {
  148. CostDepartmentProfitVO costDepartmentProfitVO = new CostDepartmentProfitVO();
  149. costDepartmentProfitVO.setYear(finalYear);
  150. costDepartmentProfitVO.setMonth(finalMonth);
  151. costDepartmentProfitVO.setReportId(j.getId());
  152. costDepartmentProfitVO.setReportNum(j.getNum());
  153. costDepartmentProfitVO.setCalcType(j.getCalcType());
  154. costDepartmentProfitVO.setReportName(j.getReportName());
  155. costDepartmentProfitVO.setCalcFormula(j.getCalcFormula());
  156. costDepartmentProfitVO.setReportParentId(j.getParentId());
  157. costDepartmentProfitVO.setResponsibilityCode(i.getResponsibilityCode());
  158. costDepartmentProfitVO.setResponsibilityName(i.getResponsibilityName());
  159. costDepartmentProfitVO.setCostType(NumberConstant.ONE);
  160. costDepartmentProfitVO.setIncomeType(NumberConstant.ONE);
  161. costDepartmentProfitVO.setHospId(hospId);
  162. list.add(costDepartmentProfitVO);
  163. });
  164. });
  165. Map<Long, List<CostDepartmentProfitVO>> listMap = list.stream().collect(Collectors.groupingBy(CostDepartmentProfitVO::getReportId));
  166. List<CostDepartmentProfitVO> allList = BeanUtil.convertList(list, CostDepartmentProfitVO.class);
  167. // 记录每一次计算的钱
  168. list.forEach(i -> {
  169. Long reportId = i.getReportId();
  170. Integer calcType = i.getCalcType();
  171. if (NumberConstant.ONE.equals(calcType)){
  172. // TODO 按照会计科目进行计算
  173. i.setAmount(setAccountReportData(i, incomeList, allocationQueryReportVOList, reportRelationMap,allList));
  174. }else if (NumberConstant.TWO.equals(calcType)){
  175. // TODO 按照分摊层级进行计算
  176. i.setAmount(setShareLevelReportData(i, costShareLevelList, reportRelationMap, allocationList,allList));
  177. }else if (NumberConstant.THREE.equals(calcType)){
  178. // TODO 按照小计进行计算
  179. i.setAmount(setSubtotal(i, costShareLevelList, listMap, list, incomeList, allocationQueryReportVOList, reportRelationMap, allocationList,allList));
  180. }else if (NumberConstant.FOUR.equals(calcType)){
  181. // TODO 按照计算公式进行计算
  182. i.setAmount(setCalculation(i, list, costShareLevelList, listMap, incomeList, allocationQueryReportVOList, reportRelationMap, allocationList,allList));
  183. }else if (NumberConstant.FIVE.equals(calcType)){
  184. // TODO 按照责任中心进行计算
  185. i.setAmount(setResponsibilityCode(i, reportRelationMap, allocationList,allList));
  186. }else {
  187. i.setAmount(new BigDecimal("0.0000"));
  188. }
  189. // switch (calcType) {
  190. // case 1:
  191. //
  192. // break;
  193. // case 2:
  194. //
  195. // break;
  196. // case 3:
  197. //
  198. // break;
  199. // case 4:
  200. //
  201. // break;
  202. // case 5:
  203. //
  204. // break;
  205. // default:
  206. // break;
  207. // }
  208. });
  209. // 删除这个年月的数据
  210. this.remove(new QueryWrapper<CostDepartmentProfit>().lambda().eq(CostDepartmentProfit::getHospId, hospId)
  211. .eq(CostDepartmentProfit::getYear, year).eq(CostDepartmentProfit::getMonth, month));
  212. // 添加数据
  213. List<CostDepartmentProfit> costDepartmentProfits = BeanUtil.convertList(list, CostDepartmentProfit.class);
  214. long l = System.currentTimeMillis();
  215. costDepartmentProfits.forEach(i -> {
  216. i.setCreateTime(l);
  217. });
  218. this.saveBatch(costDepartmentProfits);
  219. }
  220. /**
  221. * 科室损益计算导出
  222. *
  223. * @param writer
  224. * @param sheet
  225. * @param date
  226. */
  227. @Override
  228. public void getDepartmentProfit(ExcelWriter writer, Sheet sheet, String date) {
  229. Long hospId = UserContext.getHospId();
  230. UserContext.getHospId();
  231. //先展示所有责任中心 非汇总中心 收益中心的责任中心
  232. // 查询所有的节点
  233. List<Responsibility> responsibilityList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda().eq(Responsibility::getHospId, hospId));
  234. if (CollUtil.isEmpty(responsibilityList)){
  235. throw new CostException(500,"责任中心不存在");
  236. }
  237. // 设置表头
  238. Map<Long, List<Responsibility>> responsibilityMap = responsibilityList.stream().collect(Collectors.groupingBy(Responsibility::getId));
  239. List<Responsibility> responsibilities = responsibilityList.stream().filter(i -> NumberConstant.TWO.equals(i.getIsGatherCenter()) && NumberConstant.ONE.equals(i.getResponsibilityType())).collect(Collectors.toList());
  240. Map<Long, List<Responsibility>> responsibilityParentMap = responsibilities.stream().collect(Collectors.groupingBy(Responsibility::getParentId));
  241. Set<Long> keySet = responsibilityParentMap.keySet();
  242. int column=2;
  243. for (Long parentId:keySet){
  244. // 同一父节点的叶子节点数据
  245. List<Responsibility> list = responsibilityParentMap.get(parentId);
  246. for (int i=0;i<list.size();i++) {
  247. String responsibilityName1 = list.get(i).getResponsibilityName();
  248. // 父层级责任中心名称
  249. List<Responsibility> responsibilityList1 = responsibilityMap.get(list.get(i).getParentId());
  250. if (CollUtil.isEmpty(responsibilityList1)) {
  251. writer.writeCellValue(column, 0, null);
  252. } else {
  253. // 父层级责任中心名称
  254. String responsibilityName = responsibilityList1.get(0).getResponsibilityName();
  255. // 子层级责任中心名称
  256. writer.writeCellValue(column, 0, responsibilityName);
  257. }
  258. writer.writeCellValue(column, 1, responsibilityName1);
  259. column++;
  260. }
  261. }
  262. writer.merge(1,1,0,1,"项目",false);
  263. DateTime dateTime = DateUtil.parse(date);
  264. int year = DateUtil.year(dateTime);
  265. int month = DateUtil.month(dateTime)+1;
  266. // 设置列
  267. List<CostDepartmentProfit> departmentProfits = this.list(new QueryWrapper<CostDepartmentProfit>().lambda()
  268. .eq(CostDepartmentProfit::getHospId, hospId)
  269. .eq(CostDepartmentProfit::getYear, year).eq(CostDepartmentProfit::getMonth, month));
  270. // 用来筛选金额
  271. Map<String, CostDepartmentProfit> profitMap = departmentProfits.stream().filter(i->i.getReportParentId()!=0L).collect(Collectors.toMap(k -> k.getReportName() + "cost" + k.getResponsibilityName(), synOne -> synOne));
  272. // 报表的父层级报表
  273. Map<Long, List<CostDepartmentProfit>> departmentParentReportMap = departmentProfits.stream().filter(i -> i.getReportParentId() == 0L)
  274. .collect(Collectors.groupingBy(CostDepartmentProfit::getReportId)).entrySet().stream()
  275. .sorted(Map.Entry.comparingByKey()).collect(
  276. Collectors.toMap(
  277. Map.Entry::getKey,
  278. Map.Entry::getValue,
  279. (oldVal, newVal) -> oldVal,
  280. LinkedHashMap::new
  281. )
  282. );
  283. // 不是父节点的所有叶子节点
  284. Map<Long, List<CostDepartmentProfit>> listParentMap = departmentProfits.stream().filter(i -> i.getReportParentId() != 0L).collect(Collectors.groupingBy(CostDepartmentProfit::getReportParentId));
  285. Set<Long> ids = departmentParentReportMap.keySet();
  286. // 默认是在第二行开始的
  287. int row=2;
  288. int columnNum=0;
  289. for (Long id:ids){
  290. String reportParentName = departmentParentReportMap.get(id).get(0).getReportName();
  291. List<CostDepartmentProfit> profitList = listParentMap.get(id);
  292. Map<Integer, List<CostDepartmentProfit>> linkedHashMap = profitList.stream().collect(Collectors.groupingBy(CostDepartmentProfit::getReportNum)).entrySet().stream()
  293. .sorted(Map.Entry.comparingByKey()).collect(
  294. Collectors.toMap(
  295. Map.Entry::getKey,
  296. Map.Entry::getValue,
  297. (oldVal, newVal) -> oldVal,
  298. LinkedHashMap::new
  299. ));
  300. Set<Integer> reportNums = linkedHashMap.keySet();
  301. for (Integer reportNum:reportNums){
  302. // 这一行要显示的记录
  303. List<CostDepartmentProfit> costDepartmentProfits = linkedHashMap.get(reportNum);
  304. // 子层级扥报表名称
  305. String reportName = costDepartmentProfits.get(0).getReportName();
  306. for (int i=0;i<costDepartmentProfits.size();i++){
  307. // 添加项目名称
  308. columnNum++;
  309. writer.writeCellValue(0,row,reportParentName);
  310. writer.writeCellValue(1,row,reportName);
  311. for (int j=0;j<column-2;j++){
  312. // TODO 设置添加具体金额
  313. // 获取表格对应的字段的值
  314. String responsibilityTopName = sheet.getRow(1).getCell(j + 2).getStringCellValue();
  315. String reportTopName = sheet.getRow(row).getCell(1).getStringCellValue();
  316. BigDecimal amount = profitMap.get(reportTopName + "cost" + responsibilityTopName).getAmount();
  317. writer.writeCellValue(j+2,row,amount);
  318. }
  319. }
  320. row++;
  321. }
  322. }
  323. // TODO 合并留在最后
  324. int cc = 2;
  325. // 合并行
  326. for (int m = 2; m < column - 1; m++) {
  327. String cellValue1 = sheet.getRow(0).getCell(m).getStringCellValue();
  328. String cellValue2 = sheet.getRow(0).getCell(m + 1).getStringCellValue();
  329. if (!cellValue1.equals(cellValue2)) {
  330. if (cc!=m){
  331. writer.merge(0, 0, cc, m, cellValue1, false);
  332. }else {
  333. writer.writeCellValue(cc,0,cellValue1);
  334. }
  335. cc = m + 1;
  336. }else if (m == column - 2) {
  337. writer.merge(0, 0, cc, m + 1, sheet.getRow(0).getCell(m + 1).getStringCellValue(), false);
  338. }
  339. }
  340. // 合并列
  341. int jj = 2;
  342. for (int i = 2; i < row - 1; i++) {
  343. String cellValue1 = sheet.getRow(i).getCell(0).getStringCellValue();
  344. String cellValue2 = sheet.getRow(i + 1).getCell(0).getStringCellValue();
  345. if (!cellValue1.equals(cellValue2)) {
  346. if (jj != i){
  347. writer.merge(jj, i, 0, 0, cellValue1, false);
  348. }else {
  349. writer.writeCellValue(0,jj,cellValue1);
  350. }
  351. jj = i + 1;
  352. } else if (i == row - 2) {
  353. writer.merge(jj, i + 1, 0, 0, cellValue1, false);
  354. }
  355. }
  356. // 设置列宽
  357. for (int i = 0; i < 50; i++) {
  358. // 调整每一列宽度
  359. sheet.autoSizeColumn((short) i);
  360. // 解决自动设置列宽中文失效的问题
  361. sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 14 / 10);
  362. }
  363. }
  364. /**
  365. * 按照会计科目进行计算
  366. *
  367. * @param i
  368. */
  369. private BigDecimal setAccountReportData(CostDepartmentProfitVO i, List<IncomeCollection> list, List<AllocationQueryReportVO> allocationQueryReportVOList, Map<Long, List<ReportRelation>> reportRelationMap,List<CostDepartmentProfitVO> allList) {
  370. // 在报表关联里面查询当前报表关联的
  371. Long reportId = i.getReportId();
  372. List<ReportRelation> reportRelationList = reportRelationMap.get(reportId);
  373. AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.000"));
  374. if (CollUtil.isNotEmpty(reportRelationList)) {
  375. // 获取对应的会计科目信息 筛选会计科目的Code
  376. List<String> accountList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
  377. // 查找在归集数据里面当前责任中心对应的这些会计科目的金额
  378. List<IncomeCollection> incomeCollectionList = list.stream().filter(income -> income.getResponsibilityCode().equals(i.getResponsibilityCode()) && accountList.contains(income.getAccountingCode())).collect(Collectors.toList());
  379. // 需要查询分摊后的表
  380. List<AllocationQueryReportVO> reportVOList = allocationQueryReportVOList.stream().filter(m -> m.getTargetResponsibilityCode().equals(i.getResponsibilityCode()) && accountList.contains(m.getAccountingCode())).collect(Collectors.toList());
  381. if (CollUtil.isNotEmpty(incomeCollectionList)) {
  382. incomeCollectionList.forEach(m -> {
  383. sum.updateAndGet(v -> v.add(m.getAmount()));
  384. });
  385. }
  386. // 成本减
  387. if (CollUtil.isNotEmpty(reportVOList)) {
  388. reportVOList.forEach(m -> {
  389. sum.updateAndGet(v -> v.add(m.getAmount()));
  390. });
  391. }
  392. }
  393. // i.setAmount(new BigDecimal(sum.toString()));
  394. // numMap.put(i.getReportNum()+i.getResponsibilityCode(),new BigDecimal(sum.toString()));
  395. return sum.get();
  396. }
  397. /**
  398. * 按照分摊层级进行计算
  399. * 按照分摊层级计算 报表分摊层级是当前的层级 并且目标责任中心失败当前责任中心
  400. */
  401. private BigDecimal setShareLevelReportData(CostDepartmentProfitVO i, List<CostShareLevel> costShareLevelList, Map<Long, List<ReportRelation>> reportRelationMap, List<Allocation> allocationList,List<CostDepartmentProfitVO> allList) {
  402. List<ReportRelation> reportRelationList = reportRelationMap.get(i.getReportId());
  403. AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.000"));
  404. if (CollUtil.isNotEmpty(reportRelationList)) {
  405. // 找到对应的分摊层级的Id 但是分摊报表里面存的是分摊层级的序号
  406. List<Long> shareLevelIds = reportRelationList.stream().map(ReportRelation::getRelationCode).map(Long::valueOf).collect(Collectors.toList());
  407. // List<Integer> levelShortList = costShareLevelList.stream()
  408. // .filter(m -> shareLevelIds.contains(m.getId()))
  409. // .map(CostShareLevel::getLeverSort).collect(Collectors.toList());
  410. if (CollUtil.isNotEmpty(shareLevelIds)) {
  411. // 查询报表里面是当前分摊层级的数据
  412. List<Allocation> allocations = allocationList.stream().filter(m -> shareLevelIds.contains(m.getShareLevelId()) && m.getTargetResponsibilityCode().equals(i.getResponsibilityCode())).collect(Collectors.toList());
  413. if (CollUtil.isNotEmpty(allocations)) {
  414. // allocations.forEach(m -> {
  415. // sum.updateAndGet(v -> v.add(m.getAmount()));
  416. // });
  417. BigDecimal reduce = allocations.stream().map(Allocation::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
  418. sum.set(reduce);
  419. }
  420. }
  421. }
  422. // i.setAmount(new BigDecimal(sum.toString()));
  423. return sum.get();
  424. }
  425. /**
  426. * 按照责任中心进行计算
  427. * 原始责任中心是设置的责任中心 目标责任中心是报表的责任中心
  428. * 查询分摊报表里面目标责任中心是当前责任中心 报表责任中心是当前设置的责任中心
  429. */
  430. public BigDecimal setResponsibilityCode(CostDepartmentProfitVO costDepartmentProfitVO, Map<Long, List<ReportRelation>> reportRelationMap, List<Allocation> allocationList,List<CostDepartmentProfitVO> allList) {
  431. // 获取当前报表对应的责任中心
  432. List<ReportRelation> reportRelationList = reportRelationMap.get(costDepartmentProfitVO.getReportId());
  433. AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.000"));
  434. if (CollUtil.isNotEmpty(reportRelationList)) {
  435. // 获取对应的责任中心的Code集合 这个是设置的责任中心
  436. List<String> responsibilityCodes = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
  437. if (CollUtil.isNotEmpty(responsibilityCodes)) {
  438. // 查询报表里面是当前分摊层级的数据
  439. List<Allocation> allocations = allocationList.stream().filter(i -> i.getTargetResponsibilityCode().equals(costDepartmentProfitVO.getResponsibilityCode()) && responsibilityCodes.contains(i.getResponsibilityCode())).collect(Collectors.toList());
  440. if (CollUtil.isNotEmpty(allocations)) {
  441. BigDecimal reduce = allocations.stream().map(Allocation::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
  442. sum.set(reduce);
  443. // allocations.forEach(m -> {
  444. // sum.updateAndGet(v -> v.add(m.getAmount()));
  445. // });
  446. }
  447. }
  448. }
  449. // costDepartmentProfitVO.setAmount(new BigDecimal(sum.toString()));
  450. return sum.get();
  451. }
  452. /**
  453. * 按照小计的计算方式
  454. * 同一个目录下相同的其他金额的和
  455. */
  456. public BigDecimal setSubtotal(CostDepartmentProfitVO costDepartmentProfitVO,
  457. List<CostShareLevel> costShareLevelList,
  458. Map<Long, List<CostDepartmentProfitVO>> listMap,
  459. List<CostDepartmentProfitVO> profitVOS,
  460. List<IncomeCollection> list,
  461. List<AllocationQueryReportVO> allocationQueryReportVOList,
  462. Map<Long, List<ReportRelation>> reportRelationMap, List<Allocation> allocationList,List<CostDepartmentProfitVO> allList) {
  463. // 因为报表是按照报表项目的升序进行排序的 前面的报表是已经进行计算了的
  464. // 查询当前报表的父层级id
  465. Long reportParentId = costDepartmentProfitVO.getReportParentId();
  466. String responsibilityCode = costDepartmentProfitVO.getResponsibilityCode();
  467. // 查询报表里面在当前父层级下的并且不是自己的报表项目
  468. List<CostDepartmentProfitVO> costDepartmentProfitVOS = allList.stream().filter(i -> i.getReportParentId().equals(reportParentId) && i.getResponsibilityCode().equals(responsibilityCode) && !NumberConstant.THREE.equals(i.getCalcType())).collect(Collectors.toList());
  469. AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
  470. // 遍历数据 之前的已经经过了计算
  471. costDepartmentProfitVOS.forEach(i -> {
  472. Long reportId = i.getReportId();
  473. List<CostDepartmentProfitVO> costDepartmentProfitVOS1 = listMap.get(reportId);
  474. if (CollUtil.isEmpty(costDepartmentProfitVOS1)) {
  475. throw new CostException(500, "报表未找到");
  476. }
  477. BigDecimal amount = getAmount(costDepartmentProfitVOS1, costShareLevelList, responsibilityCode, list, allocationQueryReportVOList, reportRelationMap, allocationList, listMap,allList);
  478. sum.set(amount.add(sum.get()));;
  479. });
  480. // costDepartmentProfitVO.setAmount(new BigDecimal(sum.toString()));
  481. return sum.get();
  482. }
  483. /***
  484. * 按照计算方式进行计算
  485. */
  486. public BigDecimal setCalculation(CostDepartmentProfitVO costDepartmentProfitVO, List<CostDepartmentProfitVO> costDepartmentProfitVOList, List<CostShareLevel> costShareLevelList, Map<Long, List<CostDepartmentProfitVO>> listMap, List<IncomeCollection> list, List<AllocationQueryReportVO> allocationQueryReportVOList, Map<Long, List<ReportRelation>> reportRelationMap, List<Allocation> allocationList,List<CostDepartmentProfitVO> allList) {
  487. // 获取当前报表的计算方式 [1]+[2]类型/ [1]-[2]
  488. String calcFormula = costDepartmentProfitVO.getCalcFormula();
  489. String responsibilityCode = costDepartmentProfitVO.getResponsibilityCode();
  490. String replace = calcFormula.replace("[", "").replace("]", "").replace("+", ",").replace("-", ",-");
  491. List<Integer> calcFormulaList = Arrays.stream(replace.split(StrUtil.COMMA)).map(Integer::valueOf).collect(Collectors.toList());
  492. // 查询这个编号集合的报表
  493. AtomicReference<BigDecimal> bigDecimal = new AtomicReference<>(new BigDecimal("0.0000"));
  494. calcFormulaList.forEach(calc -> {
  495. Integer calcNum=Math.abs(calc);
  496. List<Long> reportIdList = allList.stream().filter(i -> i.getResponsibilityCode().equals(responsibilityCode) && calcNum.equals(i.getReportNum())).map(CostDepartmentProfitVO::getReportId).collect(Collectors.toList());
  497. if (CollUtil.isNotEmpty(reportIdList)) {
  498. reportIdList.forEach(i -> {
  499. List<CostDepartmentProfitVO> profitVOS = listMap.get(i);
  500. if (CollUtil.isEmpty(profitVOS)) {
  501. throw new CostException(500, "报表未找到");
  502. }
  503. BigDecimal amount = getAmount(profitVOS, costShareLevelList, responsibilityCode, list, allocationQueryReportVOList, reportRelationMap, allocationList, listMap,allList);
  504. if (calc>0){
  505. bigDecimal.updateAndGet(v -> v.add(amount));
  506. }else {
  507. bigDecimal.updateAndGet(v -> v.subtract(amount));
  508. }
  509. });
  510. }
  511. });
  512. return bigDecimal.get();
  513. }
  514. /**
  515. * 判断是那种计算方式 调用方法进行计算
  516. */
  517. public BigDecimal getAmount(List<CostDepartmentProfitVO> profitVOS,
  518. List<CostShareLevel> costShareLevelList,
  519. String responsibilityCode, List<IncomeCollection> list,
  520. List<AllocationQueryReportVO> allocationQueryReportVOList,
  521. Map<Long, List<ReportRelation>> reportRelationMap, List<Allocation> allocationList,
  522. Map<Long, List<CostDepartmentProfitVO>> listMap,List<CostDepartmentProfitVO> allList) {
  523. BigDecimal bigDecimal = new BigDecimal("0.0000");
  524. // 在对这个报表进行过滤
  525. List<CostDepartmentProfitVO> costDepartmentProfitVOS = profitVOS.stream().filter(i -> i.getResponsibilityCode().equals(responsibilityCode)).collect(Collectors.toList());
  526. // 都一个就是
  527. CostDepartmentProfitVO costDepartmentProfitVO = costDepartmentProfitVOS.get(0);
  528. Integer calcType = costDepartmentProfitVO.getCalcType();
  529. if (NumberConstant.ONE.equals(calcType)) {
  530. // 调用计算的方法 按照会计科目
  531. bigDecimal = setAccountReportData(costDepartmentProfitVO, list, allocationQueryReportVOList, reportRelationMap,allList);
  532. } else if (NumberConstant.TWO.equals(calcType)) {
  533. // 按照分摊层级
  534. bigDecimal = setShareLevelReportData(costDepartmentProfitVO, costShareLevelList, reportRelationMap, allocationList,allList);
  535. } else if (NumberConstant.THREE.equals(calcType)) {
  536. // 小计
  537. bigDecimal = setSubtotal(costDepartmentProfitVO, costShareLevelList, listMap, profitVOS, list, allocationQueryReportVOList, reportRelationMap, allocationList,allList);
  538. } else if (NumberConstant.FIVE.equals(calcType)) {
  539. // 按照责任中心
  540. bigDecimal = setResponsibilityCode(costDepartmentProfitVO, reportRelationMap, allocationList,allList);
  541. }else if (NumberConstant.FOUR.equals(calcType)){
  542. bigDecimal=setCalculation(costDepartmentProfitVO,costDepartmentProfitVOS,costShareLevelList,listMap,list,allocationQueryReportVOList,reportRelationMap,allocationList,allList);
  543. }
  544. return bigDecimal;
  545. }
  546. }