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