Browse Source

添加按会计科目分摊相关代码

JammeyJiang 4 months ago
parent
commit
32e94bb1c1

+ 5 - 0
src/main/java/com/kcim/common/constants/ParameterConstant.java

@@ -47,5 +47,10 @@ public interface ParameterConstant {
      */
     Long ITEM_CALC_TYPE=1902923430831984640L;
 
+    /**
+     * 成本分摊计算的分摊方式 1按责任中心分摊 2按会计科目分摊
+     */
+    Long ALLOCATION_TYPE=1907261486460440576L;
+
 
 }

+ 5 - 0
src/main/java/com/kcim/dao/mapper/AllocationMapper.java

@@ -76,4 +76,9 @@ public interface AllocationMapper extends BaseMapper<Allocation> {
     List<Allocation> getAllSortLevel(@Param("hospId") Long hospId,
                                      @Param("year") int year,
                                      @Param("month") int month);
+
+    List<Allocation> getLevelSortAllocation(@Param("hospId") Long hospId,
+                                     @Param("year") int year,
+                                     @Param("month") int month,
+                                     @Param("shareLevelId") Long shareLevelId);
 }

+ 1 - 3
src/main/java/com/kcim/dao/model/Allocation.java

@@ -1,6 +1,5 @@
 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;
@@ -115,12 +114,11 @@ public class Allocation implements Serializable {
 	/**
 	 * 会计科目Code
 	 */
-	@TableField(exist = false)
 	private String accountCode;
+
 	/**
 	 * 会计科目名称
 	 */
-	@TableField(exist = false)
 	private String accountName;
 
 	/**

+ 54 - 21
src/main/java/com/kcim/service/impl/AllocationServiceImpl.java

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.common.constants.NumberConstant;
+import com.kcim.common.constants.ParameterConstant;
 import com.kcim.common.constants.SQLParameter;
 import com.kcim.common.enums.CustomSqlTypeEnum;
 import com.kcim.common.exception.CostException;
@@ -84,8 +85,16 @@ 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);
+        //获取分摊方式
+        String parameterValue = centerService.getParameterValue(ParameterConstant.ALLOCATION_TYPE);
+        if (NumberConstant.ONE_S.equals(parameterValue)) {
+            //开始按责任中心分摊成本
+            startCostAllocation(startDTO, hospId);
+        }
+        else if (NumberConstant.TWO_S.equals(parameterValue)) {
+            //按会计科目分摊
+            startAccountAllocation(startDTO, hospId);
+        }
         //执行分摊后续处理脚本
         execAllocationSQL(startDTO);
     }
@@ -158,8 +167,9 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
         List<Allocation> allocationCostList=new ArrayList<>();
         //逐级分摊
         for (CostShareLevelVO shareLevelVO : shareLevelVOs) {
-            allocationShareLevelCost(startDTO,shareLevelVO,responsibilityList,responsibilityShareIdMap,respDirectCostMap,respParamValueList,
-                    accountShareResponsibilityMap,costAccountShareParamMap,costAccountShareDetailMap,allocationCostList,timeMillis);
+            List<Allocation> shareLevelAllocationList = allocationShareLevelCost(startDTO, shareLevelVO, responsibilityList, responsibilityShareIdMap, respDirectCostMap, respParamValueList,
+                    accountShareResponsibilityMap, costAccountShareParamMap, costAccountShareDetailMap, allocationCostList, timeMillis);
+            allocationCostList.addAll(shareLevelAllocationList);
         }
         //没有任何分摊数据
         if(CollectionUtils.isEmpty(allocationCostList)){
@@ -210,14 +220,18 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
         }
         //目标分摊层级
         List<String> targetLevelList = Arrays.stream(targetLevel.split(StrUtil.COMMA)).collect(Collectors.toList());
+        //目标层级是自己的不需要做分摊处理
+        if(NumberConstant.ONE.equals(targetLevelList.size())&&Integer.valueOf(targetLevelList.get(NumberConstant.ZERO)).equals(shareLevelVO.getLeverSort())){
+            return allocationList;
+        }
         // 得到该分摊层级下责任中心列表,如果不存在,下一个
         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)) {
+        List<Responsibility> targetResponsibilityList = responsibilityList.stream().filter(responsibility -> targetLevelList.contains(String.valueOf(responsibility.getShareLevel()))).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(targetResponsibilityList)) {
             throw new CostException(String.format("[%s-%s]的分摊目标层级没有对应的责任中心",shareLevelVO.getLeverSort(),shareLevelVO.getShareName()));
         }
         //按责任中心逐个开始分摊
@@ -288,8 +302,10 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
             }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(!CollectionUtils.isEmpty(respDirectCostList)) {
+                    //获取分摊设置对应的直接成本
+                    paramDirectCostList = respDirectCostList.stream().filter(respDirectCost -> accountList.contains(respDirectCost.getAccountCode())).collect(Collectors.toList());
+                }
                 //只有包含分摊成本的才有间接成本
                 if(NumberConstant.ONE.equals(accountShare.getIsShareCost())){
                     paramIndirectCostList=respIndirectCostList;
@@ -302,6 +318,9 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                 //获取所有目标责任中心的分摊参数数值信息
                 List<ShareParamValue> targetResponsibilityParamList = respParamValueList.stream().filter(respParamValue -> shareParam.getShareParamCode().equals(respParamValue.getShareParamCode())
                         && targetResponsibilityCodeList.contains(respParamValue.getResponsibilityCode())).collect(Collectors.toList());
+                if(CollectionUtils.isEmpty(targetResponsibilityParamList)){
+                    throw new CostException(String.format("[%s-%s]的目标责任中心找不到对应的参数数值,无法继续分摊",responsibility.getResponsibilityName(),shareParam.getShareParamName()));
+                }
                 //按分摊参数计算每个会计科目分摊到的金额
                 List<Allocation> allocationParamCosts = allocationParamCostCalc(startDTO, shareLevelVO, responsibility, targetResponsibilityList, paramDirectCostList,
                         paramIndirectCostList, accountShares.get(NumberConstant.ZERO), shareParam, targetResponsibilityParamList, timeMillis);
@@ -336,34 +355,47 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                                                CostAccountShareParam shareParam,
                                                List<ShareParamValue> targetResponsibilityParamList,
                                                long timeMillis){
-        //合并直接成本和间接成本
+        //重新定义一个列表用于合并直接成本和间接成本
+        List<CostCostingGroup> respCostList=new ArrayList<>();
+        //添加直接成本
+        if(!CollectionUtils.isEmpty(respDirectCostList)){
+            respCostList.addAll(respDirectCostList);
+        }
+        //添加间接成本
         if(!CollectionUtils.isEmpty(respIndirectCostList)){
             //转成直接成本的对象
             List<CostCostingGroup> respIndirectCosts = BeanUtil.convertList(respIndirectCostList, CostCostingGroup.class);
-            respDirectCostList.addAll(respIndirectCosts);
+            respCostList.addAll(respIndirectCosts);
         }
         //计算所有目标责任中心的分摊参数加总
-        BigDecimal totalParamValue = targetResponsibilityParamList.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalParamValue= targetResponsibilityParamList.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+        if (NumberConstant.ZERO.equals(totalParamValue.compareTo(BigDecimal.ZERO))){
+            throw new CostException(String.format("[%s-%s]的目标责任中心参数数值加总为0,无法继续分摊",responsibility.getResponsibilityName(),shareParam.getShareParamName()));
+        }
         //按责任中心分组,方便取到对应责任中心的分摊参数数值
         Map<String, List<ShareParamValue>> targetRespParamGroup = targetResponsibilityParamList.stream().collect(Collectors.groupingBy(ShareParamValue::getResponsibilityCode));
         //按会计科目分组,相同会计科目一起分摊
-        Map<String, List<CostCostingGroup>> respDirectCostGroup = respDirectCostList.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode));
+        Map<String, List<CostCostingGroup>> respDirectCostGroup = respCostList.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);
+            //没有金额的项目不需要做分摊处理
+            if (NumberConstant.ZERO.equals(totalAmount.compareTo(BigDecimal.ZERO))){
+                return;
+            }
             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 targetRespParamValue = BigDecimal.ZERO;
+                if(!CollectionUtils.isEmpty(targetRespParamValues)) {
+                    targetRespParamValue = targetRespParamValues.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
                 }
-                //参数比例
+                //计算分摊参数比例
+                BigDecimal 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);
@@ -1228,9 +1260,10 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
             throw new CostException(500, "参数异常");
         }
         // 处理第几次分摊计算值
-        List<Allocation> allocationList = baseMapper.selectList(new QueryWrapper<Allocation>().lambda()
-                .eq(Allocation::getHospId, hospId).eq(Allocation::getLevelSort, levelSort).eq(Allocation::getShareLevelId, shareLevelId).eq(Allocation::getDateYear, year)
-                .eq(Allocation::getDateMonth, month));
+//        List<Allocation> allocationList = baseMapper.selectList(new QueryWrapper<Allocation>().lambda()
+//                .eq(Allocation::getHospId, hospId).eq(Allocation::getLevelSort, levelSort).eq(Allocation::getShareLevelId, shareLevelId).eq(Allocation::getDateYear, year)
+//                .eq(Allocation::getDateMonth, month));
+        List<Allocation> allocationList =baseMapper.getLevelSortAllocation(hospId,year,month,shareLevelId);
         // 找会计科室的时候使用的
         List<Allocation> allocations = baseMapper.selectList(new QueryWrapper<Allocation>().lambda()
                 .eq(Allocation::getHospId, hospId).eq(Allocation::getDateYear, year)

+ 1 - 1
src/main/java/com/kcim/web/CostAccountShareController.java

@@ -158,7 +158,7 @@ public class CostAccountShareController {
      * @param direction 1主表向明细表同步 2明细表向主表同步
      * @return
      */
-    @GetMapping("/synCostAccountShare")
+    @PostMapping("/synCostAccountShare")
     @ApiOperation("同步分摊参数设置")
     public Result synCostAccountShare(@RequestParam(defaultValue = "1") Integer direction,
                                       @RequestParam(required = false) Long accountShareId){

+ 37 - 0
src/main/resources/mapper/AllocationMapper.xml

@@ -83,5 +83,42 @@
         group by share_level_id
     </select>
 
+    <select id="getLevelSortAllocation" resultType="com.kcim.dao.model.Allocation">
+        SELECT
+            date_year,
+            date_month,
+            level_sort,
+            level_name,
+            responsibility_code,
+            responsibility_name,
+            account_share_id,
+            account_code,
+            account_name,
+            is_base_cost,
+            SUM( amount ) AS amount,
+            target_responsibility_code,
+            target_responsibility_name,
+            share_param_code,
+            share_param_name,
+            SUM( total_amount ) AS total_amount,
+            share_param_value_num,
+            share_param_rate,
+            share_level_id,
+            target_share_level_id
+        FROM
+            cost_allocation
+        WHERE
+            date_year = #{year}
+          AND date_month = #{month}
+          AND hosp_id = #{hospId}
+          AND delete_time = 0
+          AND share_level_id = #{shareLevelId}
+        GROUP BY
+            responsibility_code,
+            target_responsibility_code,
+            account_share_id,
+            share_param_code
+    </select>
+
 
 </mapper>