using AutoMapper;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using System.Linq.Dynamic.Core;

namespace IRaCIS.Application.Services
{
    [ApiExplorerSettings(GroupName = "Trial")]
    public class DoctorWorkloadService : BaseService, IDoctorWorkloadService
    {
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<Enroll> _enrollRepository;
        private readonly IRepository<Doctor> _doctorRepository;
        private readonly IRepository<Workload> _doctorWorkloadRepository;
        private readonly IRepository<EnrollReadingCategory> _enrollReadingCategoryRepository;
        private readonly IRepository<Attachment> _attachmentRepository;
        private readonly IRepository<Payment> _costStatisticsRepository;
        private readonly IRepository<TrialRevenuesPrice> _trialRevenuesPriceRepository;
        private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;

        private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
        public DoctorWorkloadService(IRepository<Trial> clinicalTrialProjectRepository,
             IRepository<Enroll> intoGroupRepository,
            IRepository<Doctor> doctorInfoRepository,
            IRepository<Workload> doctorWorkloadRepository,
             IRepository<EnrollReadingCategory> enrollReadingCategoryRepository,
            IRepository<Attachment> attachmentRepository,
            IRepository<Payment> costStatisticsRepository,
            IRepository<TrialRevenuesPrice> trialRevenuesPriceRepository,
              IRepository<TaskAllocationRule> taskAllocationRuleRepository,
            IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository,
            IMapper mapper)
        {
            _taskAllocationRuleRepository = taskAllocationRuleRepository;
            _trialRepository = clinicalTrialProjectRepository;
            _enrollRepository = intoGroupRepository;
            _doctorRepository = doctorInfoRepository;
            _doctorWorkloadRepository = doctorWorkloadRepository;
            this._enrollReadingCategoryRepository = enrollReadingCategoryRepository;
            _attachmentRepository = attachmentRepository;
            _costStatisticsRepository = costStatisticsRepository;
            _trialRevenuesPriceRepository = trialRevenuesPriceRepository;
            _trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;

        }

        #region 入组工作量统计列表  具体详情   增删改查相关  上传\删除协议


        #region 协议废弃
        ///// <summary>
        ///// 保存协议-   ack Sow   [AUTH]
        ///// </summary>
        //[HttpPost("{trialId}")]

        //[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        //public async Task<IResponseOutput> UploadReviewerAckSOW(Guid trialId,
        //    ReviewerAckDTO attachmentViewModel)
        //{

        //    var intoGroupItem = (await _enrollRepository.Where(t => t.TrialId == trialId && t.DoctorId == attachmentViewModel.DoctorId).FirstOrDefaultAsync()).IfNullThrowException();


        //    if (attachmentViewModel.Id != Guid.Empty)
        //    {
        //        await _attachmentRepository.BatchDeleteNoTrackingAsync(t => t.Id == attachmentViewModel.Id);
        //    }

        //    var attachment = await _attachmentRepository.InsertFromDTOAsync(attachmentViewModel);

        //    //intoGroupItem.AttachmentId = attachment.Id;
        //    await _enrollRepository.UpdatePartialFromQueryAsync(intoGroupItem.Id, u => new Enroll() { AttachmentId = attachment.Id });


        //    var success = await _enrollRepository.SaveChangesAsync();

        //    return ResponseOutput.Result(success, attachment.Id.ToString());
        //}

        ///// <summary>
        ///// 删除协议
        ///// </summary>
        //[HttpDelete, Route("{trialId}/{doctorId}/{attachmentId}")]

        //[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        //public async Task<IResponseOutput> DeleteReviewerAckSOW(Guid trialId, Guid doctorId, Guid attachmentId)
        //{
        //    var success1 = await _attachmentRepository.BatchDeleteNoTrackingAsync(a => a.Id == attachmentId);
        //    await _enrollRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.DoctorId == doctorId, u =>
        //     new Enroll()
        //     {
        //         AttachmentId = Guid.Empty
        //     }, true);
        //    return ResponseOutput.Ok(success1);
        //}



        #endregion




        /// <summary>
        /// 修改项目医生的阅片类型
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
               //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> SetEnrollReadingCategory(SetEnrollReadingCategoryInDto inDto)
        {

            var enroll = await _enrollRepository.FirstAsync(t => t.Id == inDto.EnrollId);


            if (_repository.Where<VisitTask>(t => t.TrialId == enroll.TrialId && t.DoctorUserId == enroll.DoctorUserId && t.TaskAllocationState == TaskAllocationState.Allocated && t.TrialReadingCriterionId==inDto.TrialReadingCriterionId).Any())
            {

                var readingCategoryList = await _enrollReadingCategoryRepository.Where(t => t.EnrollId == inDto.EnrollId && t.TrialReadingCriterionId == inDto.TrialReadingCriterionId).Select(t => t.ReadingCategory).ToListAsync();

                if (readingCategoryList.Except(inDto.ReadingCategorys).Count() > 0)
                {
                    return ResponseOutput.NotOk("已分配任务，不允许减少阅片类型");

                }

            }

            //if (inDto.ReadingCategorys.Count > 0)
            //{
            //    await _enrollReadingCategoryRepository.BatchDeleteNoTrackingAsync(x => x.EnrollId == inDto.EnrollId);

            //}
            //else
            //{
            //    await _enrollReadingCategoryRepository.DeleteFromQueryAsync(x => x.EnrollId == inDto.EnrollId);
            //}

            await _enrollReadingCategoryRepository.DeleteFromQueryAsync(x => x.EnrollId == inDto.EnrollId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId);


            List<EnrollReadingCategory> enrollReadings = inDto.ReadingCategorys.Select(x => new EnrollReadingCategory()
            {
                TrialReadingCriterionId= inDto.TrialReadingCriterionId,
                EnrollId = inDto.EnrollId,
                ReadingCategory = x
            }).ToList();

            await _enrollReadingCategoryRepository.AddRangeAsync(enrollReadings);
            var result = await _enrollReadingCategoryRepository.SaveChangesAsync();


            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 修改项目医生启用禁用状态
        /// </summary>
        /// <param name="inCommand"></param>
        /// <returns></returns>
               //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> UpdateTrialReviewerState(SetEnrollEnableCommand inCommand)
        {
            await _taskAllocationRuleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == inCommand.TrialId && t.EnrollId == inCommand.EnrollId, u => new TaskAllocationRule() { IsEnable = inCommand.IsEnable },true);

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 0代表裁判和Tp 都可以  1、代表Tp  2 代表裁判
        /// </summary>
        /// <returns></returns>
        [HttpPost("{trialId}/{doctorId}/{type}")]
         [TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
               //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        public async Task<IResponseOutput> UpdateReviewerReadingType(Guid trialId, Guid doctorId, int type)
        {
            var success2 = await _enrollRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.DoctorId == doctorId, u =>
               new Enroll()
               {
                   ReviewerReadingType = type
               });
            return ResponseOutput.Result(success2);
        }

        /// <summary> 
        /// 获取某个项目入组的医生工作量统计列表
        /// </summary>
        [HttpPost]
        public async Task<PageOutput<WorkLoadAndAgreementDTO>> GetTrialEnrollmentWorkloadStats(WorkLoadDoctorQueryDTO doctorSearchModel)
        {
            //https://blog.csdn.net/sunshineblog/article/details/78636389

            var trialId = doctorSearchModel.TrialId;

            var doctorIntoGroupQueryable =

                from intoGroup in _enrollRepository.Where(x => x.TrialId == trialId && x.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
                join allocateRule in _taskAllocationRuleRepository.AsQueryable() on intoGroup.Id equals allocateRule.EnrollId 
 

                join attachmentItem in _attachmentRepository.AsQueryable() on intoGroup.AttachmentId equals attachmentItem.Id into cc
                from attachment in cc.DefaultIfEmpty()    

                select new WorkLoadAndAgreementDTO()
                {
                    EnrollId = intoGroup.Id,
                    IsEnable = allocateRule.IsEnable,

                    TrialReadingCriterionList = intoGroup.Trial.ReadingQuestionCriterionTrialList.Where(t=>t.IsConfirm).Select(t=>new TrialReadingCriterionDto() { TrialReadingCriterionId=t.Id,TrialReadingCriterionName=t.CriterionName,CriterionType=t.CriterionType,IsOncologyReading=t.IsOncologyReading,IsArbitrationReading=t.IsArbitrationReading,IsGlobalReading=t.IsGlobalReading,ReadingInfoSignTime=t.ReadingInfoSignTime,ReadingType=t.ReadingType}).ToList(),

                 

                    CriterionReadingCategoryList =intoGroup.EnrollReadingCategoryList.Select(t=>new TrialCriterionReadingCategory() { EnrollId=t.EnrollId,ReadingCategory=t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }).ToList(),


                    UserName= intoGroup.DoctorUser.UserName,

                    OutEnrollTime = intoGroup.OutEnrollTime,
                    EnrollTime = intoGroup.EnrollTime,
                    AgreementId = intoGroup.AttachmentId,
                    ReviewerReadingType = intoGroup.ReviewerReadingType,
                    AgreementPath = attachment.Path,



                };

            return await doctorIntoGroupQueryable.ToPagedListAsync(doctorSearchModel.PageIndex, doctorSearchModel.PageSize, doctorSearchModel.SortField == "" ? "EnrollTime" : doctorSearchModel.SortField, doctorSearchModel.Asc);

          
        }

        /// <summary>
        /// 获取入组某个项目的医生的最近几个月的工作量详情（带有填充数据）
        /// </summary>
        [HttpPost]
        public PageOutput<WorkLoadDetailDTO> GetEnrollmentWorkloadStatsDetail(WorkLoadStatsQueryDTO workLoadSearch)
        {
            #region 条件查询
            Expression<Func<Workload, bool>> workloadLambda = x => true;
            if (workLoadSearch.TrialId != Guid.Empty && workLoadSearch.TrialId != null)
            {
                workloadLambda = workloadLambda.And(x => x.TrialId == workLoadSearch.TrialId);
            }
            if (workLoadSearch.DoctorId != Guid.Empty && workLoadSearch.DoctorId != null)
            {
                workloadLambda = workloadLambda.And(t => t.DoctorId == workLoadSearch.DoctorId);
            }
            if (workLoadSearch.SearchBeginDateTime != null)
            {
                var bDate = workLoadSearch.SearchBeginDateTime;

                var beginDate = new DateTime(bDate.Value.Year, bDate.Value.Month, 1);

                workloadLambda = workloadLambda.And(t =>
                    t.WorkTime >= beginDate);
            }
            if (workLoadSearch.SearchEndDateTime != null)
            {
                var eDate = workLoadSearch.SearchEndDateTime.Value.AddMonths(1);

                DateTime endDate = new DateTime(eDate.Year, eDate.Month, 1);

                workloadLambda = workloadLambda.And(t =>
                     t.WorkTime < endDate);
            }


            #endregion

            IQueryable<WorkLoadDetailDTO>? workLoadQueryable = default;

            var tempWorkload = new List<WorkLoadDetailDTO>();
            if (workLoadSearch.WorkLoadFromStatus.Contains(1))
            {
                workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.CRO))
                                    join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
                                    join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id

                                    select new WorkLoadDetailDTO()
                                    {
                                        Id = workLoad.Id,
                                        DoctorId = workLoad.DoctorId,
                                        ChineseName = doctor.ChineseName,
                                        FirstName = doctor.FirstName,
                                        LastName = doctor.LastName,

                                        YearMonthStr = workLoad.YearMonth,
                                        CreateTime = workLoad.CreateTime,
                                        WorkTime = workLoad.WorkTime,

                                        DataFrom = workLoad.DataFrom,
                                        TrialId = workLoad.TrialId,
                                        Indication = trial.Indication,
                                        Code = trial.TrialCode,

                                        Timepoint = workLoad.Timepoint,
                                        TimepointIn24H = workLoad.TimepointIn24H,
                                        TimepointIn48H = workLoad.TimepointIn48H,
                                        Global = workLoad.Global,
                                        RefresherTraining = workLoad.RefresherTraining,
                                        Adjudication = workLoad.Adjudication,
                                        AdjudicationIn24H = workLoad.AdjudicationIn24H,
                                        AdjudicationIn48H = workLoad.AdjudicationIn48H,



                                        Training = workLoad.Training,
                                        Downtime = workLoad.Downtime,
                                        IsLock = workLoad.IsLock
                                    };
                tempWorkload.AddRange(workLoadQueryable.ToList());
            }


            if (workLoadSearch.WorkLoadFromStatus.Contains(2))
            {
                workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm))
                                    join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
                                    join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id

                                    select new WorkLoadDetailDTO()
                                    {
                                        Id = workLoad.Id,
                                        DoctorId = workLoad.DoctorId,
                                        ChineseName = doctor.ChineseName,
                                        FirstName = doctor.FirstName,
                                        LastName = doctor.LastName,

                                        YearMonthStr = workLoad.YearMonth,
                                        CreateTime = workLoad.CreateTime,
                                        WorkTime = workLoad.WorkTime,

                                        DataFrom = workLoad.DataFrom,
                                        TrialId = workLoad.TrialId,
                                        Indication = trial.Indication,
                                        Code = trial.TrialCode,

                                        Timepoint = workLoad.Timepoint,
                                        TimepointIn24H = workLoad.TimepointIn24H,
                                        TimepointIn48H = workLoad.TimepointIn48H,
                                        Global = workLoad.Global,
                                        RefresherTraining = workLoad.RefresherTraining,
                                        Adjudication = workLoad.Adjudication,
                                        AdjudicationIn24H = workLoad.AdjudicationIn24H,
                                        AdjudicationIn48H = workLoad.AdjudicationIn48H,

                                        Training = workLoad.Training,
                                        Downtime = workLoad.Downtime,
                                        IsLock = workLoad.IsLock
                                    };
                tempWorkload.AddRange(workLoadQueryable.ToList());
            }

            if (workLoadSearch.WorkLoadFromStatus.Contains(0))
            {
                workLoadQueryable =
                  from workLoad in (from workLoadItem in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.Doctor))
                                    group workLoadItem by new { workLoadItem.YearMonth, workLoadItem.DoctorId, workLoadItem.TrialId, workLoadItem.IsLock } into g
                                    select new
                                    {
                                        Id = Guid.NewGuid(),
                                        DoctorId = g.Key.DoctorId,
                                        DataFrom = 0,
                                        TrialId = g.Key.TrialId,
                                        IsLock = g.Key.IsLock,
                                        YearMonthStr = g.Key.YearMonth,
                                        Timepoint = g.Sum(workLoad => workLoad.Timepoint),
                                        TimepointIn24H = g.Sum(workLoad => workLoad.TimepointIn24H),
                                        TimepointIn48H = g.Sum(workLoad => workLoad.TimepointIn48H),
                                        Global = g.Sum(workLoad => workLoad.Global),
                                        RefresherTraining = g.Sum(workLoad => workLoad.RefresherTraining),
                                        Adjudication = g.Sum(workLoad => workLoad.Adjudication),
                                        AdjudicationIn24H = g.Sum(workLoad => workLoad.AdjudicationIn24H),
                                        AdjudicationIn48H = g.Sum(workLoad => workLoad.AdjudicationIn48H),

                                        Training = g.Sum(workLoad => workLoad.Training),
                                        Downtime = g.Sum(workLoad => workLoad.Downtime)
                                    })
                  join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
                  join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
                  select new WorkLoadDetailDTO()
                  {
                      Id = workLoad.Id,
                      DoctorId = workLoad.DoctorId,
                      ChineseName = doctor.ChineseName,
                      FirstName = doctor.FirstName,
                      LastName = doctor.LastName,
                      YearMonthStr = workLoad.YearMonthStr,

                      DataFrom = workLoad.DataFrom,
                      TrialId = workLoad.TrialId,
                      Indication = trial.Indication,
                      Code = trial.TrialCode,

                      Timepoint = workLoad.Timepoint,
                      TimepointIn24H = workLoad.TimepointIn24H,
                      TimepointIn48H = workLoad.TimepointIn48H,
                      Global = workLoad.Global,
                      RefresherTraining = workLoad.RefresherTraining,
                      Adjudication = workLoad.Adjudication,
                      AdjudicationIn24H = workLoad.AdjudicationIn24H,
                      AdjudicationIn48H = workLoad.AdjudicationIn48H,

                      Training = workLoad.Training,
                      Downtime = workLoad.Downtime,
                      IsLock = workLoad.IsLock
                  };
                tempWorkload.AddRange(workLoadQueryable.ToList());
            }

            //workLoadQueryable = workLoadQueryable.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom);

            //取选取月份的数据
            var month = (workLoadSearch.SearchEndDateTime?.Year - workLoadSearch.SearchBeginDateTime?.Year) * 12 + (workLoadSearch.SearchEndDateTime?.Month - workLoadSearch.SearchBeginDateTime?.Month) + 1;
            var count = (month ?? 1) * workLoadSearch.WorkLoadFromStatus.Count;
            //tempWorkload = tempWorkload.Take(count);
            tempWorkload.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom).Take(count);
            //var workLoadList = workLoadQueryable.ToList();
            return BuildFullData(tempWorkload, workLoadSearch);
        }

        /// <summary>
        /// 获取来自Reviewer自己的数据，某个月添加的多条
        /// </summary>
        [HttpPost]
        public async Task<List<WorkLoadDetailViewModel>> GetReviewerWorkLoadListDetail(
            WorkLoadDetailQueryDTO workLoadSearch)
        {
            Expression<Func<Workload, bool>> workloadLambda = t => t.DataFrom == (int)WorkLoadFromStatus.Doctor && t.YearMonth == workLoadSearch.YearMonthStr;

            if (workLoadSearch.TrialId != Guid.Empty)
            {
                workloadLambda = workloadLambda.And(x => x.TrialId == workLoadSearch.TrialId);
            }

            if (workLoadSearch.DoctorId != Guid.Empty)
            {
                workloadLambda = workloadLambda.And(t => t.DoctorId == workLoadSearch.DoctorId);
            }

            var workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda)
                                    join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
                                    join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id

                                    select new WorkLoadDetailViewModel()
                                    {
                                        Id = workLoad.Id,
                                        DoctorId = workLoad.DoctorId,
                                        ChineseName = doctor.ChineseName,
                                        FirstName = doctor.FirstName,
                                        LastName = doctor.LastName,
                                        YearMonthStr = workLoad.YearMonth,
                                        CreateTime = workLoad.CreateTime,
                                        WorkTime = workLoad.WorkTime,

                                        DataFrom = workLoad.DataFrom,
                                        TrialId = workLoad.TrialId,
                                        Indication = trial.Indication,
                                        Code = trial.TrialCode,

                                        Timepoint = workLoad.Timepoint,
                                        TimepointIn24H = workLoad.TimepointIn24H,
                                        TimepointIn48H = workLoad.TimepointIn48H,
                                        Global = workLoad.Global,
                                        Adjudication = workLoad.Adjudication,
                                        AdjudicationIn24H = workLoad.AdjudicationIn24H,
                                        AdjudicationIn48H = workLoad.AdjudicationIn48H,
                                        RefresherTraining = workLoad.RefresherTraining,

                                        Training = workLoad.Training,
                                        Downtime = workLoad.Downtime,
                                        IsLock = workLoad.IsLock
                                    };

            workLoadQueryable = workLoadQueryable.OrderBy("WorkTime");

            var workLoadList = await workLoadQueryable.ToListAsync();

            workLoadList.ForEach(t => t.RowGuid = Guid.NewGuid());

            return workLoadList;

        }

        /// <summary>
        /// 工作量是否存在，用于判断只能添加一条的工作量记录
        /// </summary>
        /// <summary>
        /// 查询某个医生是否在某天有某个项目的工作量数据，处理添加来自医生自己的工作量数据
        /// </summary>
        [HttpPost]
        public async Task<IResponseOutput<ExistWorkloadViewModel>> WorkloadExist(WorkloadExistQueryDTO param)
        {
            var isExist = false;
            var exist = await _doctorWorkloadRepository.FirstOrDefaultAsync(u => u.TrialId == param.TrialId && u.DoctorId == param.DoctorId
            && u.WorkTime == param.WorkDate && u.DataFrom == 0);
            if (exist != null)
            {
                isExist = true;
            }
            return ResponseOutput.Ok(new ExistWorkloadViewModel
            {
                IsExist = isExist,
                WorkLoad = _mapper.Map<WorkloadDTO>(exist),
            });
        }

        /// <summary>
        /// 添加或更新工作量
        /// </summary>
               //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        public async Task<IResponseOutput> AddOrUpdateWorkload(WorkloadCommand workLoadAddOrUpdateModel,
            Guid userId)
        {
            var yearMonthStr = workLoadAddOrUpdateModel.WorkTime.ToString("yyyy-MM");


            if (workLoadAddOrUpdateModel.Id == Guid.Empty || workLoadAddOrUpdateModel.Id == null)
            {
                //确定是那个医生 那个项目 那个月份做的
                Expression<Func<Workload, bool>> workloadLambda = x => x.DoctorId == workLoadAddOrUpdateModel.DoctorId && x.TrialId == workLoadAddOrUpdateModel.TrialId && x.YearMonth == yearMonthStr;

                //只要是来自CRO或者最终确认的 只能有一条
                switch (workLoadAddOrUpdateModel.DataFrom)
                {
                    case (int)WorkLoadFromStatus.CRO: //1  来自CRO的
                        workloadLambda = workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.CRO);
                        break;

                    case (int)WorkLoadFromStatus.FinalConfirm:   //2 最终确认的
                        workloadLambda = workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm);

                        var isExist = await _costStatisticsRepository.AnyAsync(u => u.YearMonth == yearMonthStr && u.DoctorId == workLoadAddOrUpdateModel.DoctorId);
                        if (!isExist)
                        {
                            await _costStatisticsRepository.AddAsync(new Payment
                            {
                                DoctorId = workLoadAddOrUpdateModel.DoctorId,
                                YearMonth = yearMonthStr,
                                YearMonthDate = DateTime.Parse(yearMonthStr),
                                IsLock = false
                            });
                        }

                        //处理 验证项目收入价格是否都填写了

                        var revenuesPriceExist = await _trialRevenuesPriceRepository.AsQueryable()
                                 .FirstOrDefaultAsync(t => t.TrialId == workLoadAddOrUpdateModel.TrialId);

                        //没填写收入价格 插入记录 所有的都是false  
                        if (revenuesPriceExist == null)
                        {
                            await _trialRevenuesPriceVerificationRepository.AddAsync(new TrialRevenuesPriceVerification()
                            {
                                TrialId = workLoadAddOrUpdateModel.TrialId,
                                ReviewerId = workLoadAddOrUpdateModel.DoctorId,
                                YearMonth = yearMonthStr,
                                WorkLoadDate = workLoadAddOrUpdateModel.WorkTime
                            });
                        }
                        else //有价格 校验  看全不全
                        {

                            var tpNeedSetPrice = workLoadAddOrUpdateModel.Timepoint > 0 &&
                                                 revenuesPriceExist.Timepoint <= 0;
                            var tp24HNeedSetPrice = workLoadAddOrUpdateModel.TimepointIn24H > 0 &&
                                                    revenuesPriceExist.TimepointIn24H <= 0;
                            var tp48NeedSetPrice = workLoadAddOrUpdateModel.TimepointIn48H > 0 &&
                                                   revenuesPriceExist.TimepointIn48H <= 0;
                            var adNeedSetPrice = workLoadAddOrUpdateModel.Adjudication > 0 &&
                                                 revenuesPriceExist.Adjudication <= 0;
                            var ad24NeedSetPrice = workLoadAddOrUpdateModel.AdjudicationIn24H > 0 &&
                                                   revenuesPriceExist.AdjudicationIn24H <= 0;
                            var ad48NeedSetPrice = workLoadAddOrUpdateModel.AdjudicationIn48H > 0 &&
                                                   revenuesPriceExist.AdjudicationIn48H <= 0;
                            var downtimeNeedSetPrice = workLoadAddOrUpdateModel.Downtime > 0 &&
                                                       revenuesPriceExist.Downtime <= 0;
                            var globalNeedSetPrice = workLoadAddOrUpdateModel.Global > 0 &&
                                                     revenuesPriceExist.Global <= 0;
                            var trainingNeedSetPrice = workLoadAddOrUpdateModel.Training > 0 &&
                                                       revenuesPriceExist.Training <= 0;

                            var refresherTrainingTrainingNeedSetPrice = workLoadAddOrUpdateModel.RefresherTraining > 0 &&
                                                                        revenuesPriceExist.RefresherTraining <= 0;




                            var needAdd = tpNeedSetPrice || tp24HNeedSetPrice || tp48NeedSetPrice || adNeedSetPrice || ad24NeedSetPrice ||
                                ad48NeedSetPrice || downtimeNeedSetPrice || globalNeedSetPrice && trainingNeedSetPrice || refresherTrainingTrainingNeedSetPrice;

                            //验证不通过 增加
                            if (needAdd)
                            {
                                await _trialRevenuesPriceVerificationRepository.AddAsync(new TrialRevenuesPriceVerification()
                                {
                                    TrialId = workLoadAddOrUpdateModel.TrialId,
                                    ReviewerId = workLoadAddOrUpdateModel.DoctorId,
                                    YearMonth = yearMonthStr,
                                    WorkLoadDate = workLoadAddOrUpdateModel.WorkTime,
                                    //需要设置价格和 有价格是相反的   数据库此字段存储的时候对应项是否有价格
                                    Timepoint = !tpNeedSetPrice,
                                    TimepointIn24H = !tp24HNeedSetPrice,
                                    TimepointIn48H = !tp48NeedSetPrice,
                                    Adjudication = !adNeedSetPrice,
                                    AdjudicationIn24H = !ad24NeedSetPrice,
                                    AdjudicationIn48H = !ad48NeedSetPrice,
                                    Downtime = !downtimeNeedSetPrice,
                                    Global = !globalNeedSetPrice,
                                    Training = !trainingNeedSetPrice,
                                    RefresherTraining = !refresherTrainingTrainingNeedSetPrice
                                });
                            }

                        }


                        break;
                }
                if (workLoadAddOrUpdateModel.DataFrom != (int)WorkLoadFromStatus.Doctor)
                {
                    if (await _doctorWorkloadRepository.AnyAsync(workloadLambda))
                    {

                        return ResponseOutput.NotOk("This type of data can only have one");

                    }
                }
                if (workLoadAddOrUpdateModel.DataFrom == (int)WorkLoadFromStatus.Doctor)
                {
                    Expression<Func<Workload, bool>> doctorworkloadLambda = x => x.DoctorId == workLoadAddOrUpdateModel.DoctorId && x.TrialId == workLoadAddOrUpdateModel.TrialId && x.YearMonth == yearMonthStr && workLoadAddOrUpdateModel.WorkTime == x.WorkTime;

                    doctorworkloadLambda = doctorworkloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.Doctor);
                    if (await _doctorWorkloadRepository.AnyAsync(doctorworkloadLambda))
                    {
                        return ResponseOutput.NotOk("This type of data can only have one");
                    }
                }

                var workLoad = _mapper.Map<Workload>(workLoadAddOrUpdateModel);

                workLoad.YearMonth = yearMonthStr;

                await _doctorWorkloadRepository.AddAsync(workLoad);

                await _enrollRepository.BatchUpdateNoTrackingAsync(
                      t => t.DoctorId == workLoadAddOrUpdateModel.DoctorId && t.TrialId == workLoadAddOrUpdateModel.TrialId, u => new Enroll()
                      {
                          EnrollStatus = EnrollStatus.DoctorReading,
                      });

                var success = await _doctorWorkloadRepository.SaveChangesAsync();

                return ResponseOutput.Result(success, workLoad.Id);

            }
            else
            {
                //判断是否已经被锁定
                var isLocked = await _costStatisticsRepository.AnyAsync(u => u.DoctorId == workLoadAddOrUpdateModel.DoctorId &&
                u.YearMonth == yearMonthStr && u.IsLock);
                if (isLocked)
                {

                    return ResponseOutput.NotOk("Expenses have been settled and workload cannot be modified.");

                }

                var success = await _doctorWorkloadRepository.BatchUpdateNoTrackingAsync(t => t.Id == workLoadAddOrUpdateModel.Id,
                    u => new Workload()
                    {
                        Timepoint = workLoadAddOrUpdateModel.Timepoint,
                        TimepointIn24H = workLoadAddOrUpdateModel.TimepointIn24H,
                        TimepointIn48H = workLoadAddOrUpdateModel.TimepointIn48H,

                        Adjudication = workLoadAddOrUpdateModel.Adjudication,
                        AdjudicationIn24H = workLoadAddOrUpdateModel.AdjudicationIn24H,
                        AdjudicationIn48H = workLoadAddOrUpdateModel.AdjudicationIn48H,

                        RefresherTraining = workLoadAddOrUpdateModel.RefresherTraining,

                        Downtime = workLoadAddOrUpdateModel.Downtime,
                        Training = workLoadAddOrUpdateModel.Training,
                        Global = workLoadAddOrUpdateModel.Global,

                        WorkTime = workLoadAddOrUpdateModel.WorkTime,
                        YearMonth = yearMonthStr
                    });
                return ResponseOutput.Result(success);

            }
        }

        /// <summary>
        /// 删除工作量
        /// </summary>
        public async Task<IResponseOutput> DeleteWorkload(Guid workloadId)
        {
            return ResponseOutput.Result(await _doctorWorkloadRepository.BatchDeleteNoTrackingAsync(t => t.Id == workloadId));
        }

        /// <summary>
        /// 获取工作量详情(用于判断工作量锁定时，调用)
        /// </summary>
        public async Task<WorkloadDTO> GetWorkloadDetailById(Guid id)
        {
            var workload = await _doctorWorkloadRepository.FirstOrDefaultAsync(u => u.Id == id);
            return _mapper.Map<WorkloadDTO>(workload);
        }

        #endregion

        private PageOutput<WorkLoadDetailDTO> BuildFullData(
            List<WorkLoadDetailDTO> workLoadList, WorkLoadStatsQueryDTO workLoadSearch)
        {
            var doctor = _doctorRepository.Where(t => t.Id == workLoadSearch.DoctorId).ProjectTo<DoctorBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefault().IfNullThrowException();
            //查询 1-3月的  共3个月 
            var month = (workLoadSearch.SearchEndDateTime?.Year - workLoadSearch.SearchBeginDateTime?.Year) * 12 +
                (workLoadSearch.SearchEndDateTime?.Month - workLoadSearch.SearchBeginDateTime?.Month) + 1;

            var needCount = month * workLoadSearch.WorkLoadFromStatus.Count ?? 1;

            if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.FinalConfirm))
            {
                if (workLoadList.Count != needCount)
                {
                    for (int i = 0; i < month; i++)
                    {
                        var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
                        if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
                                                   t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm))
                        {
                            workLoadList.Add(new WorkLoadDetailDTO()
                            {
                                Id = Guid.Empty,
                                DataFrom = (int)WorkLoadFromStatus.FinalConfirm,
                                YearMonthStr = yearMonthStr,
                                ChineseName = doctor.ChineseName,
                                FirstName = doctor.FirstName,
                                LastName = doctor.LastName,
                                Code = doctor.ReviewerCode
                            });
                        }
                    }
                }
            }
            if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.CRO))
            {
                if (workLoadList.Count != needCount)
                {
                    for (int i = 0; i < month; i++)
                    {
                        var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
                        if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
                                                   t.DataFrom == (int)WorkLoadFromStatus.CRO))
                        {
                            workLoadList.Add(new WorkLoadDetailDTO()
                            {
                                Id = Guid.Empty,
                                DataFrom = (int)WorkLoadFromStatus.CRO,
                                YearMonthStr = yearMonthStr,
                                ChineseName = doctor.ChineseName,
                                FirstName = doctor.FirstName,
                                LastName = doctor.LastName,
                                Code = doctor.ReviewerCode
                            });
                        }
                    }
                }
            }
            if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.Doctor))
            {
                if (workLoadList.Count != needCount)
                {
                    for (int i = 0; i < month; i++)
                    {
                        var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
                        if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
                                                   t.DataFrom == (int)WorkLoadFromStatus.Doctor))
                        {
                            workLoadList.Add(new WorkLoadDetailDTO()
                            {
                                Id = Guid.Empty,
                                DataFrom = (int)WorkLoadFromStatus.Doctor,
                                YearMonthStr = yearMonthStr,
                                ChineseName = doctor.ChineseName,
                                FirstName = doctor.FirstName,
                                LastName = doctor.LastName,
                                Code = doctor.ReviewerCode
                            });
                        }
                    }
                }

            }

            workLoadList = workLoadList.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom)
                .ToList();
            int tempRowId = 0;
            foreach (var workLoad in workLoadList)
            {
                workLoad.RowGuid = Guid.NewGuid();
                workLoad.RowIntId = tempRowId + 1;
                tempRowId++;
            }

            return new PageOutput<WorkLoadDetailDTO>(1, workLoadList.Count,
                workLoadList.Count, workLoadList);


        }


    }
}
