using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services.AllotCompute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Performance.Services
{
    /// <summary>
    /// 临床科室主任
    /// </summary>
    public class ComputeDirector : IAutoInjection
    {
        private readonly BaiscNormService baiscNormService;
        private readonly PerforCofdirectorRepository perforCofdirectorRepository;
        private readonly PerforCofworkyearRepository perforCofworkyearRepository;
        private readonly PerforResaccountRepository perforResaccountRepository;
        private readonly PerforRescomputeRepository perforRescomputeRepository;
        private readonly BudgetService budgetService;
        //private readonly PerforResaccountdoctorRepository perforResAccountdoctorRepository;

        public ComputeDirector(BaiscNormService baiscNormService,
            PerforCofdirectorRepository perforCofdirectorRepository,
            PerforCofworkyearRepository perforCofworkyearRepository,
            PerforResaccountRepository perforResaccountRepository,
            PerforRescomputeRepository perforRescomputeRepository,
            BudgetService budgetService)
        {
            this.baiscNormService = baiscNormService;
            this.perforCofdirectorRepository = perforCofdirectorRepository;
            this.perforCofworkyearRepository = perforCofworkyearRepository;
            this.perforResaccountRepository = perforResaccountRepository;
            this.perforRescomputeRepository = perforRescomputeRepository;
            this.budgetService = budgetService;
        }

        #region 老版计算
        ///// <summary>
        ///// 临床科室主任、临床科室副主任、临床科室护士长 计算
        ///// </summary>
        ///// <param name="empolyeeList"></param>
        ///// <param name="nurseList"></param>
        ///// <param name="directorList"></param>
        ///// <returns></returns>
        //public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<im_accountbasic> accountbasicList, per_allot allot)
        //{
        //    //规模绩效和效率绩效配置表
        //    var directorList = perforCofdirectorRepository.GetEntities(t => t.AllotID == allot.ID);
        //    //取出医生科室
        //    var doctorList = perforResAccountdoctorRepository.GetEntities(t => t.AllotID == allot.ID);
        //    //取出护士科室
        //    var nurseList = perforResAccountnurseRepository.GetEntities(t => t.AllotID == allot.ID);

        //    List<ComputeResult> computeList = new List<ComputeResult>();
        //    // 主任及护士长 对应 效率绩效/规模绩效 关系
        //    // 科室名称 确定绩效计算人员中的人群
        //    // 绩效考核基数参考对象  确定科室下那些考核对象归纳为 科室主任  护士长
        //    // 数据库存放的文本 与枚举 全文字中文匹配
        //    var basicRuleList = new[]
        //    {
        //        new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.临床主任, DirectorType = DirectorType.临床科室主任 },
        //        new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.临床副主任, DirectorType = DirectorType.临床科室副主任 },
        //        new { AccountUnitType = AccountUnitType.医技科室, PerforType = PerforType.医技主任, DirectorType = DirectorType.医技科室主任 },
        //        new { AccountUnitType = AccountUnitType.医技科室, PerforType = PerforType.医技副主任, DirectorType = DirectorType.医技科室副主任 },
        //        new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.护士长, DirectorType = DirectorType.临床科室护士长 },
        //    };
        //    foreach (var basicRule in basicRuleList)
        //    {
        //        var needCompute = empolyeeList.Where(t => t.AccountType == basicRule.AccountUnitType.ToString() && t.FitPeople.Trim() == EnumHelper.GetDescription(basicRule.PerforType));
        //        foreach (var item in needCompute)
        //        {
        //            var accountbasic = accountbasicList.FirstOrDefault(t => t.Department == item.Department);
        //            if (accountbasic == null) continue;

        //            //分别取出对应的 计算 人员 平均值等信息
        //            decimal? number, perforTotal, avg;
        //            if (basicRule.PerforType == PerforType.护士长)
        //            {
        //                if (!accountbasic.NurseHeadNumber.HasValue || accountbasic.NurseHeadNumber.Value == 0) continue;

        //                var resAccount = nurseList.FirstOrDefault(t => t.AccountingUnit == item.AccountingUnit);
        //                number = resAccount?.Number;
        //                perforTotal = resAccount?.PerforTotal;
        //                avg = resAccount?.Avg;
        //            }
        //            else
        //            {
        //                if (!accountbasic.DoctorDirectorNumber.HasValue || accountbasic.DoctorDirectorNumber.Value == 0) continue;

        //                var resAccount = doctorList.FirstOrDefault(t => t.AccountingUnit == item.AccountingUnit);
        //                number = resAccount?.Number;
        //                perforTotal = resAccount?.PerforTotal;
        //                avg = resAccount?.Avg;
        //            }
        //            var efficiency = (basicRule.PerforType == PerforType.护士长) ? accountbasic.NurseEffic : accountbasic.DoctorEffic;
        //            var scale = (basicRule.PerforType == PerforType.护士长) ? accountbasic.NurseScale : accountbasic.DoctorScale;
        //            var grant = (basicRule.PerforType == PerforType.护士长) ? accountbasic.NurseGrant : accountbasic.DoctorGrant;

        //            var compute = new ComputeResult
        //            {
        //                AccountType = item.AccountType,
        //                AccountingUnit = item.AccountingUnit,
        //                EmployeeName = item.DoctorName,
        //                FitPeople = item.FitPeople,
        //                JobTitle = item.JobTitle,

        //                Number = number,
        //                PerforTotal = perforTotal,
        //                Avg = avg,
        //                Efficiency = avg * (efficiency ?? 1),
        //                Scale = perforTotal * (scale ?? 1),
        //                //Grant = item.Grant ?? 1,
        //                ScoreAverageRate = item.ScoreAverageRate,
        //                Punishment = item.Punishment,
        //                OtherPerfor = item.OtherPerfor,
        //                Adjust = item.Adjust,
        //                //Workload = item.Workload
        //            };
        //            //应发管理绩效
        //            compute.ShouldGiveFee = (compute.Efficiency + compute.Scale) * grant;
        //            //绩效合计
        //            compute.PerforSumFee = compute.Avg + compute.ShouldGiveFee;
        //            //应发绩效
        //            compute.GiveFee = compute.PerforSumFee * compute.ScoreAverageRate + (item.Punishment ?? 0) + (item.OtherPerfor ?? 0);
        //            //实发绩效
        //            compute.RealGiveFee = compute.GiveFee * (item.Adjust ?? 1m);
        //            computeList.Add(compute);
        //        }

        //    }
        //    return computeList;
        //} 
        #endregion

        #region 北京东方模板改版注释20200228
        ///// <summary>
        ///// 临床科室主任、临床科室副主任、临床科室护士长 计算
        ///// </summary>
        ///// <param name="empolyeeList"></param>
        ///// <param name="nurseList"></param>
        ///// <param name="directorList"></param>
        ///// <returns></returns>
        //public List<ComputeResult> Compute2(List<ComputeEmployee> empolyeeList, List<im_accountbasic> accountbasicList, List<PerSheet> accountSheet, per_allot allot, bool isMinimum)
        //{
        //    var basicRuleList = new[]
        //    {
        //        new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.医生组 },
        //        new { AccountUnitType = AccountUnitType.护士长, UnitType = UnitType.护理组 },
        //        new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.医技组 },
        //    };
        //    //取出科室
        //    List<res_account> dataList = new List<res_account>();
        //    foreach (var account in accountSheet)
        //    {
        //        dataList.AddRange(AutoMapper.Mapper.Map<List<res_account>>(account.PerData.Select(t => (PerDataAccountBaisc)t)));
        //    }
        //    var multi = accountbasicList.GroupBy(t => new { t.UnitType, t.DoctorAccountingUnit })
        //                    .Select(t => new { t.Key.UnitType, t.Key.DoctorAccountingUnit, Count = t.Count(), })
        //                    .Where(t => t.Count > 1);
        //    List<ComputeResult> computeList = new List<ComputeResult>();
        //    foreach (var accountbasic in accountbasicList)
        //    {
        //        if (!accountbasic.DoctorDirectorNumber.HasValue || accountbasic.DoctorDirectorNumber.Value == 0)
        //            continue;
        //        //if ((!accountbasic.DoctorDirectorNumber.HasValue && "皮肤科" != accountbasic.DoctorAccountingUnit) || (accountbasic.DoctorDirectorNumber.Value == 0 && "皮肤科" != accountbasic.DoctorAccountingUnit))
        //        //    continue;

        //        //原不存在科主任则跳过科主任绩效计算20190920新都
        //        //是否共用核算单元
        //        var isShare = multi.Any(group => group.UnitType == accountbasic.UnitType && group.DoctorAccountingUnit == accountbasic.DoctorAccountingUnit);
        //        if (isShare
        //            && accountbasic.DoctorDirectorNumber.HasValue && accountbasic.DoctorDirectorNumber.Value < 1
        //            && accountbasic.Department != accountbasic.DoctorAccountingUnit)
        //            continue;
        //        //分别取出对应的 计算 人员 平均值等信息 
        //        var resAccount = dataList.Where(t => t.UnitType == accountbasic.UnitType && t.AccountingUnit == accountbasic.DoctorAccountingUnit);
        //        var number = resAccount.OrderByDescending(t => t.ManagerNumber).Sum(t => t.ManagerNumber + t.Number);
        //        var perforTotal = resAccount.Sum(t => t.PerforTotal);
        //        //var avg = resAccount.Average(t => t.Avg);
        //        //绩效参考标准，不使用实发绩效             
        //        //var realAvg = resAccount.Sum(t => (t.ManagerNumber + t.Number) == 0 ? 0 : t.RealGiveFee / (t.ManagerNumber + t.Number)) / resAccount.Count();
        //        //var realAvg = resAccount.Sum(t => t.Number + t.ManagerNumber) == 0 ? 0 : resAccount.Sum(t => t.RealGiveFee) / resAccount.Sum(t => t.Number + t.ManagerNumber);

        //        decimal? realAvg = 0, realAvg2 = 0;
        //        bool isAvg = true;
        //        //if ("内五科" == accountbasic.DoctorAccountingUnit && isShare)
        //        //    realAvg = resAccount.Sum(r => r.Number + r.ManagerNumber) == 0 ? 0 : resAccount.Sum(r => r.RealGiveFee) / resAccount.Sum(r => r.Number);
        //        //else
        //        //{
        //        foreach (var item in resAccount)
        //        {
        //            if ((item.ManagerNumber + item.Number) == 0)
        //            {
        //                isAvg = false;
        //                realAvg = resAccount.Sum(r => r.Number + r.ManagerNumber) == 0 ? 0 : resAccount.Sum(r => r.RealGiveFee) / resAccount.Sum(r => r.Number + r.ManagerNumber);
        //                realAvg2 = resAccount.Sum(r => r.PermanentStaff) == 0 ? 0 : resAccount.Sum(r => r.RealGiveFee) / resAccount.Sum(r => r.PermanentStaff);
        //                break;
        //            }
        //            else
        //            {
        //                realAvg += item.RealGiveFee / (item.ManagerNumber + item.Number);
        //                realAvg2 += item.PermanentStaff == 0 ? 0 : item.RealGiveFee / item.PermanentStaff;
        //            }
        //        }
        //        if (isAvg)
        //        {
        //            realAvg = realAvg / resAccount.Count();
        //            realAvg2 = realAvg2 / resAccount.Count();
        //        }
        //        //}

        //        var realGiveFee = resAccount.Sum(t => t.RealGiveFee);


        //        var basicRule = basicRuleList.FirstOrDefault(t => t.UnitType == (UnitType)accountbasic.UnitType);
        //        if (basicRule == null) continue;
        //        var empolyees = empolyeeList.Where(t => t.UnitType == basicRule.UnitType.ToString() && t.AccountingUnit == accountbasic.DoctorAccountingUnit);
        //        foreach (var empolyee in empolyees)
        //        {
        //            //if (empolyee == null)
        //            //{
        //            //    empolyee = new ComputeEmployee
        //            //    {
        //            //        AccountType = basicRule.AccountUnitType.ToString(),
        //            //        DoctorName = "人员信息缺失",
        //            //        FitPeople = "",
        //            //        ScoreAverageRate = 1,
        //            //        Punishment = 0,
        //            //        OtherPerfor = 0,
        //            //        Adjust = 1,
        //            //    };
        //            //}
        //            var compute = new ComputeResult
        //            {
        //                UnitType = basicRule.UnitType.ToString(),
        //                AccountingUnit = accountbasic.DoctorAccountingUnit,

        //                AccountType = basicRule.AccountUnitType.ToString(),
        //                EmployeeName = empolyee.DoctorName,
        //                FitPeople = empolyee.FitPeople,
        //                JobTitle = empolyee.JobTitle,
        //                JobNumber = empolyee.JobNumber,

        //                ScoreAverageRate = empolyee.ScoreAverageRate,
        //                Punishment = empolyee.Punishment,
        //                OtherPerfor = empolyee.OtherPerfor,

        //                Number = number,
        //                PerforTotal = realGiveFee,
        //                Avg = realAvg,
        //                Efficiency = realAvg2 * (empolyee.Efficiency ?? 1),
        //                Scale = perforTotal * (empolyee.Scale ?? 1),
        //                Adjust = empolyee.Adjust,
        //                Remark = isShare ? "特殊科室主任，共用核算单元" : ""
        //            };
        //            //应发管理绩效
        //            compute.ShouldGiveFee = (compute.Efficiency + compute.Scale) * (empolyee.Management ?? 0);
        //            //绩效合计
        //            compute.PerforSumFee = compute.Avg + compute.ShouldGiveFee;
        //            //应发绩效
        //            compute.GiveFee = compute.PerforSumFee;
        //            //实发绩效
        //            compute.RealGiveFee = (compute.GiveFee * compute.ScoreAverageRate + (compute.Punishment ?? 0) + (compute.OtherPerfor ?? 0)) * (compute.Adjust ?? 1m);
        //            // 参考基数专用绩效合计
        //            compute.BaiscNormPerforTotal = compute.RealGiveFee;

        //            computeList.Add(compute);
        //        }
        //    }
        //    return computeList;
        //}
        #endregion

        /// <summary>
        /// 临床科室主任、临床科室副主任、临床科室护士长 计算
        /// </summary>
        /// <param name="empolyeeList"></param>
        /// <param name="nurseList"></param>
        /// <param name="directorList"></param>
        /// <returns></returns>
        public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<PerSheet> accountSheet, per_allot allot)
        {
            var basicRuleList = new[]
            {
                new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.医生组 },
                new { AccountUnitType = AccountUnitType.护士长, UnitType = UnitType.护理组 },
                new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.医技组 },
                new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.其他医生组 },
                new { AccountUnitType = AccountUnitType.护士长, UnitType = UnitType.其他护理组 },
                new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.其他医技组 },
            };
            //取出科室
            List<res_account> dataList = new List<res_account>();
            foreach (var account in accountSheet)
            {
                dataList.AddRange(AutoMapper.Mapper.Map<List<res_account>>(account.PerData.Select(t => (PerDataAccountBaisc)t)));
            }
            List<ComputeResult> computeList = new List<ComputeResult>();
            if (empolyeeList == null) return computeList;

            var isBudget = budgetService.GetAdjustAndGrant(allot, out decimal adjust, out decimal grant);

            var unit = new[]
            {
                new { UnitType = UnitType.其他医生组, NewUnitType = UnitType.医生组.ToString() },
                new { UnitType = UnitType.其他护理组, NewUnitType = UnitType.护理组.ToString() },
                new { UnitType = UnitType.其他医技组, NewUnitType = UnitType.医技组.ToString() },
            };

            var empDis = empolyeeList.Select(w => new { w.DoctorName, w.JobNumber }).Distinct();
            foreach (var emp in empDis)
            {
                var empolyees = empolyeeList.Where(w => w.DoctorName == emp.DoctorName && w.JobNumber == emp.JobNumber);
                for (int i = 0; i < empolyees.Count(); i++)
                {
                    var empolyee = empolyees.ElementAt(i);

                    string unitType = empolyee.UnitType;
                    if (unit.Select(t => t.UnitType.ToString()).Contains(empolyee.UnitType))
                    {
                        unitType = unit.FirstOrDefault(t => t.UnitType.ToString() == empolyee.UnitType)?.NewUnitType;
                    }

                    var resAccount = dataList.FirstOrDefault(t => ((UnitType)t.UnitType).ToString() == empolyee.UnitType && t.AccountingUnit == empolyee.AccountingUnit)
                        ?? dataList.FirstOrDefault(t => ((UnitType)t.UnitType).ToString() == unitType && t.AccountingUnit == empolyee.AccountingUnit);
                    if (resAccount == null && empolyees.Count() > 1)
                    {
                        // 如果没有找到科室，则找相同用户的其他核算单元类型
                        //for (int j = 0; j < empolyees.Count(); j++)
                        //{
                        //    if (i == j) continue;
                        //    var empolyee2 = empolyees.ElementAt(j);
                        //    resAccount = dataList.FirstOrDefault(t => ((UnitType)t.UnitType).ToString() == empolyee2.UnitType && t.AccountingUnit == empolyee2.AccountingUnit);
                        //    if (resAccount != null) continue;
                        //}
                        //if (resAccount == null) continue;

                        var unitTypes = new[]
                        {
                            new { UnitType = new List<int>{ (int)UnitType.医生组, (int)UnitType.医技组 }, JobTitle = "主任" },
                            new { UnitType = new List<int>{ (int)UnitType.护理组 }, JobTitle = "护士长" },
                        };
                        foreach (var type in unitTypes)
                        {
                            if ((empolyee.JobTitle?.IndexOf(type.JobTitle) ?? -1) == -1) continue;
                            foreach (var item in type.UnitType)
                            {
                                resAccount = dataList.FirstOrDefault(t => t.UnitType == item && t.AccountingUnit == empolyee.AccountingUnit);
                                if (resAccount != null) continue;
                            }
                        }
                    }
                    if (resAccount == null) continue;

                    var basicRule = basicRuleList.FirstOrDefault(t => t.UnitType == (UnitType)resAccount.UnitType);
                    if (basicRule == null) continue;

                    // 优先取 实际人均绩效
                    var avg = (empolyee.FitPeopleValue.HasValue)
                        ? empolyee.FitPeopleValue
                        : resAccount.Number == 0 ? 0 : resAccount.PerforTotal / resAccount.Number;
                    var effAvg = empolyee.PermanentStaff == 0 ? 0 : resAccount.PerforTotal / empolyee.PermanentStaff;

                    //var efficiency = avg * (empolyee.Efficiency ?? 1);
                    var scale = resAccount.PerforTotal * (empolyee.Scale ?? 1);
                    var compute = new ComputeResult
                    {
                        UnitType = empolyee.UnitType,
                        AccountingUnit = empolyee.AccountingUnit,

                        AccountType = basicRule.AccountUnitType.ToString(),
                        EmployeeName = empolyee.DoctorName,
                        FitPeople = empolyee.FitPeople,
                        FitPeopleRatio = empolyee.FitPeopleRatio,
                        FitPeopleValue = empolyee.FitPeopleValue,
                        JobTitle = empolyee.JobTitle,
                        JobNumber = empolyee.JobNumber,

                        AssessBeforeOtherFee = empolyee.AssessBeforeOtherFee ?? 0,
                        ScoreAverageRate = empolyee.ScoreAverageRate ?? 1,
                        AssessLaterOtherFee = empolyee.AssessLaterOtherFee ?? 0,
                        AdjustLaterOtherFee = empolyee.AdjustLaterOtherFee ?? 0,
                        //OtherPerfor = empolyee.OtherPerfor ?? 0,
                        OtherManagePerfor = empolyee.OtherManagePerfor ?? 0,
                        Number = resAccount.Number,
                        PerforTotal = resAccount.PerforTotal,
                        Efficiency = effAvg * (empolyee.Efficiency ?? 0),
                        Scale = resAccount.PerforTotal * (empolyee.Scale ?? 0),
                        Adjust = (isBudget ? adjust : empolyee.Adjust) ?? 1m,
                        Remark = empolyees.Count() > 1 ? "核算单元共用科主任/护士长" : "",
                        Grant = (isBudget ? grant : empolyee.Management) ?? 0,
                        //ManagerNumber = resAccount.ManagerNumber,
                        MedicalNumber = resAccount.Number,
                        PermanentStaff = empolyee.PermanentStaff,
                        Attendance = empolyee.Attendance ?? 0,
                    };

                    //var extra = employeeExtra?.Where(w => !string.IsNullOrEmpty(w.AccountingUnit) && !string.IsNullOrEmpty(w.UnitType)
                    //        && (!string.IsNullOrEmpty(w.EmployeeName) || !string.IsNullOrEmpty(w.JobNumber)))
                    //    .FirstOrDefault(w => w.AccountingUnit == empolyee.AccountingUnit && w.UnitType == empolyee.UnitType
                    //        && w.JobNumber == empolyee.JobNumber && w.EmployeeName == empolyee.DoctorName)?.TotelValue;

                    compute.Avg = avg * (empolyee.Basics ?? 0) * compute.Attendance;
                    compute.Punishment = (empolyee?.Punishment ?? 0);
                    // 考核前管理绩效
                    compute.ShouldGiveFee = Math.Round((compute.Efficiency + compute.Scale) * compute.Grant + compute.OtherManagePerfor ?? 0, MidpointRounding.AwayFromZero);
                    // 考核后管理绩效
                    compute.AssessLaterManagementFee = Math.Round(compute.ShouldGiveFee * compute.ScoreAverageRate * compute.Attendance + compute.Punishment ?? 0, MidpointRounding.AwayFromZero);
                    // 考核前绩效
                    compute.PerforSumFee = compute.Attendance == 0 ? Math.Round(compute.ShouldGiveFee ?? 0, MidpointRounding.AwayFromZero) : Math.Round(compute.Avg / compute.Attendance + compute.ShouldGiveFee ?? 0, MidpointRounding.AwayFromZero);
                    // 考核后绩效
                    compute.GiveFee = Math.Round((compute.Avg ?? 0) + (compute.AssessLaterManagementFee ?? 0), MidpointRounding.AwayFromZero);
                    // 参考基数专用绩效合计
                    compute.BaiscNormPerforTotal = compute.PerforSumFee;
                    // 实发绩效
                    compute.RealGiveFee = Math.Round(((compute.Avg ?? 0) + (compute.AssessLaterManagementFee ?? 0)) * compute.Adjust + (compute.AdjustLaterOtherFee ?? 0) ?? 0, MidpointRounding.AwayFromZero);

                    ////绩效合计
                    //compute.PerforSumFee = Math.Round((compute.Avg * (empolyee.Basics ?? 0)) + compute.ShouldGiveFee + compute.AssessBeforeOtherFee ?? 0);
                    ////应发绩效
                    ////compute.GiveFee = compute.PerforSumFee;
                    //compute.GiveFee = Math.Round(compute.PerforSumFee * compute.ScoreAverageRate * compute.Attendance + compute.Punishment + compute.OtherPerfor + compute.AssessLaterOtherFee ?? 0);
                    ////实发绩效
                    ////compute.RealGiveFee = (compute.GiveFee * compute.ScoreAverageRate * (compute.Attendance ?? 0) + (compute.Punishment ?? 0) + (compute.OtherPerfor ?? 0)) * (compute.Adjust ?? 1m);
                    //compute.RealGiveFee = Math.Round(compute.GiveFee * compute.Adjust + compute.AdjustLaterOtherFee ?? 0);
                    // 参考基数专用绩效合计
                    //compute.BaiscNormPerforTotal = compute.PerforSumFee;

                    computeList.Add(compute);
                }
            }
            return computeList;
        }

        /// <summary>
        /// 行政中高层 行政后勤
        /// </summary>
        /// <param name="empolyeeList"></param>
        /// <param name="baiscnormList"></param>
        /// <returns></returns>
        public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, per_allot allot, List<res_baiscnorm> baiscnormList, List<im_accountbasic> accountbasicList = null)
        {
            List<ComputeResult> computeList = new List<ComputeResult>();
            if (empolyeeList == null) return computeList;

            List<string> involves = new List<string>
            {
                AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString()
            };

            foreach (var involve in involves)
            {
                var needCompute = empolyeeList.Where(t => involve == t.AccountType);

                if (!needCompute.Any()) continue;

                var isBudget = budgetService.GetAdjustAndGrant(allot, out decimal adjust, out decimal grant);

                var perforTypeArray = EnumHelper.GetItems<PerforType>();
                foreach (var item in needCompute)
                {
                    //// 奖罚汇总
                    //var extra = employeeExtra?.Where(w => !string.IsNullOrEmpty(w.AccountingUnit) && !string.IsNullOrEmpty(w.UnitType) && (!string.IsNullOrEmpty(w.EmployeeName) || !string.IsNullOrEmpty(w.JobNumber)))
                    //    .FirstOrDefault(w => w.AccountingUnit == item.AccountingUnit && w.UnitType == item.AccountType && w.JobNumber == item.JobNumber && w.EmployeeName == item.DoctorName)
                    //    ?.TotelValue;

                    var compute = new ComputeResult
                    {
                        AccountType = item.AccountType,
                        AccountingUnit = item.AccountingUnit,
                        EmployeeName = item.DoctorName,
                        FitPeople = item.FitPeople,
                        FitPeopleRatio = item.FitPeopleRatio ?? 0,
                        FitPeopleValue = item.FitPeopleValue ?? 0,
                        Grant = isBudget ? grant : (item.Management ?? 1),
                        //WorkTime = item.WorkTime,
                        PostCoefficient = item?.PostCoefficient ?? 0,
                        Attendance = item?.Attendance ?? 0,
                        ScoreAverageRate = item?.ScoreAverageRate ?? 1,
                        Punishment = item?.Punishment ?? 0,
                        OtherPerfor = item?.OtherPerfor ?? 0,
                        JobTitle = item.JobTitle,
                        JobNumber = item.JobNumber,
                        Adjust = (isBudget ? adjust : item.Adjust) ?? 1m,
                        //Workload = item.Workload

                        AssessBeforeOtherFee = item?.AssessBeforeOtherFee ?? 0,
                        AssessLaterOtherFee = item?.AssessLaterOtherFee ?? 0,
                        AdjustLaterOtherFee = item?.AdjustLaterOtherFee ?? 0,
                    };

                    decimal? baiscnorm = compute?.FitPeopleValue ?? 0;
                    if (baiscnorm == 0)
                    {
                        var perforTypeItem = perforTypeArray.FirstOrDefault(t => t.Description == item.FitPeople);
                        if (perforTypeItem != null)
                        {
                            var perforType = (PerforType)perforTypeItem.Value;
                            baiscnorm = item.FitPeopleValue ?? baiscNormService.GetBaiscNorm(baiscnormList, perforType);
                            compute.FitPeopleValue = baiscnorm;
                        }
                    }
                    //添加参数计算
                    compute.BaiscNormValue = baiscnorm * (item.FitPeopleRatio ?? 0);

                    if (AccountUnitType.行政高层.ToString() == involve || AccountUnitType.行政中层.ToString() == involve)
                    {
                        // 行政高层、行政中层 默认不需要二次分配
                        compute.NeedSecondAllot = "否";
                        // 行政高层 行政中层 夜班费
                        compute.NightWorkPerfor = item.NightWorkPerfor;
                        //考核前绩效
                        compute.PerforTotal = Math.Round(compute.BaiscNormValue * compute.PostCoefficient * compute.Attendance + compute.AssessBeforeOtherFee ?? 0, MidpointRounding.AwayFromZero);
                        //考核后绩效
                        compute.GiveFee = Math.Round(compute.PerforTotal * compute.ScoreAverageRate + compute.Punishment ?? 0, MidpointRounding.AwayFromZero);
                        //实发绩效
                        compute.RealGiveFee = Math.Round((compute.GiveFee * compute.Adjust + compute.AdjustLaterOtherFee) ?? 0, MidpointRounding.AwayFromZero);
                    }
                    else if (AccountUnitType.行政工勤.ToString() == involve)
                    {
                        // 行政工勤 根据测算表判读是否需要二次分配 默认不需要
                        compute.NeedSecondAllot = string.IsNullOrWhiteSpace(item.NeedSecondAllot) ? "否" : item.NeedSecondAllot;
                        #region 禅道137 
                        // 行政后勤人员不需要二次分配的时候，个人的考核得分及调节系数取4.1表里面的科室的考核得分和调节系数
                        if (compute.NeedSecondAllot == "否")
                        {
                            var resAccount = accountbasicList?.FirstOrDefault(t => UnitTypeUtil.IsOffice(t.UnitType) && t.DoctorAccountingUnit == compute.AccountingUnit);
                            compute.ScoreAverageRate = resAccount?.DoctorScoringAverage ?? 1;
                            compute.Adjust = resAccount?.DoctorAdjustFactor ?? 1m;
                        }
                        #endregion
                        //考核前绩效
                        compute.PerforTotal = Math.Round(compute.BaiscNormValue * compute.PostCoefficient * compute.Attendance + compute.OtherPerfor ?? 0, MidpointRounding.AwayFromZero);
                        //考核后绩效 更加开关来控制显示
                        compute.GiveFee = compute.PerforTotal * compute.ScoreAverageRate;
                        //实发绩效 更加开关来控制显示
                        compute.RealGiveFee = Math.Round(compute.GiveFee * compute.Adjust ?? 0, MidpointRounding.AwayFromZero);
                    }
                    computeList.Add(compute);
                    //// 行政高层 行政中层 夜班费
                    //if (AccountUnitType.行政高层.ToString() == involve || AccountUnitType.行政中层.ToString() == involve)
                    //    compute.NightWorkPerfor = item.NightWorkPerfor;
                    //// 行政高层 行政中层 考核前其他绩效
                    //if (AccountUnitType.行政高层.ToString() == involve || AccountUnitType.行政中层.ToString() == involve)
                    //    compute.PerforTotal = compute.PerforTotal + compute.AssessBeforeOtherFee;
                    ////考核后绩效
                    //compute.GiveFee = compute.BaiscNormValue * compute.PostCoefficient * compute.Attendance + compute.Punishment;
                    //// 行政中高层 不需要其他绩效 行政工勤 不需要考核得分率 区分开计算
                    //if (AccountUnitType.行政工勤.ToString() == involve)
                    //    compute.GiveFee = Math.Round(compute.GiveFee + compute.OtherPerfor ?? 0);
                    //else
                    //    compute.GiveFee = Math.Round((compute.GiveFee * compute.ScoreAverageRate + compute.AssessLaterOtherFee) ?? 0);
                    ////实发绩效
                    //compute.RealGiveFee = Math.Round((compute.GiveFee * compute.Adjust + compute.AdjustLaterOtherFee) ?? 0);
                    //computeList.Add(compute);
                }
            }

            return computeList;
        }
    }
}
