Ver Fonte

添加完全法全院项目的项目分摊参数及项目成本分摊计算

JammeyJiang há 6 meses atrás
pai
commit
e41bd922d6

+ 4 - 0
src/main/java/com/kcim/dao/mapper/ComputeShareParamMapper.java

@@ -30,4 +30,8 @@ public interface ComputeShareParamMapper extends BaseMapper<ComputeShareParam> {
     List<ComputeShareParamSumVo> getComputeShareParamSum(@Param("computeDate") String computeDate, @Param("hospId") Long hospId);
 
     List<ComputeShareParamDetailVo> getComputeShareParamDetail(String computeDate, Long hospId);
+
+    List<ComputeShareParamDetailVo> getComputeShareParamDetailGroup(String computeDate, Long hospId);
+
+    List<ComputeShareParamDetailVo> getComputeResponsibilityItem(String computeDate, Long hospId);
 }

+ 10 - 5
src/main/java/com/kcim/dao/model/ComputeProjectCostDetail.java

@@ -4,16 +4,15 @@ 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.math.BigDecimal;
-import java.io.Serializable;
-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;
+import java.util.Date;
+
 /**
  * 完全成本法项目成本计算明细表
  * 
@@ -96,4 +95,10 @@ public class ComputeProjectCostDetail implements Serializable {
 	private Integer index;
 
 	private BigDecimal computeSingleResult;
+
+	/**
+	 * 项目成本计算主表
+	 */
+	@TableField(exist = false)
+	ComputeProjectCost computeProjectCost;
 }

+ 5 - 0
src/main/java/com/kcim/dao/model/ComputeProjectGroupCostDetail.java

@@ -84,5 +84,10 @@ public class ComputeProjectGroupCostDetail implements Serializable {
 
 	private BigDecimal computeSingleResult;
 
+	/**
+	 * 项目成本计算主表
+	 */
+	@TableField(exist = false)
+	ComputeProjectCost computeProjectCost;
 
 }

+ 20 - 0
src/main/java/com/kcim/dao/repository/ComputeShareParamRepository.java

@@ -84,4 +84,24 @@ public class ComputeShareParamRepository extends ServiceImpl<ComputeShareParamMa
         return computeShareParamDetail.stream().filter(f -> !StringUtils.isEmpty(f.getResponsibilityCode())).collect(Collectors.toList());
 
     }
+
+    /**
+     * 获取责任中心的分摊参数汇总数据
+     * @param computeDate
+     * @return
+     */
+    public List<ComputeShareParamDetailVo> getComputeShareParamDetailGroup(String computeDate) {
+        List<ComputeShareParamDetailVo> computeShareParamDetail = this.baseMapper.getComputeShareParamDetailGroup(computeDate, UserContext.getHospId());
+        return computeShareParamDetail.stream().filter(f -> !StringUtils.isEmpty(f.getResponsibilityCode())).collect(Collectors.toList());
+    }
+
+    /**
+     * 获取要计算的科室收费项目
+     * @param computeDate
+     * @return
+     */
+    public List<ComputeShareParamDetailVo> getComputeResponsibilityItem(String computeDate) {
+        List<ComputeShareParamDetailVo> computeShareParamDetail = this.baseMapper.getComputeResponsibilityItem(computeDate, UserContext.getHospId());
+        return computeShareParamDetail.stream().filter(f -> !StringUtils.isEmpty(f.getResponsibilityCode())).collect(Collectors.toList());
+    }
 }

+ 19 - 0
src/main/java/com/kcim/dao/repository/CostDepartmentProfitRepository.java

@@ -46,6 +46,25 @@ public class CostDepartmentProfitRepository extends ServiceImpl<CostDepartmentPr
         return this.list(queryWrapper);
     }
 
+    /**
+     * 获取科室损益数据
+     * @param computeDate
+     * @return
+     */
+    public List<CostDepartmentProfit> getDepartmentProfit(String computeDate) {
+        Date dateTime = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM);
+        int year = DateUtil.year(dateTime);
+        int month = DateUtil.month(dateTime) + 1;
+        LambdaQueryWrapper<CostDepartmentProfit> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(CostDepartmentProfit::getYear,year);
+        queryWrapper.eq(CostDepartmentProfit::getMonth,month);
+        queryWrapper.eq(CostDepartmentProfit::getHospId, UserContext.getHospId());
+        return this.list(queryWrapper);
+
+
+
+    }
+
     public Integer getMaxYear(Long hospId) {
 
         return this.baseMapper.getMaxYear(hospId);

+ 6 - 1
src/main/java/com/kcim/service/ResponsibilityDepartmentService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.kcim.dao.model.dto.DepartDTO;
 import com.kcim.vo.CenterDepartmentVO;
 import com.kcim.dao.model.ResponsibilityDepartment;
+import com.kcim.vo.ResponsibilityDepartIdVO;
 
 import java.util.List;
 
@@ -30,6 +31,10 @@ public interface ResponsibilityDepartmentService extends IService<Responsibility
      */
     void saveCenterDepart(DepartDTO departDTO);
 
-
+    /**
+     * 获取责任中心科室对照字典
+     * @return
+     */
+    List<ResponsibilityDepartIdVO> getResponsibilityDepart();
 }
 

+ 5 - 0
src/main/java/com/kcim/service/impl/CostAccountShareServiceImpl.java

@@ -228,6 +228,11 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         } else {
             throw new CostException(500, "对不起该责任中心没有对应分摊层级");
         }
+        //合并计算的配置将责任中心名称作为会计科目名称(会计科目名称不能为空,不然后续报表会报错)
+        if(NumberConstant.ZERO.equals(costShareLevel.getCalcType())){
+            costAccountShareSaveDto.setAccountingCodes(costAccountShareSaveDto.getResponsibilityCode());
+            costAccountShareSaveDto.setAccountingNames(costAccountShareSaveDto.getResponsibilityName());
+        }
     }
 
     /**

+ 294 - 2
src/main/java/com/kcim/service/impl/ProjectCostServiceImpl.java

@@ -15,6 +15,7 @@ import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
 import com.kcim.dao.repository.*;
 import com.kcim.service.CenterService;
 import com.kcim.service.ProjectCostService;
+import com.kcim.service.ResponsibilityDepartmentService;
 import com.kcim.service.SqlService;
 import com.kcim.vo.*;
 import com.kcim.web.reponse.ProjectCostResponse;
@@ -101,7 +102,9 @@ public class ProjectCostServiceImpl implements ProjectCostService {
 
     SqlService sqlService;
 
-    public ProjectCostServiceImpl(SqlService sqlService,ResponsibilityRepository responsibilityRepository, ComputeProjectCostRepository repository, ComputeProjectCostDetailRepository detailRepository, ComputeProjectGroupCostDetailRepository groupDetailRepository, ImportPatientItemRepository importPatientItemRepository, ShareParamCostRepository shareParamCostRepository, ShareParamCostDetailRepository shareParamCostDetailRepository, CostDepartmentProfitRepository costDepartmentProfitRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ComputeShareParamRepository computeShareParamRepository, ItemRepository itemRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputePatientProjectCostRepository computePatientProjectCostRepository, ComputePatientProjectCostDetailRepository computePatientProjectCostDetailRepository, ComputePatientProjectGroupCostDetailRepository computePatientProjectGroupCostDetailRepository, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandProjectCostRepository standProjectCostRepository, ComputeStandProjectCostDetailRepository standProjectCostDetailRepository, ComputeStandProjectGroupCostDetailRepository standProjectGroupCostDetailRepository, ComputeStandPatientProjectCostRepository computeStandPatientProjectCostRepository, ComputeStandPatientProjectCostDetailRepository computeStandPatientProjectCostDetailRepository, ComputeStandPatientProjectGroupCostDetailRepository computeStandPatientProjectGroupCostDetailRepository) {
+    ResponsibilityDepartmentService responsibilityDepartmentService;
+
+    public ProjectCostServiceImpl(ResponsibilityDepartmentService responsibilityDepartmentService,SqlService sqlService,ResponsibilityRepository responsibilityRepository, ComputeProjectCostRepository repository, ComputeProjectCostDetailRepository detailRepository, ComputeProjectGroupCostDetailRepository groupDetailRepository, ImportPatientItemRepository importPatientItemRepository, ShareParamCostRepository shareParamCostRepository, ShareParamCostDetailRepository shareParamCostDetailRepository, CostDepartmentProfitRepository costDepartmentProfitRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ComputeShareParamRepository computeShareParamRepository, ItemRepository itemRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputePatientProjectCostRepository computePatientProjectCostRepository, ComputePatientProjectCostDetailRepository computePatientProjectCostDetailRepository, ComputePatientProjectGroupCostDetailRepository computePatientProjectGroupCostDetailRepository, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandProjectCostRepository standProjectCostRepository, ComputeStandProjectCostDetailRepository standProjectCostDetailRepository, ComputeStandProjectGroupCostDetailRepository standProjectGroupCostDetailRepository, ComputeStandPatientProjectCostRepository computeStandPatientProjectCostRepository, ComputeStandPatientProjectCostDetailRepository computeStandPatientProjectCostDetailRepository, ComputeStandPatientProjectGroupCostDetailRepository computeStandPatientProjectGroupCostDetailRepository) {
         this.responsibilityRepository = responsibilityRepository;
         this.repository = repository;
         this.sqlService = sqlService;
@@ -127,6 +130,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
         this.computeStandPatientProjectCostRepository = computeStandPatientProjectCostRepository;
         this.computeStandPatientProjectCostDetailRepository = computeStandPatientProjectCostDetailRepository;
         this.computeStandPatientProjectGroupCostDetailRepository = computeStandPatientProjectGroupCostDetailRepository;
+        this.responsibilityDepartmentService=responsibilityDepartmentService;
     }
 
     /**
@@ -254,7 +258,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
     @Override
     public void computeItemCost(String computeDate){
         //项目成本分摊计算
-        computeItemCostACtion(computeDate);
+        calcItemCostAllocation(computeDate);
         log.info("项目成本分摊计算完成开始执行后续处理脚本");
         //执行后续处理脚本
         execItemCostSQL(computeDate);
@@ -425,6 +429,294 @@ public class ProjectCostServiceImpl implements ProjectCostService {
         }
     }
 
+    /**
+     * 项目成本分摊计算
+     * @param computeDate
+     */
+    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
+    public void calcItemCostAllocation(String computeDate) {
+        SessionUserVO currentUser = UserContext.getCurrentUser();
+        //获取收费项目数据(项目)
+        checkImportItem(computeDate, currentUser);
+        //判断是否进行过分摊参数计算
+        long shareCount = computeShareParamRepository.getComputeShareParamCount(computeDate);
+        if (shareCount == 0) {
+            throw new CostException("未进行项目分摊参数计算,请先进行项目分摊参数计算,当前计算中止");
+        }
+        //医疗服务项目字典
+        List<Item> itemList = itemRepository.getList();
+        if (CollectionUtils.isEmpty(itemList)) {
+            throw new CostException("医疗服务项目未维护,请先添加医疗服务项目再进行计算,当前计算中止");
+        }
+        //月度患者收费项目信息
+        List<PatientItemDepartmentGroupVo> ptChargeItems = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
+        if (CollectionUtils.isEmpty(ptChargeItems)){
+            throw new CostException("没有可计算的收费项目");
+        }
+
+        //项目成本分摊配置
+        List<ShareParamCostVo> shareParamCostVos = shareParamCostRepository.getParamCost();
+        if (CollectionUtils.isEmpty(shareParamCostVos)){
+            throw new CostException("没有项目分摊配置信息无法分摊,请联系管理员");
+        }
+
+        //作废上次计算记录
+        repository.removeByComputeDate(computeDate, currentUser);
+        detailRepository.removeByComputeDate(computeDate, currentUser);
+        groupDetailRepository.removeByComputeDate(computeDate, currentUser);
+
+        //项目成本分摊配置主表信息(项目成本列配置)
+        List<ShareParamCost> ShareParamCosts = shareParamCostRepository.getList(null);
+        //科室责任中心对照信息
+        List<ResponsibilityDepartIdVO> responsibilityDeptMaps = responsibilityDepartmentService.getResponsibilityDepart();
+        //分摊参数信息
+        List<ComputeShareParamDetailVo> computeShareParamDetails = computeShareParamRepository.getComputeShareParamDetail(computeDate);
+        //分摊参数按责任中心汇总信息
+        List<ComputeShareParamDetailVo> computeShareParamDetailGroup = computeShareParamRepository.getComputeShareParamDetailGroup(computeDate);
+        //要计算的科室收费项目
+        List<ComputeShareParamDetailVo> computeResponsibilityItems = computeShareParamRepository.getComputeResponsibilityItem(computeDate);
+        //获取科室损益报表数据
+        List<CostDepartmentProfit> costDepartmentProfits = costDepartmentProfitRepository.getDepartmentProfit(computeDate);
+
+        //开始项目成本分摊计算
+        List<ComputeProjectCost> computeProjectCosts=new ArrayList<>();
+        List<ComputeProjectCostDetail> computeProjectCostDetails=new ArrayList<>();
+        List<ComputeProjectGroupCostDetail> computeProjectGroupCostDetails=new ArrayList<>();
+        //获取项目收入对应的分摊参数配置
+        ShareParamTypeMap incomeShareParam = getIncomeShareParamTypeMap();
+        //按项目类别+责任中心代码+项目代码逐个计算项目分摊金额
+        computeResponsibilityItems.stream().forEach(responsibilityItem->{
+            //创建项目成本主表对象
+            ComputeProjectCost projectCost = createComputeProjectCost(computeDate, currentUser, responsibilityItem);
+            computeProjectCosts.add(projectCost);
+            //获取项目对应分摊参数数值
+            List<ComputeShareParamDetailVo> itemShareParams = computeShareParamDetails.stream().filter(shareParamGroup -> shareParamGroup.getResponsibilityCode().equals(projectCost.getResponsibilityCode())
+                    && shareParamGroup.getCode().equals(projectCost.getCode()) && shareParamGroup.getItemType().equals(projectCost.getItemType())).collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(itemShareParams)){
+                throw new CostException(String.format("找不到项目的[%s-%s]对应的分摊分摊参数,请重新计算分摊参数",projectCost.getItemType(),projectCost.getName()));
+            }
+            //取项目对应的分摊配置
+            List<ShareParamCost> itemShareParamCost = ShareParamCosts.stream().filter(shareParamCost -> shareParamCost.getItemType().equals(projectCost.getItemType())).collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(itemShareParamCost)){
+                throw new CostException(String.format("类型[%s]没有对应分摊配置,请联系管理员",projectCost.getItemType()));
+            }
+            List<ComputeProjectCostDetail> computeProjectCostDetailChilds=new ArrayList<>();
+            //按项目分摊配置计算项目的所有项目成本列的分摊金额
+            itemShareParamCost.stream().forEach(shareParamCost->{
+                ComputeProjectCostDetail cmputeProjectCostDetail=createComputeProjectCostDetail(computeDate, currentUser,incomeShareParam,responsibilityItem,projectCost,
+                        shareParamCost,shareParamCostVos,itemShareParams,computeShareParamDetailGroup,costDepartmentProfits);
+                computeProjectCostDetailChilds.add(cmputeProjectCostDetail);
+            });
+            computeProjectCostDetails.addAll(computeProjectCostDetailChilds);
+
+            //按项目成本列类型汇总数据
+            Map<String, BigDecimal> columnTypeGroup = computeProjectCostDetailChilds.stream().collect(Collectors.groupingBy(ComputeProjectCostDetail::getCostColumnType,
+                    Collectors.mapping(ComputeProjectCostDetail::getComputeResult, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+            columnTypeGroup.forEach((columnType, computeResult) -> {
+                //创建项目成本汇总表对象
+                ComputeProjectGroupCostDetail computeProjectGroupCostDetail = createComputeProjectGroupCostDetail(computeDate, currentUser, responsibilityItem, projectCost, columnType, computeResult);
+                computeProjectGroupCostDetails.add(computeProjectGroupCostDetail);
+            });
+            //所有成本列汇总的金额就是项目成本
+            BigDecimal itemCost = computeProjectCostDetailChilds.stream().map(ComputeProjectCostDetail::getComputeResult).reduce(BigDecimal.ZERO, BigDecimal::add);
+            //创建项目成本列的汇总表对象
+            ComputeProjectGroupCostDetail itemCostGroupDetail = createComputeProjectGroupCostDetail(computeDate, currentUser, responsibilityItem, projectCost, ITEM_COST.getCode(), itemCost);
+            computeProjectGroupCostDetails.add(itemCostGroupDetail);
+        });
+
+        //没有任何可保存的数据
+        if (CollectionUtils.isEmpty(computeProjectCosts)) {
+            throw new CostException("没有任何可保存的数据");
+        }
+        //保存项目分摊主表对象数据
+        repository.saveBatch(computeProjectCosts, 500);
+        if (!CollectionUtils.isEmpty(computeProjectCostDetails)) {
+            //保存项目分摊明细表对象数据
+            computeProjectCostDetails.stream().forEach(projectCostDetail->projectCostDetail.setProjectCostId(projectCostDetail.getComputeProjectCost().getId()));
+            detailRepository.saveBatch(computeProjectCostDetails, 500);
+        }
+        if (!CollectionUtils.isEmpty(computeProjectGroupCostDetails)) {
+            //保存项目分摊汇总表对象数据
+            computeProjectGroupCostDetails.stream().forEach(projectCostDetail->projectCostDetail.setProjectCostId(projectCostDetail.getComputeProjectCost().getId()));
+            groupDetailRepository.saveBatch(computeProjectGroupCostDetails, 500);
+        }
+
+
+
+    }
+
+    /**
+     * 获取项目收入对应的分摊参数配置
+     * @return
+     */
+    public ShareParamTypeMap getIncomeShareParamTypeMap(){
+        //分摊参数设置信息
+        List<ShareParamTypeMap> shareParamTypeMaps = shareParamTypeMapRepository.getList();
+        if(CollectionUtils.isEmpty(shareParamTypeMaps)){
+            throw new CostException("没有分摊参数配置信息无法进行项目分摊计算");
+        }
+        Optional<ShareParamTypeMap> firstShareParamTypeMap = shareParamTypeMaps.stream().filter(shareParam -> shareParam.getSourceCode().equals(ITEM_INCOME.getCode())).findFirst();
+        if(!firstShareParamTypeMap.isPresent()){
+            throw new CostException("没有配置项目收入的分摊参数无法进行项目分摊计算");
+        }
+        return  firstShareParamTypeMap.get();
+    }
+
+    /**
+     * 创建项目成本主表对象
+     * @param computeDate
+     * @param currentUser
+     * @param responsibilityItem
+     * @return
+     */
+    public ComputeProjectCost createComputeProjectCost(String computeDate,SessionUserVO currentUser,ComputeShareParamDetailVo responsibilityItem){
+        //主表公共对象
+        ComputeProjectCost computeProjectCost = new ComputeProjectCost();
+        computeProjectCost.setComputeDate(computeDate);
+        computeProjectCost.setHospId(currentUser.getHospId());
+        computeProjectCost.setCreateUser(String.valueOf(currentUser.getId()));
+        computeProjectCost.setCreateTime(new Date());
+        computeProjectCost.setCode(responsibilityItem.getCode());
+        computeProjectCost.setName(responsibilityItem.getName());
+        computeProjectCost.setItemType(responsibilityItem.getItemType());
+        computeProjectCost.setResponsibilityCode(responsibilityItem.getResponsibilityCode());
+        computeProjectCost.setResponsibilityName(responsibilityItem.getResponsibilityName());
+        return computeProjectCost;
+    }
+
+    /**
+     * 创建项目成本明细表对象
+     * @param computeDate 核算年月
+     * @param currentUser 登录人信息
+     * @param responsibilityItem 责任中心的项目汇总数据
+     * @param computeProjectCost 主表对象
+     * @param shareParamCost 分摊配置主表
+     * @param shareParamCostVos 分摊配置明细
+     * @param computeShareParamDetails 分摊参数计算明细
+     * @param computeShareParamDetailGroup 分摊参数计算明细汇总
+     * @param costDepartmentProfits 科室损益数据
+     * @return
+     */
+    public ComputeProjectCostDetail createComputeProjectCostDetail(String computeDate,SessionUserVO currentUser,ShareParamTypeMap incomeShareParam,ComputeShareParamDetailVo responsibilityItem,ComputeProjectCost computeProjectCost,ShareParamCost shareParamCost,
+                                                                   List<ShareParamCostVo> shareParamCostVos,List<ComputeShareParamDetailVo> computeShareParamDetails ,
+                                                                   List<ComputeShareParamDetailVo> computeShareParamDetailGroup,List<CostDepartmentProfit> costDepartmentProfits){
+        //明细表公共对象
+        ComputeProjectCostDetail costDetail = new ComputeProjectCostDetail();
+        costDetail.setComputeDate(computeDate);
+        costDetail.setHospId(currentUser.getHospId());
+        costDetail.setCreateUser(String.valueOf(currentUser.getId()));
+        costDetail.setCreateTime(new Date());
+        costDetail.setComputeProjectCost(computeProjectCost);
+        costDetail.setCostColumnCode(shareParamCost.getColumnCode());
+        costDetail.setCostColumnType(shareParamCost.getColumnType());
+        //获取对应分摊配置明细
+        List<ShareParamCostVo> shareParamDetails = shareParamCostVos.stream().filter(shareParamDetail -> shareParamDetail.getColumnCode().equals(shareParamCost.getColumnCode())).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(shareParamDetails)){
+            throw new CostException(String.format("[%s]没有对应分摊配置,请联系管理员",shareParamCost.getColumnName()));
+        }
+        //根据主表配置找到对应的科室损益数据
+        Optional<CostDepartmentProfit> firstDepartmentProfit = costDepartmentProfits.stream().filter(departmentProfit -> String.valueOf(departmentProfit.getShareType()).equals(shareParamCost.getReportType()) &&
+                String.valueOf(departmentProfit.getReportNum()).equals(shareParamCost.getProfitNum()) &&
+                departmentProfit.getResponsibilityCode().equals(computeProjectCost.getResponsibilityCode())).findFirst();
+        //没有对应的损益项目数据或者损益项目金额为0
+        if(!firstDepartmentProfit.isPresent()||firstDepartmentProfit.get().getAmount().equals(BigDecimal.ZERO)){
+            costDetail.setComputeResult(BigDecimal.ZERO);
+            costDetail.setComputeSingleResult(BigDecimal.ZERO);
+            return costDetail;
+        }
+        //按项目分摊配置计算项目的一个项目成本列的分摊金额
+        BigDecimal itemAllocationAmount=calcItemAllocationAmount(incomeShareParam,computeProjectCost,firstDepartmentProfit.get(),
+                shareParamDetails,computeShareParamDetailGroup,computeShareParamDetails);
+        costDetail.setComputeResult(itemAllocationAmount);
+        //项目没有数量时,单个项目的分摊金额为0
+        if(responsibilityItem.getNum().compareTo(BigDecimal.ZERO)==NumberConstant.ZERO){
+            costDetail.setComputeSingleResult(BigDecimal.ZERO);
+        }else{
+            //有数量数,单个项目的分摊金额=总分摊金额/数量
+            costDetail.setComputeSingleResult(itemAllocationAmount.divide(responsibilityItem.getNum(),NumberConstant.FOUR,RoundingMode.HALF_UP));
+        }
+        return costDetail;
+    }
+
+    /**
+     * 计算项目的分摊金额
+     * @param computeProjectCost 主表对象
+     * @param costDepartmentProfit 科室损益数据
+     * @param shareParamCostVos 分摊配置明细
+     * @param computeShareParamDetailGroup 分摊参数计算明细汇总
+     * @param computeShareParamDetails 分摊参数计算明细
+     * @return
+     */
+    public  BigDecimal calcItemAllocationAmount(ShareParamTypeMap incomeShareParam,ComputeProjectCost computeProjectCost,CostDepartmentProfit costDepartmentProfit,List<ShareParamCostVo> shareParamCostVos,
+                                                List<ComputeShareParamDetailVo> computeShareParamDetailGroup,List<ComputeShareParamDetailVo> computeShareParamDetails){
+        BigDecimal itemAllocationAmount=BigDecimal.ZERO;
+        //按配置计算每个参数分摊金额
+        for (ShareParamCostVo shareParamCostVo : shareParamCostVos) {//获取参数对应的责任中心汇总数据
+            Optional<ComputeShareParamDetailVo> firstShareParamGroup = computeShareParamDetailGroup.stream().filter(shareParamGroup -> shareParamGroup.getItemType().equals(computeProjectCost.getItemType()) &&
+                    shareParamGroup.getResponsibilityCode().equals(computeProjectCost.getResponsibilityCode()) && shareParamGroup.getShareParamCode().equals(shareParamCostVo.getShareParamCode())).findFirst();
+            //责任中心的汇总数据为0时,按项目收入分摊
+            if (!firstShareParamGroup.isPresent() || firstShareParamGroup.get().getComputeResult().compareTo(BigDecimal.ZERO) == NumberConstant.ZERO) {
+                //获取项目对应的收入数据
+                Optional<ComputeShareParamDetailVo> firstComputeShareParamDetail = computeShareParamDetails.stream().filter(computeShareParamDetailVo ->
+                        computeShareParamDetailVo.getShareParamCode().equals(incomeShareParam.getShareParamCode())).findFirst();
+                if (!firstComputeShareParamDetail.isPresent()) {
+                    throw new CostException(String.format("[%s-%s]没有收入数据无法分摊,请检查对应的收费项目数据及分摊参数计算结果数据", computeProjectCost.getResponsibilityName(), computeProjectCost.getName()));
+                }
+                //找到项目收入的责任中心汇总数据
+                ComputeShareParamDetailVo incomeShareParamGroup = computeShareParamDetailGroup.stream().filter(shareParamGroup -> shareParamGroup.getItemType().equals(computeProjectCost.getItemType()) &&
+                        shareParamGroup.getResponsibilityCode().equals(computeProjectCost.getResponsibilityCode()) && shareParamGroup.getShareParamCode().equals(incomeShareParam.getShareParamCode())).findFirst().get();
+                //分摊金额=损益项目金额*分摊参数占比*收入/责任中心总收入
+                BigDecimal paramAllocationAmount = costDepartmentProfit.getAmount().multiply(shareParamCostVo.getPercent()).multiply(firstComputeShareParamDetail.get().getComputeResult())
+                        .divide(incomeShareParamGroup.getComputeResult(), NumberConstant.FOUR, RoundingMode.HALF_UP);
+                itemAllocationAmount = itemAllocationAmount.add(paramAllocationAmount);
+            } else {
+                //获取项目对应的分摊参数数据
+                Optional<ComputeShareParamDetailVo> firstComputeShareParamDetail = computeShareParamDetails.stream().filter(computeShareParamDetailVo ->
+                        computeShareParamDetailVo.getShareParamCode().equals(shareParamCostVo.getShareParamCode())).findFirst();
+                if (!firstComputeShareParamDetail.isPresent()) {
+                    throw new CostException(String.format("[%s-%s]没有收入数据无法分摊,请检查对应的收费项目数据", computeProjectCost.getResponsibilityName(), computeProjectCost.getName()));
+                }
+                //分摊金额=损益项目金额*分摊参数占比*分摊参数数值/责任中心总分摊参数数值
+                BigDecimal paramAllocationAmount = costDepartmentProfit.getAmount().multiply(shareParamCostVo.getPercent()).multiply(firstComputeShareParamDetail.get().getComputeResult())
+                        .divide(firstShareParamGroup.get().getComputeResult(), NumberConstant.FOUR, RoundingMode.HALF_UP);
+                itemAllocationAmount = itemAllocationAmount.add(paramAllocationAmount);
+            }
+        }
+        return  itemAllocationAmount;
+    }
+
+    /**
+     * 创建项目成本汇总表对象
+     * @param computeDate
+     * @param currentUser
+     * @param responsibilityItem
+     * @param computeProjectCost
+     * @param columnType
+     * @param computeResultGroup
+     * @return
+     */
+    public ComputeProjectGroupCostDetail createComputeProjectGroupCostDetail(String computeDate,SessionUserVO currentUser,
+                                                                             ComputeShareParamDetailVo responsibilityItem,ComputeProjectCost computeProjectCost,
+                                                                             String columnType,BigDecimal computeResultGroup){
+        //汇总明细表对象
+        ComputeProjectGroupCostDetail groupCostDetail = new ComputeProjectGroupCostDetail();
+        groupCostDetail.setComputeDate(computeDate);
+        groupCostDetail.setHospId(currentUser.getHospId());
+        groupCostDetail.setCreateUser(String.valueOf(currentUser.getId()));
+        groupCostDetail.setCreateTime(new Date());
+        groupCostDetail.setComputeProjectCost(computeProjectCost);
+        groupCostDetail.setType(columnType);
+        groupCostDetail.setComputeResult(computeResultGroup);
+        //项目没有数量时,单个项目的分摊金额为0
+        if(responsibilityItem.getNum().compareTo(BigDecimal.ZERO)==NumberConstant.ZERO){
+            groupCostDetail.setComputeSingleResult(BigDecimal.ZERO);
+        }else{
+            //有数量时,单个项目的金额=总金额/数量
+            groupCostDetail.setComputeSingleResult(computeResultGroup.divide(responsibilityItem.getNum(),NumberConstant.FOUR,RoundingMode.HALF_UP));
+        }
+        return groupCostDetail;
+    }
+
     /**
      * 执行项目成本计算后续处理SQL
      * @param computeDate

+ 38 - 0
src/main/java/com/kcim/service/impl/ResponsibilityDepartmentServiceImpl.java

@@ -14,13 +14,17 @@ import com.kcim.service.CenterService;
 import com.kcim.service.ResponsibilityDepartmentService;
 import com.kcim.service.ResponsibilityService;
 import com.kcim.vo.CenterDepartmentVO;
+import com.kcim.vo.ResponsibilityDepartIdVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -89,4 +93,38 @@ public class ResponsibilityDepartmentServiceImpl
     }
 
 
+    /**
+     * 获取责任中心科室对照信息
+     * @return
+     */
+    @Override
+    public List<ResponsibilityDepartIdVO> getResponsibilityDepart(){
+        Long hospId = UserContext.getHospId();
+        //获取责任中心科室对照信息
+        List<ResponsibilityDepartIdVO> responsibilityDepartIdVOS = baseMapper.getResponsibility(hospId);
+        if(CollectionUtils.isEmpty(responsibilityDepartIdVOS))
+        {
+            responsibilityDepartIdVOS=new ArrayList<>();
+            return  responsibilityDepartIdVOS;
+        }
+        //获取对照的科室字典
+        List<SysDepartment> departmentByDepartmentIds =centerService.getDepartmentFilter(null);
+        if(CollectionUtils.isEmpty(departmentByDepartmentIds))
+        {
+            return  responsibilityDepartIdVOS;
+        }
+        //组装科室代码和科室名称
+        responsibilityDepartIdVOS.stream().forEach(responsibilityDepartIdVO -> {
+            Optional<SysDepartment> firstDepartment = departmentByDepartmentIds.stream().filter(sysDepartment ->Long.valueOf(sysDepartment.getId()).equals(responsibilityDepartIdVO.getDepartmentId())).findFirst();
+            if(firstDepartment.isPresent()){
+                responsibilityDepartIdVO.setDepartmentCode(firstDepartment.get().getCode());
+                responsibilityDepartIdVO.setDepartmentName(firstDepartment.get().getName());
+            }
+        });
+        //只取有对应科室数据的记录
+        List<ResponsibilityDepartIdVO> activeResponsibilityDeparts = responsibilityDepartIdVOS.stream().filter(responsibilityDepartIdVO -> !Objects.isNull(responsibilityDepartIdVO.getDepartmentCode())).collect(Collectors.toList());
+        return  activeResponsibilityDeparts;
+    }
+
+
 }

+ 13 - 11
src/main/java/com/kcim/service/impl/ShareParamServiceImpl.java

@@ -13,10 +13,7 @@ import com.kcim.common.util.UserContext;
 import com.kcim.dao.model.*;
 import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
 import com.kcim.dao.repository.*;
-import com.kcim.service.CenterService;
-import com.kcim.service.ShareParamService;
-import com.kcim.service.SqlService;
-import com.kcim.service.StandItemService;
+import com.kcim.service.*;
 import com.kcim.vo.*;
 import com.kcim.web.reponse.ShareParamCostResponse;
 import lombok.extern.slf4j.Slf4j;
@@ -76,8 +73,9 @@ public class ShareParamServiceImpl implements ShareParamService {
 
     StandItemService standItemService;
     SqlService sqlService;
+    ResponsibilityDepartmentService  responsibilityDepartmentService;
 
-    public ShareParamServiceImpl(ComputeShareParamRepository repository, ComputeShareParamDetailRepository detailRepository, ImportPatientItemRepository importPatientItemRepository, ItemRepository itemRepository, ItemEmpMapRepository itemEmpMapRepository, ItemEquipmentMapRepository itemEquipmentMapRepository, ItemSpaceMapRepository itemSpaceMapRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandShareParamDetailRepository computeStandShareParamDetailRepository, StandItemService standItemService,SqlService sqlService) {
+    public ShareParamServiceImpl(ComputeShareParamRepository repository, ComputeShareParamDetailRepository detailRepository, ImportPatientItemRepository importPatientItemRepository, ItemRepository itemRepository, ItemEmpMapRepository itemEmpMapRepository, ItemEquipmentMapRepository itemEquipmentMapRepository, ItemSpaceMapRepository itemSpaceMapRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandShareParamDetailRepository computeStandShareParamDetailRepository, StandItemService standItemService,SqlService sqlService,ResponsibilityDepartmentService  responsibilityDepartmentService) {
         this.repository = repository;
         this.detailRepository = detailRepository;
         this.importPatientItemRepository = importPatientItemRepository;
@@ -92,6 +90,7 @@ public class ShareParamServiceImpl implements ShareParamService {
         this.computeStandShareParamDetailRepository = computeStandShareParamDetailRepository;
         this.standItemService = standItemService;
         this.sqlService=sqlService;
+        this.responsibilityDepartmentService=responsibilityDepartmentService;
     }
 
     /**
@@ -254,12 +253,12 @@ public class ShareParamServiceImpl implements ShareParamService {
         //医疗服务项目的使用空间信息
         List<ItemSpaceMap> itemSpaceMaps = itemSpaceMapRepository.getList();
         //科室责任中心对照信息
-        List<ResponsibilityDepartIdVO> responsibilityDeptMaps = responsibilityDepartmentRepository.getResponsibility(currentUser.getHospId());
+        List<ResponsibilityDepartIdVO> responsibilityDeptMaps = responsibilityDepartmentService.getResponsibilityDepart();
         //分摊参数设置信息
         List<ShareParamTypeMap> shareParamTypeMaps = shareParamTypeMapRepository.getList();
         //医疗服务项目分类字典
         DictDataVo itemTypeDict = centerService.getDict(Constant.MED_SERVICE_ITEM_TYPE);
-        //月度患者收费项目信息
+        //月度患者收费项目信息(按执行科室+收费项目代码汇总过)
         List<PatientItemDepartmentGroupVo> ptChargeItems = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
         if (CollectionUtils.isEmpty(ptChargeItems)){
             throw new CostException("没有可计算的收费项目");
@@ -352,15 +351,18 @@ public class ShareParamServiceImpl implements ShareParamService {
         computeShareCost.setName(ptItem.getItemName());
         computeShareCost.setNum(ptItem.getNum());
         //获取执行科室对应的责任中心
-        ResponsibilityDepartIdVO responsibilityDepartIdVO = responsibilityDeptMaps.stream().filter(respDeptmap -> respDeptmap.getDepartmentCode().equals(ptItem.getExecuteDepartmentCode())).findFirst().get();
-        if(Objects.isNull(responsibilityDepartIdVO)){
+        Optional<ResponsibilityDepartIdVO> firstResponsibilityDepartIdVO = responsibilityDeptMaps.stream().filter(respDeptmap -> !Objects.isNull(respDeptmap.getDepartmentCode())&& respDeptmap.getDepartmentCode().equals(ptItem.getExecuteDepartmentCode())).findFirst();
+        if(!firstResponsibilityDepartIdVO.isPresent()){
             String errMsg = String.format("【%s(%s)】没有对应的责任中心,计算中止", ptItem.getExecuteDepartmentName(), ptItem.getExecuteDepartmentCode());
             throw new CostException(errMsg);
         }
+        ResponsibilityDepartIdVO responsibilityDepartIdVO=firstResponsibilityDepartIdVO.get();
         computeShareCost.setResponsibilityCode(responsibilityDepartIdVO.getResponsibilityCode());
         computeShareCost.setResponsibilityName(responsibilityDepartIdVO.getResponsibilityName());
-        computeShareCost.setItemType(getChargeItemType(itemTypeDict,responsibilityDepartIdVO.getShareId()));
+//        computeShareCost.setItemType(getChargeItemType(itemTypeDict,responsibilityDepartIdVO.getShareId()));
+        computeShareCost.setItemType(ptItem.getDicItem().getItemType());
         return computeShareCost;
+
     }
 
     /**
@@ -411,7 +413,7 @@ public class ShareParamServiceImpl implements ShareParamService {
         }else if(shareParamType.getSourceType().equals(NumberConstant.FIVE_S)){
             //计算项目数量的参数值
             BigDecimal computeResult = ptItem.getNum();
-            costDetail.setComputeSingleResult(BigDecimal.ONE);
+            costDetail.setComputeSingleResult(BigDecimal.ONE.setScale(NumberConstant.FOUR, RoundingMode.HALF_UP));
             costDetail.setComputeResult(computeResult);
         }
         costDetail.setComputeShareCost(computeShareCost);

+ 4 - 0
src/main/java/com/kcim/vo/ComputeShareParamDetailVo.java

@@ -14,8 +14,12 @@ import java.math.BigDecimal;
 public class ComputeShareParamDetailVo {
      private String responsibilityCode;
 
+     private String responsibilityName;
+
      private String code;
 
+     private String name;
+
      private String shareParamCode;
 
      private BigDecimal computeResult;

+ 45 - 1
src/main/resources/mapper/ComputeShareParamMapper.xml

@@ -78,10 +78,35 @@
     <select id="getComputeShareParamDetail" resultType="com.kcim.vo.ComputeShareParamDetailVo">
         SELECT
             a.item_type,
-
             a.responsibility_code,
+            a.`responsibility_name`,
             sum(a.num) as num,
             a.`code`,
+            a.`name`,
+            b.share_param_code,
+            sum(b.compute_result) as compute_result,
+            sum(b.compute_single_result) as compute_single_result
+        FROM
+            compute_share_param a
+                LEFT JOIN compute_share_param_detail b ON a.id = b.share_param_id
+                AND b.del_flag = 0
+        WHERE
+            a.compute_date = #{computeDate,jdbcType=VARCHAR}
+          AND b.compute_date = #{computeDate,jdbcType=VARCHAR}
+          AND a.del_flag = 0
+          AND b.hosp_id = #{hospId,jdbcType=BIGINT}
+          AND a.hosp_id = #{hospId,jdbcType=BIGINT}
+        GROUP BY
+            a.responsibility_code,
+            b.share_param_code,
+            a.`code`,a.item_type
+    </select>
+
+    <select id="getComputeShareParamDetailGroup" resultType="com.kcim.vo.ComputeShareParamDetailVo">
+        SELECT
+            a.item_type,
+            a.responsibility_code,
+            sum(a.num) as num,
             b.share_param_code,
             sum(b.compute_result) as compute_result,
             sum(b.compute_single_result) as compute_single_result
@@ -98,6 +123,25 @@
         GROUP BY
             a.responsibility_code,
             b.share_param_code,
+            a.item_type
+    </select>
+
+    <select id="getComputeResponsibilityItem" resultType="com.kcim.vo.ComputeShareParamDetailVo">
+        SELECT
+            a.item_type,
+            a.responsibility_code,
+            a.`responsibility_name`,
+            sum(a.num) as num,
+            a.`code`,
+            a.`name`
+        FROM
+            compute_share_param a
+        WHERE
+            a.compute_date = #{computeDate,jdbcType=VARCHAR}
+          AND a.del_flag = 0
+          AND a.hosp_id = #{hospId,jdbcType=BIGINT}
+        GROUP BY
+            a.responsibility_code,
             a.`code`,a.item_type
     </select>
 

+ 3 - 8
src/main/resources/mapper/ResponsibilityDepartmentMapper.xml

@@ -22,8 +22,6 @@
     <select id="getResponsibility" resultType="com.kcim.vo.ResponsibilityDepartIdVO">
         SELECT
             b.department_id,
-            c.`code` AS department_code,
-            c.`name` AS department_name,
             b.responsibility_id,
             a.responsibility_code,
             a.responsibility_name,
@@ -31,12 +29,9 @@
             a.share_id
         FROM
             cost_responsibility a
-            INNER JOIN cost_responsibility_department b ON a.id = b.responsibility_id
-            AND b.delete_time = 0
-            AND b.hosp_id = #{hospId}
-            INNER JOIN pfm_center.sys_department c ON b.department_id = c.id
-            AND c.del_flag = 0
-            AND c.hosp_id = #{hospId}
+                INNER JOIN cost_responsibility_department b ON a.id = b.responsibility_id
+                AND b.delete_time = 0
+                AND b.hosp_id = #{hospId}
         WHERE
             a.hosp_id = #{hospId}
           AND a.delete_time = 0