| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- package com.ydtech.modules.admin.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.ydtech.core.page.HttpResult;
- import com.ydtech.modules.admin.model.dto.PayAmountExcel;
- import com.ydtech.modules.admin.model.dto.ReceivableExcel;
- 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.modules.inv.utils.EasyExcelUtils;
- 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.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import java.io.IOException;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.*;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- /**
- * @version
- * @author: hxl
- * @Date: 2024/7/1 11:36
- * @Description: 控制台-运营数据
- */
- @Service
- public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
- @Autowired
- private InvAccountMapper invAccountMapper;
- @Autowired
- private InsPlyIncomeMapper insPlyIncomeMapper;
- @Autowired
- private ProfitAnalysisMapper profitAnalysisMapper;
- @Autowired
- private InvAccountExpensesMapper invAccountExpensesMapper;
- @Value("${upload.file.path}")
- private String uploadPath;
- @Value("${upload.file.url}")
- private String uploadUrl;
- /**
- * @version
- * @author: hxl
- * @Date: 2024/7/31 17:42
- * @Description: 查询利润数据
- */
- @Override
- public List<ProfitAnalysisDto> queryPage(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
- HashMap<String, String> dateMapByType = getDateMapByType(profitAnalysisQueryDto.getDateType(), profitAnalysisQueryDto.getYear());
- profitAnalysisQueryDto.setBeginDate(dateMapByType.get("startDate"));
- profitAnalysisQueryDto.setEndDate(dateMapByType.get("endDate"));
- List<ProfitAnalysisDto> list = insPlyIncomeMapper.queryPage(profitAnalysisQueryDto);
- return list;
- }
- /**
- * @version
- * @author: whp
- * @Date: 2024/8/16 15:35
- * @Description: 查询利润分析统计
- */
- @Override
- public List<ProfitAnalysisDto> getProfitAnalysisQueryList(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
- HashMap<String, String> dateMapByType = getDateMapByType(profitAnalysisQueryDto.getDateType(), profitAnalysisQueryDto.getYear());
- profitAnalysisQueryDto.setBeginDate(dateMapByType.get("startDate"));
- profitAnalysisQueryDto.setEndDate(dateMapByType.get("endDate"));
- List<ProfitAnalysisDto> profitAnalysisQueryList = insPlyIncomeMapper.getProfitAnalysisQueryList(profitAnalysisQueryDto);
- if(!profitAnalysisQueryList.isEmpty()){
- for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisQueryList) {
- BigDecimal variableCost = BigDecimal.ZERO;
- String yearAndMonth = profitAnalysisDto.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(ObjectUtils.isNotEmpty(outAccount) && ObjectUtils.isNotEmpty(enterAccount) ){
- if( (StringUtils.isNotEmpty(outAccount.getOuterFlag()) && StringUtils.isNotEmpty(enterAccount.getOuterFlag()))){
- if(!enterAccount.getOuterFlag().equals(outAccount.getOuterFlag())){
- variableCost=variableCost.add(analysisDto.getApplyAmount());
- }
- }
- }
- }
- profitAnalysisDto.setVariableCost(variableCost);
- }
- }
- return profitAnalysisQueryList;
- }
- @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);
- 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();
- 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())) {
- addVariableCost.add(analysisDto);
- }
- }
- }
- Map<String, BigDecimal> profitAnalysisDtoMap = addVariableCost.stream()
- .collect(Collectors.toMap(
- ProfitAnalysisDto::getExpensesId, // keyMapper,用于提取键(expensesId)
- ProfitAnalysisDto::getApplyAmount, // valueMapper,用于提取初始值(applyAmount)
- BigDecimal::add // mergeFunction,用于处理键冲突(相加 applyAmount)
- ));
- for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisDtos) {
- String expensesId = profitAnalysisDto.getExpensesId();
- if (profitAnalysisDtoMap.containsKey(expensesId)) {
- BigDecimal bigDecimal = profitAnalysisDtoMap.get(expensesId);
- profitAnalysisDto.setApplyAmount(bigDecimal);
- }
- }
- 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")).setScale(2,RoundingMode.HALF_UP).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")).setScale(2,RoundingMode.HALF_UP).toString());
- }
- }
- resultList.addAll(allAccountExpenses);
- }
- List<ProfitAnalysisDto> tree = getTree(resultList);
- String orderBy = profitAnalysisQueryDto.getOrderBy();
- return sortListByField(tree, orderBy);
- }
- /**
- *
- * @param tree
- * @param orderBy
- * @return 排序
- */
- private List<ProfitAnalysisDto> sortListByField(List<ProfitAnalysisDto> tree, String orderBy) {
- if (tree == null || tree.isEmpty()) {
- return tree;
- }
- if(StringUtils.isEmpty(orderBy)){
- return tree;
- }
- // 初始化比较器
- Comparator<ProfitAnalysisDto> comparator = (dto1, dto2) -> {
- BigDecimal applyAmount = dto1.getApplyAmount();// 假设字段名为applyAmount,根据实际情况调整
- BigDecimal applyAmount1 = dto2.getApplyAmount();
- return applyAmount.compareTo(applyAmount1);
- };
- // 根据排序方向调整比较器
- if ("desc".equalsIgnoreCase(orderBy)) {
- comparator = comparator.reversed();
- }
- // 对列表进行排序
- List<ProfitAnalysisDto> sortedList = new ArrayList<>(tree);
- Collections.sort(sortedList, comparator);
- return sortedList;
- }
- 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;
- }
- /**
- * 组装树形结构结果集方法
- */
- public List<ProfitAnalysisDto> getTree(List<ProfitAnalysisDto> list){
- return list.stream().filter(accountExpenses -> accountExpenses.getParentId().equals("0"))
- .peek(accountExpenses -> accountExpenses.setChildren(getChildren(accountExpenses,list))).collect(Collectors.toList());
- }
- public List<ProfitAnalysisDto> getChildren(ProfitAnalysisDto user,List<ProfitAnalysisDto> userList){
- return userList.stream().filter(u -> Objects.equals(u.getParentId(),user.getExpensesId())).map(
- u -> {
- u.setChildren(getChildren(u,userList));
- return u;
- }
- ).collect(Collectors.toList());
- }
- /**
- * @version
- * @author: hxl
- * @Date: 2024/6/19 11:57
- * @Description: 通过时间类型判断
- */
- private static HashMap<String,String> getDateMapByType(String type, String year) {
- HashMap<String,String> map =new HashMap<>();
- String startDateStr="";
- String endDateStr="";
- if(StringUtils.isBlank(year) && StringUtils.isBlank(type)){
- Calendar cale = Calendar.getInstance();
- int yearNow = cale.get(Calendar.YEAR);
- startDateStr= SliceUpDateUtil.getYearBeginDateStr(yearNow)+" 00:00:00";
- endDateStr= SliceUpDateUtil.getYearEndDateStr(yearNow)+" 23:59:59";
- }else{
- if(StringUtils.isNotBlank(year)){
- startDateStr= SliceUpDateUtil.getYearBeginDateStr(Integer.parseInt(year))+" 00:00:00";
- endDateStr= SliceUpDateUtil.getYearEndDateStr(Integer.parseInt(year))+" 23:59:59";
- }else{
- if(StringUtils.isNotBlank(type)){
- if("1".equals(type)){
- // 一月内
- startDateStr=SliceUpDateUtil.getBeforeDay(new Date(),2)+" 00:00:00";
- endDateStr=SliceUpDateUtil.getBeforeDay(new Date(),0)+" 23:59:59";
- }else if("2".equals(type)){
- // 三月内
- startDateStr=SliceUpDateUtil.getBeforeDay(new Date(),3)+" 00:00:00";
- endDateStr=SliceUpDateUtil.getBeforeDay(new Date(),0)+" 23:59:59";
- }else if("3".equals(type)){
- // 近半年
- startDateStr=SliceUpDateUtil.getBeforeDay(new Date(),4)+" 00:00:00";
- endDateStr=SliceUpDateUtil.getBeforeDay(new Date(),0)+" 23:59:59";
- }
- }
- }
- }
- map.put("startDate",startDateStr);
- map.put("endDate",endDateStr);
- return map;
- }
- /**
- * @description: 控制台-利润分析应收金额导出明细
- * @author: whp
- **/
- @Override
- public HttpResult receivableExcel(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
- List<ReceivableExcel> list = profitAnalysisMapper.receivableExcel(profitAnalysisQueryDto);
- String uploadPath = this.uploadPath + "/excel/";
- Path path = Paths.get(uploadPath);
- if (!Files.exists(path)) {
- try {
- Files.createDirectories(path);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- String fileName = EasyExcelUtils.downExcel(uploadPath, "应收明细", ReceivableExcel.class, list);
- return HttpResult.ok("", uploadUrl + "excel/" + fileName);
- }
- /**
- * @description: 控制台-利润分析实付金额导出明细
- * @author: whp
- **/
- @Override
- public HttpResult payAmountExcel(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
- List<PayAmountExcel> list = profitAnalysisMapper.payAmountExcel(profitAnalysisQueryDto);
- String uploadPath = this.uploadPath + "/excel/";
- Path path = Paths.get(uploadPath);
- if (!Files.exists(path)) {
- try {
- Files.createDirectories(path);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- String fileName = EasyExcelUtils.downExcel(uploadPath, "实付明细", PayAmountExcel.class, list);
- return HttpResult.ok("", uploadUrl + "excel/" + fileName);
- }
- }
|