|
|
@@ -1,23 +1,28 @@
|
|
|
package com.ydtech.modules.admin.service.impl;
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto;
|
|
|
import com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisQueryDto;
|
|
|
import com.ydtech.modules.admin.service.ProfitAnalysisService;
|
|
|
import com.ydtech.modules.admin.utils.SliceUpDateUtil;
|
|
|
import com.ydtech.modules.console.dao.ProfitAnalysisMapper;
|
|
|
import com.ydtech.modules.fnc.dao.InsPlyIncomeMapper;
|
|
|
+import com.ydtech.modules.inv.dao.InvAccountExpensesMapper;
|
|
|
import com.ydtech.modules.inv.dao.InvAccountMapper;
|
|
|
import com.ydtech.modules.inv.model.InvAccount;
|
|
|
import com.ydtech.modules.inv.model.InvAccountCardVo;
|
|
|
import com.ydtech.modules.inv.model.InvAccountExpenses;
|
|
|
import com.ydtech.utils.BigDecimalUtils;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
/**
|
|
|
* @version
|
|
|
@@ -35,6 +40,10 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
|
|
|
@Autowired
|
|
|
private ProfitAnalysisMapper profitAnalysisMapper;
|
|
|
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InvAccountExpensesMapper invAccountExpensesMapper;
|
|
|
+
|
|
|
/**
|
|
|
* @version
|
|
|
* @author: hxl
|
|
|
@@ -87,11 +96,32 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
|
|
|
@Override
|
|
|
public List<ProfitAnalysisDto> getProfitAnalysisQueryDetailsList(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
|
|
|
List<ProfitAnalysisDto> resultList =new ArrayList<>();
|
|
|
-
|
|
|
+// 总支出=人员成本+固定成本+变动成本+税费
|
|
|
+ BigDecimal allExpenditure =this.getAllExpenditure(profitAnalysisQueryDto);
|
|
|
if (StringUtils.isNotEmpty(profitAnalysisQueryDto.getExpensesType()) && "3".equals(profitAnalysisQueryDto.getExpensesType())) {
|
|
|
List<ProfitAnalysisDto> profitAnalysisDtos = profitAnalysisMapper.selectAccountExpenses(profitAnalysisQueryDto);
|
|
|
- resultList.addAll(profitAnalysisDtos) ;
|
|
|
- List<ProfitAnalysisDto> addVariableCost = new ArrayList<>();
|
|
|
+
|
|
|
+ Map<String, ProfitAnalysisDto> map = new HashMap<>();
|
|
|
+ for (ProfitAnalysisDto dto : profitAnalysisDtos) {
|
|
|
+ map.put(dto.getExpensesId(), dto);
|
|
|
+ }
|
|
|
+ ArrayList<ProfitAnalysisDto> parentExpenIdList = new ArrayList<>();
|
|
|
+ // 如果没有parentId为0 的子级 则构建
|
|
|
+ for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisDtos) {
|
|
|
+ if(ObjectUtils.isEmpty(map.get(profitAnalysisDto.getParentId())) && !profitAnalysisDto.getParentId() .equals("0")){
|
|
|
+ QueryWrapper<InvAccountExpenses> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.eq("expenses_id", profitAnalysisDto.getParentId());
|
|
|
+ InvAccountExpenses invAccountExpenses = invAccountExpensesMapper.selectOne(queryWrapper);
|
|
|
+ ProfitAnalysisDto profitAnalysisDto1 = new ProfitAnalysisDto();
|
|
|
+ profitAnalysisDto1.setExpensesId(invAccountExpenses.getExpensesId());
|
|
|
+ profitAnalysisDto1.setParentId(invAccountExpenses.getParentId());
|
|
|
+ profitAnalysisDto1.setCategory(invAccountExpenses.getCategory());
|
|
|
+ parentExpenIdList.add(profitAnalysisDto1);
|
|
|
+ map.put(profitAnalysisDto1.getExpensesId(),profitAnalysisDto1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ profitAnalysisDtos.addAll(parentExpenIdList);
|
|
|
+ List<ProfitAnalysisDto> addVariableCost = new ArrayList<>(); //变动成本金额
|
|
|
List<ProfitAnalysisDto> profitAnalysisDto1 = insPlyIncomeMapper.changeAmount(profitAnalysisQueryDto);
|
|
|
for (ProfitAnalysisDto analysisDto : profitAnalysisDto1) {
|
|
|
String outCardNum = analysisDto.getOutCardNum();
|
|
|
@@ -105,7 +135,6 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
Map<String, BigDecimal> profitAnalysisDtoMap = addVariableCost.stream()
|
|
|
.collect(Collectors.toMap(
|
|
|
ProfitAnalysisDto::getExpensesId, // keyMapper,用于提取键(expensesId)
|
|
|
@@ -113,19 +142,143 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
|
|
|
BigDecimal::add // mergeFunction,用于处理键冲突(相加 applyAmount)
|
|
|
));
|
|
|
|
|
|
- for (ProfitAnalysisDto profitAnalysisDto : resultList) {
|
|
|
+ for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisDtos) {
|
|
|
String expensesId = profitAnalysisDto.getExpensesId();
|
|
|
if (profitAnalysisDtoMap.containsKey(expensesId)) {
|
|
|
BigDecimal bigDecimal = profitAnalysisDtoMap.get(expensesId);
|
|
|
profitAnalysisDto.setApplyAmount(bigDecimal);
|
|
|
}
|
|
|
}
|
|
|
- }else {
|
|
|
- resultList.addAll(profitAnalysisMapper.getAllAccountExpenses(profitAnalysisQueryDto));
|
|
|
+
|
|
|
+ for (ProfitAnalysisDto dto : profitAnalysisDtos) {
|
|
|
+ if (dto.getParentId().equals("0")) {
|
|
|
+ BigDecimal totalAmount = aggregateChildAmounts(dto.getExpensesId(), map);
|
|
|
+ dto.setApplyAmount(totalAmount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (ProfitAnalysisDto allAccountExpens : profitAnalysisDtos) {
|
|
|
+ BigDecimal applyAmount = allAccountExpens.getApplyAmount() != null ? allAccountExpens.getApplyAmount() : BigDecimal.ZERO;
|
|
|
+ if(applyAmount.compareTo(BigDecimal.ZERO)>0){
|
|
|
+ allAccountExpens.setRadio(applyAmount.divide(allExpenditure,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resultList.addAll(profitAnalysisDtos) ;
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 子类目金额
|
|
|
+ */
|
|
|
+ List<ProfitAnalysisDto> allAccountExpenses = profitAnalysisMapper.getAllAccountExpenses(profitAnalysisQueryDto);
|
|
|
+ //二级类目
|
|
|
+ List<String> collect = allAccountExpenses.stream().filter(item -> !item.getParentId().equals("0")).map(ProfitAnalysisDto::getExpensesId).collect(Collectors.toList());
|
|
|
+ profitAnalysisQueryDto.setIds(collect);
|
|
|
+
|
|
|
+ List<ProfitAnalysisDto> pidAmountList = profitAnalysisMapper.getSumCategory(profitAnalysisQueryDto);
|
|
|
+
|
|
|
+ Map<String, BigDecimal> amountMap = pidAmountList.stream().collect(Collectors.toMap(ProfitAnalysisDto::getParentId, ProfitAnalysisDto::getApplyAmount));
|
|
|
+ Map<String, List<String>> stringListMap = buildTreeMap(allAccountExpenses);
|
|
|
+ stringListMap.forEach((id ,children) ->{
|
|
|
+ profitAnalysisQueryDto.setExpensesIds(children);
|
|
|
+ ProfitAnalysisDto sumCategory = profitAnalysisMapper.getSumByparentAmount(profitAnalysisQueryDto);
|
|
|
+ if(!amountMap.containsKey(id) && ObjectUtils.isNotEmpty(sumCategory)){
|
|
|
+ amountMap.put(id,sumCategory.getApplyAmount());
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (ProfitAnalysisDto allAccountExpens : allAccountExpenses) {
|
|
|
+ if (amountMap.containsKey(allAccountExpens.getExpensesId())) {
|
|
|
+ allAccountExpens.setApplyAmount(amountMap.get(allAccountExpens.getExpensesId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (ProfitAnalysisDto allAccountExpens : allAccountExpenses) {
|
|
|
+ BigDecimal applyAmount = allAccountExpens.getApplyAmount() != null ? allAccountExpens.getApplyAmount() : BigDecimal.ZERO;
|
|
|
+ if(applyAmount.compareTo(BigDecimal.ZERO)>0){
|
|
|
+ allAccountExpens.setRadio(applyAmount.divide(allExpenditure,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ resultList.addAll(allAccountExpenses);
|
|
|
}
|
|
|
return getTree(resultList);
|
|
|
}
|
|
|
|
|
|
+ private BigDecimal aggregateChildAmounts(String expensesId, Map<String, ProfitAnalysisDto> map) {
|
|
|
+ BigDecimal totalAmount = BigDecimal.ZERO;
|
|
|
+ for (ProfitAnalysisDto dto : map.values()) {
|
|
|
+ if (dto.getParentId() .equals(expensesId) ) {
|
|
|
+ totalAmount = totalAmount.add(dto.getApplyAmount() != null ? dto.getApplyAmount() : BigDecimal.ZERO);
|
|
|
+ totalAmount = totalAmount.add(aggregateChildAmounts(dto.getExpensesId(), map)); // 递归查找子对象
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return totalAmount;
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal getAllExpenditure(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
|
|
|
+ HashMap<String, BigDecimal> sumExpenditure = profitAnalysisMapper.getTotalExpenditure(profitAnalysisQueryDto);
|
|
|
+// 查询变动成本
|
|
|
+ BigDecimal variableCost = BigDecimal.ZERO;
|
|
|
+ BigDecimal allExpenditure = BigDecimal.ZERO;
|
|
|
+
|
|
|
+
|
|
|
+ String yearAndMonth = profitAnalysisQueryDto.getYearAndMonth();
|
|
|
+ profitAnalysisQueryDto.setYearAndMonth(yearAndMonth);
|
|
|
+ List<ProfitAnalysisDto> profitAnalysisDto1 = insPlyIncomeMapper.changeAmount(profitAnalysisQueryDto);
|
|
|
+ for (ProfitAnalysisDto analysisDto : profitAnalysisDto1) {
|
|
|
+ String outCardNum = analysisDto.getOutCardNum();
|
|
|
+ String enterCardNum = analysisDto.getEnterCardNum();
|
|
|
+ InvAccountCardVo outAccount = invAccountMapper.getByCarNumber(outCardNum);
|
|
|
+ InvAccountCardVo enterAccount = invAccountMapper.getByCarNumber(enterCardNum);
|
|
|
+ if(StringUtils.isNotEmpty(outAccount.getOuterFlag()) && StringUtils.isNotEmpty(enterAccount.getOuterFlag())){
|
|
|
+ if(!enterAccount.getOuterFlag().equals(outAccount.getOuterFlag())){
|
|
|
+ variableCost=variableCost.add(analysisDto.getApplyAmount());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!sumExpenditure.isEmpty()){
|
|
|
+ BigDecimal fixedCost = sumExpenditure.get("fixedCost") != null ? sumExpenditure.get("fixedCost") : BigDecimal.ZERO;
|
|
|
+ BigDecimal laborCost = sumExpenditure.get("laborCost") != null ? sumExpenditure.get("laborCost") : BigDecimal.ZERO;
|
|
|
+ BigDecimal taxation = sumExpenditure.get("taxation") != null ? sumExpenditure.get("taxation") : BigDecimal.ZERO;
|
|
|
+ allExpenditure =allExpenditure.add(fixedCost).add(laborCost).add(taxation).add(variableCost);
|
|
|
+ }
|
|
|
+ return allExpenditure;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static Map<String, List<String>> buildTreeMap(List<ProfitAnalysisDto> nodes) {
|
|
|
+ Map<String, ProfitAnalysisDto> nodeMap = new HashMap<>();
|
|
|
+ for (ProfitAnalysisDto node : nodes) {
|
|
|
+ nodeMap.put(node.getExpensesId(), node);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, List<String>> parentChildrenMap = new HashMap<>();
|
|
|
+
|
|
|
+ for (ProfitAnalysisDto node : nodes) {
|
|
|
+ if (node.getParentId().equals("0")) {
|
|
|
+ // Root node, start recursion here
|
|
|
+ List<String> allIds = getAllIds(node, nodeMap, new ArrayList<>());
|
|
|
+ parentChildrenMap.put(String.valueOf(node.getExpensesId()), allIds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return parentChildrenMap;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private static List<String> getAllIds(ProfitAnalysisDto node, Map<String, ProfitAnalysisDto> nodeMap, List<String> ids) {
|
|
|
+ ids.add(String.valueOf(node.getExpensesId()));
|
|
|
+
|
|
|
+ for (ProfitAnalysisDto potentialChild : nodeMap.values()) {
|
|
|
+ if (potentialChild.getParentId() .equals(node.getExpensesId())) {
|
|
|
+ getAllIds(potentialChild, nodeMap, ids);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ids;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 组装树形结构结果集方法
|
|
|
*/
|