329 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
| 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;
 | ||
| using System.Linq;
 | ||
| 
 | ||
| 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;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <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.TrialSiteName.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.TrialSiteName.Contains(param.SiteName) || t.TrialSiteAliasName.Contains(param.TrialSiteAliasName))
 | ||
|                             .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.TrialSiteId == 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) || t.AliasName.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);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         public async Task<List<TrialSiteSelect>> GetTrialSiteSelectList(string? siteName)
 | ||
|         {
 | ||
|            var list= _siteRepository
 | ||
|                 .WhereIf(!string.IsNullOrWhiteSpace(siteName), t => t.SiteName.Contains(siteName) || t.SiteNameCN.Contains(siteName) || t.AliasName.Contains(siteName))
 | ||
|                 .Select(t => new TrialSiteSelect() { SiteId = t.Id, SiteName = _userInfo.IsEn_Us? t.SiteName:t.SiteNameCN, AliasName = t.AliasName }).ToList();
 | ||
| 
 | ||
|             return list;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <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);
 | ||
| 
 | ||
|             foreach (var item in addArray)
 | ||
|             {
 | ||
|                 if (item.IsDeleted==false)
 | ||
|                 {
 | ||
|                     item.EnabledTime = DateTime.Now;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             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 trialSiteId = dbEntity.Id;
 | ||
| 
 | ||
|             if (editTrialSiteCommand.IsDeleted)
 | ||
|             {
 | ||
| 
 | ||
|                 if (await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId))
 | ||
|                 {
 | ||
|                     //---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.TrialSiteId == trialSiteId && t.TrialId == trialId))
 | ||
|                 {
 | ||
|                 //---The subjects has been added to  this site, and couldn't be disable.
 | ||
|                     return ResponseOutput.NotOk(_localizer["TrialSite_ParticipantJoined"]);
 | ||
|                 }
 | ||
| 
 | ||
|               
 | ||
| 
 | ||
| 
 | ||
|             }
 | ||
|             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"]);
 | ||
|                 }
 | ||
| 
 | ||
|                 if(!string.IsNullOrEmpty(editTrialSiteCommand.TrialSiteCode) && await _trialRepository.AnyAsync(t=>t.Id==trialId && t.VitrualSiteCode == editTrialSiteCommand.TrialSiteCode,true) )
 | ||
|                 {
 | ||
|                     return ResponseOutput.NotOk(_localizer["TrialSite_CodeDuplicate2"]);
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             _mapper.Map(editTrialSiteCommand, dbEntity);
 | ||
| 
 | ||
|             if (editTrialSiteCommand.IsDeleted)
 | ||
|             {
 | ||
|                 dbEntity.EnabledTime = null;
 | ||
|                
 | ||
|             }
 | ||
|             else if (editTrialSiteCommand.IsDeleted==false && dbEntity.EnabledTime==null)
 | ||
|             {
 | ||
|                 dbEntity.EnabledTime = DateTime.Now;
 | ||
|             }
 | ||
| 
 | ||
|             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);
 | ||
| 
 | ||
|             //删除又启用改授权时间
 | ||
|             if (isDelete == false)
 | ||
|             {
 | ||
|               await  _trialSiteUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new TrialSiteUser() { CreateTime = DateTime.Now });
 | ||
|             }
 | ||
| 
 | ||
|             ////不跟踪
 | ||
|             //await _trialSiteUserRepository.ExecuteUpdateAsync(t => t.Id == id, s=>s.SetProperty(t=>t.IsDeleted,u=>isDelete)
 | ||
|             //                                                                       .SetProperty(t=>t.DeletedTime,u=> isDelete ? DateTime.Now : null)
 | ||
|             //                                                                       .SetProperty(t=>t.CreateTime,u=>isDelete?u.CreateTime:DateTime.Now));
 | ||
| 
 | ||
|             
 | ||
| 
 | ||
| 
 | ||
|             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)
 | ||
|                           .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 trialSiteId = relation.Id;
 | ||
| 
 | ||
|             if (await _repository.AnyAsync<TrialSiteUser>(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId))
 | ||
|             {
 | ||
|                 //---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.TrialSiteId == trialSiteId && t.TrialId == trialId))
 | ||
|             {
 | ||
|                 //---The subjects has been added to  this site, and couldn't be deleted.
 | ||
|                 return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedSubject"]);
 | ||
|             }
 | ||
| 
 | ||
|             await _repository.DeleteAsync(relation);
 | ||
| 
 | ||
|             return ResponseOutput.Result(await _repository.SaveChangesAsync());
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|     }
 | ||
| }
 |