package com.kcim.service.impl; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import com.kcim.common.constants.Constant; import com.kcim.common.constants.NumberConstant; import com.kcim.common.util.BeanUtil; import com.kcim.common.util.UserContext; import com.kcim.dao.model.Accounting; import com.kcim.dao.model.AllocationQuery; import com.kcim.dao.model.Responsibility; import com.kcim.dao.repository.AccountingRepository; import com.kcim.dao.repository.ResponsibilityRepository; import com.kcim.service.AllocationQueryService; import com.kcim.service.CenterService; import com.kcim.service.StandardReportService; import com.kcim.vo.*; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * @program: CostAccount * @description: * @author: Wang.YS * @create: 2024-03-19 11:10 **/ @Service("StandardReportService") @Slf4j @AllArgsConstructor public class StandardReportServiceImpl implements StandardReportService { ResponsibilityRepository responsibilityRepository; AllocationQueryService allocationQueryService; CenterService centerService; AccountingRepository accountingRepository; /** * 科室直接成本表(医疗成本) * @param computeDate 核算年月 * @return */ @Override public List getDeptDirectMedicalCost(String computeDate) { DateTime parse = DateUtil.parse(computeDate); int year = DateUtil.year(parse); int month = DateUtil.month(parse) + 1; //获取科室直接成本 List allocationQueryList = allocationQueryService.getCostByDate(UserContext.getCurrentLoginHospId(), year, month, NumberConstant.ONE); if(CollectionUtils.isEmpty(allocationQueryList)){ return new ArrayList<>(); } //获取所有的标准字典数据 StandCostDictMapVO standCostDictMaps = getStandCostDictMaps(); // 处理 allocationQueryList 数据 Map deptDirectMedicalCostMap = new HashMap<>(); //转换为DeptDirectMedicalCostVO(一个责任中心只一条记录) for (AllocationQuery allocationQuery : allocationQueryList) { addDeptDirectMedicalCostVO(deptDirectMedicalCostMap,allocationQuery, standCostDictMaps); } // 转成List便于处理 List deptDirectMedicalCostList = deptDirectMedicalCostMap.values().stream().collect(Collectors.toList()); //创建医疗业务成本合计 DeptDirectMedicalCostVO medicalBusinessTotal = createSubtotalVo(deptDirectMedicalCostList.get(NumberConstant.ZERO), "医疗业务成本合计", DeptDirectMedicalCostVO.class); //创建总计 DeptDirectMedicalCostVO grandTotal = createSubtotalVo(deptDirectMedicalCostList.get(NumberConstant.ZERO), "总计", DeptDirectMedicalCostVO.class); //按responsibilitySort正序排序 deptDirectMedicalCostList.sort(Comparator.comparing(DeptDirectMedicalCostVO::getResponsibilitySort, Comparator.nullsLast(Comparator.naturalOrder()))); // 按标准分级分组 Map> shareLevelGroup = deptDirectMedicalCostList.stream().collect(Collectors.groupingBy(DeptDirectMedicalCostVO::getStandardShareLevel)); // 科室标准分级按顺序号倒序排序 List standardShareLevelList = standCostDictMaps.getStandardShareLevelDict(); standardShareLevelList.sort(Comparator.comparing(DictDataVo::getSort,Comparator.nullsLast(Comparator.reverseOrder()))); // 创建各层级小计并按正确顺序插入 List result = new ArrayList<>(); for (DictDataVo shareLevel : standardShareLevelList) { List deptDirectMedicalCostVOS = shareLevelGroup.get(shareLevel.getCode()); if(CollectionUtils.isEmpty(deptDirectMedicalCostVOS)){ continue; } // 添加该分类下的所有记录 result.addAll(deptDirectMedicalCostVOS); // 创建小计对象 DeptDirectMedicalCostVO subtotalVo = createSubtotalVo(deptDirectMedicalCostVOS.get(NumberConstant.ZERO),String.format("%s小计", shareLevel.getName()), DeptDirectMedicalCostVO.class); //将科室的金额加到小计对象中 deptDirectMedicalCostVOS.forEach(item -> addBigDecimalFields(item, subtotalVo)); // 如果属于医疗业务成本的科室,则小计的金额加到医疗业务成本 if(NumberConstant.ONE_S.equals(shareLevel.getValue())){ addBigDecimalFields(subtotalVo, medicalBusinessTotal); } // 小计的金额加到总计 addBigDecimalFields(subtotalVo, grandTotal); // 添加小计行 result.add(subtotalVo); // 医疗业务成本加入到医疗辅助类小计后面 if(NumberConstant.TWO_S.equals(shareLevel.getCode())){ result.add(medicalBusinessTotal); } } // 总计加到列表最后面 result.add(grandTotal); return result; } /** * 科室直接成本表(全成本) * @param computeDate 核算年月 * @return 报表数据 */ @Override public List getDeptFullDirectCost(String computeDate) { DateTime parse = DateUtil.parse(computeDate); int year = DateUtil.year(parse); int month = DateUtil.month(parse) + 1; // 获取科室直接成本 List allocationQueryList = allocationQueryService.getCostByDate(UserContext.getCurrentLoginHospId(), year, month, NumberConstant.ONE); if (CollectionUtils.isEmpty(allocationQueryList)) { return new ArrayList<>(); } // 获取所有的标准字典数据 StandCostDictMapVO standCostDictMaps = getStandCostDictMaps(); // 处理 allocationQueryList 数据 Map reportMap = new HashMap<>(); // 转换为DeptDirectAllCostVO(一个责任中心只一条记录) for (AllocationQuery allocationQuery : allocationQueryList) { addDeptDirectAllCostVO(reportMap, allocationQuery, standCostDictMaps); } // 转成List便于处理 List reportList = reportMap.values().stream().collect(Collectors.toList()); // 按responsibilitySort正序排序 reportList.sort(Comparator.comparing(DeptFullDirectCostVO::getResponsibilitySort, Comparator.nullsLast(Comparator.naturalOrder()))); // 按标准分级分组 Map> shareLevelGroup = reportList.stream().collect(Collectors.groupingBy(DeptFullDirectCostVO::getStandardShareLevel)); // 科室标准分级按顺序号倒序排序 List standardShareLevelList = standCostDictMaps.getStandardShareLevelDict(); standardShareLevelList.sort(Comparator.comparing(DictDataVo::getSort, Comparator.nullsLast(Comparator.reverseOrder()))); //创建医疗业务成本合计 DeptFullDirectCostVO medicalBusinessTotal = createSubtotalVo(reportList.get(NumberConstant.ZERO), "医疗业务成本合计", DeptFullDirectCostVO.class); //创建总计 DeptFullDirectCostVO grandTotal = createSubtotalVo(reportList.get(NumberConstant.ZERO), "总计", DeptFullDirectCostVO.class); // 创建各层级小计并按正确顺序插入 List result = new ArrayList<>(); for (DictDataVo shareLevel : standardShareLevelList) { List reportVOS = shareLevelGroup.get(shareLevel.getCode()); if (CollectionUtils.isEmpty(reportVOS)) { continue; } // 添加该分类下的所有记录 result.addAll(reportVOS); // 创建小计对象 DeptFullDirectCostVO subtotalVo = createSubtotalVo(reportVOS.get(NumberConstant.ZERO),String.format("%s小计", shareLevel.getName()), DeptFullDirectCostVO.class); //将科室的金额加到小计对象中 reportVOS.forEach(item -> addBigDecimalFields(item, subtotalVo)); // 如果属于医疗业务成本的科室,则小计的金额加到医疗业务成本 if(NumberConstant.ONE_S.equals(shareLevel.getValue())){ addBigDecimalFields(subtotalVo, medicalBusinessTotal); } // 小计的金额加到总计 addBigDecimalFields(subtotalVo, grandTotal); // 添加小计行 result.add(subtotalVo); // 医疗业务成本加入到医疗辅助类小计后面 if(NumberConstant.TWO_S.equals(shareLevel.getCode())){ result.add(medicalBusinessTotal); } } // 总计加到列表最后面 result.add(grandTotal); return result; } /** * 获取科室成本明细数据 * @param computeDate 核算年月 * @return */ @Override public List getClinicalDeptMedicalCost(String computeDate) { DateTime parse = DateUtil.parse(computeDate); int year = DateUtil.year(parse); int month = DateUtil.month(parse) + 1; // 获取科室直接成本 List allocationQueryList = allocationQueryService.getAllByDate(UserContext.getCurrentLoginHospId(), year, month); if (CollectionUtils.isEmpty(allocationQueryList)) { return new ArrayList<>(); } // 获取所有的标准字典数据 StandCostDictMapVO standCostDictMaps = getStandCostDictMaps(); // 处理 allocationQueryList 数据 Map reportMap = new HashMap<>(); // 添加科室成本明细(一个责任中心只一条记录) for (AllocationQuery allocationQuery : allocationQueryList) { addDeptCostDetailVO(reportMap, allocationQuery, standCostDictMaps); } // 转成List便于处理 List reportList = reportMap.values().stream().collect(Collectors.toList()); // 创建小计对象 ClinicalDeptMedicalCostVO subtotalVo = createSubtotalVo(reportList.get(NumberConstant.ZERO),"科室全成本合计",ClinicalDeptMedicalCostVO.class); //将科室的金额加到小计对象中 reportList.forEach(item -> addBigDecimalFields(item, subtotalVo)); // 总计加到列表最后面 reportList.add(subtotalVo); return reportList; } /** * 添加科室成本明细 * @param reportMap * @param allocationQuery * @param standCostDictMaps */ private void addDeptCostDetailVO(Map reportMap, AllocationQuery allocationQuery, StandCostDictMapVO standCostDictMaps) { String responsibilityCode = allocationQuery.getResponsibilityCode(); Responsibility responsibility = standCostDictMaps.getResponsibilityMap().get(responsibilityCode); if (responsibility == null) { return; // 添加 null 检查 } String accountingCode = allocationQuery.getAccountingCode(); Accounting account = standCostDictMaps.getAccountingMap().get(accountingCode); if (account == null) { return; // 添加 null 检查 } DictDataVo accountType = standCostDictMaps.getAccountingTypeMap().get(account.getType()); if (accountType == null) { return; // 添加 null 检查 } DictDataVo costType = standCostDictMaps.getCostTypeMap().get(account.getCostType()); DictDataVo standardShareLevel = standCostDictMaps.getStandardShareLevelMap().get(responsibility.getStandardShareLevel()); ClinicalDeptMedicalCostVO reportVO = new ClinicalDeptMedicalCostVO(); if (reportMap.containsKey(allocationQuery.getResponsibilityCode())) { reportVO = reportMap.get(allocationQuery.getResponsibilityCode()); } else { //生成科室成本报表信息 initDeptCostReport(reportVO, responsibility, accountType, costType, standardShareLevel); // 初始化所有费用字段为0 BeanUtil.initBigDecimalFieldsToZero(reportVO); } // 根据费用类型累加到对应字段 switch (accountType.getExpandOne()) { case "1": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setPersonnelDirectCost(reportVO.getPersonnelDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setPersonnelIndirectCost(reportVO.getPersonnelIndirectCost().add(allocationQuery.getAmount())); } reportVO.setPersonnelTotalCost(reportVO.getPersonnelTotalCost().add(allocationQuery.getAmount())); break; case "2": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setHealthMaterialDirectCost(reportVO.getHealthMaterialDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setHealthMaterialIndirectCost(reportVO.getHealthMaterialIndirectCost().add(allocationQuery.getAmount())); } reportVO.setHealthMaterialTotalCost(reportVO.getHealthMaterialTotalCost().add(allocationQuery.getAmount())); break; case "3": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setMedicineDirectCost(reportVO.getMedicineDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setMedicineIndirectCost(reportVO.getMedicineIndirectCost().add(allocationQuery.getAmount())); } reportVO.setMedicineTotalCost(reportVO.getMedicineTotalCost().add(allocationQuery.getAmount())); break; case "4": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setFixedAssetDepreciationDirectCost(reportVO.getFixedAssetDepreciationDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setFixedAssetDepreciationIndirectCost(reportVO.getFixedAssetDepreciationIndirectCost().add(allocationQuery.getAmount())); } reportVO.setFixedAssetDepreciationTotalCost(reportVO.getFixedAssetDepreciationTotalCost().add(allocationQuery.getAmount())); break; case "5": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setIntangibleAssetAmortizationDirectCost(reportVO.getIntangibleAssetAmortizationDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setIntangibleAssetAmortizationIndirectCost(reportVO.getIntangibleAssetAmortizationIndirectCost().add(allocationQuery.getAmount())); } reportVO.setIntangibleAssetAmortizationTotalCost(reportVO.getIntangibleAssetAmortizationTotalCost().add(allocationQuery.getAmount())); break; case "6": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setMedicalRiskReserveDirectCost(reportVO.getMedicalRiskReserveDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setMedicalRiskReserveIndirectCost(reportVO.getMedicalRiskReserveIndirectCost().add(allocationQuery.getAmount())); } reportVO.setMedicalRiskReserveTotalCost(reportVO.getMedicalRiskReserveTotalCost().add(allocationQuery.getAmount())); break; case "7": if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setOtherMedicalExpensesDirectCost(reportVO.getOtherMedicalExpensesDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setOtherMedicalExpensesIndirectCost(reportVO.getOtherMedicalExpensesIndirectCost().add(allocationQuery.getAmount())); } reportVO.setOtherMedicalExpensesTotalCost(reportVO.getOtherMedicalExpensesTotalCost().add(allocationQuery.getAmount())); break; default: break; } //添加合计 if(NumberConstant.ONE.equals(allocationQuery.getOriginType().intValue())){ reportVO.setTotalDirectCost(reportVO.getTotalDirectCost().add(allocationQuery.getAmount())); }else{ reportVO.setTotalIndirectCost(reportVO.getTotalIndirectCost().add(allocationQuery.getAmount())); } reportVO.setTotalCost(reportVO.getTotalCost().add(allocationQuery.getAmount())); } /** * 生成科室成本报表信息 * @param reportVO * @param responsibility * @param accountType * @param costType * @param standardShareLevel */ private void initDeptCostReport(BaseDeptCostReportVO reportVO, Responsibility responsibility, DictDataVo accountType, DictDataVo costType, DictDataVo standardShareLevel) { reportVO.setStandardShareLevel(responsibility.getStandardShareLevel()); reportVO.setResponsibilityName(responsibility.getResponsibilityName()); reportVO.setResponsibilityCode(responsibility.getResponsibilityCode()); reportVO.setResponsibilitySort(responsibility.getSort()); reportVO.setCostType(costType.getCode()); reportVO.setStandCostType(costType.getExpandOne()); reportVO.setAccountType(accountType.getCode()); reportVO.setStandAccountType(accountType.getExpandOne()); reportVO.setShareLevelSort(standardShareLevel.getSort()); } /** * 获取所有的标准字典数据并转换所有需要的映射数据 * @return 包含所有映射数据的DTO对象 */ private StandCostDictMapVO getStandCostDictMaps() { StandCostDictMapVO dataMaps = new StandCostDictMapVO(); List responsibilityList = responsibilityRepository.getList(UserContext.getCurrentLoginHospId()); DictDataVo accountingTypeDict = centerService.getDict(Constant.ACCOUNTING_TYPE); DictDataVo costTypeDict = centerService.getDict(Constant.STANDARD_COST_CATEGORIES); DictDataVo standardShareLevelDict = centerService.getDict(Constant.STANDARD_SHARE_LEVEL); List allCostAccounting = accountingRepository.getAllCostAccounting(); // 添加 null 检查 if (responsibilityList == null) { responsibilityList = new ArrayList<>(); } if (allCostAccounting == null) { allCostAccounting = new ArrayList<>(); } // 创建一个映射,用于快速查找责任中心的科室类型,过滤掉 null 对象,过滤掉 responsibilityCode 为 null 的对象 Map responsibilityMap = responsibilityList.stream() .filter(Objects::nonNull) .filter(r -> r.getResponsibilityCode() != null) .collect(Collectors.toMap(Responsibility::getResponsibilityCode, o -> o)); // 创建一个映射,用于快速查找会计科目的类型,过滤掉 null 对象,过滤掉 accountingCode 为 null 的对象 Map accountingMap = allCostAccounting.stream() .filter(Objects::nonNull) .filter(a -> a.getAccountingCode() != null) .collect(Collectors.toMap(Accounting::getAccountingCode, o -> o)); // 添加 null 检查并创建映射 List accountingTypeDictList = (accountingTypeDict != null && accountingTypeDict.getDataVoList() != null) ? accountingTypeDict.getDataVoList() : new ArrayList<>(); List costTypeDictList = (costTypeDict != null && costTypeDict.getDataVoList() != null) ? costTypeDict.getDataVoList() : new ArrayList<>(); List standardShareLevelDictList = (standardShareLevelDict != null && standardShareLevelDict.getDataVoList() != null) ? standardShareLevelDict.getDataVoList() : new ArrayList<>(); // 创建一个映射,用于快速查找会计科目类型的扩展字段,过滤掉 null 对象,过滤掉 code 为 null 的对象 Map accountingTypeMap = accountingTypeDictList.stream() .filter(Objects::nonNull) .filter(d -> d.getCode() != null) .collect(Collectors.toMap(DictDataVo::getCode, o -> o)); // 创建一个映射,用于快速查找会计科目类型的扩展字段,过滤掉 null 对象,过滤掉 code 为 null 的对象 Map costTypeMap = costTypeDictList.stream() .filter(Objects::nonNull) .filter(d -> d.getCode() != null) .collect(Collectors.toMap(DictDataVo::getCode, o -> o)); // 创建一个映射,用于快速查找会计科目类型的扩展字段,过滤掉 null 对象,过滤掉 code 为 null 的对象 Map standardShareLevelMap = standardShareLevelDictList.stream() .filter(Objects::nonNull) .filter(d -> d.getCode() != null) .collect(Collectors.toMap(DictDataVo::getCode, o -> o)); dataMaps.setResponsibilityDict(responsibilityList); dataMaps.setCostAccountingDict(allCostAccounting); dataMaps.setCostTypeDict(costTypeDictList); dataMaps.setAccountingTypeDict(accountingTypeDictList); dataMaps.setStandardShareLevelDict(standardShareLevelDictList); dataMaps.setAccountingMap(accountingMap); dataMaps.setCostTypeMap(costTypeMap); dataMaps.setResponsibilityMap(responsibilityMap); dataMaps.setStandardShareLevelMap(standardShareLevelMap); dataMaps.setAccountingTypeMap(accountingTypeMap); return dataMaps; } /** * 转换为DeptDirectMedicalCostVO(一个责任中心只一条记录) * @param allocationQuery * @param standCostDictMaps * @return */ public void addDeptDirectMedicalCostVO(Map deptDirectMedicalCostMap, AllocationQuery allocationQuery, StandCostDictMapVO standCostDictMaps) { String responsibilityCode = allocationQuery.getResponsibilityCode(); Responsibility responsibility = standCostDictMaps.getResponsibilityMap().get(responsibilityCode); if (responsibility == null) { return; // 添加 null 检查 } String accountingCode = allocationQuery.getAccountingCode(); Accounting account = standCostDictMaps.getAccountingMap().get(accountingCode); if (account == null) { return; // 添加 null 检查 } DictDataVo accountType = standCostDictMaps.getAccountingTypeMap().get(account.getType()); if (accountType == null) { return; // 添加 null 检查 } //只处理医疗成本 if(!NumberConstant.ONE_S.equals(accountType.getExpandOne()) ){ return; } DictDataVo costType = standCostDictMaps.getCostTypeMap().get(account.getCostType()); DictDataVo standardShareLevel = standCostDictMaps.getStandardShareLevelMap().get(responsibility.getStandardShareLevel()); DeptDirectMedicalCostVO deptDirectMedicalCostVO= new DeptDirectMedicalCostVO(); if(deptDirectMedicalCostMap.containsKey(allocationQuery.getResponsibilityCode())){ deptDirectMedicalCostVO=deptDirectMedicalCostMap.get(allocationQuery.getResponsibilityCode()); }else{ initDeptCostReport(deptDirectMedicalCostVO, responsibility,accountType, costType,standardShareLevel); // 初始化所有费用字段为0 BeanUtil.initBigDecimalFieldsToZero(deptDirectMedicalCostVO); } // 根据费用类型累加到对应字段 switch (accountType.getExpandOne()) { case "1": deptDirectMedicalCostVO.setPersonnelExpense(deptDirectMedicalCostVO.getPersonnelExpense().add((allocationQuery.getAmount()))); break; case "2": deptDirectMedicalCostVO.setHealthMaterialFee(deptDirectMedicalCostVO.getHealthMaterialFee().add((allocationQuery.getAmount()))); break; case "3": deptDirectMedicalCostVO.setDrugFee(deptDirectMedicalCostVO.getDrugFee().add((allocationQuery.getAmount()))); break; case "4": deptDirectMedicalCostVO.setFixedAssetDepreciation(deptDirectMedicalCostVO.getFixedAssetDepreciation().add((allocationQuery.getAmount()))); break; case "5": deptDirectMedicalCostVO.setIntangibleAssetAmortization(deptDirectMedicalCostVO.getIntangibleAssetAmortization().add((allocationQuery.getAmount()))); break; case "6": deptDirectMedicalCostVO.setMedicalRiskFundExtraction(deptDirectMedicalCostVO.getMedicalRiskFundExtraction().add((allocationQuery.getAmount()))); break; case "7": deptDirectMedicalCostVO.setOtherMedicalExpenses(deptDirectMedicalCostVO.getOtherMedicalExpenses().add((allocationQuery.getAmount()))); break; default: break; } // 更新总计 deptDirectMedicalCostVO.setTotal(deptDirectMedicalCostVO.getTotal().add(allocationQuery.getAmount())); } /** * 转换为DeptDirectAllCostVO(一个责任中心只一条记录) * @param reportMap * @param allocationQuery * @param standCostDictMaps */ private void addDeptDirectAllCostVO(Map reportMap, AllocationQuery allocationQuery, StandCostDictMapVO standCostDictMaps) { String responsibilityCode = allocationQuery.getResponsibilityCode(); Responsibility responsibility = standCostDictMaps.getResponsibilityMap().get(responsibilityCode); if (responsibility == null) { return; // 添加 null 检查 } String accountingCode = allocationQuery.getAccountingCode(); Accounting account = standCostDictMaps.getAccountingMap().get(accountingCode); if (account == null) { return; // 添加 null 检查 } DictDataVo accountType = standCostDictMaps.getAccountingTypeMap().get(account.getType()); if (accountType == null) { return; // 添加 null 检查 } DictDataVo costType = standCostDictMaps.getCostTypeMap().get(account.getCostType()); DictDataVo standardShareLevel = standCostDictMaps.getStandardShareLevelMap().get(responsibility.getStandardShareLevel()); DeptFullDirectCostVO reportVO = new DeptFullDirectCostVO(); if (reportMap.containsKey(allocationQuery.getResponsibilityCode())) { reportVO = reportMap.get(allocationQuery.getResponsibilityCode()); } else { initDeptCostReport(reportVO, responsibility,accountType, costType,standardShareLevel); // 初始化所有费用字段为0 BeanUtil.initBigDecimalFieldsToZero(reportVO); } // 根据费用类型累加到对应字段 switch (costType.getValue()) { case "1": reportVO.setMedicalCostTotal(reportVO.getMedicalCostTotal().add(allocationQuery.getAmount())); break; case "2": reportVO.setFinancialProjectFunds(reportVO.getFinancialProjectFunds().add(allocationQuery.getAmount())); break; case "3": reportVO.setNonPeerFinancialFunds(reportVO.getNonPeerFinancialFunds().add(allocationQuery.getAmount())); break; case "4": reportVO.setEducationalExpenses(reportVO.getEducationalExpenses().add(allocationQuery.getAmount())); break; case "5": reportVO.setAssetDisposalFees(reportVO.getAssetDisposalFees().add(allocationQuery.getAmount())); break; default: break; } //不是医院全成本的都是医疗全成本 if(!NumberConstant.THREE_S.equals(costType.getExpandOne())){ // 医疗全成本合计 reportVO.setMedicalTotalCost(reportVO.getMedicalTotalCost().add(allocationQuery.getAmount())); } // 医院全成本合计 reportVO.setHospitalTotalCost(reportVO.getHospitalTotalCost().add(allocationQuery.getAmount())); } /** * 合并两个科室成本 * @param source 源对象 * @param target 目标对象 */ public void addBigDecimalFields(T source, T target) { if (source == null || target == null) { return; } Class clazz = target.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.getType().equals(BigDecimal.class)) { field.setAccessible(true); try { BigDecimal sourceValue = (BigDecimal) field.get(source); BigDecimal targetValue = (BigDecimal) field.get(target); BigDecimal result = (targetValue == null ? BigDecimal.ZERO : targetValue) .add(sourceValue == null ? BigDecimal.ZERO : sourceValue); field.set(target, result); } catch (IllegalAccessException e) { log.error("合并科室成本时发生错误", e); } } } } /** * 通用创建小计对象方法 * @param source 源对象 * @param totalName 小计名称 * @param clazz 目标类类型 * @return 小计对象 */ public T createSubtotalVo(T source, String totalName, Class clazz) { if (source == null) { return null; } T target = BeanUtil.convertObj(source, clazz); // 使用反射设置责任代码和名称 try { clazz.getMethod("setResponsibilityCode", String.class).invoke(target, totalName); clazz.getMethod("setResponsibilityName", String.class).invoke(target, totalName); } catch (Exception e) { log.error("设置责任代码和名称时发生错误", e); } // 初始化所有费用字段为0 BeanUtil.initBigDecimalFieldsToZero(target); return target; } }