using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
namespace IRaCIS.Core.Application.Triggers
{
///
/// 处理 访视 末次评估 会影响Subject 状态
///
public class SubjectVisitFinalVisitTrigger : IAfterSaveTrigger
{
private readonly IRepository _subjectVisitRepository;
private readonly IRepository _readingPeriodSetRepository;
private readonly IRepository _readingPeriodPlanRepository;
private readonly IRepository _readModuleRepository;
private readonly IRepository _subjectRepository;
private readonly IRepository _repository;
public SubjectVisitFinalVisitTrigger(IRepository subjectVisitRepository,
IRepository readingPeriodSetRepository,
IRepository readingPeriodPlanRepository,
IRepository readModuleRepository,
IRepository subjectRepository, IRepository repository)
{
_subjectVisitRepository = subjectVisitRepository;
this._readingPeriodSetRepository = readingPeriodSetRepository;
this._readingPeriodPlanRepository = readingPeriodPlanRepository;
this._readModuleRepository = readModuleRepository;
_subjectRepository = subjectRepository;
_repository = repository;
}
public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken)
{
var subjectVisit = context.Entity;
if (context.ChangeType == ChangeType.Modified)
{
// 修改了IsFinalVisit
if (context.UnmodifiedEntity?.IsFinalVisit != subjectVisit.IsFinalVisit)
{
if (subjectVisit.IsFinalVisit)
{
await VerifyDealFinalVisitAsync(subjectVisit);
}
else
{
//回退
await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisit.SubjectId,
u => new Subject() { Status = SubjectStatus.OnVisit, FinalSubjectVisitId = null });
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitExecuted == VisitExecutedEnum.Unavailable, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted });
var readingPeriodSet =await _readingPeriodSetRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.IsGlobal).FirstOrDefaultAsync();
if (readingPeriodSet != null)
{
await _readingPeriodPlanRepository.DeleteFromQueryAsync(x => x.ReadingPeriodSetId == readingPeriodSet.Id && x.SubjectVisitId == subjectVisit.Id);
await _readModuleRepository.DeleteFromQueryAsync(x => x.SubjectVisitId == subjectVisit.Id && x.ReadingPeriodSetId == readingPeriodSet.Id);
await _readModuleRepository.SaveChangesAsync();
}
}
}
}
else if (context.ChangeType == ChangeType.Added && subjectVisit.IsFinalVisit)
{
await VerifyDealFinalVisitAsync(subjectVisit);
}
}
private async Task VerifyDealFinalVisitAsync(SubjectVisit subjectVisit)
{
if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitNum > subjectVisit.VisitNum &&
(t.SubmitState == SubmitStateEnum.ToSubmit || t.SubmitState == SubmitStateEnum.Submitted)))
{
throw new BusinessValidationFailedException("该受试者已有后续访视已上传影像或已提交,当前访视不允许设置为末次访视。");
}
await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisit.SubjectId,
u => new Subject() { Status = SubjectStatus.OutOfVisit, FinalSubjectVisitId = subjectVisit.Id });
//末次访视后的 访视设置为不可用
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitNum > subjectVisit.VisitNum &&
t.VisitExecuted == VisitExecutedEnum.UnExecuted, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.Unavailable });
var trialId = subjectVisit.TrialId;
var subjectVisitId= subjectVisit.Id;
// 是否全局阅片
var trial = await _repository.Where(x => x.Id == trialId).FirstNotNullAsync();
if (trial.IsGlobalReading&&trial.IsReadingTaskViewInOrder)
{
ReadingPeriodSet? readingPeriodSet =await _readingPeriodSetRepository.FirstOrDefaultNoTrackingAsync(x => x.TrialId == trialId && x.IsGlobal);
if (readingPeriodSet==null)
{
readingPeriodSet = new ReadingPeriodSet()
{
Id = NewId.NextGuid(),
ReadingScope = ReadingScopeEnum.All,
ReadingSetType = ReadingSetType.ImageReading,
IsTakeEffect = ReadingPeriodStatus.TakeEffect,
ReadingPeriodName = "Global",
TrialId = trialId,
EffectOfTime = DateTime.Now,
IsGlobal = true,
};
await _readingPeriodSetRepository.AddAsync(readingPeriodSet);
}
await _readingPeriodPlanRepository.AddAsync(new ReadingPeriodPlan()
{
SubjectVisitId = subjectVisitId,
ReadingPeriodSetId = readingPeriodSet.Id,
});
await _readModuleRepository.DeleteFromQueryAsync(x => x.ReadingSetType == ReadingSetType.ImageReading && x.SubjectVisitId == subjectVisitId, true);
await _readModuleRepository.AddAsync(new ReadModule()
{
ReadingPeriodSetId = readingPeriodSet.Id,
IsUrgent = subjectVisit.IsUrgent,
SubjectVisitId = subjectVisitId,
ReadingStatus = ReadingStatusEnum.TaskAllocate,
SubjectId = subjectVisit.SubjectId,
ModuleName = "Global",// 全局阅片
ReadingSetType = ReadingSetType.ImageReading,
ModuleType = ModuleTypeEnum.Global,
TrialId = subjectVisit.TrialId,
VisitNum = subjectVisit.VisitNum,
});
await _readModuleRepository.SaveChangesAsync();
}
}
}
}