package com.imed.costaccount.service.impl; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.type.TypeReference; import com.imed.costaccount.common.exception.CostException; import com.imed.costaccount.common.util.BeanUtil; import com.imed.costaccount.common.util.JacksonUtil; import com.imed.costaccount.common.util.PageUtils; import com.imed.costaccount.constants.NumberConstant; import com.imed.costaccount.mapper.CostAccountShareMapper; import com.imed.costaccount.model.*; import com.imed.costaccount.model.dto.AccountShareCopyDto; import com.imed.costaccount.model.dto.CostAccountShareEditDto; import com.imed.costaccount.model.dto.CostAccountShareSaveDto; import com.imed.costaccount.model.dto.ShareParamEditDto; import com.imed.costaccount.model.vo.CostAccountShareVO; import com.imed.costaccount.model.vo.CostShareParamStatusVO; import com.imed.costaccount.model.vo.CostShareParamVO; import com.imed.costaccount.model.vo.ShareParamProportionVO; import com.imed.costaccount.service.*; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @Slf4j @Service("costAccountShareService") public class CostAccountShareServiceImpl extends ServiceImpl implements CostAccountShareService { private final ResponsibilityService responsibilityService; private final AccountingService accountingService; private final CostShareLevelService costShareLevelService; private final CostShareParamService costShareParamService; public CostAccountShareServiceImpl(ResponsibilityService responsibilityService, AccountingService accountingService, CostShareLevelService costShareLevelService, CostShareParamService costShareParamService) { this.responsibilityService = responsibilityService; this.accountingService = accountingService; this.costShareLevelService = costShareLevelService; this.costShareParamService = costShareParamService; } /** * 分页查询责任中心成本对照相关数据 * * @param current * @param pageSize * @param name * @return */ @Override public PageUtils queryList(Integer current, Integer pageSize, String name, Long hospId) { Page costAccountSharePage = new Page<>(current, pageSize); Page pages = this.page(costAccountSharePage, new QueryWrapper().lambda() .eq(!StringUtils.isEmpty(hospId), CostAccountShare::getHospId, hospId) .like(!StringUtils.isEmpty(name), CostAccountShare::getResponsibilityName, name) .orderByAsc(CostAccountShare::getShareLevel)); List costAccountShareList = pages.getRecords(); List costAccountShareVOList = BeanUtil.convertList(costAccountShareList, CostAccountShareVO.class); costAccountShareVOList.forEach(i -> { String accountingIds = i.getAccountingIds(); if (StrUtil.isNotBlank(accountingIds)) { List list = Arrays.asList(accountingIds.split(StrUtil.COMMA)); i.setAccountingIdList(list); } else { i.setAccountingIdList(null); } }); // getMessage(hospId, costAccountShareVOList); PageUtils pageUtils = new PageUtils(pages); pageUtils.setList(costAccountShareVOList); return pageUtils; } // private void getMessage(Long hospId, List costAccountShareList) { // // 设置责任中心的数据 与 会计科目的数据从对应的id里面获取 // List list = responsibilityService.list(new QueryWrapper().lambda().eq(Responsibility::getHospId, hospId)); // List accountingList = accountingService.list(new QueryWrapper().lambda().eq(Accounting::getHospId, hospId)); // Map> resMap = list.stream().collect(Collectors.groupingBy(Responsibility::getId)); // Map> accountMap = accountingList.stream().collect(Collectors.groupingBy(Accounting::getId)); // costAccountShareList.forEach(i->{ // Long id = i.getResponsibilityId(); // List responsibilities = resMap.get(id); // if (!CollectionUtils.isEmpty(responsibilities)){ // i.setResponsibilityId(id); // i.setResponsibilityName(responsibilities.get(0).getResponsibilityName()); // i.setResponsibilityCode(responsibilities.get(0).getResponsibilityCode()); // // } // Long accountingId = i.getAccountingId(); // if (accountingId>0){ // List accountingList1 = accountMap.get(accountingId); // if (!CollectionUtils.isEmpty(accountingList1)){ // i.setAccountingId(accountingId); // i.setAccountingName(accountingList1.get(0).getAccountingName()); // i.setAccountingCode(accountingList1.get(0).getAccountingCode()); // i.setAllParentIds(accountingList1.get(0).getAllParentIds()); // } // } // }); // } /** * 保存成本参数对应成本对照表 * * @param costAccountShareSaveDto {@link CostAccountShareSaveDto} */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void addCostAccountShare(CostAccountShareSaveDto costAccountShareSaveDto) { User user = (User) SecurityUtils.getSubject().getPrincipal(); Long hospId = user.getHospId(); // 检验输入的数据的合理性 checkAccountShare(costAccountShareSaveDto, hospId); CostAccountShare costAccountShareRequest = BeanUtil.convertObj(costAccountShareSaveDto, CostAccountShare.class); costAccountShareRequest.setHospId(hospId); costAccountShareRequest.setCreateTime(System.currentTimeMillis()); baseMapper.insert(costAccountShareRequest); } /** * 检验输入数据的合理性 * * @param costAccountShareSaveDto * @param hospId */ private void checkAccountShare(CostAccountShareSaveDto costAccountShareSaveDto, Long hospId) { Long responsibilityId = costAccountShareSaveDto.getResponsibilityId(); Responsibility responsibility = responsibilityService.getOne(new QueryWrapper().lambda().eq(Responsibility::getHospId, hospId).eq(Responsibility::getId, responsibilityId)); if (Objects.isNull(responsibility)) { throw new CostException(500, "输入的责任不存在"); } costAccountShareSaveDto.setResponsibilityId(responsibilityId); costAccountShareSaveDto.setResponsibilityCode(responsibility.getResponsibilityCode()); costAccountShareSaveDto.setResponsibilityName(responsibility.getResponsibilityName()); costAccountShareSaveDto.setShareLevel(responsibility.getShareLevel()); List costAccountShareList = baseMapper.selectList(new QueryWrapper().lambda().eq(CostAccountShare::getHospId, hospId).eq(CostAccountShare::getResponsibilityId, costAccountShareSaveDto.getResponsibilityId())); if (!StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) { // 这个责任中心允许输入会计科目 List accountIdList = Arrays.stream(costAccountShareSaveDto.getAccountingIds().split(StrUtil.COMMA)).map(Long::valueOf).collect(Collectors.toList()); List accountingList = accountingService.list(new QueryWrapper().lambda().eq(Accounting::getHospId, hospId).in(Accounting::getId, accountIdList).orderByDesc(Accounting::getCreateTime)); if (CollectionUtils.isEmpty(accountingList)) { throw new CostException(500, "输入的会计科目不存在"); } else { String accountIds = accountingList.stream().map(Accounting::getId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA)); costAccountShareSaveDto.setAccountingIds(accountIds); String accountNames = accountingList.stream().map(Accounting::getAccountingName).map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA)); costAccountShareSaveDto.setAccountingNames(accountNames); String accountCodes = accountingList.stream().map(Accounting::getAccountingCode).map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA)); costAccountShareSaveDto.setAccountingCodes(accountCodes); } // Map> costAccountMap = costAccountShareList.stream().collect(Collectors.groupingBy(CostAccountShare::getResponsibilityCode)); // List list = costAccountMap.get(costAccountShareSaveDto.getResponsibilityCode()); if (!CollectionUtils.isEmpty(costAccountShareList)) { costAccountShareList.forEach(i -> { String accountingIds = i.getAccountingIds(); Integer isShareCost = i.getIsShareCost(); List accountIdListRequest = Arrays.stream(accountingIds.split(StrUtil.COMMA)).map(Long::valueOf).collect(Collectors.toList()); if (!Collections.disjoint(accountIdListRequest, accountIdList)) { throw new CostException(500, "存在相同的会计科目数据"); } if (NumberConstant.ONE.equals(isShareCost) && NumberConstant.ONE.equals(costAccountShareSaveDto.getIsShareCost())) { throw new CostException(500, "同个责任中心只允许一条设置包含分摊成本"); } }); } } else { // 此时是 // 责任中心只允许出现一次 if (!CollectionUtils.isEmpty(costAccountShareList)) { throw new CostException(500, "该责任中心合并计算已存在"); } if (!NumberConstant.ONE.equals(costAccountShareSaveDto.getIsShareCost())) { throw new CostException(500, "合并计算责任中心必须要设置成包含分摊参数"); } } // 检验输入的这个责任中心是否允许输入会计科目 Long shareId = responsibility.getShareId(); CostShareLevel costShareLevel = costShareLevelService.getOne(new QueryWrapper().lambda() .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getId, shareId)); if (Objects.nonNull(costShareLevel)) { if ((!StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) && NumberConstant.ZERO.equals(costShareLevel.getCalcType())) { throw new CostException(500, "合并计算不允许选择会计科目"); } if ((StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) && NumberConstant.ONE.equals(costShareLevel.getCalcType())) { throw new CostException(500, "分开计算的责任中心需要选择会计科目"); } } else { throw new CostException(500, "对不起该责任中心没有对应分摊层级"); } } /** * 修改成本中心责任对照表 * * @param costAccountShareEditDto */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void updateByCostAccountShare(CostAccountShareEditDto costAccountShareEditDto) { User user = (User) SecurityUtils.getSubject().getPrincipal(); Long hospId = user.getHospId(); Long id = costAccountShareEditDto.getId(); CostAccountShare costAccountShare = baseMapper.selectById(id); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "成本分摊参数对应数据不存在"); } baseMapper.deleteById(id); // 新增责任中心成本对照数据 CostAccountShareSaveDto costAccountShareSaveDto = BeanUtil.convertObj(costAccountShareEditDto, CostAccountShareSaveDto.class); // 检验输入的数据是否符合规则 checkAccountShare(costAccountShareSaveDto, hospId); CostAccountShareEditDto accountShareEditDto = BeanUtil.convertObj(costAccountShareSaveDto, CostAccountShareEditDto.class); CostAccountShare costAccountShareRequest = BeanUtil.convertObj(accountShareEditDto, CostAccountShare.class); costAccountShareRequest.setId(null); costAccountShareRequest.setHospId(hospId); costAccountShareRequest.setParamList(costAccountShare.getParamList()); costAccountShareRequest.setCreateTime(System.currentTimeMillis()); baseMapper.insert(costAccountShareRequest); } /** * 修改成本分摊参数的设置 * * @param shareParamEditDto */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void updateShareParam(ShareParamEditDto shareParamEditDto) { List shareParamProportionVOList1 = shareParamEditDto.getShareParamProportionVOList(); User user = (User) SecurityUtils.getSubject().getPrincipal(); Long hospId = user.getHospId(); Long id = shareParamEditDto.getId(); CostAccountShare costAccountShare = baseMapper.selectOne(new QueryWrapper().lambda() .eq(CostAccountShare::getHospId, hospId) .eq(CostAccountShare::getId, id)); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "分摊参数对应数据不存在"); } if (!CollectionUtils.isEmpty(shareParamProportionVOList1)) { List shareParamProportionVOList = shareParamEditDto.getShareParamProportionVOList(); // 检验输入的成本分摊参数是否存在 List costShareParamServiceAll = costShareParamService.getAll(hospId); Map> listMap = costShareParamServiceAll.stream().collect(Collectors.groupingBy(CostShareParamVO::getId)); shareParamProportionVOList.forEach(i -> { if (CollectionUtils.isEmpty(listMap.get(i.getId()))) { throw new CostException(500, "分摊名称:" + i.getShareParamName() + "未找到"); } }); // 检验输入的数据的和是否是100 AtomicReference sum = new AtomicReference<>(0); shareParamProportionVOList.forEach(i -> { sum.updateAndGet(v -> v + i.getShareParamPopout()); }); int max = Integer.parseInt(sum.toString()); if (!NumberConstant.ONE_HUNDRED.equals(max)) { throw new CostException(500, "分摊比例的和不是100"); } // 判断添加的分摊是否存在一样的 HashMap hashMap = new HashMap<>(); shareParamProportionVOList.forEach(i -> { Long paramId = i.getId(); if (hashMap.containsKey(paramId)) { throw new CostException(500, "不可以添加相同的分摊参数"); } hashMap.put(paramId, i); }); // // String paramList = JsonUtil.toJSONString(shareParamProportionVOList); String paramList = JacksonUtil.obj2StrPretty(shareParamProportionVOList); costAccountShare.setParamList(paramList); } else { costAccountShare.setParamList(null); } baseMapper.updateById(costAccountShare); } /** * 获取责任中心成本表的分摊参数的集合 * * @param id * @param hospId * @return */ @Override public List selectShareParamById(Integer id, Long hospId) { CostAccountShare costAccountShare = baseMapper.selectOne(new QueryWrapper().lambda() .eq(CostAccountShare::getHospId, hospId).eq(CostAccountShare::getId, id)); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "责任中心成本不存在"); } String paramList = costAccountShare.getParamList(); // return JsonUtil.toList(paramList, ShareParamProportionVO.class); // return JacksonUtil.string2ObjList(paramList, List.class, ShareParamProportionVO.class); return JacksonUtil.str2ObjList(paramList, new TypeReference>() {}); } /** * 成本分摊参数中被分摊参数对应选中的状态 * * @param id * @param hospId * @return */ @Override public List getAllShareParamStatusById(Integer id, Long hospId) { List costShareParamServiceAll = costShareParamService.getAll(hospId); CostAccountShare costAccountShare = baseMapper.selectById(id); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "成本分摊对应数据不存在"); } String paramList = costAccountShare.getParamList(); List costShareParamStatusVOList = BeanUtil.convertList(costShareParamServiceAll, CostShareParamStatusVO.class); if (!StringUtils.isEmpty(paramList)) { // List shareParamProportionVOList = JsonUtil.toList(paramList, ShareParamProportionVO.class); List shareParamProportionVOList = JacksonUtil.str2ObjList(paramList, new TypeReference>() {}); Map> map = shareParamProportionVOList.stream().collect(Collectors.groupingBy(ShareParamProportionVO::getId)); costShareParamStatusVOList.forEach(i -> { Long paramId = i.getId(); if (!CollectionUtils.isEmpty(map.get(paramId))) { i.setShareParamStatus(NumberConstant.ONE); } }); } return costShareParamStatusVOList; } /** * 拷贝 * * @param accountShareCopyDto 赋值数据 * @param hospId 医院Id */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void copyAccountShareData(AccountShareCopyDto accountShareCopyDto, Long hospId) { Long id = accountShareCopyDto.getId(); CostAccountShare costAccountShare = this.getById(id); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "成本分摊参数设置对应数据不存在"); } List accountShareList = new ArrayList<>(); List responsibilityIds = accountShareCopyDto.getResponsibilityIds(); Map responsibilityMap = responsibilityService.list(new QueryWrapper().lambda() .eq(Responsibility::getHospId, hospId)).stream().collect(Collectors.toMap(Responsibility::getId, synOne -> synOne)); long millis = System.currentTimeMillis(); responsibilityIds.forEach(i -> { CostAccountShare accountShareRequest = BeanUtil.convertObj(costAccountShare, CostAccountShare.class); accountShareRequest.setId(null); accountShareRequest.setCreateTime(millis); Responsibility responsibility = responsibilityMap.get(i); accountShareRequest.setResponsibilityId(i); accountShareRequest.setResponsibilityCode(responsibility.getResponsibilityCode()); accountShareRequest.setResponsibilityName(responsibility.getResponsibilityName()); accountShareRequest.setShareLevel(responsibility.getShareLevel()); accountShareList.add(accountShareRequest); }); this.saveBatch(accountShareList); } /** * 获取指定类型的责任中心集合 分开计算还是合并计算 * * @param accountShareId * @param hospId * @return */ @Override public List getResponsibilityCalType(Long accountShareId, Long hospId) { CostAccountShare costAccountShare = this.getById(accountShareId); if (Objects.isNull(costAccountShare)) { throw new CostException(500, "成本分摊参数设置对应数据不存在"); } Long responsibilityId = costAccountShare.getResponsibilityId(); Responsibility responsibility = responsibilityService.getById(responsibilityId); Long shareId = responsibility.getShareId(); CostShareLevel costShareLevel = costShareLevelService.getById(shareId); Integer calcType = costShareLevel.getCalcType(); // 分摊参数设置对饮的责任中心的id集合 // List responsibilityIds = this.list(new QueryWrapper().lambda().eq(CostAccountShare::getHospId, hospId)).stream().map(CostAccountShare::getResponsibilityId).distinct().collect(Collectors.toList()); // 执行类型的分摊级别的Id的集合 List costShareIds = costShareLevelService.list(new QueryWrapper().lambda() .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getCalcType, calcType)) .stream().map(CostShareLevel::getId).distinct().collect(Collectors.toList()); String accountingIds = costAccountShare.getAccountingIds(); List responsibilityIdList=null; if (StrUtil.isNotBlank(accountingIds)){ List accountIdList = Arrays.asList(accountingIds.split(StrUtil.COMMA)); responsibilityIdList= baseMapper.getResponsibilityIdsByAccountId(accountIdList); } // 筛选指定类型的责任中心 并且当前没有设置的责任中心 List finalResponsibilityIdList = responsibilityIdList; List responsibilityList = responsibilityService.list(new QueryWrapper().lambda() .eq(Responsibility::getHospId, hospId) .ne(Responsibility::getShareId,NumberConstant.ZERO)) .stream().filter(i -> costShareIds.contains(i.getShareId()) && !responsibilityId.equals(i.getId())).collect(Collectors.toList()); // && (CollUtil.isNotEmpty(finalResponsibilityIdList) && !finalResponsibilityIdList.contains(i.getId())) return responsibilityList; } }