package com.kcim.service.impl; import com.kcim.common.constants.NumberConstant; import com.kcim.common.exception.CostException; import com.kcim.common.util.BeanUtil; import com.kcim.common.util.SnowflakeUtil; import com.kcim.common.util.UserContext; import com.kcim.dao.model.CostCostingGroup; import com.kcim.dao.model.FreeCostMap; import com.kcim.dao.model.ShareParamValue; import com.kcim.dao.repository.*; import com.kcim.service.FreeCostService; import com.kcim.service.ResponsibilityService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; /** * @program: CostAccount * @description: * @author: Wang.YS * @create: 2024-04-03 14:19 **/ @Service("FreeCostService") @Slf4j @AllArgsConstructor public class FreeCostServiceImpl implements FreeCostService { FreeCostMapRepository repository; AccountingRepository accountingRepository; CostShareParamRepository costShareParamRepository; CostCostingGroupRepository costCostingGroupRepository; ShareParamValueRepository shareParamValueRepository; ResponsibilityService responsibilityService; @Override public Object getList(String filter) { return repository.getList(filter); } /** * @param freeCostMap * @return */ @Override public void addFreeCost(FreeCostMap freeCostMap) { freeCostMap.setHospId(UserContext.getHospId()); freeCostMap.setCreateTime(new Date()); freeCostMap.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId())); repository.save(freeCostMap); } /** * @param freeCostMap */ @Override public void editFreeCost(FreeCostMap freeCostMap) { Integer id = freeCostMap.getId(); if (id == null) { throw new CostException("编辑时主键必填"); } FreeCostMap costMap = repository.getById(id); BeanUtil.convertObj(freeCostMap, costMap); costMap.setUpdateTime(new Date()); costMap.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId())); repository.updateById(costMap); } /** * @param id */ @Override public void deleteFreeCost(Integer id) { if (id == null) { throw new CostException("删除时主键必填"); } FreeCostMap costMap = repository.getById(id); costMap.setDeleteTime(new Date()); costMap.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId())); repository.updateById(costMap); repository.removeById(id); } @Override public Object getAccountList(String filter) { return accountingRepository.getBaseCostList(filter); } @Override public Object getShareParamList(String filter) { return costShareParamRepository.getList(filter); } @Override public void computeFreeCost(String computeDate) { /* 1 查询导入的成本数据 有 计算 无退出 2 通过闲置成本配置表找到对应成本项目数据 其他不计算 3 判断找到的闲置成本项目是否在当月已计算过 计算过合计需相加 未计算 取原成本项目 4 总额=闲置成本项目金额+设备成本项目金额 5 设备负荷系数=实际检查时间参数数值/可检查时间参数数值 6 设备成本项目金额=总额*设备负荷系数 7 闲置成本项目金额=总额-设备成本项目金额 8 未计算过 原数据更新 闲置成本添加 已计算过所有数据更新 9 原数据进行拆分更新 */ List list = costCostingGroupRepository.getList(computeDate); if (CollectionUtils.isEmpty(list)) { //成本数据未导入 throw new CostException("未导入成本数据,无法计算闲置成本"); } //获取所有闲置成本配置 List freeCostMaps = repository.getList(null); if (CollectionUtils.isEmpty(freeCostMaps)) { throw new CostException("未进行闲置成本对照,无法计算闲置成本"); } List shareParamValues = shareParamValueRepository.getList(computeDate); Map> shareParamValueMap = new HashMap<>(); if (!CollectionUtils.isEmpty(shareParamValues)) { Map> collect = shareParamValues.stream().collect(Collectors.groupingBy(ShareParamValue::getResponsibilityCode)); for (String s : collect.keySet()) { List shareParamValues1 = collect.get(s); Map map = shareParamValues1.stream().collect(Collectors.toMap(ShareParamValue::getShareParamCode, ShareParamValue::getValueNum, (a, b) -> b)); shareParamValueMap.put(s, map); } } //对照的会计科目为主键获取负荷系数 //提取所有设置成本 项目code List accountCodes = freeCostMaps.stream().map(FreeCostMap::getAccountCode).collect(Collectors.toList()); List collect = list.stream().filter(f -> f.getComputeType().equals(NumberConstant.ONE)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(collect)) { //已计算过 需要多一步处理原数据和现数据加起来计算总额 //上次计算过的数据 List lastCompute = list.stream().filter(f -> f.getComputeConnectId() != null).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(lastCompute)) { list.removeAll(lastCompute); //其他数据按原未计算过时计算 List collect1 = list.stream().filter(f -> accountCodes.contains(f.getAccountCode())).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(collect1)) { Map> costAccountGroup = collect1.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode)); List saveList = new ArrayList<>(); List updateList = new ArrayList<>(); for (FreeCostMap freeCostMap : freeCostMaps) { List costCostingGroups = costAccountGroup.get(freeCostMap.getAccountCode()); if (!CollectionUtils.isEmpty(costCostingGroups)) { for (CostCostingGroup costCostingGroup : costCostingGroups) { if (!CollectionUtils.isEmpty(shareParamValueMap)) { Map map = shareParamValueMap.get(costCostingGroup.getResponsibilityCode()); if (CollectionUtils.isEmpty(map)) { continue; } //可检查时间参数 BigDecimal can = map.get(freeCostMap.getCanParamCode()); if (can == null||can.compareTo(BigDecimal.ZERO)==0) { continue; } Long id = SnowflakeUtil.getId(); //实际检查时间参数 BigDecimal actual = map.get(freeCostMap.getActualParamCode()); BigDecimal divide = actual.divide(can, 4, RoundingMode.HALF_UP); BigDecimal amount = costCostingGroup.getAmount(); BigDecimal multiply = amount; if(divide.compareTo(BigDecimal.ONE)<0){ multiply = amount.multiply(divide); } CostCostingGroup freeCost = BeanUtil.convertObj(costCostingGroup, CostCostingGroup.class); costCostingGroup.setAmount(multiply); costCostingGroup.setRate(divide); costCostingGroup.setComputeConnectId(id); updateList.add(costCostingGroup); freeCost.setAmount(amount.subtract(multiply)); freeCost.setComputeType(NumberConstant.ONE); freeCost.setComputeConnectId(id); freeCost.setRate(BigDecimal.ONE.subtract(divide)); freeCost.setId(null); freeCost.setAccountCode(freeCostMap.getFreeAccountCode()); freeCost.setAccountName(freeCostMap.getFreeAccountName()); freeCost.setResponsibilityCode(freeCostMap.getFreeResponsibilityCode()); freeCost.setResponsibilityName(freeCostMap.getFreeResponsibilityName()); saveList.add(freeCost); // }else { } } } } if (!CollectionUtils.isEmpty(updateList)) { costCostingGroupRepository.updateBatchById(updateList); } if (!CollectionUtils.isEmpty(saveList)) { costCostingGroupRepository.saveBatch(saveList); } } //已计算过的数据 单独方法处理 Map> lastComputeGroup = lastCompute.stream().collect(Collectors.groupingBy(CostCostingGroup::getComputeConnectId)); //取出合计金额 Map totalMap = new HashMap<>(); for (Long aLong : lastComputeGroup.keySet()) { List costCostingGroups = lastComputeGroup.get(aLong); AtomicReference total = new AtomicReference<>(new BigDecimal("0.0000")); costCostingGroups.forEach(m -> { total.updateAndGet(v -> v.add(m.getAmount())); }); totalMap.put(aLong, total.get()); } Map accountMap = new HashMap<>(); // Map freeAccountMap = new HashMap<>(); freeCostMaps.forEach(freeCostMap -> { accountMap.put(freeCostMap.getAccountCode(), freeCostMap); // freeAccountMap.put(freeCostMap.getAccountCode(), freeCostMap); }); List lastAccount = lastCompute.stream().filter(f -> f.getComputeType().equals(NumberConstant.ZERO)).collect(Collectors.toList()); List lastFreeAccount = lastCompute.stream().filter(f -> f.getComputeType().equals(NumberConstant.ONE)).collect(Collectors.toList()); Map freeAmount = new HashMap<>(); Map freeRate = new HashMap<>(); List lastUpdateList = new ArrayList<>(); for (CostCostingGroup costCostingGroup : lastAccount) { if (!CollectionUtils.isEmpty(shareParamValueMap)) { Map map = shareParamValueMap.get(costCostingGroup.getResponsibilityCode()); if (CollectionUtils.isEmpty(map)) { continue; } FreeCostMap freeCostMap = accountMap.get(costCostingGroup.getAccountCode()); if(Objects.isNull(freeCostMap)){ continue; } //可检查时间参数 BigDecimal can = map.get(freeCostMap.getCanParamCode()); if (can == null||can.compareTo(BigDecimal.ZERO)==0) { continue; } //实际检查时间参数 BigDecimal actual = map.get(freeCostMap.getActualParamCode()); BigDecimal divide = actual.divide(can, 4, RoundingMode.HALF_UP); BigDecimal amount = totalMap.get(costCostingGroup.getComputeConnectId()); BigDecimal multiply = amount; if(divide.compareTo(BigDecimal.ONE)<0){ multiply = amount.multiply(divide); } costCostingGroup.setAmount(multiply); costCostingGroup.setRate(divide); lastUpdateList.add(costCostingGroup); freeAmount.put(costCostingGroup.getComputeConnectId(),amount.subtract(multiply)); freeRate.put(costCostingGroup.getComputeConnectId(),BigDecimal.ONE.subtract(divide)); } } for (CostCostingGroup costCostingGroup : lastFreeAccount) { costCostingGroup.setAmount(freeAmount.get(costCostingGroup.getComputeConnectId())); costCostingGroup.setRate(freeRate.get(costCostingGroup.getComputeConnectId())); lastUpdateList.add(costCostingGroup); } if (!CollectionUtils.isEmpty(lastUpdateList)) { costCostingGroupRepository.updateBatchById(lastUpdateList); } } } else { //未计算过直接到原数据作为总额 //符合条件会计科目的数据 未配置 不计算 List collect1 = list.stream().filter(f -> accountCodes.contains(f.getAccountCode())).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(collect1)) { Map> costAccountGroup = collect1.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode)); List saveList = new ArrayList<>(); List updateList = new ArrayList<>(); for (FreeCostMap freeCostMap : freeCostMaps) { List costCostingGroups = costAccountGroup.get(freeCostMap.getAccountCode()); if (!CollectionUtils.isEmpty(costCostingGroups)) { for (CostCostingGroup costCostingGroup : costCostingGroups) { if (!CollectionUtils.isEmpty(shareParamValueMap)) { Map map = shareParamValueMap.get(costCostingGroup.getResponsibilityCode()); if (CollectionUtils.isEmpty(map)) { continue; } //可检查时间参数 BigDecimal can = map.get(freeCostMap.getCanParamCode()); if (can == null||can.compareTo(BigDecimal.ZERO)==0) { continue; } Long id = SnowflakeUtil.getId(); //实际检查时间参数 BigDecimal actual = map.get(freeCostMap.getActualParamCode()); BigDecimal divide = actual.divide(can, 4, RoundingMode.HALF_UP); BigDecimal amount = costCostingGroup.getAmount(); BigDecimal multiply = amount; if(divide.compareTo(BigDecimal.ONE)<0){ multiply = amount.multiply(divide); } CostCostingGroup freeCost = BeanUtil.convertObj(costCostingGroup, CostCostingGroup.class); costCostingGroup.setAmount(multiply); costCostingGroup.setRate(divide); costCostingGroup.setComputeConnectId(id); updateList.add(costCostingGroup); freeCost.setAmount(amount.subtract(multiply)); freeCost.setComputeType(NumberConstant.ONE); freeCost.setComputeConnectId(id); freeCost.setRate(BigDecimal.ONE.subtract(divide)); freeCost.setId(null); freeCost.setAccountCode(freeCostMap.getFreeAccountCode()); freeCost.setAccountName(freeCostMap.getFreeAccountName()); freeCost.setResponsibilityCode(freeCostMap.getFreeResponsibilityCode()); freeCost.setResponsibilityName(freeCostMap.getFreeResponsibilityName()); saveList.add(freeCost); // }else { } } } } if (!CollectionUtils.isEmpty(updateList)) { costCostingGroupRepository.updateBatchById(updateList); } if (!CollectionUtils.isEmpty(saveList)) { costCostingGroupRepository.saveBatch(saveList); } } } // } @Override public Object getResponsibilityList(String filter) { return responsibilityService.getList(filter); } }