using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Application.Interfaces;
namespace IRaCIS.Core.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class TrialMaintenanceService : BaseService, ITrialSiteService
{
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<TrialSiteUser> _trialSiteUserRepository;
private readonly IRepository<Site> _siteRepository;
private readonly IRepository<Trial> _trialRepository;
public TrialMaintenanceService(IRepository<TrialSite> trialSiteRepository, IRepository<TrialSiteUser> trialSiteUserRepository
, IRepository<Site> siteRepository, IRepository<Trial> trialRepository)
{
_trialSiteRepository = trialSiteRepository;
_trialSiteUserRepository = trialSiteUserRepository;
_siteRepository = siteRepository;
_trialRepository = trialRepository;
}
#region 移动废弃
///// <summary>
///// Site用户列表导出
///// </summary>
///// <param name="param"></param>
///// <param name="_commonDocumentRepository"></param>
///// <returns></returns>
///// <exception cref="Exception"></exception>
//[HttpPost]
//[AllowAnonymous]
//public async Task<IActionResult> TrialSiteUserListExport(SiteCRCExportQueryDTO param, [FromServices] IRepository<CommonDocument> _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService)
//{
// var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
// exportInfo.List = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
// .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
// .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName))
// .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName),
// t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
// .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode),
// t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode))
// .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator,
// t => t.UserId == _userInfo.Id)
// .WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo)
// || t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo))
// .ProjectTo<SiteUserExportDTO>(_mapper.ConfigurationProvider).ToListAsync();
// exportInfo.IsEn_US = _userInfo.IsEn_Us;
// return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment,_dictionaryService,typeof(SiteUserExportDTO));
//}
///// <summary>
///// Site用户汇总表导出
///// </summary>
///// <param name="queryParam"></param>
///// <param name="_commonDocumentRepository"></param>
///// <param name="_trialSiteSurveyRepository"></param>
///// <param name="_trialSiteUserSurveyRepository"></param>
///// <param name="_dictionaryService"></param>
///// <returns></returns>
///// <exception cref="Exception"></exception>
//[HttpPost]
//[AllowAnonymous]
//public async Task<IActionResult> TrialSiteUserSummaryListExport(TrialSiteUserSurveyExportQueryDto queryParam,
// [FromServices] IRepository<CommonDocument> _commonDocumentRepository,
// [FromServices] IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
// [FromServices] IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository
// , [FromServices] IDictionaryService _dictionaryService
//)
//{
// var data = (await _trialRepository.Where(t => t.Id == queryParam.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
// var groupSelectIdQuery =
// _trialSiteSurveyRepository.Where(t => t.TrialId == queryParam.TrialId)
// .WhereIf(queryParam.SiteId != null, t => t.SiteId == queryParam.SiteId)
// .WhereIf(!string.IsNullOrEmpty(queryParam.FormWriterKeyInfo), t => (t.UserName).Contains(queryParam.FormWriterKeyInfo) || t.Email.Contains(queryParam.FormWriterKeyInfo) || t.Phone.Contains(queryParam.FormWriterKeyInfo))
// .GroupBy(t => t.SiteId)
// .Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First());
// var query = _trialSiteUserSurveyRepository
// .Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId))
// .WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId)
// .WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount)
// .WhereIf(queryParam.TrialRoleNameId != null, t => t.TrialRoleNameId == queryParam.TrialRoleNameId)
// .WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State)
// .WhereIf(queryParam.State != null && queryParam.State == TrialSiteUserStateEnum.OverTime, t => t.InviteState == TrialSiteUserStateEnum.HasSend && t.ExpireTime < DateTime.Now)
// .WhereIf(!string.IsNullOrEmpty(queryParam.UserName), t => (t.LastName + " / " + t.FirstName).Contains(queryParam.UserName))
// .WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName))
// .ProjectTo<TrialSiteUserSummaryDto>(_mapper.ConfigurationProvider);
// data.List = await query.ToListAsync();
// var exportInfo = data;
// exportInfo.IsEn_US = _userInfo.IsEn_Us;
// return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserSummary_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment,_dictionaryService,typeof(TrialSiteUserSummaryDto));
//}
#endregion
/// <summary>Pannel 进去 SiteTab </summary>
[HttpPost]
public async Task<PageOutput<SiteStatDTO>> GetSiteCRCList(SiteCrcQueryDTO param)
{
var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == param.TrialId, ignoreQueryFilters: true)
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), t => t.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode), t => t.TrialSiteCode.Contains(param.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.Id))
.WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => t.CRCUserList.Any(k => (k.User.FullName).Contains(param.UserKeyInfo)
|| k.User.UserName.Contains(param.UserKeyInfo) || k.User.EMail.Contains(param.UserKeyInfo)))
.ProjectTo<SiteStatDTO>(_mapper.ConfigurationProvider);
return await siteStatQuery.ToPagedListAsync(param.PageIndex,
param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "SiteCode" : param.SortField, param.Asc);
}
/// <summary>[new] setting页面Site列表,和getSiteCRCList对比 没有统计数据,增加了一些site信息 </summary>
[HttpPost]
public async Task<PageOutput<SiteStatSimpleDTO>> GetSiteCRCSimpleList(SiteCrcQueryDTO param)
{
var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
.WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), t => t.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode), t => t.TrialSiteCode.Contains(param.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.Id))
.WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => t.CRCUserList.Any(k => (k.User.FullName).Contains(param.UserKeyInfo)
|| k.User.UserName.Contains(param.UserKeyInfo) || k.User.EMail.Contains(param.UserKeyInfo)))
.ProjectTo<SiteStatSimpleDTO>(_mapper.ConfigurationProvider ,new { isEn_Us = _userInfo.IsEn_Us });
var result = await siteStatQuery.ToPagedListAsync(param.PageIndex,
param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "Site" : param.SortField, param.Asc);
return result;
}
/// <summary>获取某一Site下面的负责的CRC列表</summary>
[HttpGet, Route("{trialId:guid}/{siteId:guid}")]
public async Task<List<UserTrialDTO>> GetTrialSiteCRCList(Guid trialId, Guid siteId)
{
var query = _trialSiteUserRepository.Where(t => t.TrialId == trialId && t.SiteId == siteId).IgnoreQueryFilters()
.ProjectTo<UserTrialDTO>(_mapper.ConfigurationProvider);
return await query.ToListAsync();
}
/// <summary>[new] Setting页面 Site勾选列表( </summary>
[HttpPost]
public async Task<PageOutput<TrialSiteScreeningDTO>> GetTrialSiteScreeningList(TrialSiteQuery searchModel)
{
// 之前选择了的不能再次出现在列表,做的时候我就不建议这样搞,搞好了 现在又要改回去。。。 瞎折腾。。。。
var siteQueryable = _siteRepository.AsQueryable(true)
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.SiteName), t => t.SiteName.Contains(searchModel.SiteName) || t.SiteNameCN.Contains(searchModel.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.AliasName), t => t.AliasName.Contains(searchModel.AliasName))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.City), t => t.City.Contains(searchModel.City))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Country), t => t.Country.Contains(searchModel.Country))
.ProjectTo<TrialSiteScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = searchModel.TrialId , isEn_Us =_userInfo.IsEn_Us});
return await siteQueryable.ToPagedListAsync(searchModel.PageIndex,
searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "SiteName" : searchModel.SortField, searchModel.Asc);
}
/// <summary>Setting页面 Site批量添加</summary>
[HttpPost]
[UnitOfWork]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddTrialSites(List<TrialSiteCommand> trialSites)
{
var addArray = _mapper.Map<List<TrialSite>>(trialSites);
await _repository.AddRangeAsync(addArray);
return ResponseOutput.Result(await _repository.SaveChangesAsync());
}
/// <summary>
/// 项目site 编辑接口 New 可以设置为启用不启用 不启用 不会验证Code 重复
/// </summary>
/// <param name="editTrialSiteCommand"></param>
/// <returns></returns>
[HttpPut]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> EditTrialSite(EditTrialSiteCommand editTrialSiteCommand)
{
var dbEntity = await _trialSiteRepository.FirstOrDefaultAsync(t => t.Id == editTrialSiteCommand.Id, true);
if (dbEntity == null) return Null404NotFound(dbEntity);
var trialId = dbEntity.TrialId;
var siteId = dbEntity.SiteId;
if (editTrialSiteCommand.IsDeleted)
{
//if (await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId))
//{
//---The site has been associated with CRC, and couldn't be deleted.
// return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedCRC"]);
//}
if (await _repository.AnyAsync<Subject>(t => t.SiteId == siteId && t.TrialId == trialId))
{
//---The subjects has been added to this site, and couldn't be disable.
return ResponseOutput.NotOk(_localizer["TrialSite_ParticipantJoined"]);
}
//if (await _repository.AnyAsync<DicomStudy>(t => t.SiteId == siteId && t.TrialId == trialId))
//{
//---The site has been uploaded study, and couldn't be deleted.
// return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteUploadedData"]);
//}
}
else
{
if (await _trialSiteRepository.AnyAsync(t => t.Id != editTrialSiteCommand.Id && t.TrialSiteCode == editTrialSiteCommand.TrialSiteCode && t.TrialId == editTrialSiteCommand.TrialId))
{
//---Code is not allowed to be repeated
return ResponseOutput.NotOk(_localizer["TrialSite_CodeDuplicate"]);
}
}
_mapper.Map(editTrialSiteCommand, dbEntity);
await _trialSiteRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary> 批量添加Site下 CRC的负责人 </summary>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> AssignSiteCRC(List<AssginSiteCRCCommand> trialSiteCRCList)
{
var addArray = _mapper.Map<List<TrialSiteUser>>(trialSiteCRCList);
await _trialSiteUserRepository.AddRangeAsync(addArray);
await _trialSiteUserRepository.SaveChangesAsync();
return ResponseOutput.Result(true);
}
/// <summary> 删除CRC人员</summary>
[HttpDelete, Route("{id:guid}/{trialId:guid}/{isDelete:bool}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> DeleteSiteCRC(Guid id, bool isDelete)
{
await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.Id == id, u => new TrialSiteUser() { IsDeleted = isDelete, DeletedTime = isDelete ? DateTime.Now : null }, true, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 获取项目下的 site 下拉框数据 CRC只看到他负责的
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<IEnumerable<TrialSiteForSelect>> GetTrialSiteSelect(Guid trialId)
{
//CRC只看到他负责的
var list = await _trialSiteRepository.Where(t => t.TrialId == trialId).IgnoreQueryFilters()
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<TrialSiteForSelect>(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync();
return list;
}
public async Task<IEnumerable<string>> GetTrialSiteCodeSelect(Guid trialId, bool isIncludeVirtualSite = true)
{
//CRC只看到他负责的
var list = await _trialSiteRepository.Where(t => t.TrialId == trialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.Select(t => t.TrialSiteCode).ToListAsync();
var virtualList = await _repository.Where<VisitTask>(t => t.IsSelfAnalysis == true && t.TrialId == trialId).Select(t => t.BlindTrialSiteCode).Distinct().ToListAsync();
return isIncludeVirtualSite ? list.Concat(virtualList) : list;
}
/// <summary>删除 项目 下某一site </summary>
[HttpDelete("{id:guid}/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[Obsolete]
public async Task<IResponseOutput> DeleteTrialSite(Guid id)
{
var relation = await _trialSiteRepository.FirstOrDefaultAsync(t => t.Id == id);
if (relation == null) return Null404NotFound(relation);
var trialId = relation.TrialId;
var siteId = relation.SiteId;
if (await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId == siteId))
{
//---The site has been associated with CRC, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedCRC"]);
}
if (await _repository.AnyAsync<Subject>(t => t.SiteId == siteId && t.TrialId == trialId))
{
//---The subjects has been added to this site, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedSubject"]);
}
if (await _repository.AnyAsync<DicomStudy>(t => t.SiteId == siteId && t.TrialId == trialId))
{
//---The site has been uploaded study, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteUploadedData"]);
}
await _repository.DeleteAsync(relation);
return ResponseOutput.Result(await _repository.SaveChangesAsync());
}
}
}