|
@@ -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)
|