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

528 lines
26 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.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Magicodes.ExporterAndImporter.Excel.AspNetCore;
using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class VisitPlanService : BaseService, IVisitPlanService
{
private readonly IRepository<VisitStage> _visitStageRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<VisitPlanInfluenceStudy> _influnceRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<VisitPlanInfluenceStat> _visitPlanInfluenceStatRepository;
public VisitPlanService(IRepository<VisitStage> visitStageRepository, IRepository<Trial> trialRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<VisitPlanInfluenceStudy> visitPlanInfluenceStudy, IRepository<Subject> subjectRepository, IRepository<VisitPlanInfluenceStat> visitPlanInfluenceStatRepository)
{
_visitStageRepository = visitStageRepository;
_trialRepository = trialRepository;
_subjectVisitRepository = subjectVisitRepository;
_influnceRepository = visitPlanInfluenceStudy;
_visitPlanInfluenceStatRepository = visitPlanInfluenceStatRepository;
_subjectRepository = subjectRepository;
}
///暂时不用
/// <summary> 获取项目访视计划</summary>
[HttpPost]
public async Task<PageOutput<VisitStageDTO>> GetTrialVisitStageList(VisitPlanQueryDTO param)
{
var visitStageQuery = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == param.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(param.Keyword), t => t.VisitName.Contains(param.Keyword))
.ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider);
return await visitStageQuery.ToPagedListAsync(param.PageIndex, param.PageSize, "CreateTime", param.Asc);
}
/// <summary> 根据项目Id获取项目访视计划(不分页)[New]</summary>
[HttpGet("{trialId:guid}")]
public async Task<VisitPlanView> GetVisitStageList(Guid trialId)
{
var query = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == trialId)
.ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
var list = await query.ToListAsync();
var trial = (await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == trialId)).IfNullThrowException();
var isHaveGeneratedTask = (await _repository.AnyAsync<VisitTask>(t => t.TrialId == trialId));
return new VisitPlanView()
{
VisitPlanList = list,
TimePointsPerPatient = trial.TimePointsPerPatient,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
IsHaveFirstGiveMedicineDate = trial.IsHaveFirstGiveMedicineDate,
BlindBaseLineName=trial.BlindBaseLineName,
BlindFollowUpPrefix=trial.BlindFollowUpPrefix,
IsHaveGeneratedTask= isHaveGeneratedTask,
//SubjectHasAdded = _subjectVisitRepository.Any(t => t.TrialId == trialId)
};
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> UpdateVisitBlindName(VisitBlindNameCommand command)
{
await _trialRepository.UpdatePartialFromQueryAsync(command.TrialId, t => new Trial() { BlindBaseLineName = command.BlindBaseLineName, BlindFollowUpPrefix = command.BlindFollowUpPrefix });
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 获取访视计划下拉框列表
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<IEnumerable<VisitStageSelectDTO>> GetTrialVisitStageSelect(Guid trialId)
{
var query = _visitStageRepository.Where(u => u.TrialId == trialId)
.ProjectTo<VisitStageSelectDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
var list = await query.ToListAsync();
return list;
}
/// <summary> 添加或更新访视计划某项</summary>
[UnitOfWork]
[HttpPost]
[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateVisitStage(VisitPlanCommand visitPlan)
{
if (!await _trialRepository.Where(t => t.Id == visitPlan.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialState.TrialOngoing || t.TrialStatusStr == StaticData.TrialState.TrialInitializing))
{
//---只有当项目状态为:初始化或进行中时,可以操作。
throw new BusinessValidationFailedException(_localizer["VisitPlan_OnlyInitOrOngoing"]);
}
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == visitPlan.TrialId, ignoreQueryFilters: true)
.Select(t => new { t.Id, t.VisitNum, t.VisitDay }).OrderBy(t => t.VisitNum).ToListAsync();
//更新的时候,需要排除自己
if (visitPlan.Id != null)
{
visitPlanList = visitPlanList.Where(t => t.Id != visitPlan.Id).ToList();
}
if (visitPlanList.Any(t => t.VisitNum < visitPlan.VisitNum))
{
//比当前 visitNum小的 visitDay的最大值 还小 不允许添加
if (visitPlan.VisitDay <= visitPlanList.Where(t => t.VisitNum < visitPlan.VisitNum).Select(t => t.VisitDay).Max())
{
//---访视计划中,访视号大的访视,其访视间隔也应该比访视号小的访视大。
throw new BusinessValidationFailedException(_localizer["VisitPlan_LargerVisitNumLargerInterval"]);
}
}
if (visitPlanList.Any(t => t.VisitNum > visitPlan.VisitNum))
{
if (visitPlan.VisitDay >= visitPlanList.Where(t => t.VisitNum > visitPlan.VisitNum).Select(t => t.VisitDay).Min())
{
//---访视计划中,访视号大的计划访视,其访视间隔也应该比访视号小的计划访视大。
throw new BusinessValidationFailedException(_localizer["VisitPlan_LargerPlanNumLargerInterval"]);
}
}
if (visitPlan.Id == Guid.Empty || visitPlan.Id == null)//add
{
var trial = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == visitPlan.TrialId)).IfNullThrowException();
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum), true))
{
//---访视计划中已经存在具有项目访视名称或者访视号的计划访视模板。
throw new BusinessValidationFailedException(_localizer["VisitPlan_ExistNameOrNumTemplate"]);
}
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine, true) && visitPlan.IsBaseLine)
{
//---访视计划中已经存在基线。
throw new BusinessValidationFailedException(_localizer["VisitPlan_ExistBaseline"]);
}
//不用前端传递的值
visitPlan.BlindName = "B" + ((int)visitPlan.VisitNum * 10).ToString("D3");
var visitPlanItem = await _visitStageRepository.InsertFromDTOAsync(visitPlan, true);
return ResponseOutput.Ok(visitPlanItem.Id);
}
else//update
{
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum) && t.Id != visitPlan.Id, true))
{
//---访视计划中已经存在具有项目访视名称或者访视号的计划访视模板。
throw new BusinessValidationFailedException(_localizer["VisitPlan_ExistNameOrNumTemplate"]);
}
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine && t.Id != visitPlan.Id, true) && visitPlan.IsBaseLine)
{
//---访视计划中已经存在基线。
throw new BusinessValidationFailedException(_localizer["VisitPlan_ExistBaseline"]);
}
visitPlan.IsConfirmed = false;
//不用前端传递的值
visitPlan.BlindName = "B" + ((int)visitPlan.VisitNum * 10).ToString("D3");
//返回的是数据库查询的数据
var stage = await _visitStageRepository.UpdateFromDTOAsync(visitPlan, true);
if (stage.IsBaseLine && stage.IsBaseLine != visitPlan.IsBaseLine)
{
if (await _repository.Where<SubjectVisit>(t => t.TrialId == visitPlan.TrialId).AnyAsync(v => v.IsBaseLine && v.SubmitState >= SubmitStateEnum.ToSubmit))
{
//---有受试者的基线已经上传了影像数据,不允许修改基线访视。
throw new BusinessValidationFailedException(_localizer["VisitPlan_ExistBaselineImgNoModify"]);
}
}
return ResponseOutput.Ok();
}
}
[UnitOfWork]
[HttpPost("{trialId:guid}")]
[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmTrialVisitPlan(Guid trialId)
{
if (!await _trialRepository.AnyAsync(t => t.Id == trialId && (t.TrialStatusStr == StaticData.TrialState.TrialInitializing || t.TrialStatusStr == StaticData.TrialState.TrialOngoing)))
{
//---仅仅在项目初始化或者进行中时,才允许修改确认
return ResponseOutput.NotOk(_localizer["VisitPlan_OnlyInitOrOngoingModifyConfirm"]);
}
if (!await _visitStageRepository.AnyAsync(t => t.TrialId == trialId && t.IsBaseLine))
{
//---没有基线,不允许确认
return ResponseOutput.NotOk(_localizer["VisitPlan_NoBaselineNotConfirm"]);
}
if (!await _trialRepository.AnyAsync(t => t.Id == trialId && t.IsTrialBasicLogicConfirmed && t.IsTrialProcessConfirmed && t.IsTrialUrgentConfirmed))
{
//---项目配置未确认,不允许确认访视计划
return ResponseOutput.NotOk(_localizer["VisitPlan_ConfigNotConfirmNotConfirm"]);
}
var svList = await _visitStageRepository.Where(t => t.TrialId == trialId).Select(u => new { u.VisitDay, u.IsBaseLine }).ToListAsync();
if (svList.Min(t => t.VisitDay) != svList.Where(t => t.IsBaseLine).FirstOrDefault()?.VisitDay)
{
//---基线VisitDay 不是最小的, 不允许确认
return ResponseOutput.NotOk(_localizer["VisitPlan_BaselineNotMinDayNotConfirm"]);
}
//更新项目访视计划状态为已确认 必定生成更新的sql 通过状态改变 触发操作
//await _trialRepository.UpdatePartialNowNoQueryAsync(trialId, t => new Trial() { VisitPlanConfirmed = true });
var trial = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId)).IfNullThrowException();
//确认是否是首次确认
var initTrialVisitPlanConfirmed = trial.VisitPlanConfirmed;
trial.VisitPlanConfirmed = true;
#region 统一给Subject 增加访视任务
//首次确认时 IsHaveFirstConfirmed都为false 不需要给Subject 加访视
if (initTrialVisitPlanConfirmed)
{
List<SubjectVisit> subjectVisits = new List<SubjectVisit>();
var addvisitStages = await _visitStageRepository.Where(x => !x.IsHaveFirstConfirmed && x.TrialId == trialId).ToListAsync();
foreach (var visitPlan in addvisitStages)
{
var subjectSVS = await _subjectVisitRepository.Where(t => t.TrialId == visitPlan.TrialId).Select(t => new { t.SubjectId, t.SiteId, t.IsFinalVisit }).Distinct().ToListAsync();
var subjectList = subjectSVS.Select(t => new { t.SubjectId, t.SiteId }).Distinct().ToList();
foreach (var subject in subjectList)
{
var svItem = _mapper.Map<SubjectVisit>(visitPlan);
svItem.SiteId = subject.SiteId;
svItem.SubjectId = subject.SubjectId;
//设置了末次访视,那么加访视计划的时候,设置为不可用
if (subjectSVS.Any(t => t.SubjectId == svItem.SubjectId && t.IsFinalVisit))
{
svItem.VisitExecuted = VisitExecutedEnum.Unavailable;
}
//再加一层保险,防止重复
if (!await _subjectVisitRepository.AnyAsync(t => t.VisitStageId == visitPlan.Id && t.SubjectId == subject.SubjectId))
{
await _subjectVisitRepository.AddAsync(svItem);
}
}
}
await _subjectVisitRepository.AddRangeAsync(subjectVisits);
}
#endregion
#region 访视计划修改 影响检查
//找到访视计划修改的Item
var changedList = await _visitStageRepository.Where(t => t.TrialId == trial.Id && t.IsConfirmed == false)
.Select(t => new
{
t.Trial.IsHaveFirstGiveMedicineDate,
t.Id,
t.VisitName,
t.TrialId,
t.VisitWindowLeft,
t.VisitWindowRight,
t.VisitDay,
t.VisitNum,
t.IsBaseLine,
t.BlindName,
t.Description,
IsConfirmed = true,
}).ToListAsync();
var visitPlanInfluenceStat = new VisitPlanInfluenceStat() { TrialId = trial.Id };
foreach (var changedItem in changedList)
{
//找到该项目 访视已经执行,并且配置了有首次给药日期 并且更新后超窗的访视,要把超窗之前的值也要查询出来
var qcPassedVisitList = await _subjectVisitRepository.Where(t => t.TrialId == trialId
&& t.VisitExecuted == VisitExecutedEnum.Executed
&& t.AuditState == AuditStateEnum.QCPassed
&& t.Trial.IsHaveFirstGiveMedicineDate == true
&& t.VisitStageId == changedItem.Id
&& t.Subject.FirstGiveMedicineTime != null
).Select(k => new
{
SubjectVisitId = k.Id,
SelfWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowLeft),
SelfWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowRight + 1).AddSeconds(-1),
NowWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft),
NowWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight + 1).AddSeconds(-1),
NoneDicomStudyList =
k.NoneDicomStudyList //之前是查询调整之后超窗的 现在调整前超窗 调整后 没超窗的也要记录
//.Where(study => study.ImageDate <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
//|| study.ImageDate >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
.Select(t => new { NoneDicomStudyId = t.Id, t.Modality, StudyTime = t.ImageDate }),
DicomStudyList = k.StudyList
//.Where(study => study.StudyTime <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
// || study.StudyTime >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
.Select(t => new { StudyId = t.Id, Modality = t.Modalities, t.StudyTime })
}).ToListAsync();
foreach (var visit in qcPassedVisitList)
{
//找到本身没有超窗的数据 修改后超窗的
visit.DicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
{
visitPlanInfluenceStat.InconsistentCount++;
visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = false,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.StudyId,
IsDicomStudy = true,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
visit.NoneDicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
{
visitPlanInfluenceStat.InconsistentCount++;
visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = false,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.NoneDicomStudyId,
IsDicomStudy = false,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
//本身超窗 修改后没超窗的
visit.DicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
{
visitPlanInfluenceStat.InconsistentCount++;
visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = true,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.StudyId,
IsDicomStudy = true,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
visit.NoneDicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
{
visitPlanInfluenceStat.InconsistentCount++;
visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = true,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.NoneDicomStudyId,
IsDicomStudy = false,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
}
//变更某一访视计划Item 受试者访视相关字段
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id, k => new SubjectVisit()
{
IsBaseLine = changedItem.IsBaseLine,
VisitName = changedItem.VisitName,
VisitNum = changedItem.VisitNum,
VisitDay = changedItem.VisitDay,
VisitWindowLeft = changedItem.VisitWindowLeft,
VisitWindowRight = changedItem.VisitWindowRight
});
}
await _visitPlanInfluenceStatRepository.AddAsync(visitPlanInfluenceStat, true);
#endregion
//访视计划 整体状态变更为 确认
await _visitStageRepository.UpdatePartialFromQueryAsync(u => u.TrialId == trialId && u.IsConfirmed == false, t => new VisitStage() { IsConfirmed = true, IsHaveFirstConfirmed = true });
await _visitStageRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[HttpGet("{trialId:guid}")]
public async Task<List<VisitPlanInfluenceSubjectVisitStatDTO>> GetInfluenceHistoryList(Guid trialId, [FromServices] IRepository<VisitPlanInfluenceStat> _influnceStatRepository)
{
var list = await _influnceStatRepository.Where(t => t.TrialId == trialId).ProjectTo<VisitPlanInfluenceSubjectVisitStatDTO>(_mapper.ConfigurationProvider).OrderByDescending(t => t.CreateTime).ToListAsync();
return list;
}
[HttpGet("{visitPlanInfluenceStatId:guid}")]
public async Task<IActionResult> DownloadInflunceStudyList(Guid visitPlanInfluenceStatId)
{
var list = _influnceRepository.Where(t => t.VisitPlanInfluenceStatId == visitPlanInfluenceStatId)
.ProjectTo<VisitPlanInfluenceSubjectVisitDTO>(_mapper.ConfigurationProvider).ToList();
IExporter exporter = new ExcelExporter();
var result = await exporter.ExportAsByteArray(list);
//$"检查导出_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx"
return new XlsxFileResult(bytes: result, fileDownloadName: _localizer["VisitPlan_CheckExport", DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")]);
}
/// <summary> 删除项目计划某一项 废弃 </summary>
[HttpDelete("{id:guid}/{trialId:guid}")]
[Obsolete]
public async Task<IResponseOutput> DeleteVisitStage(Guid id)
{
var visitPlan = await _visitStageRepository.FirstOrDefaultAsync(t => t.Id == id);
if (visitPlan == null) return Null404NotFound(visitPlan);
if (await _repository.AnyAsync<SubjectVisit>(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId && t.VisitExecuted == VisitExecutedEnum.Executed))
{
//---The visit plan has been assigned to the subjects and executed.
return ResponseOutput.NotOk(_localizer["VisitPlan_Assigned"]);
}
await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == visitPlan.TrialId && t.VisitName == visitPlan.VisitName);
var result = await _visitStageRepository.BatchDeleteNoTrackingAsync(u => u.Id == id);
return ResponseOutput.Result(result);
}
}
}