irc-netcore-api/IRaCIS.Core.Application/Service/Visit/SubjectService.cs

292 lines
12 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 IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Infrastructure;
using Newtonsoft.Json;
using IRaCIS.Core.Domain.Common;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class SubjectService : BaseService, ISubjectService
{
private readonly IRepository<Subject> _subjectRepository;
private readonly IInspectionService _inspectionService;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
public SubjectService(IRepository<Subject> subjectRepository, IInspectionService inspectionService,IRepository<SubjectVisit> subjectVisitRepository)
{
_subjectRepository = subjectRepository;
_inspectionService = inspectionService;
_subjectVisitRepository = subjectVisitRepository;
}
/// <summary>
/// 添加或更新受试者信息[New]
/// </summary>
/// <param name="subjectCommand">state:1-访视中2-出组。0-全部</param>
/// <returns></returns>
[TrialAudit(AuditType.SubjectAudit, AuditOptType.AddOrUpdateSubject)]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput<string>> AddOrUpdateSubject([FromBody] SubjectCommand subjectCommand)
{
var svlist = new List<SubjectVisit>();
if (await _repository.AnyAsync<Trial>(t => t.Id == subjectCommand.TrialId && !t.VisitPlanConfirmed))
{
return ResponseOutput.NotOk("The trial visit plan has not been confirmed yet.Please contact the project manager to confirm the visit plan before adding subject.");
}
var verifyExp1 = new EntityVerifyExp<Subject>()
{
VerifyExp = u => u.Code == subjectCommand.Code && u.TrialId == subjectCommand.TrialId,
VerifyMsg = "A subjects with the same subject ID already existed in this trial."
};
bool isadd = false;
Subject mapedSubject = null;
if (subjectCommand.Id == null) //insert
{
isadd = true;
mapedSubject= await _subjectRepository.InsertFromDTOAsync(subjectCommand, false, verifyExp1);
//添加受试者的时候,获取访视计划列表,添加到受试者访视表。
var visitPlan = await _repository.Where<VisitStage>(t => t.TrialId == subjectCommand.TrialId).ToListAsync();
svlist = _mapper.Map<List<SubjectVisit>>(visitPlan);
var IsEnrollementQualificationConfirm = await _repository.Where<Trial>(t => t.Id == mapedSubject.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync();
svlist.ForEach(t =>
{
t.SubjectId = mapedSubject.Id;
t.TrialId = subjectCommand.TrialId;
t.SiteId = subjectCommand.SiteId;
t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false;
});
await _subjectVisitRepository.AddRangeAsync(svlist);
}
else //update
{
mapedSubject = await _subjectRepository.UpdateFromDTOAsync(subjectCommand, false,false, verifyExp1/*, verifyExp2*/);
}
await _repository.SaveChangesAsync();
var createtime = DateTime.Now.AddSeconds(1);
// 添加稽查记录
if (isadd)
{
List<DataInspection> datas = new List<DataInspection>();
// 移到仓储了
//datas.Add(new DataInspection()
//{
// TrialId = subjectCommand.TrialId,
// SiteId = subjectCommand.SiteId,
// SubjectId = mapedSubject.Id,
// SubjectCode = subjectCommand.Code,
// IsSign=false,
// CreateTime = createtime,
// Identification = "Init|Subject|Status|Subject",
// JsonDetail= JsonConvert.SerializeObject(new {
// Status= "新增",
// })
//});
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
//var jsonData = JsonConvert.SerializeObject(info, settings);
var visittime = createtime.AddSeconds(1);
foreach (var item in svlist)
{
// 添加访视
datas.Add(new DataInspection()
{
TrialId = subjectCommand.TrialId,
SiteId = subjectCommand.SiteId,
SubjectId = mapedSubject.Id,
SubjectCode = subjectCommand.Code,
SubjectVisitId = item.Id,
SubjectVisitName = item.VisitName,
BlindName = item.BlindName,
IsSign = false,
CreateTime = visittime,
Identification = "Add|Visit|Info|Visit-Image Upload",
JsonDetail = item.ToJcJson()
});
// 初始化访视
datas.Add(new DataInspection()
{
TrialId = subjectCommand.TrialId,
SiteId = subjectCommand.SiteId,
SubjectId = mapedSubject.Id,
SubjectCode = subjectCommand.Code,
SubjectVisitId = item.Id,
BlindName = item.BlindName,
SubjectVisitName = item.VisitName,
IsSign = false,
CreateTime = visittime.AddSeconds(1),
Identification = "Init|Visit|Status|Visit-Image Upload",
JsonDetail = item.ToJcJson()
});
}
await _inspectionService.AddListInspectionRecordAsync(datas);
}
return ResponseOutput.Ok(mapedSubject.Id.ToString());
}
[HttpPut("{trialId:guid}")]
[UnitOfWork]
public async Task<IResponseOutput> UpdateSubjectStatus(SubjectStatusChangeCommand subjectStatusChangeCommand)
{
await _subjectRepository.UpdateFromDTOAsync(subjectStatusChangeCommand, true);
return ResponseOutput.Ok();
}
[HttpDelete("{id:guid}/{trialId:guid}")]
[TrialAudit(AuditType.SubjectAudit, AuditOptType.DeleteSubject)]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> DeleteSubject(Guid id)
{
if (await _subjectVisitRepository.AnyAsync(u => u.SubjectId == id && u.VisitExecuted == VisitExecutedEnum.Executed))
{
return ResponseOutput.NotOk("This subject has executed a visit with uploading study images,and couldn't be deleted.");
}
var isSuccess = await _subjectRepository.BatchDeleteNoTrackingAsync(u => u.Id == id);
await _subjectVisitRepository.DeleteFromQueryAsync(u => u.SubjectId == id);
var subvisit = await _subjectVisitRepository.Where(x => x.SubjectId == id).ToListAsync();
List<DataInspection> datas = new List<DataInspection>();
foreach (var item in subvisit)
{
datas.Add(new DataInspection()
{
SiteId = item.SiteId,
SubjectId = item.SubjectId,
TrialId = item.TrialId,
SubjectVisitId = item.Id,
Identification = "Delete|Visit|Data|Visit-Image Upload",
JsonDetail = JsonConvert.SerializeObject(item)
});
};
await _inspectionService.AddListInspectionRecordAsync(datas);
return ResponseOutput.Result(isSuccess);
}
/// <summary> 分页获取受试者列表[New] </summary>
/// /// <param name="param">state:1-访视中2-出组。0-全部</param>
[HttpPost]
public async Task<IResponseOutput<PageOutput<SubjectQueryView>, TrialSubjectConfig>> GetSubjectList(SubjectQueryParam param)
{
var subjectQuery = _subjectRepository.Where(u => u.TrialId == param.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(param.Code), t => t.Code.Contains(param.Code))
.WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name))
.WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex))
.WhereIf(param.Status != null, t => t.Status == param.Status)
.WhereIf(param.SiteId != null, t => t.SiteId == param.SiteId)
// CRC 只负责他管理site的受试者
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<SubjectQueryView>(_mapper.ConfigurationProvider);
var pageList = await subjectQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == string.Empty ? "Code" : param.SortField, param.Asc);
var trialConfig = await _repository.Where<Trial>(t => t.Id == param.TrialId).ProjectTo<TrialSubjectConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return ResponseOutput.Ok(pageList, trialConfig);
}
/// <summary>
/// 计划外访视 获取受试者选择下拉框列表
/// </summary>
[HttpGet("{siteId:guid}/{trialId:guid}")]
public List<SubjectSelect> GetSubjectListBySiteId(Guid siteId, Guid trialId)
{
var query = _subjectRepository.Where(t => t.SiteId == siteId && t.TrialId == trialId && t.Status == SubjectStatus.OnVisit).Select(u => new SubjectSelect()
{
Code = u.Code,
FirstName = u.FirstName,
LastName = u.LastName,
Sex = u.Sex,
SubjectId = u.Id,
Age = u.Age,
MRN = u.MedicalNo,
Status = u.Status,
FirstGiveMedicineTime = u.FirstGiveMedicineTime
});
return query.ToList();
}
[Obsolete]
[HttpGet("{trialId:guid}/{subjectId:guid}/{finalSubjectVisitId:guid}")]
public async Task<IResponseOutput> VerifySubjectFinalVisit(Guid subjectId, Guid finalSubjectVisitId)
{
if (await _repository.AnyAsync<SubjectVisit>(t => t.SubjectId == subjectId && t.IsFinalVisit))
{
return ResponseOutput.NotOk("该受试者已经有访视设置为末次访视,不允许将该访视设置为末次访视");
}
var sv = (await _repository.FirstOrDefaultAsync<SubjectVisit>(t => t.Id == finalSubjectVisitId)).IfNullThrowException();
if (await _repository.AnyAsync<SubjectVisit>(t => t.SubjectId == subjectId && t.VisitNum > sv.VisitNum && t.SubmitState == SubmitStateEnum.ToSubmit))
{
return ResponseOutput.NotOk("该受试者此访视后有影像上传,该访视不允许设置为末次访视");
}
return ResponseOutput.Ok();
}
}
}