using AutoMapper; 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 EasyCaching.Core.Configurations; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share.AuthUser; namespace IRaCIS.Application.Services { public class SubjectService : ISubjectService { private readonly ISubjectRepository _subjectsRepository; private readonly IVisitStageRepository _visitStageRepository; private readonly ISiteRepository _siteRepository; private readonly IMapper _mapper; private readonly ISubjectVisitRepository _subjectVisitRepository; private readonly IDicomStudyRepository _studyRepository; private readonly IUserInfo _userInfo; private readonly IUserRepository _userRepository; private readonly IUserTrialRepository _userTrialRepository; private readonly ITrialRepository _trialRepository; public SubjectService(ISubjectRepository subjectRepository, IVisitStageRepository visitStageRepository, ISiteRepository siteRepository, IMapper mapper, ISubjectVisitRepository subjectVisitRepository, IDicomStudyRepository studyRepository, IUserInfo userInfo, IUserRepository userRepository, IUserTrialRepository userTrialRepository,ITrialRepository trialRepository) { _subjectsRepository = subjectRepository; _visitStageRepository = visitStageRepository; _siteRepository = siteRepository; _mapper = mapper; _subjectVisitRepository = subjectVisitRepository; _studyRepository = studyRepository; _userInfo = userInfo; _userRepository = userRepository; _userTrialRepository = userTrialRepository; _trialRepository = trialRepository; } public IResponseOutput AddOrUpdateSubject(SubjectCommand model) { model.Code = model.Code.Trim(); if (model.Id == Guid.Empty || model.Id == null) //add { var saveItem = _mapper.Map(model); saveItem.StudyCount = 0; saveItem.SubjectVisitId = Guid.Empty; saveItem.Modalities = string.Empty; //var last = _subjectsRepository.GetAll() // .OrderByDescending(c => c.Code).FirstOrDefault(); //if (last != null) //{ // var len = last.Code.Length; // if (len > 9 && int.TryParse(last.Code.Substring(len - 9, 9), out var num)) // { // saveItem.Code = "S" + (++num).ToString().PadLeft(9, '0'); // } // else // { // return ResponseOutput.NotOk("Generated Code failed.", new DicomStudy()); // } //} //else //{ // saveItem.Code = "S" + 1.ToString().PadLeft(9, '0'); //} var subject = _subjectsRepository.GetAll().FirstOrDefault(u => u.Code == model.Code && u.TrialId == model.TrialId); if (subject != null) { return ResponseOutput.NotOk("该项目下已经存在相同受试者编码的受试者。"); } if (!_trialRepository.GetAll().Any(t => t.Id == model.TrialId && t.VisitPlanConfirmed)) { return ResponseOutput.NotOk("该项目访视计划未确认,无法添加受试者及其访视计划安排"); } var result = _subjectsRepository.Add(saveItem); //获取访视计划列表 var visitPlan= _visitStageRepository.GetAll().Where(t => t.TrialId == model.TrialId).ToList(); var subjectVisitPlanList=new List(); visitPlan.ForEach(plan=>subjectVisitPlanList.Add(new SubjectVisit() { TrialId = model.TrialId, SubjectId = result.Id, SiteId = model.SiteId, InPlan =true, VisitNum=plan.VisitNum, VisitName= plan.VisitName, VisitDay = plan.VisitDay })); _subjectVisitRepository.AddRange(subjectVisitPlanList); var isSuccess = _subjectsRepository.SaveChanges(); return ResponseOutput.Result(isSuccess, result.Id.ToString()); } else // update { var subject = _subjectsRepository.GetAll().FirstOrDefault(t => t.Id == model.Id); _mapper.Map(model, subject); var temp = _subjectsRepository.GetAll().FirstOrDefault(u => u.Code == model.Code && u.TrialId == model.TrialId && u.Id != model.Id); if (temp != null) { return ResponseOutput.NotOk("该项目下已经存在相同受试者编码的受试者。"); } _subjectsRepository.Update(subject); var isSuccess = _subjectsRepository.SaveChanges(); return ResponseOutput.Result(isSuccess); } } public IResponseOutput DeleteSubject(Guid id) { if (_studyRepository.GetAll().Any(t => t.SubjectId == id) || _subjectVisitRepository.GetAll().Any(u => u.SubjectId == id)) { return ResponseOutput.NotOk("Subject’s visit or study data exists under the subject"); } var isSuccess = _subjectsRepository.Delete(u => u.Id == id); return ResponseOutput.Result(isSuccess); } public PageOutput GetSubjectList(SubjectQueryParam param) { Expression> subjectLambda = x => true; Expression> studyLambda = x => x.TrialId == param.TrialId&& x.Status != (int)StudyStatus.Abandon; Expression> subjectVisitLambda = x => x.TrialId == param.TrialId; if (!string.IsNullOrWhiteSpace(param.Code)) { subjectLambda = subjectLambda.And(t => t.Code.Contains(param.Code.Trim())); } if (!string.IsNullOrWhiteSpace(param.Name)) { subjectLambda = subjectLambda.And(t => t.Name.Contains(param.Name.Trim())); } if (!string.IsNullOrWhiteSpace(param.Sex)) { subjectLambda = subjectLambda.And(t => t.Sex==param.Sex.Trim()); } if (param.Status != null) { subjectLambda = subjectLambda.And(t => t.Status == param.Status); } if (param.SiteId != null) { subjectLambda = subjectLambda.And(t => t.SiteId == param.SiteId); studyLambda = studyLambda.And(t => t.SiteId == param.SiteId); } else { //是CRC 需要过滤 var userId = _userInfo.Id; var exist = _userRepository.GetAll() .Any(t => t.Id == userId && t.UserType.Contains(StaticData.CRC)); if (exist) { var siteIds = _userTrialRepository.GetAll().Where(t => t.SiteId != Guid.Empty && t.UserId == userId && t.TrialId== param.TrialId) .Select(u => u.SiteId); subjectLambda = subjectLambda.And(t => siteIds.Contains(t.SiteId)); studyLambda = studyLambda.And(t => siteIds.Contains(t.SiteId)); } } var query = from subject in _subjectsRepository.Find(u => u.TrialId == param.TrialId).Where(subjectLambda) join subjectVisit in _subjectVisitRepository.Find(u => u.TrialId == param.TrialId) on subject.SubjectVisitId equals subjectVisit.Id into h from subjectVisit in h.DefaultIfEmpty() join site in _siteRepository.GetAll() on subject.SiteId equals site.Id join studyStat in _studyRepository.GetAll().Where(studyLambda) .GroupBy(u => u.SubjectId).Select(g => new { SubjectId = g.Key, StudyCount = g.Count() }) on subject.Id equals studyStat.SubjectId into cc from studyStatItem in cc.DefaultIfEmpty() join visitStat in _subjectVisitRepository.Find(subjectVisitLambda).GroupBy(u => u.SubjectId).Select(g => new { SubjectId = g.Key, VisitCount = g.Count() }) on subject.Id equals visitStat.SubjectId into dd from visitStatItem in dd.DefaultIfEmpty() join subjectVisitStat2 in _subjectVisitRepository.Find(t => t.TrialId == param.TrialId && t.StudyUploaded ).GroupBy(t => t.SubjectId).Select(g => new { SubjectId = g.Key, VisitCount = g.Count() }) on subject.Id equals subjectVisitStat2.SubjectId into SSV2 from subjectVisitStatItem2 in SSV2.DefaultIfEmpty() select new SubjectQueryModel() { Id = subject.Id, TrialId = subject.TrialId, Name = subject.Name, Code = subject.Code, SubjectVisitId = subject.SubjectVisitId, Sex = subject.Sex, Age = subject.Age, MedicalNo = subject.MedicalNo, Modalities = subject.Modalities, SiteId = subject.SiteId, SiteName = site.SiteName, Status = subject.Status, UpdateTime = subject.UpdateTime, CreateTime = subject.CreateTime, Reason = subject.Reason, StudyCount = studyStatItem.StudyCount, PlanVisitCount = visitStatItem.VisitCount, VisitCount = subjectVisitStatItem2.VisitCount, VisitName = subjectVisit.VisitName, }; var count = query.Count(); var propName = param.SortField == string.Empty ? "Code" : param.SortField; query = param.Asc ? query.OrderBy(propName).ThenBy(t => t.SiteName).ThenBy(t => t.Code) : query.OrderByDescending(propName).ThenBy(t => t.SiteName).ThenBy(t => t.Code); 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 List GetSubjectListBySiteId(Guid siteId, Guid trialId) { var query = _subjectsRepository.GetAll().Where(t => t.SiteId == siteId && t.TrialId == trialId).Select(u => new SubjectSelect() { Code = u.Code, Name = u.Name, Sex = u.Sex, SubjectId = u.Id, Age = u.Age }); return query.ToList(); } } }