CostCalculationItem/IRaCIS.Core.Application/Trial/TrialService.cs

1104 lines
57 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 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.Core.Domain.Share;
using IRaCIS.Core.Domain.Share.AuthUser;
using IRaCIS.Infra.Data.ExpressionExtend;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace IRaCIS.Application.Services
{
public class TrialService : ITrialService
{
private readonly ITrialRepository _trialRepository;
private readonly IDictionaryRepository _dictionaryRepository;
private readonly IUserRepository _userRepository;
private readonly IEnrollRepository _enrollRepository;
private readonly IEnrollDetailRepository _enrollDetailRepository;
private readonly IWorkloadRepository _workloadRepository;
private readonly ITrialDictionaryRepository _trialDictionaryRepository;
private readonly IUserTrialRepository _userTrialRepository;
private readonly ICRORepository _croRepository;
private readonly ISponsorRepository _sponsorRepository;
private readonly ITrialPaymentPriceRepository _trialPaymentPriceRepository;
private readonly IMapper _mapper;
private readonly IUserInfo _userInfo;
private readonly ISubjectRepository _subjectRepository;
private readonly IDicomStudyRepository _studyRepository;
private readonly ISubjectVisitRepository _subjectVisitRepository;
public bool TrialExpeditedChange { get; set; } = false;
public TrialService(ITrialRepository clinicalTrialProjectRepository, IDictionaryRepository sysDicRepository,
IUserRepository sysUserRepository,
IEnrollRepository intoGroupRepository,
IEnrollDetailRepository intoGroupDetailRepository,
ITrialDictionaryRepository projectDictionaryRepository,
IUserTrialRepository userTrialRepository,
ICRORepository croCompanyRepository,
ISponsorRepository sponsorRepository,
ITrialPaymentPriceRepository trialExtRepository,
IWorkloadRepository workloadRepository,
IUserInfo userInfo,
ISubjectRepository subjectRepository,
IDicomStudyRepository studyRepository,
ISubjectVisitRepository subjectVisitRepository,
IMapper mapper)
{
_trialRepository = clinicalTrialProjectRepository;
_dictionaryRepository = sysDicRepository;
_userRepository = sysUserRepository;
_enrollRepository = intoGroupRepository;
_enrollDetailRepository = intoGroupDetailRepository;
_workloadRepository = workloadRepository;
_trialDictionaryRepository = projectDictionaryRepository;
_userTrialRepository = userTrialRepository;
_croRepository = croCompanyRepository;
_sponsorRepository = sponsorRepository;
_trialPaymentPriceRepository = trialExtRepository;
_userInfo = userInfo;
_subjectRepository = subjectRepository;
_studyRepository = studyRepository;
_subjectVisitRepository = subjectVisitRepository;
_mapper = mapper;
}
/// <summary>
/// 分页获取临床项目列表 默认后台加急状态为3 查所有的
/// </summary>
/// <param name="searchParam"></param>
/// <param name="userId"></param>
/// <returns></returns>
public PageOutput<TrialDetailDTO> GetTrialList(TrialQueryDTO searchParam,
Guid userId)
{
var trialLambda = GetTrialSearchLambda(searchParam);
var multiSelectCount = searchParam.ModalityIds.Count;
//有多选信息
if (multiSelectCount > 0)
{
var trialIdFilterQuery = _trialDictionaryRepository.GetAll()
.Where(t => searchParam.ModalityIds.Contains(t.DictionaryId)).GroupBy(t => t.TrialId).Select(g =>
new
{
TrialId = g.Key,
Count = g.Count()
}).Where(t => t.Count == multiSelectCount).Select(t => t.TrialId);
trialLambda = trialLambda.And(t => trialIdFilterQuery.Contains(t.Id));
}
IQueryable<TrialDetailDTO> trialQueryable = default;
var user = _userRepository.GetAll().First(t => t.Id == userId);
//超级管理员,查看所有
if (user.SuperAdmin)
{
trialQueryable = from trial in _trialRepository.GetAll().Where(trialLambda)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into t
from croItem in t.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id into d
from sponsorItem in d.DefaultIfEmpty()
//加入site 统计 注意 site因为跟对接人是一对多的关系 所以得去重
join siteStat in _userTrialRepository.Find(t => t.SiteId != Guid.Empty).Select(u=>new{ TrialId = u.TrialId,SiteId =u.SiteId} ).Distinct()
.GroupBy(t=>t.TrialId).Select(g=>new {TrialId=g.Key,SiteCount=g.Count()})
on trial.Id equals siteStat.TrialId into ST
from siteStatItem in ST.DefaultIfEmpty()
//加入subject统计
join subjectStat in _subjectRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SubjectCount = g.Count() }) on trial.Id equals subjectStat.TrialId into SS
from subjectStatItem in SS.DefaultIfEmpty()
//加入 Visit统计
join subjectVisit in _subjectVisitRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, VisitCount = g.Count() }) on trial.Id equals subjectVisit.TrialId into SSV
from subjectVisitItem in SSV.DefaultIfEmpty()
//加入 study统计
join studyStat in _studyRepository.GetAll().Where(t=>t.Status!=(int)StudyStatus.Abandon).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, StudyCount = g.Count() }) on trial.Id equals studyStat.TrialId into SSTU
from studyStatItem in SSTU.DefaultIfEmpty()
//join subjectVisit in _subjectVisitRepository
select new TrialDetailDTO()
{
Sponsor = sponsorItem.SponsorName,
CRO = croItem.CROName,
Id = trial.Id,
Code = trial.Code,
SponsorId = trial.SponsorId,
CROId = trial.CROId,
Indication = trial.Indication,
Note = trial.Note,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
CriterionId = trial.CriterionId,
ReviewModeId = trial.ReviewModeId,
TurnaroundTime = trial.TurnaroundTime,
Expedited = trial.Expedited,
ReviewProtocol = trial.ReviewProtocol,
MessageFromClient = trial.MessageFromClient,
ReviewProtocolName = trial.ReviewProtocolName,
MessageFromClientName = trial.MessageFromClientName,
GRRReviewers = trial.GRRReviewers,
TotalReviewers = trial.TotalReviewers,
TrialStatus = trial.TrialStatus,
TrialStatusStr = trial.TrialStatusStr,
CreateTime = trial.CreateTime,
VisitPlanConfirmed=trial.VisitPlanConfirmed,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
Phase = trial.Phase,
ReviewTypeId = trial.ReviewTypeId,
SiteCount = siteStatItem.SiteCount,
//VisitCount= subjectVisitItem.VisitCount,
SubjectCount = subjectStatItem.SubjectCount,
StudyCount = studyStatItem.StudyCount
};
}
else// 不是超级管理员,
{
// 协调者,查看自己所在机构下的
// 其他人员,只能查看自己参与的
if (user.UserType == StaticData.CROCoordinator)//协调者查看自己机构的
{
searchParam.CROId = user.OrganizationId;
var trialLambdaT = GetTrialSearchLambda(searchParam);
trialQueryable = from trial in _trialRepository.GetAll().Where(trialLambdaT)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into t
from croItem in t.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id into d
from sponsorItem in d.DefaultIfEmpty()
//加入site 统计 注意 site因为跟对接人是一对多的关系 所以得去重
join siteStat in _userTrialRepository.Find(t => t.SiteId != Guid.Empty).Select(u => new { TrialId = u.TrialId, SiteId = u.SiteId }).Distinct()
.GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SiteCount = g.Count() })
on trial.Id equals siteStat.TrialId into ST
from siteStatItem in ST.DefaultIfEmpty()
//加入subject统计
join subjectStat in _subjectRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SubjectCount = g.Count() }) on trial.Id equals subjectStat.TrialId into SS
from subjectStatItem in SS.DefaultIfEmpty()
////加入 Visit统计
//join subjectVisit in _subjectVisitRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, VisitCount = g.Count() }) on trial.Id equals subjectVisit.TrialId into SSV
//from subjectVisitItem in SSV.DefaultIfEmpty()
//加入 study统计
join studyStat in _studyRepository.GetAll().Where(t => t.Status != (int)StudyStatus.Abandon).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, StudyCount = g.Count() }) on trial.Id equals studyStat.TrialId into SSTU
from studyStatItem in SSTU.DefaultIfEmpty()
select new TrialDetailDTO()
{
Sponsor = sponsorItem.SponsorName,
CRO = croItem.CROName,
Id = trial.Id,
Code = trial.Code,
SponsorId = trial.SponsorId,
CROId = trial.CROId,
Indication = trial.Indication,
Note = trial.Note,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
CriterionId = trial.CriterionId,
ReviewModeId = trial.ReviewModeId,
TurnaroundTime = trial.TurnaroundTime,
Expedited = trial.Expedited,
ReviewProtocol = trial.ReviewProtocol,
MessageFromClient = trial.MessageFromClient,
ReviewProtocolName = trial.ReviewProtocolName,
MessageFromClientName = trial.MessageFromClientName,
GRRReviewers = trial.GRRReviewers,
TotalReviewers = trial.TotalReviewers,
TrialStatus = trial.TrialStatus,
TrialStatusStr = trial.TrialStatusStr,
CreateTime = trial.CreateTime,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
Phase = trial.Phase,
ReviewTypeId = trial.ReviewTypeId,
SiteCount = siteStatItem.SiteCount,
//VisitCount = subjectVisitItem.VisitCount,
SubjectCount = subjectStatItem.SubjectCount,
StudyCount = studyStatItem.StudyCount
};
}
//不是协调者,只能自己参与的项目
//if (user.IsZhiZhun || user.UserType == StaticData.PM)
else if(user.UserType == StaticData.CRC)
{
//CRC 只能看到他负责得site下的用户、访视、study 这种情况得到的siteId 不准确 因为 这个SiteId 有可能是因为他是其他项目对接人产生的
//var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == userId)
// .Select(t => t.SiteId).Distinct();
//CRC 只能看到他负责得site下的用户、访视、study 这种情况得到的siteId 不准确 因为 这个SiteId 有可能是因为他是其他项目对接人产生的 因而要加入trialId过滤
// 参与了这个项目 并且是对接人 才算拥有这个site
//var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == userId).Join(_userTrialRepository.Find(t => t.SiteId == Guid.Empty && t.UserId == userId), p =>new { p.TrialId ,p.SiteId} , q => new { q.TrialId, q.SiteId }, (p, q) => p.SiteId).Distinct();//
var siteQuery = _userTrialRepository.Find(t => t.SiteId != Guid.Empty && t.UserId == userId)
.Select(t => new { t.SiteId, t.TrialId }).Distinct();
//通过site过滤受试者
//var subjectQuery = _subjectRepository.Find(t => siteQuery.Contains(t.SiteId)).Select(u=>u.Id);
trialQueryable = from trial in _trialRepository.GetAll().Where(trialLambda)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into t
from croItem in t.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id
into d
from sponsorItem in d.DefaultIfEmpty()
join userTrial in _userTrialRepository.GetAll().Where(t => t.UserId == userId && t.SiteId == Guid.Empty) on trial.Id equals userTrial.TrialId
//加入site 统计 注意 site因为跟对接人是一对多的关系 所以得去重
join siteStat in _userTrialRepository.Find(t => t.SiteId != Guid.Empty&& t.UserId == userId).Select(u => new { TrialId = u.TrialId, SiteId = u.SiteId }).Distinct()
.GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SiteCount = g.Count() })
on trial.Id equals siteStat.TrialId into ST
from siteStatItem in ST.DefaultIfEmpty()
//加入subject统计 过滤site下的subject
join subjectStat in _subjectRepository.GetAll().Join(siteQuery, p => new { p.TrialId, p.SiteId }, q => new { q.TrialId, q.SiteId }, (p, q)=>p).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SubjectCount = g.Count() }) on trial.Id equals subjectStat.TrialId into SS
from subjectStatItem in SS.DefaultIfEmpty()
////加入 Visit统计 通过site下的受试者过滤visit
//join subjectVisit in _subjectVisitRepository.Find(t=> subjectQuery.Contains(t.SubjectId)).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, VisitCount = g.Count() }) on trial.Id equals subjectVisit.TrialId into SSV
//from subjectVisitItem in SSV.DefaultIfEmpty()
// //受试者访视加入siteId字段 修改
//join subjectVisit in _subjectVisitRepository.GetAll().Join(siteQuery, p => new { p.TrialId, p.SiteId }, q => new { q.TrialId, q.SiteId }, (p, q) => p).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, VisitCount = g.Count() }) on trial.Id equals subjectVisit.TrialId into SSV
//from subjectVisitItem in SSV.DefaultIfEmpty()
//加入 study统计 过滤site下的study
join studyStat in _studyRepository.GetAll().Join(siteQuery, p => new { p.TrialId, p.SiteId }, q => new { q.TrialId, q.SiteId }, (p, q) => p).Where(t => t.Status != (int)StudyStatus.Abandon).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, StudyCount = g.Count() }) on trial.Id equals studyStat.TrialId into SSTU
from studyStatItem in SSTU.DefaultIfEmpty()
select new TrialDetailDTO()
{
Sponsor = sponsorItem.SponsorName,
CRO = croItem.CROName,
Id = trial.Id,
Code = trial.Code,
SponsorId = trial.SponsorId,
CROId = trial.CROId,
Indication = trial.Indication,
Note = trial.Note,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
CriterionId = trial.CriterionId,
ReviewModeId = trial.ReviewModeId,
TurnaroundTime = trial.TurnaroundTime,
ReviewProtocol = trial.ReviewProtocol,
MessageFromClient = trial.MessageFromClient,
ReviewProtocolName = trial.ReviewProtocolName,
MessageFromClientName = trial.MessageFromClientName,
GRRReviewers = trial.GRRReviewers,
TotalReviewers = trial.TotalReviewers,
TrialStatus = trial.TrialStatus,
TrialStatusStr = trial.TrialStatusStr,
CreateTime = trial.CreateTime,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
Phase = trial.Phase,
ReviewTypeId = trial.ReviewTypeId,
SiteCount = siteStatItem.SiteCount,
//VisitCount = subjectVisitItem.VisitCount,
SubjectCount = subjectStatItem.SubjectCount,
StudyCount = studyStatItem.StudyCount
};
}
else //QC 和PM 参与项目的 完整统计
{
trialQueryable = from trial in _trialRepository.GetAll().Where(trialLambda)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into t
from croItem in t.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id
into d
from sponsorItem in d.DefaultIfEmpty()
join userTrial in _userTrialRepository.GetAll().Where(t => t.UserId == userId && t.SiteId == Guid.Empty) on trial.Id equals userTrial.TrialId
//加入site 统计 注意 site因为跟对接人是一对多的关系 所以得去重
join siteStat in _userTrialRepository.Find(t => t.SiteId != Guid.Empty).Select(u => new { TrialId = u.TrialId, SiteId = u.SiteId }).Distinct()
.GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SiteCount = g.Count() })
on trial.Id equals siteStat.TrialId into ST
from siteStatItem in ST.DefaultIfEmpty()
//加入subject统计
join subjectStat in _subjectRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, SubjectCount = g.Count() }) on trial.Id equals subjectStat.TrialId into SS
from subjectStatItem in SS.DefaultIfEmpty()
////加入 Visit统计
//join subjectVisit in _subjectVisitRepository.GetAll().GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, VisitCount = g.Count() }) on trial.Id equals subjectVisit.TrialId into SSV
//from subjectVisitItem in SSV.DefaultIfEmpty()
//加入 study统计
join studyStat in _studyRepository.GetAll().Where(t => t.Status != (int)StudyStatus.Abandon).GroupBy(t => t.TrialId).Select(g => new { TrialId = g.Key, StudyCount = g.Count() }) on trial.Id equals studyStat.TrialId into SSTU
from studyStatItem in SSTU.DefaultIfEmpty()
select new TrialDetailDTO()
{
Sponsor = sponsorItem.SponsorName,
CRO = croItem.CROName,
Id = trial.Id,
Code = trial.Code,
SponsorId = trial.SponsorId,
CROId = trial.CROId,
Indication = trial.Indication,
Note = trial.Note,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
CriterionId = trial.CriterionId,
ReviewModeId = trial.ReviewModeId,
TurnaroundTime = trial.TurnaroundTime,
ReviewProtocol = trial.ReviewProtocol,
MessageFromClient = trial.MessageFromClient,
ReviewProtocolName = trial.ReviewProtocolName,
MessageFromClientName = trial.MessageFromClientName,
GRRReviewers = trial.GRRReviewers,
TotalReviewers = trial.TotalReviewers,
TrialStatus = trial.TrialStatus,
TrialStatusStr = trial.TrialStatusStr,
CreateTime = trial.CreateTime,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
Phase = trial.Phase,
ReviewTypeId = trial.ReviewTypeId,
SiteCount = siteStatItem.SiteCount,
//VisitCount = subjectVisitItem.VisitCount,
SubjectCount = subjectStatItem.SubjectCount,
StudyCount = studyStatItem.StudyCount
};
}
}
var propName = string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField;
//处理升序和降序
trialQueryable = searchParam.Asc
? trialQueryable.OrderBy(propName).ThenBy(t => t.Code)
: trialQueryable.OrderByDescending(propName).ThenBy(t => t.Code);
var count = trialQueryable.Count();
trialQueryable = trialQueryable
.Skip((searchParam.PageIndex - 1) * searchParam.PageSize)
.Take(searchParam.PageSize);
var tempTrialList = trialQueryable.ToList();
if (tempTrialList.Count != 0)
{
var dic = GetDic();
//处理项目Code 是否锁定 不能编辑
//var trialIds = tempTrialList.Select(t => t.Id).ToList();
//var lockQuery = _workloadRepository.GetAll().Where(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm ).Select(t=>t.TrialId)
//var lockTrialIds = lockQuery.Distinct().ToList();
tempTrialList.ForEach(trialViewItem =>
{
//trialViewItem.LockTrialCode = lockTrialIds.Contains(trialViewItem.Id);
ConnectTrialInfo(trialViewItem, dic);
});
return new PageOutput<TrialDetailDTO>(searchParam.PageIndex,
searchParam.PageSize, count, tempTrialList);
}
return new PageOutput<TrialDetailDTO>(searchParam.PageIndex, searchParam.PageSize, 0,
new List<TrialDetailDTO>());
}
#region 项目基本信息 查询、添加、删除和更新
/// <summary>
/// 获取项目基本信息
/// </summary>
/// <param name="projectId"></param>
/// <returns></returns>
public TrialDetailDTO GetTrialInfoAndLockState(Guid projectId)
{
var trialQueryable = from trial in _trialRepository.Find(o => o.Id == projectId)
.Include(t => t.TrialDicList)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into d
from croItem in d.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id into e
from sponsorItem in e.DefaultIfEmpty()
join trialExt in _trialPaymentPriceRepository.GetAll() on trial.Id equals trialExt.TrialId into f
from trialExt in f.DefaultIfEmpty()
select new TrialDetailDTO()
{
Id = trial.Id,
Code = trial.Code,
Indication = trial.Indication,
TrialStatus = trial.TrialStatus,
TrialStatusStr = trial.TrialStatusStr,
Phase = trial.Phase,
CRO = croItem.CROName,
CROId = trial.CROId,
SponsorId = trial.SponsorId,
Sponsor = sponsorItem.SponsorName,
ReviewTypeId = trial.ReviewTypeId,
CriterionId = trial.CriterionId,
Note = trial.Note,
TurnaroundTime = trial.TurnaroundTime,
ReviewModeId = trial.ReviewModeId,
Expedited = trial.Expedited,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
GRRReviewers = trial.GRRReviewers,
TotalReviewers = trial.TotalReviewers,
ReviewProtocol = trial.ReviewProtocol,
ReviewProtocolName = trial.ReviewProtocolName,
MessageFromClient = trial.MessageFromClient,
MessageFromClientName = trial.MessageFromClientName,
CreateTime = trial.CreateTime,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
SowName = trialExt.SowName,
SowPath = trialExt.SowPath,
AttendedReviewerType = trial.AttendedReviewerType,
};
var trialInfo = trialQueryable.FirstOrDefault();
if (trialInfo != null)
{
var dic = GetDic();
trialInfo.IsLocked = _workloadRepository.GetAll().Any(u => u.TrialId == trialInfo.Id &&
u.DataFrom ==
(int)WorkLoadFromStatus.FinalConfirm);
return ConnectTrialInfo(trialInfo, dic);
}
return null;
}
public int GetTrialMaxState(Guid trialId)
{
return _enrollDetailRepository.GetAll().Where(t => t.TrialId == trialId).Max(u => (int?)u.EnrollStatus) ?? 0;
}
public int GetTrialExpeditedState(Guid trialId)
{
return _trialRepository.GetAll().First(u => u.Id == trialId).Expedited;
}
/// <summary>
/// 添加项目
/// </summary>
/// <param name="trialAddModel"></param>
/// <param name="userId"></param>
/// <returns></returns>
public IResponseOutput AddOrUpdateTrial(TrialCommand trialAddModel, Guid userId)
{
if (trialAddModel.Id == Guid.Empty)
{
var existItem = _trialRepository.FindSingleOrDefault(u => u.Code == trialAddModel.Code);
if (existItem != null)
{
return ResponseOutput.NotOk("Same Trial ID already exists.");
}
var trial = _mapper.Map<Trial>(trialAddModel);
trialAddModel.ModalityIds.ForEach(modalityId => trial.TrialDicList.Add(
new TrialDictionary()
{
DictionaryId = modalityId,
KeyName = StaticData.Modality,
TrialId = trialAddModel.Id
}));
//添加项目后 项目状态变更为申请下载简历
trial.TrialStatus = (int)TrialEnrollStatus.ChooseDoctor;
trial.TrialStatusStr = "RFP";
//状态变更详细表
trial.ClinicalTrialProjectDetails.Add(new TrialStatusDetail()
{
TrialId = trial.Id,
TrialStatus = (int)TrialEnrollStatus.ChooseDoctor
});
trial = _trialRepository.Add(trial);
//如果是PM 则需要将该人员添加到 运维人员表
var user = _userRepository.GetAll().FirstOrDefault(t => t.Id == userId);
if (user != null)
{
_userTrialRepository.Add(new UserTrial()
{
//SiteIds = siteIds,
//UserType = "PM",
//OrganizationType = dicitem.Value,
//OrganizationTypeId = dicitem.Id
TrialId = trial.Id,
UserId = userId,
OrganizationId = user.OrganizationId,
OrganizationName = user.OrganizationName,
UserTypeId = user.UserTypeId,
OrganizationType = user.OrganizationType,
OrganizationTypeId = user.OrganizationTypeId,
UserType = user.UserType,
UserRealName = user.RealName
});
}
// 添加扩展信息表记录
_trialPaymentPriceRepository.Add(new TrialPaymentPrice() {TrialId = trial.Id});
var success = _trialRepository.SaveChanges();
return ResponseOutput.Result(success, trial.Id.ToString());
}
else
{
var updateModel = trialAddModel;
// 判断项目Id 是否已经存在
var existItem = _trialRepository.FindSingleOrDefault(u => u.Code == updateModel.Code && u.Id != updateModel.Id);
if (existItem != null)
{
return ResponseOutput.NotOk("Same Trial ID already exists.");
}
var trial = _trialRepository.Find(t => t.Id == updateModel.Id).FirstOrDefault();
if (trial != null)
{
//删除中间表 Title对应的记录
_trialDictionaryRepository.Delete(t => t.TrialId == updateModel.Id && t.KeyName == StaticData.Modality);
//重新插入新的 Title记录
updateModel.ModalityIds.ForEach(modalityId => _trialDictionaryRepository.Add(new TrialDictionary()
{
TrialId = updateModel.Id,
KeyName = StaticData.Modality,
DictionaryId = modalityId
}));
if (updateModel.Expedited != trial.Expedited && updateModel.Expedited != null)
{
TrialExpeditedChange = true;
TrialExpeditedStatusChange(trial.Id, trial.Expedited, (int)updateModel.Expedited);
}
_mapper.Map(updateModel, trial);
_trialRepository.Update(trial);
var success = _trialRepository.SaveChanges();
return ResponseOutput.Result(success);
}
else
{
return ResponseOutput.NotOk(" Update failed. Database can not find this trial record ID");
}
}
}
private void TrialExpeditedStatusChange(Guid trialId, int oldState, int newState)
{
switch (oldState)
{
case (int)TrialExpedited.None:
switch (newState)
{
case (int)TrialExpedited.ExpeditedIn24H:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn24H = u.Timepoint,
AdjudicationIn24H = u.Adjudication,
Timepoint = 0,
Adjudication = 0
});
break;
case (int)TrialExpedited.ExpeditedIn48H:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn48H = u.Timepoint,
AdjudicationIn48H = u.Adjudication,
Timepoint = 0,
Adjudication = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// Timepoint = 0,
// Adjudication = 0
//});
break;
case (int)TrialExpedited.ExpeditedIn24H:
switch (newState)
{
case (int)TrialExpedited.None:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
Timepoint = u.TimepointIn24H,
Adjudication = u.AdjudicationIn24H,
TimepointIn24H = 0,
AdjudicationIn24H = 0
});
break;
case (int)TrialExpedited.ExpeditedIn48H:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn48H = u.TimepointIn24H,
AdjudicationIn48H = u.AdjudicationIn24H,
TimepointIn24H = 0,
AdjudicationIn24H = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// TimepointIn24H = 0,
// AdjudicationIn24H = 0
//});
break;
case (int)TrialExpedited.ExpeditedIn48H:
switch (newState)
{
case (int)TrialExpedited.None:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
Timepoint = u.TimepointIn48H,
Adjudication = u.AdjudicationIn48H,
TimepointIn48H = 0,
AdjudicationIn48H = 0
});
break;
case (int)TrialExpedited.ExpeditedIn24H:
_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn24H = u.TimepointIn48H,
AdjudicationIn24H = u.AdjudicationIn48H,
TimepointIn48H = 0,
AdjudicationIn48H = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// TimepointIn48H = 0,
// AdjudicationIn48H = 0
//});
break;
}
}
/// <summary>
/// 手动更新项目状态
/// </summary>
/// <param name="trialId">项目Id</param>
/// <param name="statusStr">状态值</param>
/// <returns></returns>
public IResponseOutput UpdateTrialStatus(Guid trialId, string statusStr)
{
if (statusStr.ToUpper().Contains("FINISH"))
{
_enrollRepository.Update(u => u.TrialId == trialId, e => new Enroll
{
EnrollStatus = (int)EnrollStatus.End
});
}
return ResponseOutput.Result(_trialRepository.Update(u => u.Id == trialId, s => new Trial { TrialStatusStr = statusStr }));
}
/// <summary>
/// 删除项目
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public IResponseOutput DeleteTrial(Guid trialId)
{
return ResponseOutput.Result(_trialRepository.Delete(o => o.Id == trialId));
}
#endregion //end 项目基本增删改查
#region 获取字典表、 连接字典表、表达式树查询条件
/// <summary>
/// 获取字典表
/// </summary>
/// <returns></returns>
private List<DicViewModelDTO> GetDic()
{
return //字典表 后面做缓存
_dictionaryRepository.GetAll().ProjectTo<DicViewModelDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.KeyName)
.ThenBy(t => t.ShowOrder).ToList();
}
/// <summary>
/// 连接字典表处理--私有方法
/// </summary>
private TrialDetailDTO ConnectTrialInfo(TrialDetailDTO transformModel, List<DicViewModelDTO> dic)
{
foreach (var item in dic)
{
if (transformModel.ModalityIds.Contains(item.Id))
{
transformModel.ModalityList.AddRange(dic.Where(u => u.Id == item.Id).Select(h => h.Value));
}
}
transformModel.Criterion = dic.FirstOrDefault(o => o.Id == transformModel.CriterionId)?.Value ?? string.Empty;
transformModel.ReviewMode = dic.FirstOrDefault(o => o.Id == transformModel.ReviewModeId)?.Value ?? string.Empty;
transformModel.ReviewType = dic.FirstOrDefault(o => o.Id == transformModel.ReviewTypeId)?.Value ?? string.Empty;
return transformModel;
}
/// <summary>
/// 项目查询 [多选]
/// </summary>
private Expression<Func<Trial, bool>> GetTrialSearchLambda(TrialQueryDTO trialSearchModel)
{
Expression<Func<Trial, bool>> trialLambda = x => true;
if (!string.IsNullOrEmpty(trialSearchModel.TrialStatus))
{
var trialStatus = trialSearchModel.TrialStatus.Trim();
trialLambda = trialLambda.And(o => o.TrialStatusStr.Contains(trialStatus));
}
if (trialSearchModel.CriterionId != Guid.Empty && trialSearchModel.CriterionId != null)
{
trialLambda = trialLambda.And(o => o.CriterionId == trialSearchModel.CriterionId);
}
if (trialSearchModel.SponsorId != Guid.Empty && trialSearchModel.SponsorId != null)
{
trialLambda = trialLambda.And(o => o.SponsorId == trialSearchModel.SponsorId);
}
if (trialSearchModel.Expedited != (int)TrialExpedited.All && trialSearchModel.Expedited != null)
{
trialLambda = trialLambda.And(o => o.Expedited == trialSearchModel.Expedited);
}
if (!string.IsNullOrEmpty(trialSearchModel.Code))
{
var code = trialSearchModel.Code.Trim();
trialLambda = trialLambda.And(o => o.Code.Contains(code));
}
if (!string.IsNullOrWhiteSpace(trialSearchModel.Indication))
{
var indication = trialSearchModel.Indication.Trim();
trialLambda = trialLambda.And(o => o.Indication.Contains(indication));
}
if (!string.IsNullOrWhiteSpace(trialSearchModel.Phase))
{
trialLambda = trialLambda.And(o => o.Phase == trialSearchModel.Phase);
}
if (trialSearchModel.CROId != Guid.Empty && trialSearchModel.CROId != null)
{
trialLambda = trialLambda.And(o => o.CROId == trialSearchModel.CROId);
}
if (trialSearchModel.ReviewTypeId != Guid.Empty && trialSearchModel.ReviewTypeId != null)
{
trialLambda = trialLambda.And(o => o.ReviewTypeId == trialSearchModel.ReviewTypeId);
}
if (trialSearchModel.BeginDate != null)
{
var beginDate = new DateTime(trialSearchModel.BeginDate.Value.Year, trialSearchModel.BeginDate.Value.Month, trialSearchModel.BeginDate.Value.Day);
trialLambda = trialLambda.And(o => o.CreateTime >= beginDate);
}
if (trialSearchModel.EndDate != null)
{
var endDate = new DateTime(trialSearchModel.EndDate.Value.Year, trialSearchModel.EndDate.Value.Month, trialSearchModel.EndDate.Value.Day);
trialLambda = trialLambda.And(o => o.CreateTime <= endDate);
}
if (trialSearchModel.AttendedReviewerType != null)
{
trialLambda = trialLambda.And(o => o.AttendedReviewerType == trialSearchModel.AttendedReviewerType);
}
return trialLambda;
}
#endregion
public PageOutput<TrialDetailDTO> GetReviewerTrialListByEnrollmentStatus(TrialByStatusQueryDTO param)
{
Expression<Func<Enroll, bool>> enrollExpression = u => u.DoctorId == param.DoctorId;
switch (param.Status)
{
case 5:
enrollExpression = enrollExpression.And(u => u.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO);
break;
case 8:
enrollExpression = enrollExpression.And(u => u.EnrollStatus == (int)EnrollStatus.InviteIntoGroup);
break;
case 10:
enrollExpression = enrollExpression.And(u => u.EnrollStatus == (int)EnrollStatus.DoctorReading);
break;
default:
break;
}
var trialQueryable = from enrollItem in _enrollRepository.Find(enrollExpression)
join trial in _trialRepository.GetAll()
on enrollItem.TrialId equals trial.Id into d
from trialItem in d.DefaultIfEmpty()
join cro in _croRepository.GetAll() on trialItem.CROId equals cro.Id into tt
from cro in tt.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trialItem.SponsorId equals sponsor.Id into uu
from sponsor in uu.DefaultIfEmpty()
select new TrialDetailDTO()
{
Sponsor = sponsor.SponsorName,
CRO = cro.CROName,
Id = trialItem.Id,
Code = trialItem.Code,
SponsorId = trialItem.SponsorId,
CROId = trialItem.CROId,
Indication = trialItem.Indication,
Note = trialItem.Note,
ExpectedPatients = trialItem.ExpectedPatients,
TimePointsPerPatient = trialItem.TimePointsPerPatient,
CriterionId = trialItem.CriterionId,
ReviewTypeId = trialItem.ReviewTypeId,
//ReviewMode = trial.Re,
ReviewModeId = trialItem.ReviewModeId,
TurnaroundTime = trialItem.TurnaroundTime,
Expedited = trialItem.Expedited,
ReviewProtocol = trialItem.ReviewProtocol,
GRRReviewers = trialItem.GRRReviewers,
TotalReviewers = trialItem.TotalReviewers,
TrialStatus = trialItem.TrialStatus,
CreateTime = trialItem.CreateTime,
Phase = trialItem.Phase,
ModalityIds = trialItem.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList()
};
var count = trialQueryable.Count();
var propName = param.SortField == "" ? "CreateTime" : param.SortField;
trialQueryable = param.Asc
? trialQueryable.OrderBy(propName)
: trialQueryable.OrderByDescending(propName);
trialQueryable = trialQueryable
.Skip((param.PageIndex - 1) * param.PageSize)
.Take(param.PageSize);
var trialList = trialQueryable.ToList();
if (trialList.Count != 0)
{
var dic = GetDic();
trialList.ForEach(trialViewItem => ConnectTrialInfo(trialViewItem, dic));
return new PageOutput<TrialDetailDTO>(param.PageIndex,
param.PageSize, count, trialList);
}
return new PageOutput<TrialDetailDTO>(param.PageIndex, param.PageSize, 0,
new List<TrialDetailDTO>());
}
/// <summary>
/// 根据项目Id 获取医生Id用于出发计算费用
/// </summary>
public List<Guid> GetTrialEnrollmentReviewerIds(Guid trialId)
{
return _enrollRepository.Find(u => u.TrialId == trialId &&
u.EnrollStatus >= (int)EnrollStatus.DoctorReading).Select(u => u.DoctorId).Distinct().ToList();
}
#region 医生用户接口
public PageOutput<TrialDetailDTO> GetTrialListByReviewer(ReviewerTrialQueryDTO trialSearchModel, Guid reviewerId)
{
Expression<Func<Trial, bool>> trialLambda = x => true;
if (!string.IsNullOrEmpty(trialSearchModel.Code))
{
var code = trialSearchModel.Code.Trim();
trialLambda = trialLambda.And(o => o.Code.Contains(code));
}
if (!string.IsNullOrWhiteSpace(trialSearchModel.Indication))
{
var indication = trialSearchModel.Indication.Trim();
trialLambda = trialLambda.And(o => o.Indication.Contains(indication));
}
if (trialSearchModel.Expedited != (int)TrialExpedited.All && trialSearchModel.Expedited != null)
{
trialLambda = trialLambda.And(o => o.Expedited == trialSearchModel.Expedited);
}
Expression<Func<Enroll, bool>> enrollLambda = x => true;
enrollLambda = enrollLambda.And(o => o.DoctorId == reviewerId);
if (trialSearchModel.EnrollStatus != null)
{
if ((int)trialSearchModel.EnrollStatus == 10)
{
enrollLambda = enrollLambda.And(o => o.EnrollStatus >= 10 && o.EnrollStatus <= 13);
}
else enrollLambda = enrollLambda.And(o => o.EnrollStatus == trialSearchModel.EnrollStatus);
}
IQueryable<TrialDetailDTO> trialQueryable = default;
trialQueryable = from trial in _trialRepository.GetAll().Where(trialLambda)
join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into t
from croItem in t.DefaultIfEmpty()
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id
into d
from sponsorItem in d.DefaultIfEmpty()
join enroll in _enrollRepository.GetAll().Where(enrollLambda) on trial.Id equals enroll.TrialId
select new TrialDetailDTO()
{
Sponsor = sponsorItem.SponsorName,
CRO = croItem.CROName,
Id = trial.Id,
Code = trial.Code,
SponsorId = trial.SponsorId,
CROId = trial.CROId,
Indication = trial.Indication,
Note = trial.Note,
ExpectedPatients = trial.ExpectedPatients,
TimePointsPerPatient = trial.TimePointsPerPatient,
CriterionId = trial.CriterionId,
ReviewModeId = trial.ReviewModeId,
TurnaroundTime = trial.TurnaroundTime,
Expedited = trial.Expedited,
CreateTime = trial.CreateTime,
ModalityIds = trial.TrialDicList.Where(u => u.KeyName == StaticData.Modality)
.Select(z => z.DictionaryId).ToList(),
Phase = trial.Phase,
EnrollStatus = enroll.EnrollStatus
};
var propName = string.IsNullOrWhiteSpace(trialSearchModel.SortField) ? "CreateTime" : trialSearchModel.SortField;
//处理升序和降序
trialQueryable = trialSearchModel.Asc
? trialQueryable.OrderBy(propName).ThenBy(t => t.Code)
: trialQueryable.OrderByDescending(propName).ThenBy(t => t.Code);
var count = trialQueryable.Count();
trialQueryable = trialQueryable
.Skip((trialSearchModel.PageIndex - 1) * trialSearchModel.PageSize)
.Take(trialSearchModel.PageSize);
var tempTrialList = trialQueryable.ToList();
if (tempTrialList.Count != 0)
{
var dic = GetDic();
tempTrialList.ForEach(trialViewItem =>
{
ConnectTrialInfo(trialViewItem, dic);
});
return new PageOutput<TrialDetailDTO>(trialSearchModel.PageIndex,
trialSearchModel.PageSize, count, tempTrialList);
}
return new PageOutput<TrialDetailDTO>(trialSearchModel.PageIndex, trialSearchModel.PageSize, 0,
new List<TrialDetailDTO>());
}
public IResponseOutput UpdateEnrollStatus(Guid trialId, int status)
{
_enrollDetailRepository.Add(new EnrollDetail()
{
DoctorId = _userInfo.Id,
TrialId = trialId,
EnrollStatus = status,
OptUserType = (int)UserType.DoctorUser,
});
return ResponseOutput.Result(_enrollRepository.Update(u => u.TrialId == trialId && u.DoctorId == _userInfo.Id, e => new Enroll
{
EnrollStatus = status
}));
}
public IResponseOutput ConfirmTrialVisitPlan(Guid trialId)
{
return ResponseOutput.Result(_trialRepository.Update(u => u.Id == trialId,
t => new Trial() {VisitPlanConfirmed = true}));
}
#endregion
}
}