using AutoMapper; using AutoMapper.QueryableExtensions; using IRaCIS.Application.ExpressionExtend; using IRaCIS.Application.Interfaces; using IRaCIS.Application.ViewModels; using IRaCIS.Core.Application.Contracts.RequestAndResponse; 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; using IRaCIS.Core.Domain.Share.AuthUser; using Microsoft.EntityFrameworkCore; namespace IRaCIS.Application.Servicess { public class UserTrialService : IUserTrialService { private readonly IUserTrialRepository _userTrialRepository; private readonly IDictionaryRepository _dictionaryRepository; private readonly IUserRepository _userRepository; private readonly ISiteRepository _siteRepository; private readonly IMapper _mapper; private readonly IUserInfo _userInfo; private readonly ISubjectRepository _subjectRepository; private readonly IDicomStudyRepository _studyRepository; private readonly ISubjectVisitRepository _subjectVisitRepository; public UserTrialService(IUserTrialRepository userTrialRepository, IDictionaryRepository dictionaryRepository, IUserRepository userRepository, ISiteRepository researchCenterRepository, IMapper mapper, IUserInfo userInfo,ISubjectRepository subjectRepository,IDicomStudyRepository studyRepository,ISubjectVisitRepository subjectVisitRepository) { _userTrialRepository = userTrialRepository; _dictionaryRepository = dictionaryRepository; _userRepository = userRepository; _siteRepository = researchCenterRepository; _mapper = mapper; _userInfo = userInfo; _subjectRepository = subjectRepository; _studyRepository = studyRepository; _subjectVisitRepository = subjectVisitRepository; } public IEnumerable GetTrialSiteSelect(Guid trialId) { var userId = _userInfo.Id; var exist = _userRepository.GetAll() .Any(t => t.Id == userId && t.UserType.Contains(StaticData.CRC)); IQueryable query = default; if (exist) { query = from userTrial in _userTrialRepository.GetAll() .Where(t => t.TrialId == trialId && t.SiteId != Guid.Empty && t.UserId == userId) join site in _siteRepository.GetAll() on userTrial.SiteId equals site.Id select new TrialSiteSelect() { Id = site.Id, SiteName = site.SiteName }; } else { query = (from userTrial in _userTrialRepository.GetAll() .Where(t => t.TrialId == trialId && t.SiteId != Guid.Empty) join site in _siteRepository.GetAll() on userTrial.SiteId equals site.Id select new TrialSiteSelect() { Id = site.Id, SiteName = site.SiteName }).Distinct(); } return query.OrderBy(t => t.SiteName).ToList(); } public IEnumerable GetMaintenanceUserList(TrialMaintenanceQuery param) { Expression> userTrialLambda = x => x.SiteId == Guid.Empty; if (param.UserTypeId != Guid.Empty && param.UserTypeId != null) { userTrialLambda = userTrialLambda.And(t => t.UserTypeId == param.UserTypeId); } Expression> userLambda = x => true; if (!string.IsNullOrWhiteSpace(param.UserName)) { userLambda = userLambda.And(t => t.UserName.Contains(param.UserName.Trim())); } var query = from userTrial in _userTrialRepository.Find(t => t.TrialId == param.TrialId).Where(userTrialLambda) join user in _userRepository.GetAll().Where(userLambda) on userTrial.UserId equals user.Id select new UserTrialDTO() { Id = userTrial.Id, UserId = userTrial.UserId, UserRealName = user.RealName, UserName = user.UserName, TrialId = userTrial.TrialId, UserTypeId = userTrial.UserTypeId, OrganizationTypeId = userTrial.OrganizationTypeId, OrganizationType = userTrial.OrganizationType, OrganizationId = userTrial.OrganizationId, OrganizationName = userTrial.OrganizationName, UpdateTime = userTrial.UpdateTime, UserType = userTrial.UserType }; return query.OrderBy(t => t.UpdateTime).ToList(); } public PageOutput GetUserTrialList(UserTrialListQueryDTO param) { Expression> userTrialLambda = x => x.SiteId == Guid.Empty; if (param.UserTypeId != Guid.Empty && param.UserTypeId != null) { userTrialLambda = userTrialLambda.And(t => t.UserTypeId == param.UserTypeId); } Expression> userLambda = x => true; if (!string.IsNullOrWhiteSpace(param.UserName)) { userLambda = userLambda.And(t => t.UserName.Contains(param.UserName.Trim())); } var query = from userTrial in _userTrialRepository.Find(t => t.TrialId == param.TrialId).Where(userTrialLambda) join user in _userRepository.GetAll().Where(userLambda) on userTrial.UserId equals user.Id select new UserTrialDTO() { Id = userTrial.Id, UserId = userTrial.UserId, UserRealName = user.RealName, TrialId = userTrial.TrialId, UserTypeId = userTrial.UserTypeId, OrganizationId = userTrial.OrganizationId, OrganizationName = userTrial.OrganizationName, UpdateTime = userTrial.UpdateTime, UserType = userTrial.UserType //OrganizationTypeId = userTrial.OrganizationTypeId, //OrganizationType = userTrial.OrganizationType, }; var count = query.Count(); var propName = string.IsNullOrWhiteSpace(param.SortField) ? "UserRealName" : param.SortField; query = param.Asc ? query.OrderBy(propName) : query.OrderByDescending(propName); query = query.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize); var list = query.ToList(); return new PageOutput(param.PageIndex, param.PageSize, count, list); } public IEnumerable GetUserSelectionList(Guid userTypeId, Guid institutionId) { var query = _userRepository.Find(u => u.UserTypeId == userTypeId && u.OrganizationId == institutionId).ProjectTo(_mapper.ConfigurationProvider); return query.ToList(); } /// 添加或更新运维人员 public IResponseOutput AddOrUpdateUserTrial(UserTrialCommand param) { if (param.Id == Guid.Empty || param.Id == null)//新增 { if (_userTrialRepository.GetAll().Any(u => u.UserId == param.UserId && u.TrialId == param.TrialId && u.SiteId == Guid.Empty)) { return ResponseOutput.NotOk("Trial participants already exist"); } if (param.UserType == "PM" && param.OrganizationName == "ZhiZhun") { //&& t.OrganizationType == param.OrganizationType) if (_userTrialRepository.GetAll().Any(t => t.TrialId == param.TrialId && t.UserType == "PM" && t.OrganizationName == "ZhiZhun" && t.SiteId == Guid.Empty)) { return ResponseOutput.NotOk("Trial can only have one ZhiZhun PM"); } } var temp = _mapper.Map(param); temp.SiteId = Guid.Empty; var result = _userTrialRepository.Add(temp); bool isSuccess = _userTrialRepository.SaveChanges(); return ResponseOutput.Result(isSuccess); } else //更新 { //此处过滤一定要加上 u.SiteId==Guid.Empty 一个用户可能负责多个site 不加过滤 会存在提示出问题 if (_userTrialRepository.GetAll().Any(u => u.UserId == param.UserId && u.TrialId == param.TrialId && u.Id != param.Id && u.SiteId == Guid.Empty)) { return ResponseOutput.NotOk("Trial participants already exist"); } if (param.UserType == "PM" && param.OrganizationName == "ZhiZhun") { //&& t.OrganizationType == param.OrganizationType if (_userTrialRepository.GetAll().Any(t => t.Id != param.Id && t.UserType == "PM" && t.TrialId == param.TrialId && t.OrganizationName == "ZhiZhun" && t.SiteId == Guid.Empty)) { return ResponseOutput.NotOk("Trial can only have one ZhiZhun PM"); } } var isSuccess = _userTrialRepository.Update(u => u.Id == param.Id, t => new UserTrial { TrialId = param.TrialId, UserId = param.UserId, UserTypeId = param.UserTypeId, UserType = param.UserType, SiteId = Guid.Empty, OrganizationTypeId = param.OrganizationTypeId, OrganizationType = param.OrganizationType, OrganizationId = param.OrganizationId, OrganizationName = param.OrganizationName, UserRealName = param.UserRealName, UpdateTime = DateTime.Now }); return ResponseOutput.Result(isSuccess); } } /// 删除运维人员 public IResponseOutput DeleteUserTrial(Guid id) { var user= _userTrialRepository.GetAll().FirstOrDefault(t => t.Id == id); if (_userTrialRepository.GetAll().Any(t => t.UserId == user.UserId&&t.SiteId!=Guid.Empty&&t.TrialId==user.TrialId)) { return ResponseOutput.NotOk("Participant has participated in site maintenance"); } var isSuccess = _userTrialRepository.Delete(u => u.Id == id); return ResponseOutput.Result(isSuccess); } public PageOutput GetSiteCRCList(SiteCrcQueryDTO param) { Expression> userLambda = x => true; if (!string.IsNullOrWhiteSpace(param.UserRealName)) { userLambda = userLambda.And(t => t.RealName.Contains(param.UserRealName.Trim())); } Expression> siteLambda = x => true; if (!string.IsNullOrWhiteSpace(param.SiteName)) { siteLambda = siteLambda.And(t => t.SiteName.Contains(param.SiteName.Trim())); } #region before //var query = from userTrial in _userTrialRepository.Find(t => t.TrialId == param.TrialId && t.SiteId != Guid.Empty)/*.Where(userTrialLambda)*/ // join user in _userRepository.GetAll().Where(userLambda) on userTrial.UserId equals user.Id // join site in _siteRepository.GetAll().Where(siteLambda) on userTrial.SiteId equals site.Id // select new SiteCrcDTO() // { // Id = userTrial.Id, // UserId = userTrial.UserId, // UserRealName = user.RealName, // UserName = user.UserName, // TrialId = userTrial.TrialId, // Phone = user.Phone, // UserTypeId = userTrial.UserTypeId, // UserType = userTrial.UserType, // OrganizationTypeId = userTrial.OrganizationTypeId, // OrganizationType = userTrial.OrganizationType, // OrganizationId = userTrial.OrganizationId, // OrganizationName = userTrial.OrganizationName, // UpdateTime = userTrial.UpdateTime, // SiteId = site.Id, // Site = site.SiteName, // City = site.City, // Country = site.Country // }; #endregion IQueryable siteStatQuery = default; var requestUser = _userRepository.GetAll().First(t => t.Id == _userInfo.Id); if (requestUser.SuperAdmin|| requestUser.UserType == StaticData.CROCoordinator|| requestUser.UserType == StaticData.PM|| requestUser.UserType == StaticData.QC) { siteStatQuery = from site in _siteRepository.GetAll().Where(siteLambda) join userTrialStat in _userTrialRepository .Find(t => t.TrialId == param.TrialId && t.SiteId != Guid.Empty).GroupBy(u => u.SiteId) .Select(g => new { SiteId = g.Key, UserCount = g.Count() }) on site.Id equals userTrialStat.SiteId join subjectStat in _subjectRepository.Find(t => t.TrialId == param.TrialId).GroupBy(u => u.SiteId) .Select(g => new { SiteId = g.Key, SubjectCount = g.Count() }) on site.Id equals subjectStat .SiteId into ST from subjectStatItem in ST.DefaultIfEmpty() ////加入 Visit统计 通过site下的受试者过滤visit 加入siteId 后修改 不用通过site下的用户过滤 //join subjectVisitStat in _subjectVisitRepository.Find(t=>t.TrialId==param.TrialId).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat.SiteId into SSV //from subjectVisitStatItem in SSV.DefaultIfEmpty() //join subjectVisitStat2 in _subjectVisitRepository.Find(t => t.TrialId == param.TrialId&&t.StudyUploaded).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat2.SiteId into SSV2 //from subjectVisitStatItem2 in SSV2.DefaultIfEmpty() join studyStat in _studyRepository.Find(t => t.TrialId == param.TrialId && t.Status != (int)StudyStatus.Abandon).GroupBy(u => u.SiteId).Select(g => new { SiteId = g.Key, StudyCount = g.Count() }) on site.Id equals studyStat.SiteId into STT from studyStatItem in STT.DefaultIfEmpty() select new SiteStatDTO() { SiteId = site.Id, Site = site.SiteName, City = site.City, Country = site.Country, //VisitCount = subjectVisitStatItem2.VisitCount, //PlanVisitCount = subjectVisitStatItem.VisitCount, StudyCount = studyStatItem.StudyCount, UserCount = userTrialStat.UserCount, SubjectCount = subjectStatItem.SubjectCount }; } else //CRC 或者其他的 { //CRC 只能看到他负责得site下的用户、访视、study 这种情况得到的siteId 不准确 因为 这个SiteId 有可能是因为他是其他项目对接人产生的 因而要加入trialId过滤 这里不用 自连接过滤 因为 指定了trialId //var userId = requestUser.Id; //var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == userId).Join(_userTrialRepository.Find(t => t.SiteId == Guid.Empty && t.UserId == userId), p => p.TrialId, q => q.TrialId, (p, q) => p.SiteId).Distinct(); // CRC 只能看到他负责得site下的用户、访视、study var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == requestUser.Id) .Select(t => t.SiteId).Distinct(); //通过site过滤受试者 //var subjectQuery = _subjectRepository.Find(t => siteQuery.Contains(t.SiteId)).Select(u => u.Id); //过滤site siteLambda = siteLambda.And(t => siteQuery.Contains(t.Id)); siteStatQuery = from site in _siteRepository.GetAll().Where(siteLambda) join userTrialStat in _userTrialRepository .Find(t => t.TrialId == param.TrialId && t.SiteId != Guid.Empty && t.UserId == requestUser.Id).GroupBy(u => u.SiteId) .Select(g => new { SiteId = g.Key, UserCount = g.Count() }) on site.Id equals userTrialStat.SiteId // subject 过滤site join subjectStat in _subjectRepository.Find(t => t.TrialId == param.TrialId&& siteQuery.Contains(t.SiteId)).GroupBy(u => u.SiteId) .Select(g => new { SiteId = g.Key, SubjectCount = g.Count() }) on site.Id equals subjectStat .SiteId into ST from subjectStatItem in ST.DefaultIfEmpty() ////加入 Visit统计 通过site下的受试者过滤visit 加入siteId 后修改 不用通过site下的用户过滤 //join subjectVisitStat in _subjectVisitRepository.Find(t => siteQuery.Contains(t.SiteId)&& t.TrialId == param.TrialId).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat.SiteId into SSV //from subjectVisitStatItem in SSV.DefaultIfEmpty() //join subjectVisitStat2 in _subjectVisitRepository.Find(t => t.TrialId == param.TrialId && t.StudyUploaded&& siteQuery.Contains(t.SiteId)).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat2.SiteId into SSV2 //from subjectVisitStatItem2 in SSV2.DefaultIfEmpty() // study 过滤site join studyStat in _studyRepository.Find(t => t.TrialId == param.TrialId && t.Status != (int)StudyStatus.Abandon && siteQuery.Contains(t.SiteId)).GroupBy(u => u.SiteId) .Select(g => new { SiteId = g.Key, StudyCount = g.Count() }) on site.Id equals studyStat.SiteId into STT from studyStatItem in STT.DefaultIfEmpty() select new SiteStatDTO() { SiteId = site.Id, Site = site.SiteName, City = site.City, Country = site.Country, //VisitCount = subjectVisitStatItem2.VisitCount, //PlanVisitCount = subjectVisitStatItem.VisitCount, StudyCount = studyStatItem.StudyCount, UserCount = userTrialStat.UserCount, SubjectCount = subjectStatItem.SubjectCount }; } var count = siteStatQuery.Count(); var propName = string.IsNullOrWhiteSpace(param.SortField) ? "Site" : param.SortField; siteStatQuery = param.Asc ? siteStatQuery.OrderBy(propName) : siteStatQuery.OrderByDescending(propName); siteStatQuery = siteStatQuery.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize); var list = siteStatQuery.ToList(); var siteIds = list.Select(t => t.SiteId).ToList(); var userQuery = from userTrial in _userTrialRepository .Find(t => t.TrialId == param.TrialId && siteIds.Contains(t.SiteId)) join user in _userRepository.GetAll().Where(userLambda) on userTrial.UserId equals user.Id select new { Id = userTrial.Id, SiteId = userTrial.SiteId, Phone = user.Phone, UserId = userTrial.UserId, UserRealName = user.RealName, UserName = user.UserName, TrialId = userTrial.TrialId, UserTypeId = userTrial.UserTypeId, UserType = userTrial.UserType, OrganizationTypeId = userTrial.OrganizationTypeId, OrganizationType = userTrial.OrganizationType, OrganizationId = userTrial.OrganizationId, OrganizationName = userTrial.OrganizationName, UpdateTime = userTrial.UpdateTime, }; var userList = userQuery.ToList(); list.ForEach(t=> t.UserList= userList.Where(u=>u.SiteId==t.SiteId).Select(userTrial=>new UserTrialDTO() { Id = userTrial.Id, SiteId = t.SiteId, Phone = userTrial.Phone, UserId = userTrial.UserId, UserRealName = userTrial.UserRealName, UserName = userTrial.UserName, TrialId = userTrial.TrialId, UserTypeId = userTrial.UserTypeId, UserType = userTrial.UserType, OrganizationTypeId = userTrial.OrganizationTypeId, OrganizationType = userTrial.OrganizationType, OrganizationId = userTrial.OrganizationId, OrganizationName = userTrial.OrganizationName, UpdateTime = userTrial.UpdateTime, }).ToList()); return new PageOutput(param.PageIndex, param.PageSize, count, list); } public IResponseOutput AddOrUpdateSiteCRC(SiteCRCCommand param) { if (param.Id == Guid.Empty || param.Id == null)//新增 { if (_userTrialRepository.GetAll().Any(u => u.UserId == param.UserId && u.TrialId == param.TrialId && u.SiteId == param.SiteId)) { return ResponseOutput.NotOk("the same Site already exist the same CRC participants "); } var temp = _mapper.Map(param); temp.UpdateTime = DateTime.Now; var result = _userTrialRepository.Add(temp); bool isSuccess = _userTrialRepository.SaveChanges(); return ResponseOutput.Result(isSuccess); } else //更新 { if (_userTrialRepository.GetAll().Any(u => u.UserId == param.UserId && u.TrialId == param.TrialId && u.SiteId == param.SiteId && u.Id != param.Id)) { return ResponseOutput.NotOk("the same Site already exist the same CRC participants "); } var isSuccess = _userTrialRepository.Update(u => u.Id == param.Id, t => new UserTrial { TrialId = param.TrialId, UserId = param.UserId, UserTypeId = param.UserTypeId, UserType = param.UserType, SiteId = param.SiteId, OrganizationTypeId = param.OrganizationTypeId, OrganizationType = param.OrganizationType, OrganizationId = param.OrganizationId, OrganizationName = param.OrganizationName, UserRealName = param.UserRealName, UpdateTime = DateTime.Now }); return ResponseOutput.Result(isSuccess); } } public IResponseOutput DeleteSiteCRC(Guid id) { var isSuccess = _userTrialRepository.Delete(u => u.Id == id); return ResponseOutput.Result(isSuccess); } } }