420 lines
17 KiB
C#
420 lines
17 KiB
C#
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<SubjectVisitSelectDTO> 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<SubjectVisitDTO> 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<Func<VisitStage, bool>> visitStageLambda = x => x.TrialId == trialId;
|
||
|
||
//IQueryable<double> 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<SubjectVisit>(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<SubjectVisitNewDTO> GetVisitList(SubjectVisitSearchDTO subjectVisitSearch)
|
||
{
|
||
Expression<Func<Subject, bool>> subjectLambda = x => true;
|
||
|
||
Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == subjectVisitSearch.TrialId;
|
||
Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == subjectVisitSearch.TrialId&&x.Status!= (int)StudyStatus.Abandon;
|
||
//Expression<Func<VisitStage, bool>> 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<SubjectVisitNewDTO> 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<SubjectVisitNewDTO>(subjectVisitSearch.PageIndex,
|
||
subjectVisitSearch.PageSize, count, list);
|
||
}
|
||
}
|
||
}
|