Quellcode durchsuchen

添加按会计科目相关代码

JammeyJiang vor 4 Monaten
Ursprung
Commit
041d1fb5d7

+ 16 - 5
src/main/java/com/kcim/dao/model/Allocation.java

@@ -1,18 +1,17 @@
 package com.kcim.dao.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
-
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+
 /**
  * 成本分摊后表
  * 
@@ -94,6 +93,7 @@ public class Allocation implements Serializable {
 	/**
 	 * 分摊参数名称
 	 */
+
 	private String shareParamName;
 	/**
 	 * 分摊参数数值
@@ -112,6 +112,17 @@ public class Allocation implements Serializable {
 
 	private Long targetShareLevelId;
 
+	/**
+	 * 会计科目Code
+	 */
+	@TableField(exist = false)
+	private String accountCode;
+	/**
+	 * 会计科目名称
+	 */
+	@TableField(exist = false)
+	private String accountName;
+
 	/**
 	 * 
 	 */

+ 6 - 0
src/main/java/com/kcim/dao/model/CostAccountShareParam.java

@@ -1,5 +1,6 @@
 package com.kcim.dao.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.AllArgsConstructor;
@@ -43,6 +44,11 @@ public class CostAccountShareParam implements Serializable {
 	 * 分摊参数代码
 	 */
 	private String shareParamCode;
+	/**
+	 * 分摊参数代码
+	 */
+	@TableField(exist = false)
+	private String shareParamName;
 	/**
 	 * 分摊参数占比
 	 */

+ 3 - 1
src/main/java/com/kcim/dao/repository/CostAccountShareDetailRepository.java

@@ -32,7 +32,9 @@ public class CostAccountShareDetailRepository extends ServiceImpl<CostAccountSha
         LambdaQueryWrapper<CostAccountShareDetail> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(CostAccountShareDetail::getHospId, UserContext.getHospId());
         queryWrapper.eq(CostAccountShareDetail::getDelFlag, NumberConstant.ZERO);
-        queryWrapper.eq(CostAccountShareDetail::getAccountShareId, accountShareId);
+        if(!ObjectUtils.isEmpty(accountShareId)) {
+            queryWrapper.eq(CostAccountShareDetail::getAccountShareId, accountShareId);
+        }
         return this.list(queryWrapper);
     }
 

+ 3 - 1
src/main/java/com/kcim/dao/repository/CostAccountShareParamRepository.java

@@ -31,7 +31,9 @@ public class CostAccountShareParamRepository extends ServiceImpl<CostAccountShar
         LambdaQueryWrapper<CostAccountShareParam> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(CostAccountShareParam::getHospId, UserContext.getHospId());
         queryWrapper.eq(CostAccountShareParam::getDelFlag, NumberConstant.ZERO);
-        queryWrapper.eq(CostAccountShareParam::getAccountShareId, accountShareId);
+        if(!ObjectUtils.isEmpty(accountShareId)) {
+            queryWrapper.eq(CostAccountShareParam::getAccountShareId, accountShareId);
+        }
         return this.list(queryWrapper);
     }
 

+ 429 - 24
src/main/java/com/kcim/service/impl/AllocationServiceImpl.java

@@ -19,9 +19,12 @@ import com.kcim.common.util.UserContext;
 import com.kcim.dao.mapper.AllocationMapper;
 import com.kcim.dao.model.*;
 import com.kcim.dao.model.dto.StartDTO;
+import com.kcim.dao.repository.CostAccountShareDetailRepository;
+import com.kcim.dao.repository.CostAccountShareParamRepository;
 import com.kcim.dao.repository.ResponsibilityRepository;
 import com.kcim.service.*;
 import com.kcim.vo.*;
+import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.springframework.stereotype.Service;
@@ -36,6 +39,7 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 @Slf4j
+@AllArgsConstructor
 @Service("allocationService")
 public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocation> implements AllocationService {
     //    @Value("${file.serverPath}")
@@ -55,18 +59,21 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
 
     private final SqlService sqlService;
 
-    public AllocationServiceImpl(CostCostingGroupService costCostingGroupService, CostShareLevelService shareLevelService, ResponsibilityService responsibilityService, CostAccountShareService accountShareService, ShareParamValueService shareParamValueService, CostShareParamService shareParamService, AllocationQueryService allocationQueryService, ResponsibilityRepository responsibilityRepository, CenterService centerService, SqlService sqlService) {
-        this.costCostingGroupService = costCostingGroupService;
-        this.shareLevelService = shareLevelService;
-        this.responsibilityService = responsibilityService;
-        this.accountShareService = accountShareService;
-        this.shareParamValueService = shareParamValueService;
-        this.shareParamService = shareParamService;
-        this.allocationQueryService = allocationQueryService;
-        this.responsibilityRepository = responsibilityRepository;
-        this.centerService = centerService;
-        this.sqlService = sqlService;
-    }
+    private final CostAccountShareDetailRepository costAccountShareDetailRepository;
+    private final CostAccountShareParamRepository costAccountShareParamRepository;
+
+//    public AllocationServiceImpl(CostCostingGroupService costCostingGroupService, CostShareLevelService shareLevelService, ResponsibilityService responsibilityService, CostAccountShareService accountShareService, ShareParamValueService shareParamValueService, CostShareParamService shareParamService, AllocationQueryService allocationQueryService, ResponsibilityRepository responsibilityRepository, CenterService centerService, SqlService sqlService) {
+//        this.costCostingGroupService = costCostingGroupService;
+//        this.shareLevelService = shareLevelService;
+//        this.responsibilityService = responsibilityService;
+//        this.accountShareService = accountShareService;
+//        this.shareParamValueService = shareParamValueService;
+//        this.shareParamService = shareParamService;
+//        this.allocationQueryService = allocationQueryService;
+//        this.responsibilityRepository = responsibilityRepository;
+//        this.centerService = centerService;
+//        this.sqlService = sqlService;
+//    }
 
     /**
      * 分摊成本数据
@@ -77,6 +84,413 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
     @Override
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
     public void startAllocation(StartDTO startDTO, Long hospId) {
+        //开始按责任中心分摊成本
+        startCostAllocation(startDTO, hospId);
+        //执行分摊后续处理脚本
+        execAllocationSQL(startDTO);
+    }
+
+    /**
+     * 按会计科目分摊
+     * @param startDTO
+     */
+    public void startAccountAllocation(StartDTO startDTO, Long hospId){
+        long timeMillis = System.currentTimeMillis();
+        // 得到这个月的所有导入的成本数据
+        List<CostCostingGroup> costingGroups = costCostingGroupService.getByYearAndDate(startDTO.getYear(), startDTO.getMonth(), hospId);
+        // 没有重新导入
+        if (costingGroups.isEmpty()) {
+            throw new CostException("本月分摊数据未导入");
+        }
+        // 导入数据按责任中心归类
+        Map<String, List<CostCostingGroup>> respDirectCostMap = costingGroups.stream().collect(Collectors.groupingBy(CostCostingGroup::getResponsibilityCode));
+        // 得到这个月导入的成本分摊参数值列表
+        List<ShareParamValue> respParamValueList = shareParamValueService.getListByYearAndMonth(startDTO.getYear(), startDTO.getMonth(), hospId);
+        if (respParamValueList.isEmpty()) {
+            throw new CostException("本月成本分摊参数值未导入");
+        }
+        // 得到这个医院所有的分摊层级列表排序
+        List<CostShareLevelVO> shareLevelVOs = shareLevelService.getAll(hospId);
+        if (CollUtil.isEmpty(shareLevelVOs)) {
+            throw new CostException("请先设置医院分摊层级");
+        }
+        //优化循环调用  责任中心  分摊层级对应
+        //成本分摊字典
+        List<CostShareParamVO> costShareParamList = shareParamService.getAll(hospId);
+        if (CollUtil.isEmpty(costShareParamList)) {
+            throw new CostException("请先设置分摊参数字典");
+        }
+        Map<String,String> ShareParamNameMap = costShareParamList.stream().collect(Collectors.toMap(CostShareParamVO::getShareParamCode, CostShareParamVO::getShareParamName, (a, b) -> b));
+
+        //责任中心
+        List<Responsibility> responsibilityList = responsibilityRepository.getList(hospId);
+        if (CollUtil.isEmpty(responsibilityList)) {
+            throw new CostException("请先设置责任中心");
+        }
+        //按shareId分组
+        Map<Long, List<Responsibility>> responsibilityShareIdMap = responsibilityList.stream().collect(Collectors.groupingBy(Responsibility::getShareId));
+        //按责任中心代码分组
+        Map<String, List<Responsibility>> responsibilityCodeMap = responsibilityList.stream().collect(Collectors.groupingBy(Responsibility::getResponsibilityCode));
+        //分摊参数对应
+        List<CostAccountShare> accountShareList = accountShareService.getAll();
+        if (CollUtil.isEmpty(accountShareList)) {
+            throw new CostException("请先设置责任中心分摊参数对应");
+        }
+        //责任中心的分摊参数对应设置
+        Map<String, List<CostAccountShare>> accountShareResponsibilityMap = accountShareList.stream().collect(Collectors.groupingBy(CostAccountShare::getResponsibilityCode));
+        //分摊设置对应的分摊参数明细
+        List<CostAccountShareParam> costAccountShareParamList = costAccountShareParamRepository.getCostAccountShareParam(null);
+        if (CollUtil.isEmpty(costAccountShareParamList)) {
+            throw new CostException("请先设置责任中心的分摊参数");
+        }
+        //设置分摊参数名称
+        costAccountShareParamList.forEach(shareParam->shareParam.setShareParamName(ShareParamNameMap.get(shareParam.getShareParamCode())));
+        //按分摊设置ID分组
+        Map<Long, List<CostAccountShareParam>> costAccountShareParamMap = costAccountShareParamList.stream().collect(Collectors.groupingBy(CostAccountShareParam::getAccountShareId));
+        //分摊设置对应的会计科目明细
+        List<CostAccountShareDetail> costAccountShareDetailList = costAccountShareDetailRepository.getCostAccountShareDetail(null);
+        Map<Long, List<CostAccountShareDetail>> costAccountShareDetailMap =new HashMap<>();
+        //全部都是合并计算时会有会计科目明细为空的情况
+        if(!CollectionUtils.isEmpty(costAccountShareDetailList)) {
+            costAccountShareDetailMap=costAccountShareDetailList.stream().collect(Collectors.groupingBy(CostAccountShareDetail::getAccountShareId));
+        }
+        //分摊成本列表
+        List<Allocation> allocationCostList=new ArrayList<>();
+        //逐级分摊
+        for (CostShareLevelVO shareLevelVO : shareLevelVOs) {
+            allocationShareLevelCost(startDTO,shareLevelVO,responsibilityList,responsibilityShareIdMap,respDirectCostMap,respParamValueList,
+                    accountShareResponsibilityMap,costAccountShareParamMap,costAccountShareDetailMap,allocationCostList,timeMillis);
+        }
+        //没有任何分摊数据
+        if(CollectionUtils.isEmpty(allocationCostList)){
+            log.error("没有任何分摊数据......");
+            return;
+        }
+        // 删除该年月已经分摊过的数据
+        removeData(startDTO, hospId);
+        //保存分摊结果信息
+        this.saveBatch(allocationCostList);
+        //保存分摊结果查询表
+        applyAllocationQuery(startDTO,respDirectCostMap,allocationCostList,responsibilityCodeMap);
+    }
+
+    /**
+     * 一个分摊层级的分摊计算
+     * @param startDTO 分摊年月所在对象
+     * @param shareLevelVO 分摊层级
+     * @param responsibilityList 责任中心字典
+     * @param responsibilityShareIdMap 各分摊层级的责任中心
+     * @param respDirectCostMap 直接成本
+     * @param respParamValueList 分摊参数数值
+     * @param accountShareResponsibilityMap 分摊参数对应
+     * @param costAccountShareParamMap 分摊设置对应的分摊参数
+     * @param costAccountShareDetailMap 分摊设置对应的会计科目
+     * @param allocationCostList 间接成本
+     * @param timeMillis 时间戳
+     * @return
+     */
+    public List<Allocation> allocationShareLevelCost(StartDTO startDTO, CostShareLevelVO shareLevelVO,
+                                                     List<Responsibility> responsibilityList,
+                                                     Map<Long, List<Responsibility>> responsibilityShareIdMap,
+                                                     Map<String, List<CostCostingGroup>> respDirectCostMap ,
+                                                     List<ShareParamValue> respParamValueList,
+                                                     Map<String,List<CostAccountShare>> accountShareResponsibilityMap,
+                                                     Map<Long, List<CostAccountShareParam>> costAccountShareParamMap,
+                                                     Map<Long, List<CostAccountShareDetail>> costAccountShareDetailMap,
+                                                     List<Allocation> allocationCostList,
+                                                     long timeMillis){
+        //分摊成本列表
+        List<Allocation> allocationList=new ArrayList<>();
+        // 分摊层级id
+        Long levelId = shareLevelVO.getId();
+        // 目标分摊层级,可能不存在
+        String targetLevel = shareLevelVO.getTargetLevel();
+        if (StrUtil.isBlank(targetLevel)) {
+            throw new CostException("未设置目标层级");
+        }
+        //目标分摊层级
+        List<String> targetLevelList = Arrays.stream(targetLevel.split(StrUtil.COMMA)).collect(Collectors.toList());
+        // 得到该分摊层级下责任中心列表,如果不存在,下一个
+        List<Responsibility> responsibilities = responsibilityShareIdMap.get(levelId);
+        if (CollectionUtils.isEmpty(responsibilities)) {
+            return allocationList;
+        }
+        //目标责任中心列表
+        List<Responsibility> targetResponsibilityList = responsibilityList.stream().filter(responsibility -> targetLevelList.contains(responsibility.getShareLevel())).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(responsibilities)) {
+            throw new CostException(String.format("[%s-%s]的分摊目标层级没有对应的责任中心",shareLevelVO.getLeverSort(),shareLevelVO.getShareName()));
+        }
+        //按责任中心逐个开始分摊
+        for (Responsibility responsibility : responsibilities) {
+            //分摊一个责任中心的成本
+            List<Allocation> allocationRespCosts = allocationResponsibilityCost(startDTO, shareLevelVO, responsibility, targetResponsibilityList, respDirectCostMap, respParamValueList,
+                    accountShareResponsibilityMap, costAccountShareParamMap, costAccountShareDetailMap, allocationCostList, timeMillis);
+            allocationList.addAll(allocationRespCosts);
+        }
+        return allocationList;
+    }
+
+
+    /**
+     * 分摊一个责任中心的成本
+     * @param startDTO 分摊年月所在对象
+     * @param shareLevelVO 分摊层级
+     * @param responsibility 责任中心
+     * @param respDirectCostMap 直接成本
+     * @param respParamValueList 分摊参数数值
+     * @param accountShareResponsibilityMap 分摊参数对应
+     * @param costAccountShareParamMap 分摊设置对应的分摊参数
+     * @param costAccountShareDetailMap 分摊设置对应的会计科目
+     * @param allocationCostList 间接成本
+     * @param timeMillis 时间戳
+     */
+    public List<Allocation> allocationResponsibilityCost(StartDTO startDTO,
+                                             CostShareLevelVO shareLevelVO,
+                                             Responsibility responsibility,
+                                             List<Responsibility> targetResponsibilityList,
+                                             Map<String, List<CostCostingGroup>> respDirectCostMap ,
+                                             List<ShareParamValue> respParamValueList,
+                                             Map<String,List<CostAccountShare>> accountShareResponsibilityMap,
+                                             Map<Long, List<CostAccountShareParam>> costAccountShareParamMap,
+                                             Map<Long, List<CostAccountShareDetail>> costAccountShareDetailMap,
+                                             List<Allocation> allocationCostList,
+                                             long timeMillis){
+        //分摊结果列表
+        List<Allocation> allocationList=new ArrayList<>();
+        // 得到分摊参数对应记录,不存在,下一个
+        List<CostAccountShare> accountShares = accountShareResponsibilityMap.get(responsibility.getResponsibilityCode());
+        if (CollectionUtils.isEmpty(accountShares)) {
+            return allocationList;
+        }
+        // 计算方式 0是合并计算  1是分开计算
+        Integer calcType = shareLevelVO.getCalcType();
+        //合并计算时不应该有多个分摊设置
+        if(NumberConstant.ZERO.equals(calcType) &&NumberConstant.ONE!=accountShares.size()){
+            throw new CostException(String.format("[%s-%s]的分摊设置有问题,合并计算的责任中心只允许设置一个分摊配置",responsibility.getResponsibilityCode(),responsibility.getResponsibilityName()));
+        }
+        //所有目标责任中心的责任中心代码列表
+        List<String> targetResponsibilityCodeList = targetResponsibilityList.stream().map(Responsibility::getResponsibilityCode).collect(Collectors.toList());
+        //间接成本
+        List<Allocation> respIndirectCostList = allocationCostList.stream().filter(allocationCost -> allocationCost.getTargetResponsibilityCode().equals(responsibility.getResponsibilityCode())).collect(Collectors.toList());
+        //直接成本
+        List<CostCostingGroup> respDirectCostList = respDirectCostMap.get(responsibility.getResponsibilityCode());
+        //按分摊设置逐个计算
+        for (CostAccountShare accountShare : accountShares) {
+            //分摊设置对应的直接成本
+            List<CostCostingGroup> paramDirectCostList=new ArrayList<>();
+            //分摊设置对应的间接成本
+            List<Allocation> paramIndirectCostList=new ArrayList<>();
+            //合并计算
+            if(NumberConstant.ZERO.equals(calcType)){
+                //合并计算时分摊参数的成本=责任中心的成本
+                paramDirectCostList=respDirectCostList;
+                paramIndirectCostList=respIndirectCostList;
+            }else{
+                //分摊设置对应的会计科目
+                List<String> accountList = costAccountShareDetailMap.get(accountShare.getId()).stream().map(CostAccountShareDetail::getAccountingCode).collect(Collectors.toList());
+                //获取分摊设置对应的直接成本
+                paramDirectCostList = respDirectCostList.stream().filter(respDirectCost -> accountList.contains(respDirectCost.getAccountCode())).collect(Collectors.toList());
+                //只有包含分摊成本的才有间接成本
+                if(NumberConstant.ONE.equals(accountShare.getIsShareCost())){
+                    paramIndirectCostList=respIndirectCostList;
+                }
+            }
+            //分摊设置对应的分摊参数
+            List<CostAccountShareParam> costAccountShareParams = costAccountShareParamMap.get(accountShare.getId());
+            //按分摊参数逐个计算所有目标责任中心的分摊金额
+            for (CostAccountShareParam shareParam : costAccountShareParams) {
+                //获取所有目标责任中心的分摊参数数值信息
+                List<ShareParamValue> targetResponsibilityParamList = respParamValueList.stream().filter(respParamValue -> shareParam.getShareParamCode().equals(respParamValue.getShareParamCode())
+                        && targetResponsibilityCodeList.contains(respParamValue.getResponsibilityCode())).collect(Collectors.toList());
+                //按分摊参数计算每个会计科目分摊到的金额
+                List<Allocation> allocationParamCosts = allocationParamCostCalc(startDTO, shareLevelVO, responsibility, targetResponsibilityList, paramDirectCostList,
+                        paramIndirectCostList, accountShares.get(NumberConstant.ZERO), shareParam, targetResponsibilityParamList, timeMillis);
+                allocationList.addAll(allocationParamCosts);
+            }
+        }
+        return allocationList;
+    }
+
+
+    /**
+     * 按分摊参数计算每个会计科目分摊到的金额
+     * @param startDTO 分摊年月所在对象
+     * @param shareLevelVO 分摊层级
+     * @param responsibility 责任中心
+     * @param targetResponsibilityList 目标责任中心列表
+     * @param respDirectCostList 直接成本
+     * @param respIndirectCostList 间接成本
+     * @param costAccountShare 分摊参数对应
+     * @param shareParam 分摊参数
+     * @param targetResponsibilityParamList 目标责任中心的分摊参数数值列表
+     * @param timeMillis 时间戳
+     * @return
+     */
+    public List<Allocation> allocationParamCostCalc(StartDTO startDTO,
+                                               CostShareLevelVO shareLevelVO,
+                                               Responsibility responsibility,
+                                               List<Responsibility> targetResponsibilityList,
+                                               List<CostCostingGroup> respDirectCostList,
+                                               List<Allocation> respIndirectCostList,
+                                               CostAccountShare costAccountShare,
+                                               CostAccountShareParam shareParam,
+                                               List<ShareParamValue> targetResponsibilityParamList,
+                                               long timeMillis){
+        //合并直接成本和间接成本
+        if(!CollectionUtils.isEmpty(respIndirectCostList)){
+            //转成直接成本的对象
+            List<CostCostingGroup> respIndirectCosts = BeanUtil.convertList(respIndirectCostList, CostCostingGroup.class);
+            respDirectCostList.addAll(respIndirectCosts);
+        }
+        //计算所有目标责任中心的分摊参数加总
+        BigDecimal totalParamValue = targetResponsibilityParamList.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+        //按责任中心分组,方便取到对应责任中心的分摊参数数值
+        Map<String, List<ShareParamValue>> targetRespParamGroup = targetResponsibilityParamList.stream().collect(Collectors.groupingBy(ShareParamValue::getResponsibilityCode));
+        //按会计科目分组,相同会计科目一起分摊
+        Map<String, List<CostCostingGroup>> respDirectCostGroup = respDirectCostList.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode));
+        //分摊结果列表
+        List<Allocation> allocationList=new ArrayList<>();
+        // 按会计科目进行分摊计算
+        respDirectCostGroup.forEach((accountCode, costCostingGroups) -> {
+            //会计科目总金额
+            BigDecimal totalAmount = costCostingGroups.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+            for (Responsibility targetResponsibility : targetResponsibilityList) {
+                List<ShareParamValue> targetRespParamValues = targetRespParamGroup.get(targetResponsibility.getResponsibilityCode());
+                //目标责任中心的分摊参数数值
+                BigDecimal targetRespParamValue = targetRespParamValues.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+                //计算分摊参数比例
+                BigDecimal shareParamRate = BigDecimal.ZERO;
+                if (totalParamValue.compareTo(BigDecimal.ZERO) != 0) {
+                    shareParamRate = targetRespParamValue.divide(totalParamValue, NumberConstant.FOUR, RoundingMode.HALF_UP);
+                }
+                //参数比例
+                BigDecimal paramRate = shareParam.getShareParamProportion().divide(new BigDecimal(NumberConstant.ONE_HUNDRED), NumberConstant.FOUR, RoundingMode.HALF_UP);
+                //计算分摊到的金额=目标责任中心的分摊参数数值*会计科目总金额/所有目标责任中心的分摊参数数值加总*参数比例
+                BigDecimal targetAmount = targetRespParamValue.multiply(totalAmount).multiply(paramRate).divide(totalParamValue, NumberConstant.FOUR, RoundingMode.HALF_UP);
+                //生成分摊结果的对象
+                Allocation targetAllocation = new Allocation();
+                targetAllocation.setDateMonth(startDTO.getMonth()).setDateYear(startDTO.getYear()).setLevelSort(shareLevelVO.getLeverSort())
+                        .setLevelName(shareLevelVO.getShareName()).setHospId(UserContext.getHospId()).setResponsibilityCode(responsibility.getResponsibilityCode())
+                        .setResponsibilityName(responsibility.getResponsibilityName()).setAccountShareId(costAccountShare.getId()).setAmount(targetAmount)
+                        .setCreateTime(timeMillis).setTargetResponsibilityCode(targetResponsibility.getResponsibilityCode()).setTargetResponsibilityName(targetResponsibility.getResponsibilityName())
+                        .setShareParamCode(shareParam.getShareParamCode()).setShareParamName(shareParam.getShareParamName()).setTotalAmount(totalAmount).setShareParamValueNum(targetRespParamValue)
+                        .setShareParamRate(shareParamRate).setShareLevelId(responsibility.getShareId()).setTargetShareLevelId(targetResponsibility.getShareId())
+                        .setAccountCode(accountCode).setAccountName(costCostingGroups.get(NumberConstant.ZERO).getAccountName());
+                allocationList.add(targetAllocation);
+            }
+        });
+        return allocationList;
+    }
+
+    /**
+     * 保存分摊结果查询表
+     * @param startDTO 分摊年月所在对象
+     * @param respDirectCostMap 责任中心的直接成本
+     * @param allocationCostList 所有责任中心的间接成本
+     * @param responsibilityCodeMap 责任中心字典
+     */
+    public void applyAllocationQuery(StartDTO startDTO, Map<String, List<CostCostingGroup>> respDirectCostMap ,List<Allocation> allocationCostList,Map<String, List<Responsibility>> responsibilityCodeMap){
+        List<AllocationQuery> allocationQueryList=new ArrayList<>();
+        //处理直接成本,直接成本可能是多次导入的没有按会计科目汇总的,需按责任中心+会计科目汇总保存
+        respDirectCostMap.forEach((respCode,respCostList)->{
+            List<AllocationQuery> directAllocationQueryList = createDirectAllocationQuery(startDTO, respCode, respCostList, responsibilityCodeMap);
+            allocationQueryList.addAll(directAllocationQueryList);
+        });
+        //处理直接成本,间接成本肯定是按会计科目汇总的,可直接生成对象
+        for (Allocation indirectCost : allocationCostList) {
+            AllocationQuery indirectAllocationQuery = createIndirectAllocationQuery(startDTO, indirectCost);
+            allocationQueryList.add(indirectAllocationQuery);
+        }
+        if(CollectionUtils.isEmpty(allocationQueryList)){
+            log.error("没有任何分摊结果数据......");
+            return;
+        }
+        //保存分摊结果查询对象信息
+        allocationQueryService.saveBatch(allocationQueryList);
+    }
+
+    /**
+     * 创建直接成本的分摊结果查询对象
+     * @param startDTO 分摊年月所在对象
+     * @param respCode 责任中心代码
+     * @param respCostList 责任中心的直接成本数据
+     * @param responsibilityCodeMap 责任中心字典
+     * @return
+     */
+    public List<AllocationQuery> createDirectAllocationQuery(StartDTO startDTO,String respCode,List<CostCostingGroup> respCostList, Map<String, List<Responsibility>> responsibilityCodeMap){
+        List<AllocationQuery> allocationQueryList=new ArrayList<>();
+        if(!responsibilityCodeMap.containsKey(respCode)){
+            log.error(String.format("[%s-%s]的责任中心数据已过期",respCode,respCostList.get(NumberConstant.ZERO).getResponsibilityName()));
+            return allocationQueryList;
+        }
+        //责任中心数据
+        Responsibility responsibility=responsibilityCodeMap.get(respCode).get(NumberConstant.ZERO);
+        //按会计科目代码分组
+        Map<String, List<CostCostingGroup>> respDirectCostGroup = respCostList.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode));
+        //按会计科目逐个生成分摊结果查询对象
+        respDirectCostGroup.forEach((respAccountCode,respAccountCostList)->{
+            CostCostingGroup firtsDirectCost = respAccountCostList.get(NumberConstant.ZERO);
+            //汇总金额
+            BigDecimal totalAccountCost = respAccountCostList.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+            //创建分摊结果查询对象
+            AllocationQuery allocationQuery = new AllocationQuery();
+            allocationQuery.setDateYear(startDTO.getYear()).setDateMonth(startDTO.getMonth())
+                    .setHospId(UserContext.getHospId()).setResponsibilityCode(responsibility.getResponsibilityCode()).setResponsibilityName(responsibility.getResponsibilityName())
+                    .setCreateTime(System.currentTimeMillis())
+                    .setLevelSort(responsibility.getShareLevel()).setLevelName(responsibility.getShareName())
+                    .setTargetResponsibilityCode(responsibility.getResponsibilityCode())
+                    .setTargetResponsibilityName(responsibility.getResponsibilityName())
+                    .setShareLevelId(responsibility.getShareId())
+                    .setOriginId(firtsDirectCost.getId()).setOriginType(Long.valueOf(NumberConstant.ONE)).setAmount(totalAccountCost)
+                    .setAccountingCode(firtsDirectCost.getAccountCode()).setAccountingName(firtsDirectCost.getAccountName());
+            allocationQueryList.add(allocationQuery);
+        });
+        return allocationQueryList;
+    }
+
+    /**
+     * 创建间接成本的分摊结果查询对象
+     * @param startDTO 分摊年月所在对象
+     * @param indirectCost 间接成本对象
+     * @return
+     */
+    public AllocationQuery createIndirectAllocationQuery(StartDTO startDTO,Allocation indirectCost){
+        AllocationQuery allocationQuery = new AllocationQuery();
+        allocationQuery.setDateYear(startDTO.getYear()).setDateMonth(startDTO.getMonth())
+                .setHospId(UserContext.getHospId()).setResponsibilityCode(indirectCost.getResponsibilityCode())
+                .setResponsibilityName(indirectCost.getResponsibilityName())
+                .setOriginId(indirectCost.getId()).setOriginType(Long.valueOf(NumberConstant.TWO)).setAmount(indirectCost.getAmount())
+                .setAccountingCode(indirectCost.getAccountCode()).setAccountingName(indirectCost.getAccountName())
+                .setCreateTime(System.currentTimeMillis())
+                .setLevelSort(indirectCost.getLevelSort()).setLevelName(indirectCost.getLevelName())
+                .setTargetResponsibilityCode(indirectCost.getTargetResponsibilityCode())
+                .setTargetResponsibilityName(indirectCost.getTargetResponsibilityName())
+                .setShareLevelId(indirectCost.getShareLevelId());
+        return allocationQuery;
+    }
+
+    /**
+     * 执行分摊后续处理脚本
+     * @param startDTO
+     */
+    public void execAllocationSQL(StartDTO startDTO){
+        //执行分摊后续处理脚本
+        Map<String,String> sqlParameter = new HashMap<>();
+        if(startDTO.getMonth()<10){
+            sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,startDTO.getYear()+"-0"+startDTO.getMonth());
+        }else{
+            sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,startDTO.getYear()+"-"+startDTO.getMonth());
+        }
+        sqlService.autoExecuteSql(CustomSqlTypeEnum.COST_ALLOCATION_CALC.getCode(),sqlParameter);
+    }
+
+
+    /**
+     * 按责任中心分摊
+     * @param startDTO
+     * @param hospId
+     */
+    public  void startCostAllocation(StartDTO startDTO, Long hospId){
         long timeMillis = System.currentTimeMillis();
         // 得到这个月的所有导入的成本数据
         List<CostCostingGroup> costingGroups = costCostingGroupService.getByYearAndDate(startDTO.getYear(), startDTO.getMonth(), hospId);
@@ -207,14 +621,14 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                                 String valueResponsibilityCode = paramValue.getResponsibilityCode();
                                 //优化循环调用
                                 String targetRespName = responsibilityNameMap.get(valueResponsibilityCode);
-    //                            String targetRespName = responsibilityService.getByCode(valueResponsibilityCode, hospId);
+                                //                            String targetRespName = responsibilityService.getByCode(valueResponsibilityCode, hospId);
                                 Long targetShareLevelId = responsibilityShareIdDictMap.get(valueResponsibilityCode);
-    //                            Long targetShareLevelId = responsibilityService.getLevelIdByCode(valueResponsibilityCode, hospId);
+                                //                            Long targetShareLevelId = responsibilityService.getLevelIdByCode(valueResponsibilityCode, hospId);
                                 if (Objects.isNull(targetShareLevelId)) {
                                     throw new CostException("目标责任中心分摊层级异常");
                                 }
                                 String shareParamName = ShareParamNameMap.get(paramValue.getShareParamCode());
-    //                            String shareParamName = shareParamService.getByCode(paramValue.getShareParamCode(), hospId);
+                                //                            String shareParamName = shareParamService.getByCode(paramValue.getShareParamCode(), hospId);
                                 targetAllocation.setDateMonth(startDTO.getMonth()).setDateYear(startDTO.getYear()).setLevelSort(shareLevelVO.getLeverSort())
                                         .setLevelName(shareLevelVO.getShareName()).setHospId(hospId).setResponsibilityCode(responsibility.getResponsibilityCode())
                                         .setResponsibilityName(responsibility.getResponsibilityName()).setAccountShareId(accountShareId).setAmount(targetAmount)
@@ -244,15 +658,6 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
         // 入cost_allocation_query 表 便于后续操作
         this.saveAllocationQuery(list, hospId, startDTO.getYear(), startDTO.getMonth(),shareLevelVOs,accountShareList);
 
-        Map<String,String> sqlParameter = new HashMap<>();
-        if(startDTO.getMonth()<10){
-            sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,startDTO.getYear()+"-0"+startDTO.getMonth());
-
-        }else{
-            sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,startDTO.getYear()+"-"+startDTO.getMonth());
-
-        }
-        sqlService.autoExecuteSql(CustomSqlTypeEnum.COST_ALLOCATION_CALC.getCode(),sqlParameter);
     }
 
     private void removeData(StartDTO startDTO, Long hospId) {