using AutoMapper; using IRaCIS.Application.ExpressionExtend; using IRaCIS.Application.ViewModels; using IRaCIS.Core.Application.Contracts.RequestAndResponse; using IRaCIS.Core.Application.Contracts.Trial; using IRaCIS.Core.Domain.Interfaces; using IRaCIS.Core.Domain.Models; using IRaCIS.Infra.Data.ExpressionExtend; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using IRaCIS.Core.Domain.Share.AuthUser; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Trial { public class SubjectVisitService : ISubjectVisitService { private readonly ISubjectVisitRepository _subjectVisitRepository; private readonly IDicomStudyRepository _studyRepository; private readonly IVisitStageRepository _visitStageRepository; private readonly ISubjectRepository _subjectRepository; private readonly IUserInfo _userInfo; private readonly IUserRepository _userRepository; private readonly IUserTrialRepository _userTrialRepository; private readonly ISiteRepository _siteRepository; private readonly IMapper _mapper; public SubjectVisitService(ISubjectVisitRepository visitPointRepository, IDicomStudyRepository studyRepository, IVisitStageRepository visitStageRepository, ISubjectRepository subjectRepository, IUserInfo userInfo, IUserRepository userRepository, IUserTrialRepository userTrialRepository, ISiteRepository siteRepository, IMapper mapper) { _subjectVisitRepository = visitPointRepository; _studyRepository = studyRepository; _visitStageRepository = visitStageRepository; _subjectRepository = subjectRepository; _userInfo = userInfo; _userRepository = userRepository; _userTrialRepository = userTrialRepository; _siteRepository = siteRepository; _mapper = mapper; } public List GetSubjectVisitSelectList(Guid trialId, Guid siteId, Guid subjectId) { var subjectVisitQuery = from subjectVisit in _subjectVisitRepository.GetAll() .Where(t => t.TrialId == trialId && t.SubjectId == subjectId) select new SubjectVisitSelectDTO { SubjectVisitId = subjectVisit.Id, VisitName = subjectVisit.VisitName, VisitNum = subjectVisit.VisitNum, SVUPDES = subjectVisit.SVUPDES, SVSTDTC = subjectVisit.SVSTDTC, SVENDTC = subjectVisit.SVENDTC, StudyUploaded = subjectVisit.StudyUploaded }; var subjectVisitList = subjectVisitQuery.OrderBy(t => t.VisitNum).ToList(); var subjectVisitIds = subjectVisitList.Select(t => t.SubjectVisitId).ToList(); //获取访视下面的study列表 var studyQuery = _studyRepository.GetAll().Where(t => t.TrialId == trialId && t.SiteId == siteId && t.SubjectId == subjectId && subjectVisitIds.Contains(t.SubjectVisitId)) .Select(u => new SubjectVisitStudyDTO() { SubjectVisitId = u.SubjectVisitId, Modalities = u.Modalities, StudyCode = u.StudyCode, StudyId = u.Id, Status = u.Status }); var studyList = studyQuery.ToList(); subjectVisitList.ForEach(t => { t.StudyList = studyList.Where(u => u.SubjectVisitId == t.SubjectVisitId).ToList(); }); return subjectVisitList; #region 受试者访视一次次加 改为 添加受试者的时候一次性加时 遗弃 不用处理访视计划表 //var visitPlanQuery = _visitStageRepository.Find(u => u.TrialId == trialId).Select(u => // new SubjectVisitSelectDTO() // { // VisitStageId = u.Id, // VisitName = u.VisitName, // VisitNum = u.VisitNum, // SVUPDES = u.Description // }); //var visitPlanList = visitPlanQuery.OrderBy(t => t.VisitNum).ToList(); ////如果不存在受试者访视记录 直接返回方式计划 //if (!subjectVisitList.Any()) //{ // return visitPlanList; //} //else //{ // visitPlanList.ForEach(t => // { // // 当前访视计划号 不在受试者访视表中 那么需要返回 // if (!subjectVisitList.Any(u => Math.Abs(t.VisitNum - u.VisitNum) < 0.01)) // { // subjectVisitList.Add(t); // } // }); // return subjectVisitList.OrderBy(t => t.VisitNum).ToList(); //} #endregion } public IEnumerable GetSubjectVisitList(Guid trialId, Guid subjectId) { //受试者已经访视得列表 + study统计 var query = from subjectVisit in _subjectVisitRepository.GetAll() .Where(t => t.TrialId == trialId && t.SubjectId == subjectId) //join visitStage in _visitStageRepository.Find(u => u.TrialId == trialId) on // new { subjectVisit.TrialId, subjectVisit.VisitDay } equals new // { visitStage.TrialId, visitStage.VisitDay } into dd //from visitStage in dd.DefaultIfEmpty() join subjectVisitStat in _studyRepository.GetAll().Where(t => t.TrialId == trialId && t.SubjectId == subjectId) .GroupBy(u => u.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals subjectVisitStat.SubjectVisitId into cc from subjectVisitStat in cc.DefaultIfEmpty() select new SubjectVisitDTO { Id = subjectVisit.Id, InPlan = subjectVisit.InPlan, TrialId = subjectVisit.TrialId, SubjectId = subjectVisit.SubjectId, VisitNum = subjectVisit.VisitNum, VisitName = subjectVisit.VisitName, VisitDay = subjectVisit.VisitDay, SVUPDES = subjectVisit.SVUPDES, SVSTDTC = subjectVisit.SVSTDTC, SVENDTC = subjectVisit.SVENDTC, StudyCount = subjectVisitStat.StudyCount }; var list = query.OrderBy(t => t.VisitNum).ToList(); #region 受试者访视一次次加 改为 添加受试者的时候一次性加时 遗弃 不用处理访视计划表 ////受试者未访视得列表 //Expression> visitStageLambda = x => x.TrialId == trialId; //IQueryable subjectVisitQuery = _subjectVisitRepository.GetAll() // .Where(t => t.TrialId == trialId && t.SubjectId == subjectId).Select(u => u.VisitNum); //visitStageLambda = visitStageLambda.And(t => !subjectVisitQuery.Contains(t.VisitNum)); //var planVisitList = _visitStageRepository.GetAll().Where(visitStageLambda).Select(t => new SubjectVisitDTO //{ // TrialId = t.TrialId, // SubjectId = subjectId, // VisitNum = t.VisitNum, // VisitName = t.VisitName, // VisitDay = t.VisitDay //}).ToList(); //list.AddRange(planVisitList); //return list.OrderBy(t => t.VisitNum).ToList(); #endregion return list; } public IResponseOutput AddOrUpdateSV(SubjectVisitCommand svCommand) { if (svCommand.Id == Guid.Empty || svCommand.Id == null) { var sv = _subjectVisitRepository.Add(_mapper.Map(svCommand)); var success = _subjectVisitRepository.SaveChanges(); var latest = _subjectVisitRepository.GetAll() .Where(t => t.SubjectId == svCommand.SubjectId && t.TrialId == svCommand.TrialId) .OrderByDescending(t => t.SVSTDTC).FirstOrDefault(); if (latest != null) { _subjectRepository.Update(t => t.Id == svCommand.SubjectId, u => new Subject() { SubjectVisitId = latest.Id }); } return ResponseOutput.Result(success, sv.Id.ToString()); } else { var success = _subjectVisitRepository.Update(t => t.Id == svCommand.Id, u => new SubjectVisit() { SubjectId = svCommand.SubjectId, TrialId = svCommand.TrialId, SiteId = svCommand.SiteId, VisitDay = svCommand.VisitDay, VisitNum = svCommand.VisitNum, VisitName = svCommand.VisitName, SVENDTC = svCommand.SVENDTC, SVSTDTC = svCommand.SVSTDTC, SVUPDES = svCommand.SVUPDES, InPlan = svCommand.InPlan, UpdateTime = DateTime.Now }); var latest = _subjectVisitRepository.GetAll() .Where(t => t.SubjectId == svCommand.SubjectId && t.TrialId == svCommand.TrialId) .OrderByDescending(t => t.SVSTDTC).FirstOrDefault(); if (latest != null) { _subjectRepository.Update(t => t.Id == svCommand.SubjectId, u => new Subject() { SubjectVisitId = latest.Id }); } return ResponseOutput.Result(success); } } public IResponseOutput DeleteSV(Guid id) { if (_studyRepository.GetAll().Any(t => t.SubjectVisitId == id)) { return ResponseOutput.NotOk("There are Study data under the subject’s visit"); } return ResponseOutput.Result( _subjectVisitRepository.Delete(s => s.Id == id)); } public PageOutput GetVisitList(SubjectVisitSearchDTO subjectVisitSearch) { Expression> subjectLambda = x => true; Expression> subjectVisitLambda = x => x.TrialId == subjectVisitSearch.TrialId; Expression> studyLambda = x => x.TrialId == subjectVisitSearch.TrialId&&x.Status!= (int)StudyStatus.Abandon; //Expression> visitPlanLambda = x => x.TrialId == subjectVisitSearch.TrialId; if (subjectVisitSearch.SiteId != null&& subjectVisitSearch.SiteId != Guid.Empty) { subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId ==subjectVisitSearch.SiteId.Value); studyLambda = studyLambda.And(t => t.SiteId == subjectVisitSearch.SiteId.Value); } if (subjectVisitSearch.SubjectId != null && subjectVisitSearch.SubjectId != Guid.Empty) { subjectLambda = subjectLambda.And(t => t.Id == subjectVisitSearch.SubjectId.Value); studyLambda= studyLambda.And(t => t.SubjectId == subjectVisitSearch.SubjectId.Value); } if (!string.IsNullOrEmpty(subjectVisitSearch.SubjectInfo)) { var search = subjectVisitSearch.SubjectInfo.Trim(); subjectLambda = subjectLambda.And(t => t.Name.Contains(search) ||t.Code.Contains(search)); } if (!string.IsNullOrWhiteSpace(subjectVisitSearch.VisitPlanInfo)) { var visitInfo = subjectVisitSearch.VisitPlanInfo.Trim(); if (visitInfo.Contains('.')) { subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum.ToString().Contains(".")); } else { if (int.TryParse(visitInfo, out var visitNum)) { subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum == visitNum); } } } var requestUser = _userRepository.GetAll().First(t => t.Id == _userInfo.Id); IQueryable query = default; if (requestUser.SuperAdmin || requestUser.UserType == StaticData.CROCoordinator || requestUser.UserType == StaticData.PM || requestUser.UserType == StaticData.QC) { query = from subjectVisit in _subjectVisitRepository.Find(subjectVisitLambda) join subject in _subjectRepository.Find(subjectLambda) on subjectVisit.SubjectId equals subject.Id join site in _siteRepository.GetAll() on subjectVisit.SiteId equals site.Id join study in _studyRepository.Find(studyLambda).GroupBy(t=>t.SubjectVisitId).Select(g=>new { SubjectVisitId= g.Key,StudyCount=g.Count()} ) on subjectVisit.Id equals study.SubjectVisitId into d from study in d.DefaultIfEmpty() select new SubjectVisitNewDTO() { Id= subjectVisit.Id, //VisitPlanId = visitStage.Id, SubjectId = subjectVisit.SubjectId, TrialId = subjectVisit.TrialId, SiteId = subjectVisit.SiteId, VisitDay = subjectVisit.VisitDay, VisitNum = subjectVisit.VisitNum, VisitName = subjectVisit.VisitName, SVENDTC = subjectVisit.SVENDTC, SVSTDTC = subjectVisit.SVSTDTC, SVUPDES = subjectVisit.SVUPDES, InPlan = subjectVisit.InPlan, StudyUploaded = subjectVisit.StudyUploaded, UpdateTime = subjectVisit.UpdateTime, SubjectCode = subject.Code, SubjectName = subject.Name, StudyCount = study.StudyCount, SiteCode = site.SiteCode, SiteName = site.SiteName }; } else//CRC 或者其他的 { //CRC 只能看到他负责得site下的用户、访视 var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == requestUser.Id) .Select(t => t.SiteId).Distinct(); subjectVisitLambda = subjectVisitLambda.And(t => siteQuery.Contains(t.SiteId)); query = from subjectVisit in _subjectVisitRepository.Find(subjectVisitLambda) join subject in _subjectRepository.Find(subjectLambda) on subjectVisit.SubjectId equals subject.Id join site in _siteRepository.GetAll() on subjectVisit.SiteId equals site.Id join study in _studyRepository.Find(studyLambda).GroupBy(t => t.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals study.SubjectVisitId into d from study in d.DefaultIfEmpty() select new SubjectVisitNewDTO() { Id = subjectVisit.Id, SubjectId = subjectVisit.SubjectId, TrialId = subjectVisit.TrialId, SiteId = subjectVisit.SiteId, VisitDay = subjectVisit.VisitDay, VisitNum = subjectVisit.VisitNum, VisitName = subjectVisit.VisitName, SVENDTC = subjectVisit.SVENDTC, SVSTDTC = subjectVisit.SVSTDTC, SVUPDES = subjectVisit.SVUPDES, InPlan = subjectVisit.InPlan, StudyUploaded = subjectVisit.StudyUploaded, UpdateTime = subjectVisit.UpdateTime, SubjectCode = subject.Code, SubjectName = subject.Name, StudyCount = study.StudyCount, SiteCode = site.SiteCode, SiteName = site.SiteName, }; } var count = query.Count(); var propName = subjectVisitSearch.SortField == string.Empty ? "UpdateTime" : subjectVisitSearch.SortField; query = subjectVisitSearch.Asc ? query.OrderBy(t=>t.SubjectId) : query.OrderByDescending(propName); query = query.Skip((subjectVisitSearch.PageIndex - 1) * subjectVisitSearch.PageSize).Take(subjectVisitSearch.PageSize); var list = query.ToList(); return new PageOutput(subjectVisitSearch.PageIndex, subjectVisitSearch.PageSize, count, list); } } }