123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- package com.kcim.service.impl;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.kcim.common.constants.NumberConstant;
- import com.kcim.common.constants.ParameterConstant;
- import com.kcim.common.constants.RedisKeyConstant;
- import com.kcim.common.enums.EmpCostComputeTypeEnum;
- import com.kcim.common.enums.ItemTypeEnum;
- import com.kcim.common.enums.ReportItemTypeEnum;
- import com.kcim.common.exception.CostException;
- import com.kcim.common.token.RedisUtil;
- import com.kcim.common.util.BeanUtil;
- import com.kcim.common.util.PageUtils;
- import com.kcim.dao.model.*;
- import com.kcim.dao.model.dto.ComputeItemCostPageDto;
- import com.kcim.dao.repository.*;
- import com.kcim.service.CenterService;
- import com.kcim.service.ComputeItemCostService;
- import com.kcim.vo.CommonParameterVo;
- import com.kcim.vo.SessionUserVO;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.jdbc.datasource.DataSourceTransactionManager;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.TransactionDefinition;
- import org.springframework.transaction.annotation.Isolation;
- import org.springframework.transaction.annotation.Propagation;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.CollectionUtils;
- import org.springframework.web.context.request.RequestAttributes;
- import org.springframework.web.context.request.RequestContextHolder;
- import javax.sql.DataSource;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * @program: CostAccount
- * @description: 收费项目成本计算接口实现类
- * @author: Wang.YS
- * @create: 2023-10-25 14:39
- **/
- @Service("ComputeItemCostService")
- @Slf4j
- @AllArgsConstructor
- public class ComputeItemCostServiceImpl implements ComputeItemCostService {
- /**
- * 项目成本计算主表
- */
- ComputeItemCostRepository repository;
- /**
- * 项目成本计算明细表
- */
- ComputeItemCostDetailRepository detailRepository;
- /**
- * 项目导入数据
- */
- ImportPatientItemRepository importPatientItemRepository;
- /**
- * 人事成本计算数据
- */
- ComputeEmpCostRepository computeEmpCostRepository;
- /**
- * 药品成本
- */
- DrugRepository drugRepository;
- /**
- * 材料成本
- */
- MaterialRepository materialRepository;
- /**
- * 设备字典
- */
- EquipmentRepository equipmentRepository;
- /**
- * 空间字典
- */
- SpaceRepository spaceRepository;
- /**
- * 标准项目字典
- */
- StandItemRepository standItemRepository;
- /**
- * 标准项目与人员对照
- */
- StandItemEmpMapRepository standItemEmpMapRepository;
- /**
- * 标准项目与设备对照
- */
- StandItemEquipmentMapRepository standItemEquipmentMapRepository;
- /**
- * 标准项目与空间对照
- */
- StandItemSpaceMapRepository standItemSpaceMapRepository;
- /**
- * 人事分类字典
- */
- EmpCostTypeRepository empCostTypeRepository;
- /**
- * 人事分类人员对照
- */
- EmpCostMapRepository empCostMapRepository;
- /**
- * 收费项目管理
- */
- ItemRepository itemRepository;
- CenterService centerService;
- DataSourceTransactionManager dataSourceTransactionManager;
- TransactionDefinition transactionDefinition;
- DataSource dataSource;
- RedisUtil redisUtil;
- private static final Integer LIMIT = 1000;
- /**
- * 成本核算-收费项目成本计算-获取列表
- *
- * @param current 当前页
- * @param pageSize 页容量
- * @param computeDate 核算年月
- * @param itemType 项目类别
- * @param itemName 项目名称
- * @return 列表
- */
- @Override
- public Object getItemCostCalculateList(Integer current, Integer pageSize, String computeDate, String itemType, String itemName) {
- Page<ComputeItemCostPageDto> page = repository.getByPage(current, pageSize, computeDate, itemType, itemName);
- if (CollectionUtils.isEmpty(page.getRecords())) {
- return new PageUtils(new ArrayList<>(), NumberConstant.ZERO, pageSize, current);
- }
- return new PageUtils(page.getRecords(), Math.toIntExact(page.getTotal()), pageSize, current);
- }
- /**
- * 成本核算-收费项目成本计算-计算
- *
- * @param computeDate 核算年月
- * @param currentUser
- * @param requestAttributes
- * @param progressKey
- */
- @Override
- @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
- public void itemCostCalculate(String computeDate, SessionUserVO currentUser, RequestAttributes requestAttributes, String progressKey) {
- // 从主线程获取用户数据 放到局部变量中
- try {
- RequestContextHolder.setRequestAttributes(requestAttributes, true);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 1.0);
- // connection.setAutoCommit(false);
- long itemSize = importPatientItemRepository.getCount(computeDate, currentUser);
- if (Objects.equals(itemSize, NumberConstant.ZERO_L)) {
- log.error("当前核算年月【" + computeDate + "】未导入收费项目数据,计算中止");
- throw new CostException("当前核算年月【" + computeDate + "】未导入收费项目数据,计算中止");
- }
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 2.0);
- //把当月需要计算数据置成0
- importPatientItemRepository.updateCalculateFlag(computeDate, currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 4.0);
- List<Integer> integers = repository.removeByComputeDate(computeDate, currentUser);
- if (!CollectionUtils.isEmpty(integers)) {
- detailRepository.removeByItemCostId(integers, currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 10.0);
- }
- // redisUtil.set(RedisKeyConstant.PROGRESS+ progressKey,100.0);
- // List<PatientItemVo> items = importPatientItemRepository.getAllGroupByCompute(computeDate);
- //人事项目成本
- List<ComputeEmpCost> computeEmpCosts = computeEmpCostRepository.getByComputeDate(computeDate, currentUser);
- if (CollectionUtils.isEmpty(computeEmpCosts)) {
- log.error("当前核算年月【" + computeDate + "】人事成本未完成计算,请先完成人事成本计算,当前项目计算中止");
- throw new CostException("当前核算年月【" + computeDate + "】人事成本未完成计算,请先完成人事成本计算,当前项目计算中止");
- }
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 12.0);
- CommonParameterVo parameter = centerService.getParameter(ParameterConstant.ITEM_CONTAINS_SPACE);
- String ITEM_CONTAINS_SPACE = Objects.nonNull(parameter.getValue()) ? parameter.getValue() : "0";
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 14.0);
- //药品成本
- Map<String, BigDecimal> drugCostMap = drugRepository.getCostMap(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 15.0);
- //材料成本
- Map<String, BigDecimal> materialCostMap = materialRepository.getCostMap(currentUser);
- //人事项目成本
- // List<ComputeEmpCost> computeEmpCosts = computeEmpCostRepository.getByComputeDate(computeDate,currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 16.0);
- //按人事分类进行分组
- Map<String, List<ComputeEmpCost>> empComputeCostGroup = computeEmpCosts.stream().collect(Collectors.groupingBy(ComputeEmpCost::getEmpType));
- //标准项目字典
- Map<String, StandItem> standItemMap = getStandItem(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 17.0);
- //人事成本分类
- Map<String, EmpCostType> empCostType = getEmpCostType(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 18.0);
- Map<String, String> itemStandMap = getItemStandMap(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 20.0);
- //获取设备每分钟成本
- Map<String, BigDecimal> equipmentMinuteMap = equipmentRepository.getEquipmentMinuteMap(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 21.0);
- Map<String, BigDecimal> spaceMinuteMap = spaceRepository.getSpaceMinuteMap(currentUser);
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 22.0);
- //主表公共对象
- ComputeItemCost computeItemCost = new ComputeItemCost();
- computeItemCost.setComputeDate(computeDate);
- computeItemCost.setHospId(currentUser.getHospId());
- computeItemCost.setCreateUser(String.valueOf(currentUser.getId()));
- computeItemCost.setCreateTime(new Date());
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 24.0);
- //明细表公共对象
- ComputeItemCostDetail costDetail = new ComputeItemCostDetail();
- costDetail.setHospId(currentUser.getHospId());
- costDetail.setCreateUser(String.valueOf(currentUser.getId()));
- costDetail.setCreateTime(new Date());
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 25.0);
- long count = (itemSize + LIMIT - 1) / LIMIT;
- long l = 0;
- for (int j = 0; j < count; j++) {
- List<ImportPatientItem> items = importPatientItemRepository.getByNoCalculateComputeDate(computeDate, currentUser);
- List<ComputeItemCostDetail> saveDetails = new ArrayList<>();
- List<ComputeItemCost> saveCost = new ArrayList<>();
- if (!CollectionUtils.isEmpty(items)) {
- for (int i = 0; i < items.size(); i++) {
- ImportPatientItem item = items.get(i);
- ComputeItemCost itemCost = BeanUtil.convertObj(computeItemCost, ComputeItemCost.class);
- itemCost.setVisitNo(item.getVisitNo());
- itemCost.setCode(item.getItemCode());
- itemCost.setName(item.getItemName());
- String typeCode = item.getItemTypeCode();
- itemCost.setItemTypeCode(typeCode);
- itemCost.setItemType(item.getItemType());
- itemCost.setOrderCode(item.getOrderCode());
- itemCost.setOrderName(item.getOrderName());
- itemCost.setNum(item.getNum());
- itemCost.setIndex(i);
- saveCost.add(itemCost);
- costDetail.setIndex(i);
- List<ComputeItemCostDetail> details = setDetails(drugCostMap, materialCostMap, empComputeCostGroup, standItemMap,
- empCostType, equipmentMinuteMap, spaceMinuteMap, costDetail, item, typeCode, ITEM_CONTAINS_SPACE, itemStandMap);
- if (!CollectionUtils.isEmpty(details)) {
- saveDetails.addAll(details);
- }
- double percent = (l + 1) / (double) itemSize * 100;
- //这里对小数采用向下取整,例如99.5会取整为99
- percent = Math.floor(percent / 2 + 25.0);
- if (l == itemSize - 1) {
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 98.0);
- } else {
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, percent);
- }
- System.out.println(l + "-" + itemSize);
- l++;
- }
- if (!CollectionUtils.isEmpty(saveCost)) {
- //作废当前核算年月已有数据
- repository.saveBatch(saveCost, 100);
- if (!CollectionUtils.isEmpty(saveDetails)) {
- Map<Integer, Integer> indexId = saveCost.stream().collect(Collectors.toMap(ComputeItemCost::getIndex, ComputeItemCost::getId, (a, b) -> b));
- Map<Integer, List<ComputeItemCostDetail>> collect = saveDetails.stream().collect(Collectors.groupingBy(ComputeItemCostDetail::getIndex));
- List<ComputeItemCostDetail> saveCostDetails = new ArrayList<>();
- collect.keySet().forEach(integer -> {
- Integer costId = indexId.get(integer);
- List<ComputeItemCostDetail> details = collect.get(integer);
- details.forEach(detail -> detail.setItemCostId(costId));
- saveCostDetails.addAll(details);
- });
- detailRepository.saveBatch(saveCostDetails, 100);
- }
- }
- //保存完把已计算过的置1
- importPatientItemRepository.updateCalculateFlag(items);
- // connection.commit();
- }
- }
- redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 100.0);
- } catch (Exception e) {
- throw new CostException("收费项目计算错误:"+ e.getMessage());
- }
- // Result result = new Result();
- // result.setStatus(200);
- // result.setMsg("计算完成");
- // return result;
- }
- private Map<String, String> getItemStandMap(SessionUserVO currentUser) {
- List<Item> list = itemRepository.getList(currentUser);
- if (!CollectionUtils.isEmpty(list)) {
- List<Item> collect = list.stream().filter(f -> Objects.nonNull(f.getStandItemCode())).collect(Collectors.toList());
- if (!CollectionUtils.isEmpty(collect)) {
- return collect.stream().collect(Collectors.toMap(Item::getCode, Item::getStandItemCode, (a, b) -> b));
- }
- }
- return new HashMap<>();
- }
- /**
- * 计算收费项目明细
- *
- * @param drugCostMap 药品成本字典
- * @param materialCostMap 材料成本字典
- * @param empComputeCostGroup 人员成本计算
- * @param standItemMap 标准项目字典
- * @param empCostType 人员类别字典
- * @param equipmentMinuteMap 设备每分钟成本
- * @param spaceMinuteMap 空间每分钟成本
- * @param costDetail 明细表入参
- * @param item 收费项目
- * @param typeCode 项目类别
- * @param ITEM_CONTAINS_SPACE
- * @param itemStandMap
- * @return 项目明细出参
- */
- private List<ComputeItemCostDetail> setDetails(Map<String, BigDecimal> drugCostMap, Map<String, BigDecimal> materialCostMap,
- Map<String, List<ComputeEmpCost>> empComputeCostGroup, Map<String, StandItem> standItemMap,
- Map<String, EmpCostType> empCostType, Map<String, BigDecimal> equipmentMinuteMap,
- Map<String, BigDecimal> spaceMinuteMap, ComputeItemCostDetail costDetail,
- ImportPatientItem item, String typeCode, String ITEM_CONTAINS_SPACE,
- Map<String, String> itemStandMap) {
- List<ComputeItemCostDetail> details = new ArrayList<>();
- if (typeCode.equals(ItemTypeEnum.DRUG.getCode())) {
- // 药品 取药品收入 药品成本
- //取药品收入
- ComputeItemCostDetail income = getIncome(costDetail, item);
- income.setType(ReportItemTypeEnum.DRUG_INCOME.getCode());
- details.add(income);
- //药品成本
- ComputeItemCostDetail cost = getCost(costDetail, item, drugCostMap);
- cost.setType(ReportItemTypeEnum.DRUG_COST.getCode());
- details.add(cost);
- } else if (typeCode.equals(ItemTypeEnum.MATERIAL.getCode())) {
- //材料 取材料收入 材料成本
- //取材料收入
- ComputeItemCostDetail income = getIncome(costDetail, item);
- income.setType(ReportItemTypeEnum.MATERIAL_INCOME.getCode());
- details.add(income);
- //材料成本
- ComputeItemCostDetail cost = getCost(costDetail, item, materialCostMap);
- cost.setType(ReportItemTypeEnum.MATERIAL_COST.getCode());
- details.add(cost);
- } else if (typeCode.equals(ItemTypeEnum.ITEM.getCode())) {
- //项目 取项目收入 项目成本
- //取项目收费
- ComputeItemCostDetail income = getIncome(costDetail, item);
- income.setType(ReportItemTypeEnum.ITEM_INCOME.getCode());
- details.add(income);
- //当前项目的标准项目
- BigDecimal num = item.getNum();
- if (!CollectionUtils.isEmpty(itemStandMap)) {
- StandItem standItem = standItemMap.get(itemStandMap.get(item.getItemCode()));
- if (Objects.nonNull(standItem)) {
- BigDecimal weight = new BigDecimal("0.005");
- //人力成本
- List<StandItemEmpMap> empMaps = standItem.getEmpMaps();
- BigDecimal empCost = getEmpCost(empMaps, empComputeCostGroup, empCostType, item);
- ComputeItemCostDetail empCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- BigDecimal empCostNum = new BigDecimal("0.0000");
- if (num != null) {
- empCostNum = empCost.multiply(num);
- }
- empCostResult.setComputeResult(empCostNum);
- empCostResult.setComputeSingleResult(empCost);
- empCostResult.setType(ReportItemTypeEnum.WEIGHT_EMP_COST.getCode());
- details.add(empCostResult);
- // 2023.12.18 添加加成算法
- BigDecimal riskDegree = standItem.getRiskDegree();
- BigDecimal technicalDifficulty = standItem.getTechnicalDifficulty();
- if (riskDegree == null) {
- riskDegree = BigDecimal.ZERO;
- }
- if (technicalDifficulty == null) {
- technicalDifficulty = BigDecimal.ZERO;
- }
- BigDecimal technical = technicalDifficulty.multiply(weight).add(BigDecimal.ONE);
- BigDecimal risk = riskDegree.multiply(weight).add(BigDecimal.ONE);
- BigDecimal bigDecimal = empCost.multiply(technical).multiply(risk).setScale(4, RoundingMode.HALF_UP);
- BigDecimal bigDecimalNum = empCostNum.multiply(technical).multiply(risk).setScale(4, RoundingMode.HALF_UP);
- ComputeItemCostDetail empWeightCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- empWeightCostResult.setComputeResult(bigDecimalNum);
- empWeightCostResult.setComputeSingleResult(bigDecimal);
- empWeightCostResult.setType(ReportItemTypeEnum.EMP_COST.getCode());
- details.add(empWeightCostResult);
- //设备成本
- List<StandItemEquipmentMap> equipmentMaps = standItem.getEquipmentMaps();
- BigDecimal equipmentCost = getEquipmentCost(equipmentMaps, equipmentMinuteMap);
- ComputeItemCostDetail equipmentCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- BigDecimal equipmentCostNum = new BigDecimal("0.0000");
- if (num != null) {
- equipmentCostNum = equipmentCost.multiply(num);
- }
- equipmentCostResult.setComputeResult(equipmentCostNum);
- equipmentCostResult.setComputeSingleResult(equipmentCost);
- equipmentCostResult.setType(ReportItemTypeEnum.EQUIPMENT_COST.getCode());
- details.add(equipmentCostResult);
- //空间成本
- List<StandItemSpaceMap> spaceMaps = standItem.getSpaceMaps();
- BigDecimal spaceCost = getSpaceCost(spaceMaps, spaceMinuteMap);
- ComputeItemCostDetail spaceCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- BigDecimal spaceCostNum = new BigDecimal("0.0000");
- if (num != null) {
- spaceCostNum = spaceCost.multiply(num);
- }
- spaceCostResult.setComputeSingleResult(spaceCost);
- spaceCostResult.setComputeResult(spaceCostNum);
- spaceCostResult.setType(ReportItemTypeEnum.SPACE_COST.getCode());
- details.add(spaceCostResult);
- //项目成本=人力成本+设备成本+空间成本
- ComputeItemCostDetail cost = getCost(costDetail, item, materialCostMap);
- cost.setType(ReportItemTypeEnum.ITEM_COST.getCode());
- if (ITEM_CONTAINS_SPACE.equals(NumberConstant.ONE_S)) {
- //项目成本=人力成本+设备成本
- cost.setComputeResult(bigDecimalNum.add(equipmentCostNum));
- cost.setComputeSingleResult(bigDecimal.add(equipmentCost));
- } else {
- //项目成本=人力成本+设备成本+空间成本
- cost.setComputeResult(bigDecimalNum.add(equipmentCostNum).add(spaceCostNum));
- cost.setComputeSingleResult(bigDecimal.add(equipmentCost).add(spaceCost));
- }
- details.add(cost);
- } else {
- //人力成本
- ComputeItemCostDetail empCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (empCostResult != null) {
- empCostResult.setComputeResult(BigDecimal.ZERO);
- empCostResult.setComputeSingleResult(BigDecimal.ZERO);
- empCostResult.setType(ReportItemTypeEnum.EMP_COST.getCode());
- }
- details.add(empCostResult);
- //设备成本
- ComputeItemCostDetail equipmentCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (equipmentCostResult != null) {
- equipmentCostResult.setComputeResult(BigDecimal.ZERO);
- equipmentCostResult.setComputeSingleResult(BigDecimal.ZERO);
- equipmentCostResult.setType(ReportItemTypeEnum.EQUIPMENT_COST.getCode());
- }
- details.add(equipmentCostResult);
- //空间成本
- ComputeItemCostDetail spaceCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (spaceCostResult != null) {
- spaceCostResult.setComputeResult(BigDecimal.ZERO);
- spaceCostResult.setComputeSingleResult(BigDecimal.ZERO);
- spaceCostResult.setType(ReportItemTypeEnum.SPACE_COST.getCode());
- }
- details.add(spaceCostResult);
- //项目成本=人力成本+设备成本+空间成本
- ComputeItemCostDetail cost = getCost(costDetail, item, materialCostMap);
- cost.setType(ReportItemTypeEnum.ITEM_COST.getCode());
- cost.setComputeResult(BigDecimal.ZERO);
- cost.setComputeSingleResult(BigDecimal.ZERO);
- details.add(cost);
- }
- } else {
- //人力成本
- ComputeItemCostDetail empCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (empCostResult != null) {
- empCostResult.setComputeResult(BigDecimal.ZERO);
- empCostResult.setComputeSingleResult(BigDecimal.ZERO);
- empCostResult.setType(ReportItemTypeEnum.EMP_COST.getCode());
- }
- details.add(empCostResult);
- //设备成本
- ComputeItemCostDetail equipmentCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (equipmentCostResult != null) {
- equipmentCostResult.setComputeResult(BigDecimal.ZERO);
- equipmentCostResult.setComputeSingleResult(BigDecimal.ZERO);
- equipmentCostResult.setType(ReportItemTypeEnum.EQUIPMENT_COST.getCode());
- }
- details.add(equipmentCostResult);
- //空间成本
- ComputeItemCostDetail spaceCostResult = BeanUtil.convertObj(costDetail, ComputeItemCostDetail.class);
- if (spaceCostResult != null) {
- spaceCostResult.setComputeResult(BigDecimal.ZERO);
- spaceCostResult.setComputeSingleResult(BigDecimal.ZERO);
- spaceCostResult.setType(ReportItemTypeEnum.SPACE_COST.getCode());
- }
- details.add(spaceCostResult);
- //项目成本=人力成本+设备成本+空间成本
- ComputeItemCostDetail cost = getCost(costDetail, item, materialCostMap);
- cost.setType(ReportItemTypeEnum.ITEM_COST.getCode());
- cost.setComputeResult(BigDecimal.ZERO);
- cost.setComputeSingleResult(BigDecimal.ZERO);
- details.add(cost);
- }
- } //其他 目前不知算法
- return details;
- }
- /**
- * 获取空间成本
- *
- * @param spaceMaps 标准项目空间成本对照
- * @param spaceMinuteMap 每分钟空间成本
- * @return 空间成本
- */
- private BigDecimal getSpaceCost(List<StandItemSpaceMap> spaceMaps, Map<String, BigDecimal> spaceMinuteMap) {
- if (!CollectionUtils.isEmpty(spaceMaps)) {
- BigDecimal totalCost = new BigDecimal("0.0000");
- for (StandItemSpaceMap space : spaceMaps) {
- //设备每分钟成本
- BigDecimal bigDecimal = spaceMinuteMap.get(space.getSpaceCode());
- //设备成本=每分钟成本*数量*执行时间
- totalCost = bigDecimal != null ? totalCost.add(bigDecimal.multiply(space.getExecuteTime()).multiply(space.getNum())) : totalCost.add(BigDecimal.ZERO);
- }
- return totalCost;
- } else {
- return new BigDecimal("0.0000");
- }
- }
- /**
- * 获取设备成本
- *
- * @param equipmentMaps 标准项目设备对照
- * @param equipmentMinuteMap 设备每分钟成字典
- * @return 设备成本
- */
- private BigDecimal getEquipmentCost(List<StandItemEquipmentMap> equipmentMaps, Map<String, BigDecimal> equipmentMinuteMap) {
- if (!CollectionUtils.isEmpty(equipmentMaps)) {
- BigDecimal totalCost = new BigDecimal("0.0000");
- for (StandItemEquipmentMap equipmentMap : equipmentMaps) {
- //设备每分钟成本
- BigDecimal bigDecimal = equipmentMinuteMap.get(equipmentMap.getEquipmentCode());
- //设备成本=每分钟成本*数量*执行时间
- totalCost = totalCost.add(bigDecimal.multiply(equipmentMap.getExecuteTime()).multiply(equipmentMap.getNum()));
- }
- return totalCost;
- } else {
- return new BigDecimal("0.0000");
- }
- }
- private BigDecimal getEmpCost(List<StandItemEmpMap> empMaps, Map<String, List<ComputeEmpCost>> empCostGroup,
- Map<String, EmpCostType> empCostType, ImportPatientItem item) {
- /*
- 单位人事成本获取规则:
- 人员类别的计算方式为科室的:按执行科室取对应科室的每分钟成本,取不到则取执行人对应人事分类的每分钟成本
- 人员类别的计算方式为岗位的:取执行人对应岗位的每分钟成本,取不到则取执行人对应人事分类的每分钟成本
- 人员类别的计算方式为人事分类的:取执行人对应人事分类的每分钟成本
- 人力成本=每分钟成本*数量*执行时间
- */
- if (!CollectionUtils.isEmpty(empMaps)) {
- BigDecimal totalCost = new BigDecimal("0.0000");
- for (StandItemEmpMap empMap : empMaps) {
- //标准项目人员对照
- String empTypeCode = empMap.getEmpTypeCode();
- BigDecimal num = empMap.getNum();
- BigDecimal executeTime = empMap.getExecuteTime();
- //人事分类
- EmpCostType costType = empCostType.get(empTypeCode);
- //计算方式
- String computeType = costType.getComputeType();
- //人事成本计算数据
- List<ComputeEmpCost> computeEmpCosts = empCostGroup.get(empTypeCode);
- //每分钟成本
- Map<String, BigDecimal> minuteCost = computeEmpCosts.stream().collect(Collectors.toMap(ComputeEmpCost::getCode, ComputeEmpCost::getMinuteCost, (a, b) -> b));
- //人事分类对应的人员信息
- if (computeType.equals(EmpCostComputeTypeEnum.DEPARTMENT.getCode())) {
- //人员类别的计算方式为科室的:按执行科室取对应科室的每分钟成本,取不到当前人事分类的每分钟成本
- //当前项目执行科室
- String departmentCode = item.getExecuteDepartmentCode();
- BigDecimal bigDecimal = minuteCost.get(departmentCode);
- if (bigDecimal == null) {
- bigDecimal = minuteCost.get(empTypeCode);
- }
- totalCost = totalCost.add(bigDecimal.multiply(executeTime).multiply(num));
- } else if (computeType.equals(EmpCostComputeTypeEnum.POSITION.getCode())) {
- String userCode = item.getExecuteUserCode();
- List<EmpCostMap> empCostTypeMaps = costType.getEmpCostMaps();
- if (!CollectionUtils.isEmpty(empCostTypeMaps)) {
- Map<String, String> empPositionMap = empCostTypeMaps.stream().collect(Collectors.toMap(EmpCostMap::getAccount, EmpCostMap::getPosition, (a, b) -> b));
- String position = empPositionMap.get(userCode);
- BigDecimal bigDecimal = minuteCost.get(position);
- if (bigDecimal == null) {
- bigDecimal = minuteCost.get(empTypeCode);
- }
- totalCost = totalCost.add(bigDecimal.multiply(executeTime).multiply(num));
- } else {
- BigDecimal bigDecimal = minuteCost.get(empTypeCode);
- totalCost = totalCost.add(bigDecimal.multiply(executeTime).multiply(num));
- }
- } else {
- BigDecimal bigDecimal = minuteCost.get(empTypeCode);
- totalCost = totalCost.add(bigDecimal.multiply(executeTime).multiply(num));
- }
- }
- return totalCost;
- } else {
- return new BigDecimal("0.0000");
- }
- }
- private Map<String, EmpCostType> getEmpCostType(SessionUserVO currentUser) {
- List<EmpCostType> empCostTypes = empCostTypeRepository.getList(currentUser);
- if (CollectionUtils.isEmpty(empCostTypes)) {
- throw new CostException("人事成本分类,请先添加人事成本分类再进行计算,当前项目计算中止");
- }
- List<EmpCostMap> empCostMaps = empCostMapRepository.getList(currentUser);
- Map<String, List<EmpCostMap>> empMapGroup = new HashMap<>();
- if (!CollectionUtils.isEmpty(empCostMaps)) {
- empMapGroup = empCostMaps.stream().collect(Collectors.groupingBy(EmpCostMap::getCostTypeCode));
- }
- Map<String, EmpCostType> map = new HashMap<>();
- for (EmpCostType empCostType : empCostTypes) {
- empCostType.setEmpCostMaps(empMapGroup.get(empCostType.getCostTypeCode()));
- map.put(empCostType.getCostTypeCode(), empCostType);
- }
- return map;
- }
- /**
- * 获取标准项目字典
- *
- * @return 字典列表
- */
- private Map<String, StandItem> getStandItem(SessionUserVO currentUser) {
- //标准项目字典
- List<StandItem> list = standItemRepository.getList(currentUser);
- if (CollectionUtils.isEmpty(list)) {
- throw new CostException("标准项目未维护,请先添加标准项目再进行计算,当前项目计算中止");
- }
- //标准项目字典人员对照
- List<StandItemEmpMap> empMapList = standItemEmpMapRepository.getList(currentUser);
- Map<String, List<StandItemEmpMap>> empMapGroup = new HashMap<>();
- if (!CollectionUtils.isEmpty(empMapList)) {
- empMapGroup = empMapList.stream().collect(Collectors.groupingBy(StandItemEmpMap::getStandItemCode));
- }
- //标准项目字典空间对照
- List<StandItemSpaceMap> spaceMapList = standItemSpaceMapRepository.getList(currentUser);
- Map<String, List<StandItemSpaceMap>> spaceMapGroup = new HashMap<>();
- if (!CollectionUtils.isEmpty(spaceMapList)) {
- spaceMapGroup = spaceMapList.stream().collect(Collectors.groupingBy(StandItemSpaceMap::getStandItemCode));
- }
- //标准项目字典设备对照
- List<StandItemEquipmentMap> equipmentMapList = standItemEquipmentMapRepository.getList(currentUser);
- Map<String, List<StandItemEquipmentMap>> equipmentMapGroup = new HashMap<>();
- if (!CollectionUtils.isEmpty(equipmentMapList)) {
- equipmentMapGroup = equipmentMapList.stream().collect(Collectors.groupingBy(StandItemEquipmentMap::getStandItemCode));
- }
- Map<String, StandItem> map = new HashMap<>();
- for (StandItem standItem : list) {
- standItem.setEmpMaps(empMapGroup.get(standItem.getCode()));
- standItem.setEquipmentMaps(equipmentMapGroup.get(standItem.getCode()));
- standItem.setSpaceMaps(spaceMapGroup.get(standItem.getCode()));
- map.put(standItem.getCode(), standItem);
- }
- return map;
- }
- /**
- * 获取收入对象
- *
- * @param detail 公用明细
- * @param item 导入项目
- * @return 收入对象
- */
- private ComputeItemCostDetail getIncome(ComputeItemCostDetail detail, ImportPatientItem item) {
- ComputeItemCostDetail result = BeanUtil.convertObj(detail, ComputeItemCostDetail.class);
- result.setComputeResult(item.getAmount());
- result.setComputeSingleResult(item.getPrice());
- return result;
- }
- /**
- * 获取成本对象
- *
- * @param detail 公用明细
- * @param item 导入项目
- * @param costMap 成本字典
- * @return 成本对象
- */
- private ComputeItemCostDetail getCost(ComputeItemCostDetail detail, ImportPatientItem item, Map<String, BigDecimal> costMap) {
- ComputeItemCostDetail result = BeanUtil.convertObj(detail, ComputeItemCostDetail.class);
- BigDecimal bigDecimal = costMap.get(item.getItemCode());
- BigDecimal num = item.getNum();
- if (bigDecimal != null && num != null) {
- result.setComputeResult(bigDecimal.multiply(num));
- result.setComputeSingleResult(bigDecimal);
- } else if(bigDecimal != null){
- result.setComputeSingleResult(bigDecimal);
- }else {
- log.info("【" + item.getItemName() + "】未找到成本信息,默认为 0");
- result.setComputeResult(BigDecimal.ZERO);
- result.setComputeSingleResult(BigDecimal.ZERO);
- }
- return result;
- }
- @Override
- public List<String> getItemTypeList() {
- List<String> s = new ArrayList<>();
- s.add(ReportItemTypeEnum.DRUG_INCOME.getCode());
- s.add(ReportItemTypeEnum.MATERIAL_INCOME.getCode());
- s.add(ReportItemTypeEnum.ITEM_INCOME.getCode());
- s.add(ReportItemTypeEnum.DRUG_COST.getCode());
- s.add(ReportItemTypeEnum.MATERIAL_COST.getCode());
- s.add(ReportItemTypeEnum.ITEM_COST.getCode());
- s.add(ReportItemTypeEnum.EMP_COST.getCode());
- s.add(ReportItemTypeEnum.EQUIPMENT_COST.getCode());
- s.add(ReportItemTypeEnum.SPACE_COST.getCode());
- return s;
- }
- }
|