CostCalculationItem/IRaCIS.Core.Application/Trial/Subject/SubjectVisitService.cs

420 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 subjects 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);
}
}
}