package com.imed.costaccount.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; 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.imed.costaccount.common.util.BeanUtil; import com.imed.costaccount.common.util.DateUtils; import com.imed.costaccount.common.util.PageUtils; import com.imed.costaccount.constants.NumberConstant; import com.imed.costaccount.enums.DateStyleEnum; import com.imed.costaccount.mapper.CostDepartmentProfitMapper; import com.imed.costaccount.model.*; import com.imed.costaccount.model.vo.CostDepartmentProfitVO; import com.imed.costaccount.service.*; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @Service("costDepartmentProfitService") public class CostDepartmentProfitServiceImpl extends ServiceImpl implements CostDepartmentProfitService { private final ReportFormService reportFormService; private final IncomeCollectionService incomeCollectionService; private final CostShareLevelService costShareLevelService; private final ResponsibilityService responsibilityService; private final ReportRelationService reportRelationService; private final AllocationService allocationService; public CostDepartmentProfitServiceImpl(ReportFormService reportFormService, IncomeCollectionService incomeCollectionService, CostShareLevelService costShareLevelService, ResponsibilityService responsibilityService, ReportRelationService reportRelationService, AllocationService allocationService) { this.reportFormService = reportFormService; this.incomeCollectionService = incomeCollectionService; this.costShareLevelService = costShareLevelService; this.responsibilityService = responsibilityService; this.reportRelationService = reportRelationService; this.allocationService = allocationService; } /** * 查询科室损益数据 * * @param current * @param pageSize * @param responsibilityCode * @param date * @param hospId * @return */ @Override public PageUtils queryList(Integer current, Integer pageSize, String responsibilityCode, String date, Long hospId) { int year = 0; int month = 0; if (StrUtil.isNotBlank(date)) { Date dateTime = DateUtils.StringToDate(date, DateStyleEnum.YYYY_MM_DD); year = DateUtil.year(dateTime); month = DateUtil.month(dateTime) + 1; } Page departmentProfitPage = new Page<>(current, pageSize); Page pages = this.page(departmentProfitPage, new QueryWrapper().lambda() .eq(CostDepartmentProfit::getHospId, hospId) .eq(StrUtil.isNotBlank(responsibilityCode), CostDepartmentProfit::getResponsibilityCode, responsibilityCode) .eq(StrUtil.isNotBlank(date), CostDepartmentProfit::getYear, year) .eq(StrUtil.isNotBlank(date), CostDepartmentProfit::getMonth, month)); List records = pages.getRecords(); List costDepartmentProfitVOList = BeanUtil.convertList(records, CostDepartmentProfitVO.class); PageUtils pageUtils = new PageUtils(pages); pageUtils.setList(costDepartmentProfitVOList); return pageUtils; } /** * 科室损益计算 * * @param date * @param hospId */ @Override public void setDepartmentProfit(String date, Long hospId) { int year = 0; int month = 0; if (StrUtil.isNotBlank(date)) { Date dateTime = DateUtils.StringToDate(date, DateStyleEnum.YYYY_MM_DD); year = DateUtil.year(dateTime); month = DateUtil.month(dateTime) + 1; } // 先查询指定条件的报表数据 List reportFormList = reportFormService.list(new QueryWrapper().lambda() .eq(ReportForm::getHospId, hospId) .eq(ReportForm::getReportType, NumberConstant.ZERO).ne(ReportForm::getCalcType, NumberConstant.ZERO)); // 遍历报表数据根据报表数据计算方式进行计算 // 查询最后一个层级的责任中心 List costShareLevelList = costShareLevelService.list(new QueryWrapper().lambda() .eq(CostShareLevel::getHospId, hospId).orderByDesc(CostShareLevel::getLeverSort)); Long id = costShareLevelList.get(0).getId(); // 查询责任中心里面是这个层级的所有的收益中心 List responsibilityList = responsibilityService.list(new QueryWrapper().lambda() .eq(Responsibility::getHospId, hospId).eq(Responsibility::getResponsibilityType, NumberConstant.ONE)); // 归集前 List incomeList = incomeCollectionService.list(new QueryWrapper().lambda() .eq(IncomeCollection::getHospId, hospId) .eq(year > 0, IncomeCollection::getYear, year).eq(month > 0, IncomeCollection::getMonth, month)); Map> reportRelationMap = reportRelationService.list(new QueryWrapper().lambda().eq(ReportRelation::getHospId, hospId)).stream().collect(Collectors.groupingBy(ReportRelation::getReportId)); // TODO 需要查询归集后的数据 // 查询分摊的报表数据 List allocationList = allocationService.list(new QueryWrapper().lambda().eq(Allocation::getHospId, hospId) .eq(year > 0, Allocation::getDateYear, year).eq(month > 0, Allocation::getDateMonth, month)); // 查询所有指定类型的损益表 // 每个责任中心对应报表都要生成记录 // 封装需要设置的数据 List list = new ArrayList<>(); int finalYear = year; int finalMonth = month; responsibilityList.forEach(i->{ reportFormList.forEach(j->{ CostDepartmentProfitVO costDepartmentProfitVO = new CostDepartmentProfitVO(); costDepartmentProfitVO.setYear(finalYear); costDepartmentProfitVO.setMonth(finalMonth); costDepartmentProfitVO.setReportNum(j.getNum()); costDepartmentProfitVO.setCostType(j.getCalcType()); costDepartmentProfitVO.setReportName(j.getReportName()); costDepartmentProfitVO.setResponsibilityCode(i.getResponsibilityCode()); costDepartmentProfitVO.setResponsibilityName(i.getResponsibilityName()); costDepartmentProfitVO.setReportParentId(i.getParentId()); costDepartmentProfitVO.setCostType(NumberConstant.ONE); costDepartmentProfitVO.setIncomeType(NumberConstant.ONE); costDepartmentProfitVO.setHospId(hospId); list.add(costDepartmentProfitVO); }); }); list.forEach(i->{ Integer calcType = i.getCostType(); switch (calcType){ case 1: // TODO 按照会计科目进行计算 setAccountReportData(i,incomeList,reportRelationMap); break; case 2: // TODO 按照分摊层级进行计算 break; case 3: // TODO 按照小计进行计算 break; case 4: // TODO 按照计算公式进行计算 break; case 5: // TODO 按照责任中心进行计算 break; default: i.setAmount(new BigDecimal("0.0000")); break; } }); } /** * 按照会计科目进行计算 * @param i */ private void setAccountReportData(CostDepartmentProfitVO i,List list,Map> reportRelationMap) { // 在报表关联里面查询当前报表关联的 List reportRelationList = reportRelationMap.get(i.getId()); if (CollUtil.isNotEmpty(reportRelationList)){ // 获取对应的会计科目信息 筛选会计科目的Code List accountList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList()); // 查找在归集数据里面当前责任中心对应的这些会计科目的金额 List incomeCollectionList = list.stream().filter(income -> income.getResponsibilityCode().equals(i.getResponsibilityCode()) && accountList.contains(income.getAccountingCode())).collect(Collectors.toList()); AtomicReference sum= new AtomicReference<>(new BigDecimal("0.000")); incomeCollectionList.forEach(m->{ sum.updateAndGet(v -> v.add(m.getAmount())); }); // TODO 需要查询分摊后的表 i.setAmount(new BigDecimal(sum.toString())); }else { i.setAmount(new BigDecimal("0.0000")); } } /** * 按照分摊层级进行计算 */ private void setShareLevelReportData(CostDepartmentProfitVO i,Map> reportRelationMap,List allocationList){ List reportRelationList = reportRelationMap.get(i.getId()); // 找到对应的分摊层级的Id List shareLevelIds = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList()); if (CollUtil.isNotEmpty(shareLevelIds)){ // 查询报表里面是当前分摊层级的数据 AtomicReference sum= new AtomicReference<>(new BigDecimal("0.000")); List allocations = allocationList.stream().filter(m -> m.getLevelSort().equals(i.getLevelSort()) && m.getTargetResponsibilityCode().equals(i.getResponsibilityCode())).collect(Collectors.toList()); allocations.forEach(m->{ sum.updateAndGet(v -> v.add(m.getAmount())); }); i.setAmount(new BigDecimal(sum.toString())); }else { i.setAmount(new BigDecimal("0.0000")); } } /** * 按照责任中心进行计算 * 原始责任中心是设置的责任中心 目标责任中心是报表的责任中心 */ public void setResponsibilityCode(){ } }