diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 86367b4bc..543df1665 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -46,13 +46,16 @@ namespace IRaCIS.Core.Application.Service private readonly IRepository _trialClinicalDataSetRepository; private readonly IRepository _readingClinicalDataRepository; + private readonly IRepository _subjectCriteriaEvaluationRepository; + public VisitTaskHelpeService(IRepository visitTaskRepository, IRepository subjectUserRepository, IRepository trialRepository, IEasyCachingProvider provider, IRepository subjectVisitRepository, IRepository readModuleRepository, IRepository readingJudgeInfoRepository, IRepository taskAllocationRuleRepository, IMapper mapper, IUserInfo userInfo, IRepository visitTaskReReadingRepository, - IRepository trialReadingCriterionRepository, IRepository trialClinicalDataSetRepository, IRepository readingClinicalDataRepository) + IRepository trialReadingCriterionRepository, IRepository trialClinicalDataSetRepository, IRepository readingClinicalDataRepository, + IRepository subjectCriteriaEvaluationRepository) { _readingClinicalDataRepository = readingClinicalDataRepository; _trialClinicalDataSetRepository = trialClinicalDataSetRepository; @@ -68,7 +71,7 @@ namespace IRaCIS.Core.Application.Service _mapper = mapper; _userInfo = userInfo; _visitTaskReReadingRepository = visitTaskReReadingRepository; - + _subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository; } @@ -116,7 +119,7 @@ namespace IRaCIS.Core.Application.Service await _visitTaskRepository.AddAsync(taskInfo); - await _visitTaskRepository.BatchUpdateNoTrackingAsync(x=>x.Id==taskId, x => new VisitTask() + await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == taskId, x => new VisitTask() { TaskState = TaskState.Freeze }); @@ -132,12 +135,12 @@ namespace IRaCIS.Core.Application.Service if (isManualSelectVisit == null) { //找到一致性核查通过且没有产生任务的访视 - needGenerateVisit = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.CheckState == CheckStateEnum.CVPassed && - !t.VisitTaskList.Any(u => u.TrialReadingCriterionId == confirmedTrialReadingCriterionId && u.SourceSubjectVisitId == t.Id && u.TaskState == TaskState.Effect && u.IsAnalysisCreate == false)).ToListAsync(); + needGenerateVisit = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.CheckState == CheckStateEnum.CVPassed && + !t.VisitTaskList.Any(u => u.TrialReadingCriterionId == confirmedTrialReadingCriterionId && u.SourceSubjectVisitId == t.Id && u.TaskState == TaskState.Effect && u.IsAnalysisCreate == false)).ToListAsync(); } else { - needGenerateVisit = await _subjectVisitRepository.Where(t=> subjectVisitIdList.Contains(t.Id)).ToListAsync(); + needGenerateVisit = await _subjectVisitRepository.Where(t => subjectVisitIdList.Contains(t.Id)).ToListAsync(); } @@ -215,13 +218,13 @@ namespace IRaCIS.Core.Application.Service VisitTask? task1 = null; VisitTask? task2 = null; - + if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) { currentMaxCodeInt = currentMaxCodeInt + 1; - + task1 = await _visitTaskRepository.AddAsync(new VisitTask() { @@ -232,7 +235,7 @@ namespace IRaCIS.Core.Application.Service TaskName = subjectVisit.VisitName, VisitTaskNum = subjectVisit.VisitNum, TaskUrgentType = taskUrgentType, - IsCanEditUrgentState= isCanEditUrgentState, + IsCanEditUrgentState = isCanEditUrgentState, //CheckPassedTime = subjectVisit.CheckPassedTime, ArmEnum = Arm.DoubleReadingArm1,//特殊 Code = currentMaxCodeInt, @@ -243,7 +246,7 @@ namespace IRaCIS.Core.Application.Service TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, IsNeedClinicalDataSign = isNeedClinicalDataSign, IsClinicalDataSign = isClinicalDataSign - }) ; + }); } @@ -291,7 +294,7 @@ namespace IRaCIS.Core.Application.Service task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; task1.AllocateTime = DateTime.Now; - task1.SuggesteFinishedTime = GetSuggessFinishTime(true,UrgentType.NotUrget); + task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); } if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null) @@ -361,7 +364,7 @@ namespace IRaCIS.Core.Application.Service } - + private bool IsNeedClinicalDataSign(ReadingCategory readingCategory, bool isbaseLine, Guid trialReadingCriterionId, List trialClinicalDataSetList) { @@ -469,10 +472,10 @@ namespace IRaCIS.Core.Application.Service } - public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType ) + public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) { - var datetime= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day , 22, 0, 0).AddDays(7); + var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); //switch (urgentType) @@ -504,7 +507,7 @@ namespace IRaCIS.Core.Application.Service // datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day + 7, 22, 0, 0); // break; - + // default: // break; //} @@ -522,7 +525,7 @@ namespace IRaCIS.Core.Application.Service var trialId = generateTaskCommand.TrialId; var isAssignSubjectToDoctor = generateTaskCommand.IsAssignSubjectToDoctor; - var trialReadingCriterionConfigList = _trialReadingCriterionRepository.Where(t => t.TrialId == trialId && t.ReadingInfoSignTime != null && t.IsAutoCreate).Select(t => new { TrialReadingCriterionId = t.Id, t.ReadingTool, t.ReadingType, t.IsReadingTaskViewInOrder, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState, t.TaskAllocateObjEnum, t.CriterionType }).ToList(); + var trialReadingCriterionConfigList = _trialReadingCriterionRepository.Where(t => t.TrialId == trialId && t.ReadingInfoSignTime != null).Select(t => new { TrialReadingCriterionId = t.Id, t.ReadingTool, t.ReadingType, t.IsReadingTaskViewInOrder, t.IsFollowVisitAutoAssign, t.IsAutoCreate, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState, t.TaskAllocateObjEnum, t.CriterionType }).ToList(); var visitBlindConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.BlindBaseLineName, t.BlindFollowUpPrefix }).FirstOrDefault(); @@ -536,7 +539,7 @@ namespace IRaCIS.Core.Application.Service int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode; - + switch (generateTaskCommand.ReadingCategory) @@ -583,148 +586,360 @@ namespace IRaCIS.Core.Application.Service foreach (var trialReadingCriterionConfig in trialReadingCriterionConfigList) { - var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + var subjectCriteriaEvaluation = _subjectCriteriaEvaluationRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.IsJoinEvaluation && t.SubjectId == subjectVisit.SubjectId).FirstOrDefault(); + if (trialReadingCriterionConfig.IsAutoCreate == true || (trialReadingCriterionConfig.IsAutoCreate == false && subjectCriteriaEvaluation != null && subjectCriteriaEvaluation?.IsJoinEvaluation == true)) - var blindTaskName = string.Empty; - - var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList); - var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId); - - - if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0) { - blindTaskName = visitBlindConfig.BlindBaseLineName; - } - else - { - if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) + + var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + + + var blindTaskName = string.Empty; + + var isNeedClinicalDataSign = IsNeedClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList); + var isClinicalDataSign = IsClinicalDataSign(ReadingCategory.Visit, subjectVisit.IsBaseLine, trialReadingCriterionConfig.TrialReadingCriterionId, clinicalDataConfirmList, subjectVisit.Id, trialId); + + + if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0) { - blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum); + blindTaskName = visitBlindConfig.BlindBaseLineName; } else { - blindTaskName = visitBlindConfig.BlindFollowUpPrefix; - } - } - - - //每个访视 根据项目配置生成任务 双审生成两个 - - //双重 可能有一个人的任务没分配,然后影像回退不会影响未分配的任务,所以生成的时候 要进行判断 不能每次都生成两个 - if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) - { - - var existCurrentVisitTaskList = _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId - && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.TaskState == TaskState.Effect - && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.SourceSubjectVisitId == subjectVisit.Id).ToList(); - - VisitTask? task1 = null; - VisitTask? task2 = null; - - - if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) - { - currentMaxCodeInt = currentMaxCodeInt + 1; - - task1 = await _visitTaskRepository.AddAsync(new VisitTask() + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - TaskBlindName = blindTaskName, - - IsUrgent = subjectVisit.IsUrgent, - TaskUrgentType = taskUrgentType, - IsCanEditUrgentState = isCanEditUrgentState, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm1,//特殊 - Code = currentMaxCodeInt, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, - IsNeedClinicalDataSign = isNeedClinicalDataSign, - IsClinicalDataSign = isClinicalDataSign - }); - } - - if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) - { - currentMaxCodeInt = currentMaxCodeInt + 1; - task2 = await _visitTaskRepository.AddAsync(new VisitTask() + blindTaskName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(subjectVisit.VisitNum); + } + else { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - TaskBlindName = blindTaskName, - TaskName = subjectVisit.VisitName, - IsUrgent = subjectVisit.IsUrgent, - - TaskUrgentType = taskUrgentType, - IsCanEditUrgentState = isCanEditUrgentState, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm2,//特殊 - Code = currentMaxCodeInt, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, - IsNeedClinicalDataSign = isNeedClinicalDataSign, - IsClinicalDataSign = isClinicalDataSign - }); + blindTaskName = visitBlindConfig.BlindFollowUpPrefix; + } } + //每个访视 根据项目配置生成任务 双审生成两个 - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - - - #region 分配 - if (isAssignSubjectToDoctor) + //双重 可能有一个人的任务没分配,然后影像回退不会影响未分配的任务,所以生成的时候 要进行判断 不能每次都生成两个 + if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) { + var existCurrentVisitTaskList = _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId + && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.TaskState == TaskState.Effect + && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.SourceSubjectVisitId == subjectVisit.Id).ToList(); - if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) + VisitTask? task1 = null; + VisitTask? task2 = null; + + + if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) { - var allocateSubjectArmList = _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) - .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); + currentMaxCodeInt = currentMaxCodeInt + 1; - //当前任务没有分配医生,初次分配 不处理 只生成任务,后续根据生成的任务 再进行分配 - if (allocateSubjectArmList.Count == 0) + task1 = await _visitTaskRepository.AddAsync(new VisitTask() { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + TaskBlindName = blindTaskName, - } - else + IsUrgent = subjectVisit.IsUrgent, + TaskUrgentType = taskUrgentType, + IsCanEditUrgentState = isCanEditUrgentState, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, + IsNeedClinicalDataSign = isNeedClinicalDataSign, + IsClinicalDataSign = isClinicalDataSign + }); + } + + if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) + { + currentMaxCodeInt = currentMaxCodeInt + 1; + task2 = await _visitTaskRepository.AddAsync(new VisitTask() { - //并且配置了医生 - if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign) + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + IsUrgent = subjectVisit.IsUrgent, + + TaskUrgentType = taskUrgentType, + IsCanEditUrgentState = isCanEditUrgentState, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, + IsNeedClinicalDataSign = isNeedClinicalDataSign, + IsClinicalDataSign = isClinicalDataSign + }); + } + + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + #region 分配 + if (isAssignSubjectToDoctor) + { + + + if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) + { + var allocateSubjectArmList = _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) + .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); + + //当前任务没有分配医生,初次分配 不处理 只生成任务,后续根据生成的任务 再进行分配 + if (allocateSubjectArmList.Count == 0) { - #region 后续访视 未分配的进行再次分配,重置的或者失效的 需要重新生成新的任务 (PM 有序退回 或者PM 有序 申请重阅) - - - if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) + } + else + { + //并且配置了医生 + if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign) { - //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) - var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + #region 后续访视 未分配的进行再次分配,重置的或者失效的 需要重新生成新的任务 (PM 有序退回 或者PM 有序 申请重阅) - //之前有回退的,那么当前访视任务生成但是不分配 - if (beforeBackVisitTask != null) + + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - //不用进行额外处理 + //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) + + var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //之前有回退的,那么当前访视任务生成但是不分配 + if (beforeBackVisitTask != null) + { + //不用进行额外处理 + + //访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + } + else + { + #region 当前访视根据配置规则分配出去 + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null) + { + task1.TaskAllocationState = defaultState; + //分配给对应Arm的人 + task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; + task1.AllocateTime = DateTime.Now; + + task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null) + { + task2.TaskAllocationState = defaultState; + task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; + task2.AllocateTime = DateTime.Now; + task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + + #endregion + } + + //后续最近的未一致性核查通过的访视任务 + var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成 + + //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 + var followVisitTaskList = await _visitTaskRepository + .Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) + .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) + .ToListAsync(); + + var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); + + //每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置需要重新生成) + foreach (var visitGroup in followVisitGroup) + { + + var visit = await _subjectVisitRepository.Where(x => x.Id == visitGroup.First().SourceSubjectVisitId).Select(x => new + { + x.PDState, + x.IsEnrollmentConfirm, + x.IsUrgent, + }).FirstNotNullAsync(); + + + TaskUrgentType? urgentType = null; + + if (subjectVisitInfo.PDState == PDStateEnum.PDProgress) + { + urgentType = TaskUrgentType.PDProgress; + } + else if (subjectVisitInfo.IsEnrollmentConfirm) + { + urgentType = TaskUrgentType.EnrollmentConfirm; + } + else if (subjectVisitInfo.IsUrgent) + { + urgentType = TaskUrgentType.VisitUrgent; + } + + bool isCanEdit = urgentType == TaskUrgentType.EnrollmentConfirm || urgentType == TaskUrgentType.PDProgress ? false : true; + + //如果后续访视已分配有效 就不用处理 + if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm1)) + { + //不做处理 + } + else + { + var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1); + + if (arm1 != null) + { + + //有可能仅仅只分配了一个Subject 未分配 那么 + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null) + { + arm1.IsUrgent = visit.IsUrgent; + arm1.TaskUrgentType = urgentType; + arm1.IsCanEditUrgentState = isCanEdit; + arm1.TaskAllocationState = TaskAllocationState.Allocated; + arm1.AllocateTime = DateTime.Now; + arm1.DoctorUserId = task1.DoctorUserId; + arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First(); + + + + + var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = visit.IsUrgent, + TaskUrgentType = urgentType, + IsCanEditUrgentState = isCanEdit, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + AllocateTime = DateTime.Now, + DoctorUserId = task1.DoctorUserId, + SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), + TrialReadingCriterionId = latestTask.TrialReadingCriterionId, + IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, + IsClinicalDataSign = latestTask.IsClinicalDataSign + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + + } + + //如果后续访视已分配有效 就不用处理 + if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm2)) + { + //不做处理 + } + else + { + var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2); + if (arm2 != null) + { + //有可能仅仅只分配了一个Subject + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null) + { + arm2.IsUrgent = visit.IsUrgent; + arm2.TaskUrgentType = urgentType; + arm2.IsCanEditUrgentState = isCanEdit; + arm2.TaskAllocationState = TaskAllocationState.Allocated; + arm2.AllocateTime = DateTime.Now; + arm2.DoctorUserId = task2.DoctorUserId; + arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First(); + + var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = visit.IsUrgent, + TaskUrgentType = urgentType, + IsCanEditUrgentState = isCanEdit, + + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + + AllocateTime = DateTime.Now, + DoctorUserId = task2.DoctorUserId, + SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), + + TrialReadingCriterionId = latestTask.TrialReadingCriterionId, + IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, + IsClinicalDataSign = latestTask.IsClinicalDataSign + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + } + + } + - //访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 } + //无序的时候 生成任务并分配出去 else { - #region 当前访视根据配置规则分配出去 - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null) @@ -745,308 +960,206 @@ namespace IRaCIS.Core.Application.Service task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); } - #endregion } - //后续最近的未一致性核查通过的访视任务 - var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); - - //大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成 - - //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 - var followVisitTaskList = await _visitTaskRepository - .Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) - .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) - .ToListAsync(); - - var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); - - //每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置需要重新生成) - foreach (var visitGroup in followVisitGroup) - { - - var visit = await _subjectVisitRepository.Where(x => x.Id == visitGroup.First().SourceSubjectVisitId).Select(x => new - { - x.PDState, - x.IsEnrollmentConfirm, - x.IsUrgent, - }).FirstNotNullAsync(); - - - TaskUrgentType? urgentType = null; - - if (subjectVisitInfo.PDState == PDStateEnum.PDProgress) - { - urgentType = TaskUrgentType.PDProgress; - } - else if (subjectVisitInfo.IsEnrollmentConfirm) - { - urgentType = TaskUrgentType.EnrollmentConfirm; - } - else if (subjectVisitInfo.IsUrgent) - { - urgentType = TaskUrgentType.VisitUrgent; - } - - bool isCanEdit = urgentType == TaskUrgentType.EnrollmentConfirm || urgentType == TaskUrgentType.PDProgress ? false : true; - - //如果后续访视已分配有效 就不用处理 - if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm1)) - { - //不做处理 - } - else - { - var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1); - - if (arm1 != null) - { - - //有可能仅仅只分配了一个Subject 未分配 那么 - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null) - { - arm1.IsUrgent = visit.IsUrgent; - arm1.TaskUrgentType = urgentType; - arm1.IsCanEditUrgentState = isCanEdit; - arm1.TaskAllocationState = TaskAllocationState.Allocated; - arm1.AllocateTime = DateTime.Now; - arm1.DoctorUserId = task1.DoctorUserId; - arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } - - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First(); - - - - - var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = visit.IsUrgent, - TaskUrgentType = urgentType, - IsCanEditUrgentState = isCanEdit, - ArmEnum = Arm.DoubleReadingArm1,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - AllocateTime = DateTime.Now, - DoctorUserId = task1.DoctorUserId, - SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), - TrialReadingCriterionId = latestTask.TrialReadingCriterionId, - IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, - IsClinicalDataSign = latestTask.IsClinicalDataSign - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - - } - - //如果后续访视已分配有效 就不用处理 - if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm2)) - { - //不做处理 - } - else - { - var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2); - if (arm2 != null) - { - //有可能仅仅只分配了一个Subject - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null) - { - arm2.IsUrgent = visit.IsUrgent; - arm2.TaskUrgentType = urgentType; - arm2.IsCanEditUrgentState = isCanEdit; - arm2.TaskAllocationState = TaskAllocationState.Allocated; - arm2.AllocateTime = DateTime.Now; - arm2.DoctorUserId = task2.DoctorUserId; - arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } - - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First(); - - var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = visit.IsUrgent, - TaskUrgentType = urgentType, - IsCanEditUrgentState = isCanEdit, - - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm2,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - - AllocateTime = DateTime.Now, - DoctorUserId = task2.DoctorUserId, - SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), - - TrialReadingCriterionId = latestTask.TrialReadingCriterionId, - IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, - IsClinicalDataSign = latestTask.IsClinicalDataSign - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - } - - } + #endregion } - //无序的时候 生成任务并分配出去 else + //后续访视不自动分配,或者配置的医生数量不足,就不进行分配 { - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null) - { - task1.TaskAllocationState = defaultState; - //分配给对应Arm的人 - task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; - task1.AllocateTime = DateTime.Now; - - task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } - - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null) - { - task2.TaskAllocationState = defaultState; - task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; - task2.AllocateTime = DateTime.Now; - task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } } - - #endregion - } - else - //后续访视不自动分配,或者配置的医生数量不足,就不进行分配 - { - } } } - + #endregion } - #endregion - - } - else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) - { - - - var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = blindTaskName, - TaskName = subjectVisit.VisitName, - TaskUrgentType = taskUrgentType, - IsCanEditUrgentState = isCanEditUrgentState, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.SingleReadingArm, //特殊 - Code = currentMaxCodeInt + 1, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, - IsNeedClinicalDataSign = isNeedClinicalDataSign, - IsClinicalDataSign = isClinicalDataSign - }); - - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - - #region 分配 - - if (isAssignSubjectToDoctor) + else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) { - if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) + + var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + TaskUrgentType = taskUrgentType, + IsCanEditUrgentState = isCanEditUrgentState, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.SingleReadingArm, //特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, + IsNeedClinicalDataSign = isNeedClinicalDataSign, + IsClinicalDataSign = isClinicalDataSign + }); + + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + #region 分配 + + if (isAssignSubjectToDoctor) { - if (trialReadingCriterionConfig.IsFollowVisitAutoAssign) + if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) { - - //该Subject 之前是否有已分配的 如果改变配置 可能会出现 一个Subject 分配的同一个医生 有的在Arm1 有的在Arm2 - var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) - .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); - - //不是初次分配 - if (allocateSubjectArmList.Count != 0) + if (trialReadingCriterionConfig.IsFollowVisitAutoAssign) { - //if (_taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable).Count() < 2) - //{ - // throw new BusinessValidationFailedException("能参与读片的医生数量必须>=2,自动分配任务中止"); - //} - //配置了医生 - if (assignConfigList.Count > 0) + //该Subject 之前是否有已分配的 如果改变配置 可能会出现 一个Subject 分配的同一个医生 有的在Arm1 有的在Arm2 + var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) + .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); + + //不是初次分配 + if (allocateSubjectArmList.Count != 0) { + //if (_taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable).Count() < 2) + //{ + // throw new BusinessValidationFailedException("能参与读片的医生数量必须>=2,自动分配任务中止"); - #region 重阅/退回的时候,需要将取消分配的访视类型的 任务重新分配 + //} - if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) + //配置了医生 + if (assignConfigList.Count > 0) { - //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) - var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + #region 重阅/退回的时候,需要将取消分配的访视类型的 任务重新分配 - if (beforeBackVisitTask == null) + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - #region 访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) + var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + if (beforeBackVisitTask == null) + { + #region 访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + + if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) + { + singleTask.TaskAllocationState = defaultState; + + singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; + + singleTask.AllocateTime = DateTime.Now; + + singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + + + #endregion + + + var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 + var followVisitTaskList = await _visitTaskRepository + .Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) + .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) + .ToListAsync(); + + var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); + + //每个访视去判断 是分配还是生成 + + + foreach (var visitGroup in followVisitGroup) + { + //如果后续访视已分配有效 就不用处理 + if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.SingleReadingArm)) + { + //不做处理 + } + + else + { + var arm = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.SingleReadingArm); + if (arm != null) + { + arm.TaskAllocationState = TaskAllocationState.Allocated; + arm.AllocateTime = DateTime.Now; + arm.DoctorUserId = singleTask.DoctorUserId; + arm.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.SingleReadingArm).OrderByDescending(t => t.CreateTime).First(); + + var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + ArmEnum = Arm.SingleReadingArm,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + TaskUrgentType = latestTask.TaskUrgentType, + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + AllocateTime = DateTime.Now, + DoctorUserId = singleTask.DoctorUserId, + SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), + + TrialReadingCriterionId = latestTask.TrialReadingCriterionId, + IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, + IsClinicalDataSign = latestTask.IsClinicalDataSign + + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + } + + + } + + } + //之前有回退的 后续访视不生成或者分配 当前访视生成但是不分配出去 + else + { + + //不用进行额外处理 + } + + + + } + //无序的时候 生成任务并分配出去 + else + { var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; @@ -1062,137 +1175,32 @@ namespace IRaCIS.Core.Application.Service } - #endregion - - - var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); - - //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 - var followVisitTaskList = await _visitTaskRepository - .Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) - .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) - .ToListAsync(); - - var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); - - //每个访视去判断 是分配还是生成 - - - foreach (var visitGroup in followVisitGroup) - { - //如果后续访视已分配有效 就不用处理 - if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.SingleReadingArm)) - { - //不做处理 - } - - else - { - var arm = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.SingleReadingArm); - if (arm != null) - { - arm.TaskAllocationState = TaskAllocationState.Allocated; - arm.AllocateTime = DateTime.Now; - arm.DoctorUserId = singleTask.DoctorUserId; - arm.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.SingleReadingArm).OrderByDescending(t => t.CreateTime).First(); - - var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - ArmEnum = Arm.SingleReadingArm,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - TaskUrgentType = latestTask.TaskUrgentType, - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum), - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - AllocateTime = DateTime.Now, - DoctorUserId = singleTask.DoctorUserId, - SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), - - TrialReadingCriterionId = latestTask.TrialReadingCriterionId, - IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign, - IsClinicalDataSign = latestTask.IsClinicalDataSign - - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - } - - - } - - } - //之前有回退的 后续访视不生成或者分配 当前访视生成但是不分配出去 - else - { - - //不用进行额外处理 } - + #endregion } - //无序的时候 生成任务并分配出去 - else - { - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - - if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) - { - singleTask.TaskAllocationState = defaultState; - - singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; - - singleTask.AllocateTime = DateTime.Now; - - singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - } - - - } - - #endregion - } } - } - else - { - //后续Subect 不自动分配 不处理 - } + else + { + //后续Subect 不自动分配 不处理 + } + } + + } + #endregion } - #endregion - } - } @@ -1215,7 +1223,7 @@ namespace IRaCIS.Core.Application.Service if (reReadingVisitTask.SourceSubjectVisitId == null) { - subjectVisitId= _readModuleRepository.Where(t=>t.Id==reReadingVisitTask.SouceReadModuleId).Select(t=>t.SubjectVisitId).FirstOrDefault(); + subjectVisitId = _readModuleRepository.Where(t => t.Id == reReadingVisitTask.SouceReadModuleId).Select(t => t.SubjectVisitId).FirstOrDefault(); } else { @@ -1253,7 +1261,7 @@ namespace IRaCIS.Core.Application.Service TaskName = reReadingVisitTask.TaskName, TaskBlindName = reReadingVisitTask.TaskBlindName, - IsUrgent = reReadingVisitTask.IsAnalysisCreate?false: subjectVisitUrgentInfo.IsUrgent, + IsUrgent = reReadingVisitTask.IsAnalysisCreate ? false : subjectVisitUrgentInfo.IsUrgent, TaskUrgentType = reReadingVisitTask.IsAnalysisCreate ? null : taskUrgent, IsCanEditUrgentState = isCanEditUrgent, VisitTaskNum = reReadingVisitTask.VisitTaskNum, @@ -1426,7 +1434,7 @@ namespace IRaCIS.Core.Application.Service VisitTaskNum = firstTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge], TrialId = firstTask.TrialId, Code = currentMaxCodeInt + 1, - IsCanEditUrgentState= firstTask.IsCanEditUrgentState, + IsCanEditUrgentState = firstTask.IsCanEditUrgentState, SourceSubjectVisitId = firstTask.SourceSubjectVisitId, SouceReadModuleId = firstTask.SouceReadModuleId, TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), @@ -1483,8 +1491,8 @@ namespace IRaCIS.Core.Application.Service VisitTaskNum = item.VisitNum + ReadingCommon.TaskNumDic[ReadingCategory.Global], TaskName = item.ReadingName, ArmEnum = originalTaskInfo.ArmEnum,//特殊 - TaskUrgentType= originalTaskInfo.TaskUrgentType, - IsCanEditUrgentState= originalTaskInfo.IsCanEditUrgentState, + TaskUrgentType = originalTaskInfo.TaskUrgentType, + IsCanEditUrgentState = originalTaskInfo.IsCanEditUrgentState, TaskUrgentRemake = originalTaskInfo.TaskUrgentRemake, DoctorUserId = originalTaskInfo.DoctorUserId, AllocateTime = DateTime.Now, @@ -1492,7 +1500,7 @@ namespace IRaCIS.Core.Application.Service SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), Code = currentMaxCodeInt + 1, - TaskBlindName = "G-"+ visitNumList.IndexOf(originalTaskInfo.VisitTaskNum), + TaskBlindName = "G-" + visitNumList.IndexOf(originalTaskInfo.VisitTaskNum), SouceReadModuleId = item.ReadModuleId, TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), ReadingCategory = item.ReadingCategory, diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 01a5f77e1..a7ffd32b6 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1173,7 +1173,12 @@ namespace IRaCIS.Core.Application.Service.Allocation var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + if (criterionConfig.IsAutoCreate == false) + { + return ResponseOutput.NotOk("手动生成任务的不允许PM 申请影像重阅"); + } foreach (var task in taskList) { @@ -1952,7 +1957,12 @@ namespace IRaCIS.Core.Application.Service.Allocation var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + if (criterionConfig.IsAutoCreate==false) + { + return ResponseOutput.NotOk("手动生成任务的不允许影像退回"); + } if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) { diff --git a/IRaCIS.Core.Application/Service/Document/_MapConfig.cs b/IRaCIS.Core.Application/Service/Document/_MapConfig.cs index 61a8836f5..3cec4fc79 100644 --- a/IRaCIS.Core.Application/Service/Document/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Document/_MapConfig.cs @@ -20,7 +20,7 @@ namespace IRaCIS.Core.Application.Service CreateMap() .ForMember(d => d.FileType, u => u.MapFrom(s => s.FileType.MappedValue)) - .ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any())) + .ForMember(d => d.IsSomeUserSigned, u => u.MapFrom(s => s.TrialDocConfirmedUserList.Any(t=>t.ConfirmTime!=null))) .ForMember(d => d.FullFilePath, u => u.MapFrom(s => s.Path )); diff --git a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs index 316456b3f..662fe3180 100644 --- a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs +++ b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs @@ -516,13 +516,14 @@ namespace IRaCIS.Core.Application.Service SeriesNumber = series.SeriesNumber, SeriesTime = series.SeriesTime, - + InstanceCount=series.InstanceCount, StudyTime = series.DicomStudy.StudyTime, StudyId = series.StudyId, SeriesId = series.Id, SubjectVisitId = series.SubjectVisitId, TrialReadingCriterionId = inQuery.TrialReadingCriterionId, + IsReading=visitStudyFilter.IsReading, Id = visitStudyFilter.Id, CreateTime = visitStudyFilter.CreateTime,