删除不要的功能

Uat_Study
he 2023-07-24 14:40:31 +08:00
parent f0cde942fb
commit 53251e53a0
143 changed files with 133 additions and 15972 deletions

View File

@ -35,50 +35,7 @@ namespace IRaCIS.Api.Controllers
{
/// <summary>
/// 获取医生详情
/// </summary>
/// <param name="attachmentService"></param>
/// <param name="_doctorService"></param>
/// <param name="_educationService"></param>
/// <param name="_trialExperienceService"></param>
/// <param name="_researchPublicationService"></param>
/// <param name="_vacationService"></param>
/// <param name="doctorId"></param>
/// <returns></returns>
[HttpGet, Route("doctor/getDetail/{doctorId:guid}")]
public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
[FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
[FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
{
var education = await _educationService.GetEducation(doctorId);
var sowList = _doctorService.GetDoctorSowList(doctorId);
var ackSowList = _doctorService.GetDoctorAckSowList(doctorId);
var doctorDetail = new DoctorDetailDTO
{
AuditView =await _doctorService.GetAuditState(doctorId),
BasicInfoView = await _doctorService.GetBasicInfo(doctorId),
EmploymentView = await _doctorService.GetEmploymentInfo(doctorId),
AttachmentList = await attachmentService.GetAttachments(doctorId),
EducationList = education.EducationList,
PostgraduateList = education.PostgraduateList,
TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId),
ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId),
SpecialtyView =await _doctorService.GetSpecialtyInfo(doctorId),
InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess,
IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId),
SowList = sowList,
AckSowList = ackSowList
};
return ResponseOutput.Ok(doctorDetail);
}

View File

@ -22,14 +22,14 @@ namespace IRaCIS.Core.API.Controllers.Special
public class FinancialChangeController : ControllerBase
{
private readonly ITrialService _trialService;
private readonly ICalculateService _calculateService;
private IStringLocalizer _localizer { get; set; }
public FinancialChangeController(ITrialService trialService, ICalculateService calculateService, IStringLocalizer localizer
public FinancialChangeController(ITrialService trialService, IStringLocalizer localizer
)
{
_localizer = localizer;
_trialService = trialService;
_calculateService = calculateService;
}
@ -60,268 +60,28 @@ namespace IRaCIS.Core.API.Controllers.Special
var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialService.AddOrUpdateTrial(param);
if (_trialService.TrialExpeditedChange)
{
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(param.Id.Value);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
calcList.ForEach(t =>
{
if (needCalReviewerIds.Contains(t.DoctorId))
{
_calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
t.DoctorId
},
CalculateMonth = DateTime.Parse(t.YearMonth)
}, User.FindFirst("id").Value);
}
});
}
return result;
}
/// <summary>
/// 添加或更新工作量[AUTH]
/// </summary>
/// <param name="_trialWorkloadService"></param>
/// <param name="workLoadAddOrUpdateModel"></param>
/// <returns></returns>
[HttpPost, Route("doctorWorkload/workLoadAddOrUpdate")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> WorkLoadAddOrUpdate([FromServices] IDoctorWorkloadService _trialWorkloadService, WorkloadCommand workLoadAddOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result = await _trialWorkloadService.AddOrUpdateWorkload(workLoadAddOrUpdateModel, userId);
if (result.IsSuccess && workLoadAddOrUpdateModel.DataFrom == 2)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
workLoadAddOrUpdateModel.DoctorId
},
CalculateMonth = workLoadAddOrUpdateModel.WorkTime
}, User.FindFirst("id").Value);
}
return result;
}
[HttpDelete, Route("doctorWorkload/deleteWorkLoad/{id:guid}/{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> DeleteWorkLoad([FromServices] IDoctorWorkloadService _trialWorkloadService, Guid id)
{
//先判断该工作量的费用是否被锁定,如果被锁定,则不能删除
var workload = await _trialWorkloadService.GetWorkloadDetailById(id);
var yearMonth = workload.WorkTime.ToString("yyyy-MM");
var isLock = await _calculateService.IsLock(workload.DoctorId, yearMonth);
if (isLock)
{
//---Expenses have been settled and workload can not be reset.
return ResponseOutput.NotOk(_localizer["Financial_ChargeSettled"]);
}
var deleteResult = await _trialWorkloadService.DeleteWorkload(id);
if (workload.DataFrom == (int)Domain.Share.WorkLoadFromStatus.FinalConfirm)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
workload.DoctorId
},
CalculateMonth = workload.WorkTime
}, User.FindFirst("id").Value);
}
return deleteResult;
}
/// <summary>
/// 添加或更新汇率(会触发没有对锁定的费用计算)
/// </summary>
[HttpPost, Route("exchangeRate/addOrUpdateExchangeRate")]
public async Task<IResponseOutput> AddOrUpdateExchangeRate([FromServices] IExchangeRateService _exchangeRateService, [FromServices] IPaymentAdjustmentService _costAdjustmentService, ExchangeRateCommand addOrUpdateModel)
{
var result = await _exchangeRateService.AddOrUpdateExchangeRate(addOrUpdateModel);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, addOrUpdateModel.YearMonth);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
await _costAdjustmentService.CalculateCNY(addOrUpdateModel.YearMonth, addOrUpdateModel.Rate);
return result;
}
/// <summary>
/// 添加或更新 职称单价[AUTH]
/// </summary>
[HttpPost, Route("rankPrice/addOrUpdateRankPrice")]
public async Task<IResponseOutput> AddOrUpdateRankPrice([FromServices] IReviewerPayInfoService _reviewerPayInfoService, [FromServices] IRankPriceService _rankPriceService, RankPriceCommand addOrUpdateModel)
{
if (addOrUpdateModel.Id != Guid.Empty && addOrUpdateModel.Id != null)
{
var needCalReviewerIds =await _reviewerPayInfoService.GetReviewerIdByRankId(Guid.Parse(addOrUpdateModel.Id.ToString()));
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null && needCalReviewerIds.Contains(item.DoctorId))
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
}
var userId = Guid.Parse(User.FindFirst("id").Value);
return await _rankPriceService.AddOrUpdateRankPrice(addOrUpdateModel, userId);
}
/// <summary>
/// 添加或更新(替换)医生支付展信息[AUTH]
/// </summary>
[HttpPost, Route("reviewerPayInfo/addOrUpdateReviewerPayInfo")]
public async Task<IResponseOutput> AddOrUpdateReviewerPayInfo([FromServices] IReviewerPayInfoService _doctorPayInfoService, ReviewerPayInfoCommand addOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result =await _doctorPayInfoService.AddOrUpdateReviewerPayInfo(addOrUpdateModel, userId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(addOrUpdateModel.DoctorId, string.Empty);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 保存(替换)项目支付价格信息(会触发没有被锁定的费用计算)[AUTH]
/// </summary>
[HttpPost, Route("trialPaymentPrice/addOrUpdateTrialPaymentPrice")]
public async Task<IResponseOutput> AddOrUpdateTrialPaymentPrice([FromServices] ITrialPaymentPriceService _trialPaymentPriceService, TrialPaymentPriceCommand addOrUpdateModel)
{
var userId = Guid.Parse(User.FindFirst("id").Value);
var result =await _trialPaymentPriceService.AddOrUpdateTrialPaymentPrice(addOrUpdateModel);
var needCalReviewerIds = await _trialService.GetTrialEnrollmentReviewerIds(addOrUpdateModel.TrialId);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null && needCalReviewerIds.Contains(item.DoctorId))
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 批量更新奖励费用[AUTH]
/// </summary>
[HttpPost, Route("volumeReward/addOrUpdatevolumeRewardPriceList")]
public async Task<IResponseOutput> AddOrUpdateAwardPriceList([FromServices] IVolumeRewardService _volumeRewardService, IEnumerable<AwardPriceCommand> addOrUpdateModel)
{
var result =await _volumeRewardService.AddOrUpdateVolumeRewardPriceList(addOrUpdateModel);
var calcList = await _calculateService.GetNeedCalculateReviewerList(Guid.Empty, string.Empty);
foreach (var item in calcList)
{
if (item != null)
{
await _calculateService.CalculateMonthlyPayment(new CalculateDoctorAndMonthDTO()
{
NeedCalculateReviewers = new List<Guid>()
{
item.DoctorId
},
CalculateMonth = DateTime.Parse(item.YearMonth)
}, User.FindFirst("id").Value);
}
}
return result;
}
/// <summary>
/// 计算医生月度费用,并将计算的结果存入费用表
/// </summary>
[HttpPost, Route("financial/calculateMonthlyPayment")]
public async Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param)
{
if (!ModelState.IsValid)
{
//---Invalid parameter.
return ResponseOutput.NotOk(_localizer["Financial_InvalidParameter"]);
}
return await _calculateService.CalculateMonthlyPayment(param, User.FindFirst("id").Value);
}
/// <summary>
/// Financials /Monthly Payment 列表查询接口
/// </summary>
[HttpPost, Route("financial/getMonthlyPaymentList")]
public async Task<IResponseOutput<PaymentDTO>> GetMonthlyPaymentList([FromServices] IPaymentService _paymentService, [FromServices] IExchangeRateService _exchangeRateService, MonthlyPaymentQueryDTO queryParam)
{
return ResponseOutput.Ok(new PaymentDTO
{
CostList = await _paymentService.GetMonthlyPaymentList(queryParam),
ExchangeRate = await _exchangeRateService.GetExchangeRateByMonth(queryParam.StatisticsDate.ToString("yyyy-MM"))
});
}
}
}

View File

@ -993,73 +993,8 @@ namespace IRaCIS.Core.API.Controllers
}
/// <summary>
/// 下载多个医生的所有附件
/// </summary>
/// <param name="doctorIds"></param>
/// <returns></returns>
[HttpPost, Route("file/downloadDoctorAttachments")]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachment(Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = path,
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载医生官方简历
/// </summary>
/// <param name="language"></param>
/// <param name="doctorIds"></param>
/// <returns></returns>
[HttpPost, Route("file/downloadOfficialCV/{language}")]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadOfficialResume(int language, Guid[] doctorIds)
{
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateOfficialResumeZip(language, doctorIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
/// <summary>
/// 下载指定医生的指定附件
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <param name="attachmentIds">要下载的附件Id</param>
/// <returns></returns>
[HttpPost, Route("file/downloadByAttachmentId/{doctorId}")]
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachmentById(Guid doctorId, Guid[] attachmentIds)
{
var path = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds);
return ResponseOutput.Ok(new UploadFileInfoDTO
{
FilePath = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds),
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
});
}
[HttpPost, Route("enroll/downloadResume/{trialId:guid}/{language}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[AllowAnonymous]
public async Task<IResponseOutput<string>> DownloadResume(int language, Guid trialId, Guid[] doctorIdArray)
{
var zipPath = await _fileService.CreateOfficialResumeZip(language, doctorIdArray);
return ResponseOutput.Ok(zipPath);
}
}
#endregion

View File

@ -16,19 +16,6 @@
医生基本信息 、工作信息 专业信息、审核状态
</summary>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
<summary>
获取医生详情
</summary>
<param name="attachmentService"></param>
<param name="_doctorService"></param>
<param name="_educationService"></param>
<param name="_trialExperienceService"></param>
<param name="_researchPublicationService"></param>
<param name="_vacationService"></param>
<param name="doctorId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
<summary> 系统用户登录接口[New] </summary>
</member>
@ -41,49 +28,6 @@
<param name="param"></param>
<returns>新记录Id</returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.WorkLoadAddOrUpdate(IRaCIS.Application.Services.IDoctorWorkloadService,IRaCIS.Application.Contracts.WorkloadCommand)">
<summary>
添加或更新工作量[AUTH]
</summary>
<param name="_trialWorkloadService"></param>
<param name="workLoadAddOrUpdateModel"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateExchangeRate(IRaCIS.Application.Interfaces.IExchangeRateService,IRaCIS.Application.Interfaces.IPaymentAdjustmentService,IRaCIS.Application.Contracts.ExchangeRateCommand)">
<summary>
添加或更新汇率(会触发没有对锁定的费用计算)
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateRankPrice(IRaCIS.Application.Interfaces.IReviewerPayInfoService,IRaCIS.Application.Interfaces.IRankPriceService,IRaCIS.Application.Contracts.RankPriceCommand)">
<summary>
添加或更新 职称单价[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateReviewerPayInfo(IRaCIS.Application.Interfaces.IReviewerPayInfoService,IRaCIS.Application.Contracts.ReviewerPayInfoCommand)">
<summary>
添加或更新(替换)医生支付展信息[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialPaymentPrice(IRaCIS.Application.Interfaces.ITrialPaymentPriceService,IRaCIS.Application.Contracts.TrialPaymentPriceCommand)">
<summary>
保存(替换)项目支付价格信息(会触发没有被锁定的费用计算)[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateAwardPriceList(IRaCIS.Application.Interfaces.IVolumeRewardService,System.Collections.Generic.IEnumerable{IRaCIS.Application.Interfaces.AwardPriceCommand})">
<summary>
批量更新奖励费用[AUTH]
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.CalculateMonthlyPayment(IRaCIS.Application.Contracts.CalculateDoctorAndMonthDTO)">
<summary>
计算医生月度费用,并将计算的结果存入费用表
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.GetMonthlyPaymentList(IRaCIS.Application.Interfaces.IPaymentService,IRaCIS.Application.Interfaces.IExchangeRateService,IRaCIS.Application.Contracts.MonthlyPaymentQueryDTO)">
<summary>
Financials /Monthly Payment 列表查询接口
</summary>
</member>
<member name="M:IRaCIS.Core.API.Controllers.InspectionController.GetInspectionList(IRaCIS.Core.Application.Service.Inspection.DTO.GetDataInspectionDto)">
<summary>
获取稽查数据
@ -359,29 +303,6 @@
<param name="type">文件类型</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[])">
<summary>
下载多个医生的所有附件
</summary>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
<summary>
下载医生官方简历
</summary>
<param name="language"></param>
<param name="doctorIds"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
<summary>
下载指定医生的指定附件
</summary>
<param name="doctorId">医生Id</param>
<param name="attachmentIds">要下载的附件Id</param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.LocalFilePreview(System.String)">
<summary> 缩略图 </summary>
</member>

File diff suppressed because it is too large Load Diff

View File

@ -1,225 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-07 13:14:38
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 分配规则
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TaskAllocationRuleService : BaseService, ITaskAllocationRuleService
{
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<User> _userRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository;
public TaskAllocationRuleService(IRepository<TaskAllocationRule> taskAllocationRuleRepository, IRepository<User> userRepository, IRepository<Trial> trialRepository, IRepository<SubjectCanceDoctor> subjectCanceDoctorRepository)
{
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_userRepository = userRepository;
_trialRepository = trialRepository;
_subjectCanceDoctorRepository = subjectCanceDoctorRepository;
}
/// <summary>
/// 获取计划列表 医生带阅片类型
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<(List<TaskAllocationRuleDTO>,object)> GetDoctorPlanAllocationRuleList(Guid trialId)
{
var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo<TaskAllocationRuleDTO>(_mapper.ConfigurationProvider).ToListAsync();
//所有标准都是一样 后台只返回任意一个标准的就好了
var trialTaskConfig = _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
return (list, trialTaskConfig);
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTaskAllocationRule(TaskAllocationRuleAddOrEdit addOrEditTaskAllocationRule)
{
//冗余 存
var enrollId = _repository.Where<Enroll>(t => t.TrialId == addOrEditTaskAllocationRule.TrialId && t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId).Select(t => t.Id).FirstOrDefault();
if (enrollId == Guid.Empty)
{
//"错误未在入组表中找到该医生得账号Id"
return ResponseOutput.NotOk(_localizer["TaskAllocation_DoctorIdNotFound"]);
}
addOrEditTaskAllocationRule.EnrollId = enrollId;
var verifyExp1 = new EntityVerifyExp<TaskAllocationRule>()
{
VerifyExp = t => t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId && t.TrialId == addOrEditTaskAllocationRule.TrialId,
// "已有该医生配置,不允许继续增加"
VerifyMsg = _localizer["TaskAllocation_DoctorConfigExists"]
};
var entity = await _taskAllocationRuleRepository.InsertOrUpdateAsync(addOrEditTaskAllocationRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString());
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpDelete("{taskAllocationRuleId:guid}")]
public async Task<IResponseOutput> DeleteTaskAllocationRule(Guid taskAllocationRuleId)
{
if (await _taskAllocationRuleRepository.Where(t => t.Id == taskAllocationRuleId).AnyAsync(t => t.DoctorUser.VisitTaskList.Where(u => u.TrialId == t.TrialId).Any()))
{
//"已分配任务给该医生,不允许删除"
return ResponseOutput.NotOk(_localizer["TaskAllocation_TaskAssigned"]);
}
var success = await _taskAllocationRuleRepository.DeleteFromQueryAsync(t => t.Id == taskAllocationRuleId, true);
return ResponseOutput.Ok();
}
//public async Task<IResponseOutput> AddSubjectCancelDoctorNote(CancelDoctorCommand command)
//{
// await _subjectCanceDoctorRepository.InsertOrUpdateAsync(command, true);
// return ResponseOutput.Ok();
//}
public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId)
{
var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();
return list;
}
/// <summary>
/// 获取项目下 医生账户信息下拉
/// </summary>
/// <param name="trialId"></param>
/// <param name="_enrollRepository"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<List<TrialDoctorUserSelectView>> GetDoctorUserSelectList(Guid trialId, [FromServices] IRepository<Enroll> _enrollRepository)
{
var query = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
join user in _userRepository.AsQueryable() on enroll.DoctorId equals user.DoctorId
select new TrialDoctorUserSelectView()
{
TrialId = enroll.TrialId,
//ReadingType = enroll.Trial.ReadingType,
DoctorUserId = user.Id,
FullName = user.FullName,
UserCode = user.UserCode,
UserName = user.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList()
};
return await query.ToListAsync();
}
[HttpPost]
public async Task<List<TrialDoctorUserSelectView>> GetDoctorSelectList(DoctorSelectQuery selectQuery, [FromServices] IRepository<Enroll> _enrollRepository)
{
var query = from allocationRule in _taskAllocationRuleRepository.Where(t => t.TrialId == selectQuery.TrialId && t.IsEnable)
.WhereIf(selectQuery.ReadingCategory != null && selectQuery.TrialReadingCriterionId == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.ReadingCategory == selectQuery.ReadingCategory))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId))
.WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory !=null,
t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory==selectQuery.ReadingCategory))
join user in _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
select new TrialDoctorUserSelectView()
{
TrialId = allocationRule.TrialId,
DoctorUserId = user.Id,
FullName = user.FullName,
UserCode = user.UserCode,
UserName = user.UserName,
UserTypeEnum = user.UserTypeRole.UserTypeEnum,
ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
allocationRule.Enroll.EnrollReadingCategoryList.Where(t=> (selectQuery.ReadingCategory == null ?true: t.ReadingCategory == selectQuery.ReadingCategory) ).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() :
allocationRule.Enroll.EnrollReadingCategoryList
.Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null?true : t.ReadingCategory == selectQuery.ReadingCategory) )
.Select(t => t.ReadingCategory).OrderBy(t => t).ToList()
};
return await query.ToListAsync();
}
#region 废弃
/// <summary>
/// 获取访视任务 应用Subject后 医生比率情况
/// </summary>
/// <returns></returns>
[HttpPost]
[Obsolete]
public async Task<List<DoctorVisitTaskStatView>> GetSubjectApplyDoctorTaskStatList(ApplySubjectCommand assignConfirmCommand)
{
var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.IsJudgeDoctor == assignConfirmCommand.IsJudgeDoctor)
.ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider, new { subjectIdList = assignConfirmCommand.SubjectIdList, isJudgeDoctor = assignConfirmCommand.IsJudgeDoctor });
return await taskAllocationRuleQueryable.ToListAsync();
}
[HttpPost]
[Obsolete]
public async Task<List<DoctorVisitTaskStatView>> GetTaskAllocationRuleList(TaskAllocationRuleQuery queryTaskAllocationRule)
{
var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == queryTaskAllocationRule.TrialId /*&& t.IsJudgeDoctor == queryTaskAllocationRule.IsJudgeDoctor*/)
.ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider);
//var trialTaskConfig = _trialRepository.Where(t => t.Id == queryTaskAllocationRule.TrialId).ProjectTo<TrialProcessConfigDTO>(_mapper.ConfigurationProvider, new { isJudgeDoctor = queryTaskAllocationRule.IsJudgeDoctor }).FirstOrDefault();
return await taskAllocationRuleQueryable.ToListAsync();
}
#endregion
}
}

View File

@ -1,777 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-07-01 15:33:04
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using IRaCIS.Core.Infra.EFCore.Common;
using System.Linq;
using Nito.AsyncEx;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 一致性分析配置表
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TaskConsistentRuleService : BaseService, ITaskConsistentRuleService
{
private readonly IRepository<TaskConsistentRule> _taskConsistentRuleRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly AsyncLock _mutex = new AsyncLock();
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository)
{
_taskConsistentRuleRepository = taskConsistentRuleRepository;
_visitTaskRepository = visitTaskRepository;
_subjectUserRepository = subjectUserRepository;
_subjectRepository = subjectRepository;
_enrollRepository = enrollRepository;
}
/// <summary>
/// 设置一致性分析任务失效
/// </summary>
/// <param name="taskIdList"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetAnalysisTaskInvalid(List<Guid> taskIdList)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.Id), u => new VisitTask() { TaskState = TaskState.NotEffect },true);
await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 一致性分析列表 (自身 组内 最后勾选 产生的任务)
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<AnalysisTaskView>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.IsAnalysisCreate)
.WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
.WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis)
.WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum)
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
.WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
.WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
.ProjectTo<AnalysisTaskView>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);
//var trialTaskConfig = _repository.Where<Trial>(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
return pageList;
}
/// <summary>
/// 为自身一致性分析医生选择Subejct 列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<DoctorSelfConsistentSubjectView>> GetDoctorSelfConsistentRuleSubjectList(ConsistentQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var pagedList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc);
return pagedList;
}
/// <summary>
/// 确认生成自身一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TaskConsistentRuleId);
var doctorUserId = inCommand.DoctorUserId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
//var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList);
//var list = query.OrderByDescending(t => t.IsHaveGeneratedTask).ToList();
using (await _mutex.LockAsync())
{
int maxCodeInt = 0;
foreach (var subject in list)
{
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId==trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask!=null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if ( !string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
subject.VisitTaskList = subject.VisitTaskList.Take(filterObj.PlanVisitCount).ToList();
subject.VisitTaskList.ForEach(t =>
{
t.DoctorUserId = doctorUserId;
//t.TaskConsistentRuleId = filterObj.Id;
t.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
t.BlindSubjectCode = blindSubjectCode;
});
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subject.VisitTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId &&t.TrialReadingCriterionId==trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ArmEnum = lastTask.ArmEnum,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId=trialReadingCriterionId,
};
}
existGlobal.DoctorUserId = doctorUserId;
existGlobal.BlindSubjectCode = lastTask.BlindSubjectCode;
existGlobal.BlindTrialSiteCode = lastTask.BlindTrialSiteCode;
subject.VisitTaskList.Add(existGlobal);
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.SelfConsistent,
//产生的过滤掉已经生成的
GenerataConsistentTaskList = subject.VisitTaskList.Where(t => t.IsHaveGeneratedTask == false).ToList()
});
await _visitTaskRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 组间一致性分析 选择Subejct 列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<DoctorGroupConsistentSubjectView>> GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery)
{
var trialId = inQuery.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
if (filterObj == null)
{
return new PageOutput<DoctorGroupConsistentSubjectView>();
}
var query = await GetGroupConsistentQueryAsync(filterObj);
var pagedList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(DoctorSelfConsistentSubjectView.SubjectCode) : inQuery.SortField, inQuery.Asc);
return pagedList;
}
/// <summary>
/// 确认生成组间一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
{
var trialId = inCommand.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IsSelfAnalysis == false);
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
var subjectList = query.ToList();
var doctorUserIdQuery = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId==trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit))
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
select user.Id;
var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync();
using (await _mutex.LockAsync())
{
int maxCodeInt = 0;
foreach (var subject in subjectList.Where(t => t.IsHaveGeneratedTask == false))
{
//组间一致性分析 也用盲态SubjectCode
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis==false).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if (!string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
var subjectAddTaskList = new List<VisitTaskGroupSimpleDTO>();
//需要处理的医生
var needAddDoctorUserIdList = configDoctorUserIdList.Except(subject.VisitTaskList.Select(t => (Guid)t.DoctorUserId)).ToList();
if (needAddDoctorUserIdList.Count == 0)
{
//"请配置一致性分析的医生"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_ConsistencyConfigExists"]);
}
foreach (var needAddDoctorUserId in needAddDoctorUserIdList)
{
//每个医生 都生成处理的任务
foreach (var task in subject.SubjectTaskVisitList.Take(filterObj.PlanVisitCount))
{
subjectAddTaskList.Add(new VisitTaskGroupSimpleDTO()
{
ReadingCategory = task.ReadingCategory,
ReadingTaskState = task.ReadingTaskState,
TaskBlindName = task.TaskBlindName,
TaskName = task.TaskName,
TaskState = task.TaskState,
SubjectId = task.SubjectId,
VisitTaskNum = task.VisitTaskNum,
TrialId = task.TrialId,
DoctorUserId = needAddDoctorUserId,
ArmEnum = Arm.GroupConsistentArm,
SouceReadModuleId = task.SouceReadModuleId,
SourceSubjectVisitId = task.SourceSubjectVisitId,
TrialReadingCriterionId = task.TrialReadingCriterionId,
BlindSubjectCode=blindSubjectCode,
BlindTrialSiteCode=filterObj.BlindTrialSiteCode
});
}
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subjectAddTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo<VisitTaskGroupSimpleDTO>(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
};
}
existGlobal.BlindSubjectCode = blindSubjectCode;
existGlobal.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
existGlobal.ArmEnum = Arm.GroupConsistentArm;
existGlobal.DoctorUserId = needAddDoctorUserId;
subjectAddTaskList.Add(existGlobal);
}
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.GroupConsistent,
GenerataGroupConsistentTaskList = subjectAddTaskList
});
await _taskConsistentRuleRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 仅仅自身一致性时使用(
/// </summary>
/// <param name="filterObj"></param>
/// <param name="doctorUserId"></param>
/// <param name="subejctIdList"></param>
/// <returns></returns>
private IQueryable<DoctorSelfConsistentSubjectView> GetIQueryableDoctorSelfConsistentSubjectView(TaskConsistentRule filterObj, Guid doctorUserId, List<Guid>? subejctIdList = null)
{
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
#region Subejct 维度
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId== trialReadingCriterionId &&
u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId;
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
////所选访视数量 的访视 其中必有一个访视后有全局任务
//if (filterObj.IsHaveReadingPeriod == true)
//{
// //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍
// visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned &&
// t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)));
//}
var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount)
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
;
var query = subjectQuery.Select(t => new DoctorSelfConsistentSubjectView()
{
TrialId = t.TrialId,
SiteId = t.SiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis=t.IsReReadingOrBackInfluenceAnalysis,
BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(),
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId==trialReadingCriterionId),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).OrderBy(t => t.VisitTaskNum).Select(c => new VisitTaskSimpleDTO()
{
Id = c.Id,
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskCode = c.TaskCode,
TaskName = c.TaskName,
TaskState = c.TaskState,
ArmEnum = c.ArmEnum,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId=c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
//自身一致性才有意义
//IsHaveGeneratedTask = c.Subject.SubjectVisitTaskList.Any(t => t.ConsistentAnalysisOriginalTaskId == c.Id),
GlobalVisitTaskList = c.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).Select(c => new VisitTaskSimpleDTO()
{
Id = c.Id,
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskCode = c.TaskCode,
TaskName = c.TaskName,
TaskState = c.TaskState,
ArmEnum = c.ArmEnum,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
}).ToList(),
}).ToList()
});
return query.OrderByDescending(t => t.IsHaveGeneratedTask);
#endregion
}
private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null)
{
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//var trialConfig = (await _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId
&& (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
////所选访视数量 的访视 其中必有一个访视后有全局任务
//if (filterObj.IsHaveReadingPeriod == true)
//{
// //visitTaskFilter = visitTaskFilter.And(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Any(u => u.VisitTaskNum == t.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && u.ReadingCategory == ReadingCategory.Global));
// //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍
// visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned &&
// t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)));
//}
IQueryable<Subject> subjectQuery = default;
//单重阅片没有组件一致性
subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Select(t => t.DoctorUserId).Distinct().Count() == 2 &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count() >= filterObj.PlanVisitCount
)
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global))
;
var query = subjectQuery.Select(t => new DoctorGroupConsistentSubjectView()
{
TrialId = t.TrialId,
SiteId = t.SiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId==trialReadingCriterionId),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
.Select(c => new VisitTaskGroupSimpleDTO()
{
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskName = c.TaskName,
TaskState = c.TaskState,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
DoctorUserId = c.DoctorUserId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
}).ToList()
//
});
query = query.OrderByDescending(t => t.IsHaveGeneratedTask);
return query;
}
[HttpPost]
public async Task<TaskConsistentRuleBasic?> GetConsistentRule(TaskConsistentRuleQuery inQuery)
{
return await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
}
/// <summary>
/// 自身一致性分配 配置+ 统计已经生成数量统计表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<TaskConsistentRuleView>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
{
var trialId = inQuery.TrialId;
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus==EnrollStatus.ConfirmIntoGroup)
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId &&t.TrialReadingCriterionId==inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView()
{
Id = taskConsistentRule.Id,
CreateTime = taskConsistentRule.CreateTime,
BlindTrialSiteCode = taskConsistentRule.BlindTrialSiteCode,
BlindSubjectNumberOfPlaces = taskConsistentRule.BlindSubjectNumberOfPlaces,
CreateUserId = taskConsistentRule.CreateUserId,
IntervalWeeks = taskConsistentRule.IntervalWeeks,
IsEnable = taskConsistentRule.IsEnable,
PlanSubjectCount = taskConsistentRule.PlanSubjectCount,
Note = taskConsistentRule.Note,
TrialId = taskConsistentRule.TrialId,
UpdateTime = taskConsistentRule.UpdateTime,
UpdateUserId = taskConsistentRule.UpdateUserId,
IsGenerateGlobalTask = taskConsistentRule.IsGenerateGlobalTask,
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
PlanVisitCount = taskConsistentRule.PlanVisitCount,
GeneratedSubjectCount = taskConsistentRule.Trial.VisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
AnalysisDoctorUser = new UserSimpleInfo()
{
UserId = user.Id,
UserCode = user.UserCode,
FullName = user.FullName,
UserName = user.UserName
}
};
//if (await _taskConsistentRuleRepository.AnyAsync(t => t.TrialId == inQuery.TrialId))
//{
// var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId).ProjectTo<TaskConsistentRuleBatchAddOrEdit>(_mapper.ConfigurationProvider).FirstAsync();
// rule.IsBatchAdd = true;
// await BatchAddOrUpdateTaskConsistentRule(rule);
//}
//#endregion
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
// .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);
return await taskConsistentRuleQueryable.ToListAsync();
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTaskConsistentRule(TaskConsistentRuleAddOrEdit addOrEditTaskConsistentRule)
{
var verifyExp1 = new EntityVerifyExp<TaskConsistentRule>()
{
VerifyExp = t => t.TrialId == addOrEditTaskConsistentRule.TrialId && t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialReadingCriterionId==addOrEditTaskConsistentRule.TrialReadingCriterionId,
//"已有该项目配置,不允许继续增加"
VerifyMsg = _localizer["TaskConsistent_TaskGenerated"]
};
if (await _visitTaskRepository.AnyAsync(t => t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialId == addOrEditTaskConsistentRule.TrialId && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId))
{
//"该标准已有Subject 生成了任务,不允许修改配置"
return ResponseOutput.NotOk(_localizer["TaskConsistent_MedicalAuditTaskExists"]);
}
var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString());
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpDelete("{taskConsistentRuleId:guid}")]
public async Task<IResponseOutput> DeleteTaskConsistentRule(Guid taskConsistentRuleId)
{
var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId);
if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.TrialId == config.TrialId && t.IsSelfAnalysis == config.IsSelfAnalysis && t.TrialReadingCriterionId==config.TrialReadingCriterionId))
{
//"该标准已产生一致性分析任务,不允许删除"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_SignedTaskCannotBeInvalidated"]);
}
var success = await _taskConsistentRuleRepository.DeleteFromQueryAsync(t => t.Id == taskConsistentRuleId, true);
return ResponseOutput.Ok();
}
}
}

View File

@ -34,8 +34,6 @@ namespace IRaCIS.Core.Application.Service
private readonly IEasyCachingProvider _provider;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
@ -51,10 +49,9 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<ClinicalDataTrialSet> _trialClinicalDataSetRepository;
private readonly IRepository<ReadingClinicalData> _readingClinicalDataRepository;
private readonly IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository;
public VisitTaskHelpeService(IRepository<VisitTask> visitTaskRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Trial> trialRepository, IEasyCachingProvider provider,
public VisitTaskHelpeService(IRepository<VisitTask> visitTaskRepository, IRepository<Trial> trialRepository, IEasyCachingProvider provider,
IRepository<SubjectVisit> subjectVisitRepository,
IRepository<ReadModule> readModuleRepository,
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
@ -63,9 +60,9 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
IRepository<ReadingJudgeInfo> readingJudgeInfoRepository,
IRepository<TaskAllocationRule> taskAllocationRuleRepository, IMapper mapper, IUserInfo userInfo, IRepository<VisitTaskReReading> visitTaskReReadingRepository,
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IRepository<ClinicalDataTrialSet> trialClinicalDataSetRepository, IRepository<ReadingClinicalData> readingClinicalDataRepository,
IRepository<SubjectCriteriaEvaluation> subjectCriteriaEvaluationRepository)
IMapper mapper, IUserInfo userInfo, IRepository<VisitTaskReReading> visitTaskReReadingRepository,
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IRepository<ClinicalDataTrialSet> trialClinicalDataSetRepository, IRepository<ReadingClinicalData> readingClinicalDataRepository
)
{
_readingClinicalDataRepository = readingClinicalDataRepository;
_trialClinicalDataSetRepository = trialClinicalDataSetRepository;
@ -81,12 +78,9 @@ namespace IRaCIS.Core.Application.Service
_provider = provider;
_subjectVisitRepository = subjectVisitRepository;
this._readingJudgeInfoRepository = readingJudgeInfoRepository;
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_subjectUserRepository = subjectUserRepository;
_mapper = mapper;
_userInfo = userInfo;
_visitTaskReReadingRepository = visitTaskReReadingRepository;
_subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository;
_trialReadingCriterionRepository = trialReadingCriterionRepository;
}
@ -186,7 +180,6 @@ namespace IRaCIS.Core.Application.Service
foreach (var subjectGroup in needGenerateVisit.GroupBy(t => t.SubjectId).Select(g => new { SubjectId = g.Key, SubjectVisitList = g.ToList() }))
{
var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectGroup.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync();
@ -314,24 +307,6 @@ namespace IRaCIS.Core.Application.Service
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
task1.TaskAllocationState = defaultState;
//分配给对应Arm的人
task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId;
task1.AllocateTime = DateTime.Now;
task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
task2.TaskAllocationState = defaultState;
task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId;
task2.AllocateTime = DateTime.Now;
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single)
{
@ -374,20 +349,6 @@ namespace IRaCIS.Core.Application.Service
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm))
{
singleTask.TaskAllocationState = defaultState;
singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId;
singleTask.AllocateTime = DateTime.Now;
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
await _visitTaskRepository.SaveChangesAsync();
@ -655,7 +616,7 @@ namespace IRaCIS.Core.Application.Service
{
var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync();
//var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync();
var blindTaskName = string.Empty;
@ -771,269 +732,7 @@ namespace IRaCIS.Core.Application.Service
}
else
{
//并且配置了医生
if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign)
{
#region 后续访视 未分配的进行再次分配,重置的或者失效的 需要重新生成新的任务 (PM 有序退回 或者PM 有序 申请重阅)
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder)
{
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//之前有回退的,那么当前访视任务生成但是不分配
if (beforeBackVisitTask != null)
{
//不用进行额外处理
//访视2 PM 回退 基线回退 访视2先一致性核查通过生成访视2任务但是不分配
}
else
{
#region 当前访视根据配置规则分配出去
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
task1.TaskAllocationState = defaultState;
//分配给对应Arm的人
task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId;
task1.AllocateTime = DateTime.Now;
task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
task2.TaskAllocationState = defaultState;
task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId;
task2.AllocateTime = DateTime.Now;
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
#endregion
}
//后续最近的未一致性核查通过的访视任务
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成
//存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过但是访视1还未通过时 生成任务
var followVisitTaskList = await _visitTaskRepository
.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
.WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum)
.ToListAsync();
var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum);
//每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置需要重新生成)
foreach (var visitGroup in followVisitGroup)
{
var visit = await _subjectVisitRepository.Where(x => x.Id == visitGroup.First().SourceSubjectVisitId).Select(x => new
{
x.PDState,
x.IsEnrollmentConfirm,
x.IsUrgent,
}).FirstNotNullAsync();
TaskUrgentType? urgentType = null;
if (subjectVisitInfo.PDState == PDStateEnum.PDProgress)
{
urgentType = TaskUrgentType.PDProgress;
}
else if (subjectVisitInfo.IsEnrollmentConfirm)
{
urgentType = TaskUrgentType.EnrollmentConfirm;
}
else if (subjectVisitInfo.IsUrgent)
{
urgentType = TaskUrgentType.VisitUrgent;
}
bool isCanEdit = urgentType == TaskUrgentType.EnrollmentConfirm || urgentType == TaskUrgentType.PDProgress ? false : true;
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm1))
{
//不做处理
}
else
{
var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1);
if (arm1 != null)
{
//有可能仅仅只分配了一个Subject 未分配 那么
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
arm1.IsUrgent = visit.IsUrgent;
arm1.TaskUrgentType = urgentType;
arm1.IsCanEditUrgentState = isCanEdit;
arm1.TaskAllocationState = TaskAllocationState.Allocated;
arm1.AllocateTime = DateTime.Now;
arm1.DoctorUserId = task1.DoctorUserId;
arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First();
var taskOne = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
ArmEnum = Arm.DoubleReadingArm1,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TaskAllocationState = TaskAllocationState.Allocated,
AllocateTime = DateTime.Now,
DoctorUserId = task1.DoctorUserId,
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm2))
{
//不做处理
}
else
{
var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2);
if (arm2 != null)
{
//有可能仅仅只分配了一个Subject
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
arm2.IsUrgent = visit.IsUrgent;
arm2.TaskUrgentType = urgentType;
arm2.IsCanEditUrgentState = isCanEdit;
arm2.TaskAllocationState = TaskAllocationState.Allocated;
arm2.AllocateTime = DateTime.Now;
arm2.DoctorUserId = task2.DoctorUserId;
arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First();
var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
//CheckPassedTime = subjectVisit.CheckPassedTime,
ArmEnum = Arm.DoubleReadingArm2,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TaskAllocationState = TaskAllocationState.Allocated,
AllocateTime = DateTime.Now,
DoctorUserId = task2.DoctorUserId,
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
}
}
//无序的时候 生成任务并分配出去
else
{
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
task1.TaskAllocationState = defaultState;
//分配给对应Arm的人
task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId;
task1.AllocateTime = DateTime.Now;
task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
task2.TaskAllocationState = defaultState;
task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId;
task2.AllocateTime = DateTime.Now;
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
#endregion
}
else
//后续访视不自动分配,或者配置的医生数量不足,就不进行分配
{
}
}
@ -1101,148 +800,7 @@ namespace IRaCIS.Core.Application.Service
//}
//配置了医生
if (assignConfigList.Count > 0)
{
#region 重阅/退回的时候,需要将取消分配的访视类型的 任务重新分配
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder)
{
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
if (beforeBackVisitTask == null)
{
#region 访视2 PM 回退 基线回退 访视2先一致性核查通过生成访视2任务但是不分配
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm))
{
singleTask.TaskAllocationState = defaultState;
singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId;
singleTask.AllocateTime = DateTime.Now;
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
#endregion
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过但是访视1还未通过时 生成任务
var followVisitTaskList = await _visitTaskRepository
.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
.WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum)
.ToListAsync();
var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum);
//每个访视去判断 是分配还是生成
foreach (var visitGroup in followVisitGroup)
{
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.SingleReadingArm))
{
//不做处理
}
else
{
var arm = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.SingleReadingArm);
if (arm != null)
{
arm.TaskAllocationState = TaskAllocationState.Allocated;
arm.AllocateTime = DateTime.Now;
arm.DoctorUserId = singleTask.DoctorUserId;
arm.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.SingleReadingArm).OrderByDescending(t => t.CreateTime).First();
var taskOne = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = subjectVisit.IsUrgent,
ArmEnum = Arm.SingleReadingArm,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
TaskUrgentType = latestTask.TaskUrgentType,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TaskAllocationState = TaskAllocationState.Allocated,
AllocateTime = DateTime.Now,
DoctorUserId = singleTask.DoctorUserId,
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
}
}
//之前有回退的 后续访视不生成或者分配 当前访视生成但是不分配出去
else
{
//不用进行额外处理
}
}
//无序的时候 生成任务并分配出去
else
{
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm))
{
singleTask.TaskAllocationState = defaultState;
singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId;
singleTask.AllocateTime = DateTime.Now;
singleTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
#endregion
}
}
}
else
@ -1493,7 +1051,7 @@ namespace IRaCIS.Core.Application.Service
case GenerateTaskCategory.Judge:
var firstTask = await _visitTaskRepository.Where(x => generateTaskCommand.JudgeVisitTaskIdList.Contains(x.Id)).FirstOrDefaultAsync();
var subjectUser = await _subjectUserRepository.Where(x => x.SubjectId == firstTask.SubjectId && x.ArmEnum == Arm.JudgeArm && x.IsConfirmed && x.TrialReadingCriterionId == firstTask.TrialReadingCriterionId).FirstOrDefaultAsync();
VisitTask visitTask = new VisitTask()
{
@ -1512,10 +1070,6 @@ namespace IRaCIS.Core.Application.Service
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
TaskState = TaskState.Effect,
TaskBlindName = firstTask.TaskBlindName,
DoctorUserId = subjectUser == null ? null : subjectUser.DoctorUserId,
TaskAllocationState = subjectUser == null ? TaskAllocationState.NotAllocate : TaskAllocationState.Allocated,
AllocateTime = subjectUser == null ? null : DateTime.Now,
SuggesteFinishedTime = subjectUser == null ? null : GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = firstTask.TrialReadingCriterionId,
@ -1598,8 +1152,7 @@ namespace IRaCIS.Core.Application.Service
foreach (var item in generateTaskCommand.ReadingGenerataTaskList)
{
//需要 根据标准筛选
var oncologySubjectUser = await _subjectUserRepository.Where(x => x.SubjectId == item.SubjectId && x.ArmEnum == Arm.TumorArm && x.IsConfirmed && x.TrialReadingCriterionId == originalTaskInfo.TrialReadingCriterionId).FirstOrDefaultAsync();
item.VisitNum = await _readModuleRepository.Where(x => x.Id == item.ReadModuleId).Select(x => x.SubjectVisit.VisitNum).FirstOrDefaultAsync();
@ -1618,10 +1171,7 @@ namespace IRaCIS.Core.Application.Service
SouceReadModuleId = item.ReadModuleId,
TaskBlindName = item.ReadingName,
DoctorUserId = oncologySubjectUser == null ? null : oncologySubjectUser.DoctorUserId,
AllocateTime = oncologySubjectUser == null ? null : DateTime.Now,
TaskAllocationState = oncologySubjectUser == null ? TaskAllocationState.NotAllocate : TaskAllocationState.Allocated,
SuggesteFinishedTime = oncologySubjectUser == null ? null : GetSuggessFinishTime(true, UrgentType.NotUrget),
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = item.ReadingCategory,

View File

@ -37,9 +37,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;
@ -47,43 +45,34 @@ namespace IRaCIS.Core.Application.Service.Allocation
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingClinicalData> _readingClinicalDataReposiotry;
private readonly IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitFilter> _subjectCriteriaEvaluationVisitFilterRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository;
private readonly IRepository<PIAudit> _PIAuditRepository;
public VisitTaskService(IRepository<SubjectVisit> subjectVisitRepository, IRepository<VisitTask> visitTaskRepository, IRepository<Trial> trialRepository,
IRepository<Subject> subjectRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<TaskAllocationRule> taskAllocationRuleRepository,
IRepository<Subject> subjectRepository,
IRepository<ReadModule> readModuleRepository, IRepository<VisitTaskReReading> visitTaskReReadingRepository,
IRepository<TaskMedicalReview> taskMedicalReviewRepository,
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository
, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
IRepository<ReadingClinicalData> readingClinicalDataReposiotry,
IRepository<SubjectCriteriaEvaluation> subjectCriteriaEvaluationRepository,
IRepository<SubjectCriteriaEvaluationVisitFilter> subjectCriteriaEvaluationVisitFilterRepository,
IRepository<SubjectCriteriaEvaluationVisitStudyFilter> subjectCriteriaEvaluationVisitStudyFilterRepository,
IRepository<PIAudit> PIAuditRepository
)
{
_PIAuditRepository = PIAuditRepository;
_readingClinicalDataReposiotry = readingClinicalDataReposiotry;
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_visitTaskRepository = visitTaskRepository;
_trialRepository = trialRepository;
_subjectVisitRepository = subjectVisitRepository;
_subjectRepository = subjectRepository;
_subjectUserRepository = subjectUserRepository;
_readModuleRepository = readModuleRepository;
_visitTaskReReadingRepository = visitTaskReReadingRepository;
_taskMedicalReviewRepository = taskMedicalReviewRepository;
_readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
_trialReadingCriterionRepository = trialReadingCriterionRepository;
_subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository;
_subjectCriteriaEvaluationVisitFilterRepository = subjectCriteriaEvaluationVisitFilterRepository;
_subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository;
}
/// <summary>
@ -1196,7 +1185,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
await SetMedicalReviewInvalidAsync(influenceTaskList, false);
await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => (Guid)t.SourceSubjectVisitId).Distinct().ToList(), false);
}
@ -1597,7 +1586,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
if (influenceTask.Id == task.Id)
{
await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => (Guid)t.SourceSubjectVisitId).Distinct().ToList());
await SetReReadingOrBackInfluenceAnalysisAsync(influenceTask.SubjectId);
@ -1675,65 +1664,7 @@ namespace IRaCIS.Core.Application.Service.Allocation
}
/// <summary>
/// 基线退回 影响附加评估标准 是否参与评估
/// </summary>
/// <returns></returns>
private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List<Guid> otherVisitIdList, bool isImageBack = true)
{
var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId);
if (criterion.CriterionType == CriterionType.RECIST1Point1)
{
//影像回退了|| IR 申请及基线重阅
if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine))
{
await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation()
{
IsJoinEvaluation = false
});
//删除筛选的访视数据
await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId);
//删除筛选的序列数据
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId);
}
else if (isImageBack)
{
//当前访视筛选状态重置,任务生成状态重置
if (task.SourceSubjectVisitId != null)
{
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId,
t => new SubjectCriteriaEvaluationVisitFilter()
{
ImageFilterState = ImageFilterState.None,
ImageDeterminationResultState = ImageDeterminationResultState.None,
IsGeneratedTask = false
});
//删除序列数据
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId);
}
//BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配)
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId),
t => new SubjectCriteriaEvaluationVisitFilter()
{
IsGeneratedTask = false
});
}
else
{
//IR 端 非基线申请重阅 不影响
}
}
}
//包括临床数据签名状态
private async Task VisitBackAsync(Guid? subjectVisitId)

View File

@ -18,93 +18,30 @@ namespace IRaCIS.Core.Application.Service
CreateMap<ConvertedRowInfo, ReadingTableAnswerRowInfo>();
CreateMap<TaskAllocationRule, TaskAllocationRuleView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
List<Guid> subjectIdList = new List<Guid>();
bool isJudgeDoctor = false;
CreateMap<TaskAllocationRule, DoctorVisitTaskStatView>()
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName))
//.ForMember(o => o.ArmList, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(c => c.TrialId == u.TrialId).Select(t => t.ArmEnum).Distinct()))
.ForMember(o => o.TotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count()))
.ForMember(o => o.SelfUndoTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId == u.DoctorUserId && t.ReadingTaskState != ReadingTaskState.HaveSigned)))
.ForMember(o => o.TotalSubjectCount, t => t.MapFrom(u => u.Trial.SubjectList.Count()))
.ForMember(o => o.SelfApplyedTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId == u.DoctorUserId)))
.ForMember(o => o.ApplyedTotalTaskCount, t => t.MapFrom(u => u.Trial.VisitTaskList.Count(t => t.DoctorUserId != null)))
//.ForMember(o => o.SelfApplyedSubjectCount, t => t.MapFrom(u => u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && t.SubjectArmVisitTaskList.Any(c => c.DoctorUserId != null)).Count()))
.ForMember(o => o.SelfSubjectCount, t => t.MapFrom(u => u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId).Count()))
.ForMember(o => o.ApplyedTotalSubjectCount, t => t.MapFrom(u => u.Trial.SubjectList.Count(c => c.SubjectVisitTaskList.Any(d => d.DoctorUserId != null))))
//该医生未应用Subject 数量
//.ForMember(o => o.WaitApplySelfSubjectCount, t => t.MapFrom(u =>
// subjectIdList.Count == 0 ? u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
// : u.Trial.SubjectDoctorUserList.Where(t => t.DoctorUserId == u.DoctorUserId && subjectIdList.Contains(t.SubjectId) && t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
// ))
.ForMember(o => o.WaitApplyTotalSubjectCount, t => t.MapFrom(u =>
subjectIdList.Count == 0 ? u.Trial.SubjectList.Where(t => t.SubjectVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
: u.Trial.SubjectList.Where(t => subjectIdList.Contains(t.Id) && t.SubjectVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any(c => c.DoctorUserId == null)).Count()
))
//.ForMember(o => o.WaitApplySelfTaskCount, t => t.MapFrom(u =>
//subjectIdList.Count == 0 ? u.Trial.SubjectDoctorUserList.Where(d => d.DoctorUserId == u.DoctorUserId).SelectMany(t => t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null)).Count()
//: u.Trial.SubjectDoctorUserList.Where(d => d.DoctorUserId == u.DoctorUserId && subjectIdList.Contains(d.SubjectId)).SelectMany(t => t.SubjectArmVisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null)).Count()
// ))
.ForMember(o => o.WaitApplyTotalTaskCount, t => t.MapFrom(u =>
subjectIdList.Count == 0 ? u.Trial.VisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null).Count()
: u.Trial.VisitTaskList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.DoctorUserId == null && subjectIdList.Contains(t.SubjectId)).Count()))
;
var trialReadingCriterionId = Guid.Empty;
CreateMap<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser))
.ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId })))
.ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm)))
.ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList()))
;
CreateMap<ReadingQuestionCriterionTrial, TrialReadingCriterionDto>()
.ForMember(t => t.TrialReadingCriterionId, u => u.MapFrom(c => c.Id))
.ForMember(t => t.TrialReadingCriterionName, u => u.MapFrom(c => c.CriterionName));
CreateMap<TaskAllocationRule, AssignDoctorStatView>().IncludeBase<TaskAllocationRule, TaskAllocationRuleDTO>()
.ForMember(o => o.AssignedSubjectCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Select(t => t.SubjectId).Distinct().Count()))
.ForMember(o => o.WaitDealTrialTaskCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect).Count()))
.ForMember(o => o.WaitDealAllTaskCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect).Count()));
CreateMap<Subject, SubjectAssignStat>()
.ForMember(o => o.SubjectId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Code))
.ForMember(o => o.VisitTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.TrialReadingCriterionId==trialReadingCriterionId && t.TaskState==TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.VisitTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Visit && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.GlobalTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.OncologyTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Oncology && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.JudgeTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()))
.ForMember(o => o.DoctorUserList, t => t.MapFrom(u => u.SubjectDoctorList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId)));
.ForMember(o => o.JudgeTaskTypeCount, t => t.MapFrom(u => u.SubjectVisitTaskList.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect).Select(t => t.VisitTaskNum).Distinct().Count()));
CreateMap<SubjectUser, SubjectUserView>()
.ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.DoctorUser));
CreateMap<SubjectUser, SubjectUserDTO>().IncludeBase<SubjectUser, SubjectUserView>()
.ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId)));
CreateMap<SubjectVisit, VisitGenerataTaskDTO>();
@ -154,9 +91,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<CancelDoctorCommand, SubjectCanceDoctor>();
CreateMap<SubjectCanceDoctor, SubjectCancelDoctorView>();
@ -189,22 +124,17 @@ namespace IRaCIS.Core.Application.Service
.ForMember(o => o.SubjectId, t => t.MapFrom(u => u.Id))
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.TrialSite.TrialSiteCode))
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Code))
.ForMember(o => o.IsJudge, t => t.MapFrom(u => isJudgeDoctor))
.ForMember(o => o.IsAssignedDoctorUser, t => t.MapFrom(u => u.SubjectDoctorList.Where(t => isJudgeDoctor ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Any()))
.ForMember(o => o.IsJudge, t => t.MapFrom(u => isJudgeDoctor));
.ForMember(o => o.TotalDoctorUserList, t => t.MapFrom(u => u.SubjectDoctorList.Where(t => isJudgeDoctor ? true : t.ArmEnum != Arm.JudgeArm).OrderBy(t => t.ArmEnum)));
CreateMap<SubjectUser, AssignDoctorView>()
//.ForMember(o => o.AssignTime, t => t.MapFrom(u => u.AssignTime))
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
CreateMap<TaskAllocationRuleAddOrEdit, TaskAllocationRule>();
CreateMap<User, TrialDoctorUserSelectView>()
@ -292,11 +222,6 @@ namespace IRaCIS.Core.Application.Service
//CreateMap<TaskConsistentRule, TaskConsistentRuleView>()
// .ForMember(o => o.GeneratedSubjectCount, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(t => t.IsAnalysisCreate && t.TaskConsistentRuleId == u.Id).Select(t => t.SubjectId).Distinct().Count())) ;
CreateMap<TaskConsistentRule, TaskConsistentRuleBasic>();
CreateMap<TaskConsistentRuleAddOrEdit, TaskConsistentRule>();
CreateMap<TaskConsistentRuleBatchAddOrEdit, TaskConsistentRule>().ForMember(t => t.Id, u => u.Ignore()).ReverseMap();
CreateMap<VisitTask, VisitTaskSimpleView>()

View File

@ -16,9 +16,7 @@ namespace IRaCIS.Application.Services
public class DictionaryService : BaseService, IDictionaryService
{
private readonly IRepository<Dictionary> _dicRepository;
private readonly IRepository<DoctorDictionary> _doctorDictionaryRepository;
private readonly IRepository<TrialDictionary> _trialDictionaryRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCodeRepository;
private readonly IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCodeRepository;
@ -29,8 +27,8 @@ namespace IRaCIS.Application.Services
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
private readonly IReadingQuestionService _readingQuestionService;
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<DoctorDictionary> doctorDictionaryRepository, IRepository<TrialDictionary> trialDictionaryRepository,
IRepository<Doctor> doctorRepository, IRepository<Trial> trialRepository,
public DictionaryService(IRepository<Dictionary> sysDicRepository, IRepository<TrialDictionary> trialDictionaryRepository,
IRepository<Trial> trialRepository,
IRepository<SystemCriterionDictionaryCode> systemCriterionDictionaryCodeRepository,
IRepository<TrialCriterionDictionaryCode> trialCriterionDictionaryCodeRepository,
@ -44,9 +42,9 @@ namespace IRaCIS.Application.Services
)
{
_dicRepository = sysDicRepository;
_doctorDictionaryRepository = doctorDictionaryRepository;
_trialDictionaryRepository = trialDictionaryRepository;
_doctorRepository = doctorRepository;
_trialRepository = trialRepository;
this._systemCriterionDictionaryCodeRepository = systemCriterionDictionaryCodeRepository;
this._trialCriterionDictionaryCodeRepository = trialCriterionDictionaryCodeRepository;
@ -229,14 +227,6 @@ namespace IRaCIS.Application.Services
return ResponseOutput.NotOk(_localizer["Dictionary_SubitemDeletion"]);
}
if ((await _doctorDictionaryRepository.AnyAsync(t => t.DictionaryId == id)) ||
(await _doctorRepository.AnyAsync(t => t.SpecialityId == id || t.PositionId == id || t.DepartmentId == id || t.RankId == id))
)
{
//---当前条目已经在阅片人的简历中被引用。
return ResponseOutput.NotOk(_localizer["Dictionary_ResumeReference"]);
}
if (await _trialDictionaryRepository.AnyAsync(t => t.DictionaryId == id) ||
await _trialRepository.AnyAsync(t => t.ReviewModeId == id))

View File

@ -11,180 +11,25 @@ namespace IRaCIS.Application.Services
public class FileService : IFileService
{
private readonly IDoctorService _doctorService;
private readonly IAttachmentService _attachmentService;
private readonly IWebHostEnvironment _hostEnvironment;
private string defaultUploadFilePath = string.Empty;
private readonly ILogger<FileService> _logger;
public FileService(IDoctorService doctorService, IAttachmentService attachmentService,
public FileService(
IWebHostEnvironment hostEnvironment, ILogger<FileService> logger)
{
_doctorService = doctorService;
_attachmentService = attachmentService;
_hostEnvironment = hostEnvironment;
defaultUploadFilePath = FileStoreHelper.GetIRaCISRootPath(_hostEnvironment);
_logger = logger;
}
/// <summary>
/// 打包医生官方简历
/// </summary>
/// <param name="language"></param>
/// <param name="doctorIds"></param>
/// <returns></returns>
public async Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds)
{
//准备下载文件的临时路径
var guidStr = Guid.NewGuid().ToString();
string uploadFolderPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "UploadFile");
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
if (!Directory.Exists(tempSavePath))
{
Directory.CreateDirectory(tempSavePath);
}
//找到服务器简历路径 循环拷贝简历到临时路径
foreach (var doctorId in doctorIds)
{
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
//找官方简历存在服务器的相对路径
var sourceCvPath = await _attachmentService.GetDoctorOfficialCV(language, doctorId);
if (!string.IsNullOrWhiteSpace(sourceCvPath))
{
//服务器简历文件实际路径
//var sourceCvFullPath = HostingEnvironment.MapPath(sourceCvPath);
var sourceCvPathTemp = sourceCvPath.Substring(1, sourceCvPath.Length - 1);//.Replace('/','\\');
string sourceCvFullPath = Path.Combine(defaultUploadFilePath, sourceCvPathTemp);
var arr = sourceCvPath.Split('.');
string extensionName = arr[arr.Length - 1]; //得到扩展名
//需要拷贝到的路径
var doctorPath = Path.Combine(tempSavePath, doctor.ReviewerCode.ToString() + "_" + doctorName + "." + extensionName);
if (File.Exists(sourceCvFullPath))
{
File.Copy(sourceCvFullPath, doctorPath, true);
}
}
}
//创建ZIP
DateTime now = DateTime.Now;
StringBuilder sb = new StringBuilder();
sb.Append(now.Year).Append(now.Month.ToString().PadLeft(2, '0')).Append(now.Day.ToString().PadLeft(2, '0'))
.Append(now.Hour.ToString().PadLeft(2, '0')).Append(now.Minute.ToString().PadLeft(2, '0'))
.Append(now.Second.ToString().PadLeft(2, '0')).Append(now.Millisecond.ToString().PadLeft(3, '0'));
string targetZipPath = Path.Combine(uploadFolderPath, "CV_" + sb.ToString() + ".zip");
ZipHelper.CreateZip(tempSavePath, targetZipPath);
//返回Zip路径
return Path.Combine("/IRaCISData/UploadFile/", "CV_" + sb.ToString() + ".zip");
}
/// <summary>
/// 打包医生的所有附件
/// </summary>
/// <param name="doctorIds"></param>
/// <returns></returns>
public async Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds)
{
//准备下载文件的临时路径
var guidStr = Guid.NewGuid().ToString();
//string uploadFolderPath = HostingEnvironment.MapPath("/UploadFile/");
string uploadFolderPath = Path.Combine(FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment), "UploadFile");
var tempSavePath = Path.Combine(uploadFolderPath, "temp", guidStr); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
if (!Directory.Exists(tempSavePath))
{
Directory.CreateDirectory(tempSavePath);
}
foreach (var doctorId in doctorIds)
{
//获取医生基本信息
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
var doctorCode = doctor.ReviewerCode;
var doctorDestPath = Path.Combine(tempSavePath, doctorCode + "_" + doctorName);
if (!Directory.Exists(doctorDestPath))
{
Directory.CreateDirectory(doctorDestPath);
}
//服务器上传后的源路径
string doctorFileSourcePath = Path.Combine(uploadFolderPath, doctorId.ToString());
if (Directory.Exists(doctorFileSourcePath))
{
CopyDirectory(doctorFileSourcePath, doctorDestPath);
}
}
string target = Guid.NewGuid().ToString();
string targetPath = Path.Combine(uploadFolderPath, target + ".zip");
ZipHelper.CreateZip(tempSavePath, targetPath);
return Path.Combine("/IRaCISData/UploadFile/", target + ".zip");
}
public async Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds)
{
var doctor = await _doctorService.GetBasicInfo(doctorId);
var doctorName = doctor.FirstName + "_" + doctor.LastName;
Guid temp = Guid.NewGuid();
//string root = HostingEnvironment.MapPath("/UploadFile/"); //文件根目录
string root = Path.Combine(defaultUploadFilePath, "UploadFile");
var tempPath = Path.Combine(root, "temp", temp.ToString(), doctor.ReviewerCode + doctorName); //待压缩的文件夹,将需要下载的文件拷贝到此文件夹
var packagePath = Path.Combine(root, "temp", temp.ToString()); //打包目录
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
var attachemnts = (await _attachmentService.GetAttachments(doctorId)).Where(a => attachmentIds.Contains(a.Id));
foreach (var item in attachemnts)
{
var arr = item.Path.Trim().Split('/');
var myPath = string.Empty;
var myFile = string.Empty;
//需要改进
if (arr.Length > 0)
{
myFile = arr[arr.Length - 1];
foreach (var arrItem in arr)
{
if (arrItem != string.Empty && !"UploadFile".Equals(arrItem))
{
myPath += (arrItem + "/");
}
}
myPath = myPath.TrimEnd('/');
}
var sourcePath = Path.Combine(root, myPath);
if (!string.IsNullOrWhiteSpace(sourcePath) && File.Exists(sourcePath))
{
File.Copy(sourcePath, Path.Combine(tempPath, myFile), true);
}
}
string target = Guid.NewGuid().ToString();
string targetPath = Path.Combine(root, target + ".zip");
ZipHelper.CreateZip(packagePath, targetPath);
return Path.Combine("/IRaCISData/UploadFile/", target + ".zip");
}
private static void CopyDirectory(string srcPath, string destPath)
{

View File

@ -8,10 +8,10 @@ namespace IRaCIS.Application.Interfaces
//IResponseOutput<UploadFileInfo> DownloadOfficialResume(Guid[] doctorIds);
Task<string> CreateOfficialResumeZip(int language, Guid[] doctorIds);
Task<string> CreateDoctorsAllAttachmentZip(Guid[] doctorIds);
Task<string> CreateZipPackageByAttachment(Guid doctorId, Guid[] attachmentIds);
}
}

View File

@ -32,7 +32,7 @@ namespace IRaCIS.Application.Services
Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl);
}
@ -53,7 +53,7 @@ namespace IRaCIS.Application.Services
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<UserType> _userTypeRepository;
private readonly IRepository<Doctor> _doctorTypeRepository;
private readonly AsyncLock _mutex = new AsyncLock();
@ -68,7 +68,6 @@ namespace IRaCIS.Application.Services
ITokenService tokenService,
IRepository<Trial> trialRepository,
IRepository<UserType> userTypeRepository,
IRepository<Doctor> doctorTypeRepository,
IMapper mapper, IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig)
{
_systemEmailConfig = systemEmailConfig.CurrentValue;
@ -84,7 +83,6 @@ namespace IRaCIS.Application.Services
_trialRepository = trialRepository;
_userTypeRepository = userTypeRepository;
_doctorTypeRepository = doctorTypeRepository;
}
@ -598,122 +596,6 @@ namespace IRaCIS.Application.Services
}
//医生生成账号加入 或者已存在账号加入到项目中
public async Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl)
{
var doctor = await _doctorTypeRepository.FindAsync(doctorId);
User sysUserInfo = null;
var userType = await _userTypeRepository.FirstAsync(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer);
using (await _mutex.LockAsync())
{
var isDoctorHaveAccount = await _userRepository.AnyAsync(t => t.DoctorId == doctorId);
if (!isDoctorHaveAccount)
{
var saveItem = new User() { FirstName = doctor.FirstName, LastName = doctor.LastName, EMail = doctor.EMail };
var trialType = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefaultAsync();
if (trialType == TrialType.NoneOfficial)
{
saveItem.IsTestUser = true;
}
saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User));
saveItem.UserName = saveItem.UserCode;
saveItem.UserTypeEnum = UserTypeEnum.IndependentReviewer;
saveItem.DoctorId = doctorId;
saveItem.UserTypeId = userType.Id;
var savedUser = await _userRepository.AddAsync(saveItem);
//下面获取Token 需要这部分信息
sysUserInfo = savedUser.Clone();
sysUserInfo.UserTypeRole = userType;
await _userRepository.SaveChangesAsync();
}
else
{
sysUserInfo = (await _userRepository.Where(t => t.DoctorId == doctorId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
}
}
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail));
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
messageToSend.Subject = _localizer["Mail_InvitationEmail", trialInfo.ResearchProgramNo];
var builder = new BodyBuilder();
var basicInfo = IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo));
////第一次添加的时候 注意赋值
//basicInfo.PermissionStr = userType.PermissionStr;
//basicInfo.UserTypeShortName = userType.UserTypeShortName;
var token = _tokenService.GetToken(basicInfo);
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
}
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ (sysUserInfo.IsFirstAdd ? (_userInfo.IsEn_Us ? "TrialDoctorFirstJoin_US.html" : "TrialDoctorFirstJoin.html") : (_userInfo.IsEn_Us ? "TrialDoctorExistJoin_US.html" : "TrialDoctorExistJoin.html") );
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
userType.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null);
return sysUserInfo.Id;
}

View File

@ -1,254 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
/// <summary>
/// 医生文档关联关系维护
/// </summary>
[ApiExplorerSettings(GroupName = "Reviewer")]
public class AttachmentService : BaseService, IAttachmentService
{
private readonly IRepository<Attachment> _attachmentrepository;
public AttachmentService(IRepository<Attachment> attachmentrepository)
{
this._attachmentrepository = attachmentrepository;
}
/// <summary>
/// 删除附件
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<IResponseOutput> DeleteAttachment([FromBody]AttachementCommand param)
{
//var attachment = _doctorAttachmentApp.GetDetailById(id);
//string file = HostingEnvironment.MapPath(attachment.Path);
//if (File.Exists(file))
//{
// File.Delete(file);
//}
//var temp = HostingEnvironment.MapPath(param.Path);
//if (File.Exists(temp))
//{
// File.Delete(temp);
//}
var success =await _attachmentrepository.BatchDeleteNoTrackingAsync(a => a.Id == param.Id);
return ResponseOutput.Result(success);
}
/// <summary>
/// 根据医生Id 和 附件类型,获取记录
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <param name="type">附件类型</param>
/// <returns></returns>
[HttpGet("{doctorId:guid}/{type}")]
public async Task<IEnumerable<AttachmentDTO>> GetAttachmentByType(Guid doctorId, string type)
{
var attachmentList = await _attachmentrepository.Where(a => a.DoctorId == doctorId && a.Type.Equals(type)).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
return attachmentList;
}
/// <summary>
/// 获取单个医生的多种证书附件
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <param name="types">类型数组</param>
/// <returns></returns>
[HttpPost("{doctorId:guid}")]
public async Task<IEnumerable<AttachmentDTO>> GetAttachmentByTypes(Guid doctorId, string[] types)
{
var attachmentList =await _attachmentrepository.Where(a => a.DoctorId == doctorId && types.Contains(a.Type)).OrderBy(s => s.Type).ThenBy(m => m.CreateTime).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
return attachmentList;
}
/// <summary>
/// 根据医生Id获取医生附件
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <returns></returns>
[HttpGet("{doctorId:guid}")]
public async Task<IEnumerable<AttachmentDTO>> GetAttachments(Guid doctorId)
{
var attachmentList =await _attachmentrepository.Where(a => a.DoctorId == doctorId).OrderBy(s => s.Type).ThenBy(m => m.CreateTime).ProjectTo<AttachmentDTO>(_mapper.ConfigurationProvider).ToListAsync();
attachmentList.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
return attachmentList;
}
[NonDynamicMethod]
public async Task<AttachmentDTO> GetDetailById(Guid attachmentId)
{
var attachment = await _attachmentrepository.FirstOrDefaultAsync(a => a.Id == attachmentId).IfNullThrowException();
var temp= _mapper.Map<AttachmentDTO>(attachment);
temp.FullPath = temp.Path + "?access_token=" + _userInfo.UserToken;
return temp;
}
/// <summary>
/// 保存多个附件
/// </summary>
/// <param name="attachmentList"></param>
/// <returns></returns>
public async Task<IEnumerable<AttachmentDTO>> SaveAttachments(IEnumerable<AttachmentDTO> attachmentList)
{
var attachments = _mapper.Map<IEnumerable<Attachment>>(attachmentList).ToList();
//1 是中文 2是英文 中英文第一份简历默认设置为官方
var zhCount = attachments.Count(t => t.Language == 1);
var usCount = attachments.Count(t => t.Language == 2);
if (zhCount == 1)
{
var k = attachments.First(t => t.Language == 1);
k.IsOfficial = true;
}
if (usCount == 1)
{
var k = attachments.First(t => t.Language == 2);
k.IsOfficial = true;
}
//处理重传
var reUpload = attachmentList.FirstOrDefault(t => t.ReUpload == true);
if (reUpload != null)
{
//因为界面现实的列表用了 接口返回的列表,所以要把返回的模型对应的字段也要更改
var attach = attachments.First(t => t.Id == reUpload.Id);
attach.CreateTime = DateTime.Now;
//重传的时候,发现 相同语言的官方简历数量为2 那么将重传的简历设置为非官方
if (attachments.Count(t => t.Language == reUpload.Language && t.IsOfficial) == 2)
{
await _attachmentrepository.BatchUpdateNoTrackingAsync(t => t.Id == reUpload.Id, u => new Attachment()
{
Path = reUpload.Path,
CreateTime = DateTime.Now,
Language = reUpload.Language,
IsOfficial = false
});
attach.IsOfficial = false;
}
else //相同语言的重传
{
await _attachmentrepository.BatchUpdateNoTrackingAsync(t => t.Id == reUpload.Id, u => new Attachment()
{
Path = reUpload.Path,
CreateTime = DateTime.Now,
Language = reUpload.Language
});
}
}
var newAttachment = attachments.Where(t => t.Id == Guid.Empty);
await _repository.AddRangeAsync(newAttachment);
await _repository.SaveChangesAsync();
//_doctorAttachmentRepository.AddRange(newAttachment);
//_doctorAttachmentRepository.SaveChanges();
var list = _mapper.Map<IEnumerable<AttachmentDTO>>(attachments).ToList();
list.ForEach(t => t.FullPath = t.Path + "?access_token=" + _userInfo.UserToken);
return list;
}
public async Task<IResponseOutput<AttachmentDTO>> AddAttachment(AttachmentDTO attachment)
{
var newAttachment = _mapper.Map<Attachment>(attachment);
//如果这个医生不存在 这个语言的官方简历 就设置为官方简历
if (! await _attachmentrepository.AnyAsync(t => t.Type == "Resume" && t.DoctorId == attachment.DoctorId && t.Language == attachment.Language && t.IsOfficial))
{
newAttachment.IsOfficial = true;
attachment.IsOfficial = true;
}
await _repository.AddAsync(newAttachment);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, attachment);
}
[NonDynamicMethod]
public async Task<string> GetDoctorOfficialCV(int language, Guid doctorId)
{
var result = await _attachmentrepository.FirstOrDefaultAsync(a => a.DoctorId == doctorId &&
a.IsOfficial && a.Type.Equals("Resume") && a.Language == language);
if (result != null)
{
return result.Path;
}
return string.Empty;
}
/// <summary>
/// 将简历设置为官方简历
/// </summary>
/// <param name="doctorId"></param>
/// <param name="attachmentId"></param>
/// <param name="language"></param>
/// <returns></returns>
[HttpPost("{doctorId:guid}/{attachmentId:guid}/{language}")]
public async Task<IResponseOutput> SetOfficial(Guid doctorId, Guid attachmentId, int language)
{
var resumeList = await _attachmentrepository.Where(t => t.DoctorId == doctorId && t.Type == "Resume" && t.Language == language).ToListAsync();
foreach (var item in resumeList)
{
if (item.Id == attachmentId) item.IsOfficial = true;
else item.IsOfficial = false;
await _repository.UpdateAsync(item);
}
return ResponseOutput.Result(await _repository.SaveChangesAsync());
}
/// <summary>
/// 设置简历的语言类型
/// </summary>
/// <param name="doctorId"></param>
/// <param name="attachmentId"></param>
/// <param name="language">0-未设置1-中文2-英文</param>
/// <returns></returns>
[HttpPost("{doctorId:guid}/{attachmentId:guid}/{language}")]
public async Task<IResponseOutput> SetLanguage(Guid doctorId, Guid attachmentId, int language)
{
bool result =await _attachmentrepository.BatchUpdateNoTrackingAsync(t => t.Id == attachmentId, a => new Attachment
{
Language = language,
IsOfficial = false
});
return ResponseOutput.Result(result);
}
}
}

View File

@ -1,64 +0,0 @@
namespace IRaCIS.Application.Contracts
{
public class AttachmentDTO
{
public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public bool IsOfficial { get; set; }
public string Type { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public string FullPath { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public DateTime? CreateTime { get; set; }
public int Language { get; set; }
public bool ReUpload { get; set; } = false;
}
public class ReviewerAckDTO
{
public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public string Type { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public string FullPath => Path;
public string FileName { get; set; } = string.Empty;
}
public class TrialSOWPathDTO
{
public Guid TrialId { get; set; }
public string SowName { get; set; } = string.Empty;
public string SowPath { get; set; } = string.Empty;
}
public class DeleteSowPathDTO
{
public Guid TrialId { get; set; }
public string Path { get; set; } = string.Empty;
}
public class UploadAgreementAttachmentDTO
{
public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public string Type { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public string FullPath => Path;
public string FileName { get; set; } = string.Empty;
}
public class AttachementCommand
{
public Guid Id { get; set; }
public string Path { get; set; } = string.Empty;
}
}

View File

@ -1,12 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class DoctorAccountRegisterModel : DoctorAccountLoginDTO
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string EMail { get; set; } = string.Empty;
public DateTime RegisterTime { get; set; }
}
}

View File

@ -244,12 +244,10 @@ namespace IRaCIS.Application.Contracts
public DoctorBasicInfoDTO BasicInfoView { get; set; }
public EmploymentDTO EmploymentView { get; set; }
public SpecialtyDTO SpecialtyView { get; set; }
public IEnumerable<EducationInfoViewModel> EducationList { get; set; }
public IEnumerable<PostgraduateViewModel> PostgraduateList { get; set; }
public ResearchPublicationDTO ResearchPublicationView { get; set; }
public TrialExperienceModel TrialExperienceView { get; set; }
public ResumeConfirmDTO AuditView { get; set; }
public IEnumerable<AttachmentDTO> AttachmentList { get; set; }
public List<SowDTO> SowList { get; set; }
public List<SowDTO> AckSowList { get; set; }
@ -262,12 +260,9 @@ namespace IRaCIS.Application.Contracts
BasicInfoView = new DoctorBasicInfoDTO();
EmploymentView = new EmploymentDTO();
SpecialtyView = new SpecialtyDTO();
EducationList = new List<EducationInfoViewModel>();
PostgraduateList = new List<PostgraduateViewModel>();
ResearchPublicationView = new ResearchPublicationDTO();
TrialExperienceView = new TrialExperienceModel();
AuditView = new ResumeConfirmDTO();
AttachmentList = new List<AttachmentDTO>();
IntoGroupInfo = new DoctorEnrollInfoDTO();
SowList = new List<SowDTO>();
AckSowList = new List<SowDTO>();

View File

@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
namespace IRaCIS.Application.Contracts
{
public class EducationCommand
{
public Guid? Id { get; set; }
public Guid DoctorId { get; set; }
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
public string Degree { get; set; } = String.Empty;
public string Major { get; set; } = String.Empty;
public string Organization { get; set; } = String.Empty;
public string Country { get; set; } = String.Empty;
public string Province { get; set; } = String.Empty;
public string City { get; set; } = String.Empty;
public string DegreeCN { get; set; } = String.Empty;
public string MajorCN { get; set; } = String.Empty;
public string OrganizationCN { get; set; } = String.Empty;
public string CountryCN { get; set; } = String.Empty;
public string ProvinceCN { get; set; } = String.Empty;
public string CityCN { get; set; } = String.Empty;
}
public class EducationInfoViewModel : EducationCommand
{
public DateTime? CreateTime { get; set; }
public string BeginDateStr => BeginDate.ToString("yyyy-MM");
public string EndDateStr => EndDate.ToString("yyyy-MM");
}
public class PostgraduateCommand
{
public Guid? Id { get; set; }
public Guid DoctorId { get; set; }
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
public string Training { get; set; } = String.Empty;
public string Major { get; set; } = String.Empty;
public string Hospital { get; set; } = String.Empty;
public string School { get; set; } = String.Empty;
public string Country { get; set; } = String.Empty;
public string Province { get; set; } = String.Empty;
public string City { get; set; } = String.Empty;
public string TrainingCN { get; set; } = String.Empty;
public string MajorCN { get; set; } = String.Empty;
public string HospitalCN { get; set; } = String.Empty;
public string SchoolCN { get; set; } = String.Empty;
public string CountryCN { get; set; } = String.Empty;
public string ProvinceCN { get; set; } = String.Empty;
public string CityCN { get; set; } = String.Empty;
}
public class PostgraduateViewModel: PostgraduateCommand
{
public DateTime? CreateTime { get; set; }
public string BeginDateStr => BeginDate.ToString("yyyy-MM");
public string EndDateStr => EndDate.ToString("yyyy-MM");
}
public class DoctorEducationExperienceDTO
{
public IEnumerable<EducationInfoViewModel> EducationList=new List<EducationInfoViewModel>();
public IEnumerable<PostgraduateViewModel> PostgraduateList = new List<PostgraduateViewModel>();
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class VacationCommand
{
public Guid? Id { get; set; }
public Guid DoctorId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int Status { get; set; } = 1;
}
}

View File

@ -1,21 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class ResearchPublicationDTO
{
public Guid? Id { get; set; }
public Guid DoctorId { get; set; }
public string Research { get; set; } = String.Empty;
public string Grants { get; set; } = String.Empty;
public string Publications { get; set; } = String.Empty;
public string AwardsHonors { get; set; } = String.Empty;
public string ResearchCN { get; set; } = String.Empty;
public string GrantsCN { get; set; } = String.Empty;
public string PublicationsCN { get; set; } = String.Empty;
public string AwardsHonorsCN { get; set; } = String.Empty;
}
}

View File

@ -1,87 +0,0 @@
namespace IRaCIS.Application.Contracts
{
public class TrialExperienceCommand
{
public Guid? Id { get; set; }
public Guid DoctorId { get; set; }
public Guid? PhaseId { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public string EvaluationContent { get; set; } = String.Empty;
public int VisitReadingCount { get; set; }
//public string Term { get; set; }
//public string EvaluationCriteria { get; set; }
public List<Guid> EvaluationCriteriaIdList { get; set; } = new List<Guid>();
}
public class TrialExperienceListDTO: TrialExperienceCommand
{
public string Phase { get; set; } = String.Empty;
public List<string> EvaluationCriteriaList { get; set; } = new List<string>();
}
//public class EvaluationCriteriaDTO
//{
// public Guid EvaluationCriteriaId { get; set; }
// public string EvaluationCriteria { get; set; }
//}
public class TrialExperienceModel : GcpAndOtherExperienceDTO
{
public List<TrialExperienceListDTO> ClinicalTrialExperienceList = new List<TrialExperienceListDTO>();
public string ExpiryDateStr { get; set; } = string.Empty;
public string GCPFullPath { get; set; } = String.Empty;
}
public class GcpAndOtherExperienceDTO
{
public Guid Id { get; set; }
public int GCP { get; set; }
public Guid? GCPId { get; set; }
public string OtherClinicalExperience { get; set; }=String.Empty;
public string OtherClinicalExperienceCN { get; set; } = String.Empty;
public string Type { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
}
public class GCPExperienceCommand
{
public Guid Id { get; set; }
public int GCP { get; set; }
public Guid? GCPId { get; set; }
}
public class ClinicalExperienceCommand
{
public Guid DoctorId { get; set; }
public string OtherClinicalExperience { get; set; } = String.Empty;
public string OtherClinicalExperienceCN { get; set; } = String.Empty;
}
}

View File

@ -1,279 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using System.Linq.Dynamic.Core;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Reviewer")]
public class DoctorListService : BaseService, IDoctorListQueryService
{
private readonly IRepository<Doctor> _doctorRepository;
public DoctorListService(IRepository<Doctor> doctorRepository)
{
_doctorRepository = doctorRepository;
}
/// <summary>
/// Reviewer列表分页查询
/// </summary>
[HttpPost]
public async Task<PageOutput<DoctorDTO>> GetDoctorSearchList(DoctorSearchDTO doctorSearch)
{
// 项目经验 多选
var evaluationCriteriaCount = doctorSearch.EvaluationCriteriaIdList.Count();
// 搜索条件 ReadingType 、Subspeciality、Title 多选
var count = doctorSearch.ReadingTypeIdList.Count + doctorSearch.TitleIdList.Count + doctorSearch.SubspecialityIdList.Count;
var guidList = doctorSearch.ReadingTypeIdList.Concat(doctorSearch.SubspecialityIdList).Concat(doctorSearch.TitleIdList);
var query = _doctorRepository.AsQueryable()
.WhereIf(doctorSearch.DepartmentId != null, t => t.DepartmentId == doctorSearch.DepartmentId)
.WhereIf(doctorSearch.SpecialityId != null, t => t.SpecialityId == doctorSearch.SpecialityId)
.WhereIf(doctorSearch.HospitalId != null, t => t.HospitalId == doctorSearch.HospitalId)
.WhereIf(doctorSearch.PositionId != null, t => t.PositionId == doctorSearch.PositionId)
.WhereIf(doctorSearch.RankId != null, t => t.RankId == doctorSearch.RankId)
.WhereIf(doctorSearch.ContractorStatus != null, t => t.CooperateStatus == doctorSearch.ContractorStatus)
.WhereIf(doctorSearch.InformationConfirmed != null, t => t.ResumeStatus == doctorSearch.InformationConfirmed)
.WhereIf(doctorSearch.AcceptingNewTrial != null, t => t.AcceptingNewTrial == doctorSearch.AcceptingNewTrial)
.WhereIf(!string.IsNullOrWhiteSpace(doctorSearch.Name), t => t.ChineseName.Contains(doctorSearch.Name) || (t.LastName + t.FirstName).Contains(doctorSearch.Name))
.WhereIf(doctorSearch.Nation != null, t => t.Nation == doctorSearch.Nation)
.WhereIf(evaluationCriteriaCount > 0, t => t.TrialExperienceCriteriaList.Count(t => doctorSearch.EvaluationCriteriaIdList.Contains(t.EvaluationCriteriaId)) == evaluationCriteriaCount)
////用户类型 看到简历的范围这里需要确认
//.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ReviewerCoordinator, t => t.UserList.Any(u => u.UserId == _userInfo.Id))
.WhereIf(count > 0, t => t.DoctorDicRelationList.Count(u => guidList.Contains(u.DictionaryId)) == count)
.WhereIf(doctorSearch.EnrollStatus != null && doctorSearch.EnrollStatus == (int)ReviewerEnrollStatus.Yes, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.DoctorReading))
.ProjectTo<DoctorDTO>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(doctorSearch.PageIndex, doctorSearch.PageSize, doctorSearch.SortField == string.Empty ? "CreateTime" : doctorSearch.SortField, doctorSearch.Asc);
}
#region 入组查询相关
/// <summary>
/// 获取可筛选筛选及已经筛选的医生列表
/// </summary>
[HttpPost]
public async Task<PageOutput<SelectionReviewerDTO>> GetSelectionReviewerList(
ReviewerSelectionQueryDTO selectionQuery)
{
//项目配置需要的医生过滤 2表示混合
var trialConfig = await _repository.Where<Trial>(s => s.Id == selectionQuery.TrialId).Select(t=>new { t.AttendedReviewerTypeEnumList ,t.TrialType} ).FirstOrDefaultAsync().IfNullThrowException();
//var nation = trialConfig.AttendedReviewerType;
// 临床项目经验 多选
var evaluationCriteriaCount = selectionQuery.EvaluationCriteriaIdList.Count();
// 搜索条件 ReadingType 、Subspeciality、Title 多选
var count = selectionQuery.ReadingTypeIdList.Count + selectionQuery.TitleIdList.Count + selectionQuery.SubspecialityIdList.Count;
var guidList = selectionQuery.ReadingTypeIdList.Concat(selectionQuery.SubspecialityIdList).Concat(selectionQuery.TitleIdList);
var query = _doctorRepository/*.WhereIf(nation != AttendedReviewerType.USAndCN, t => t.Nation ==(int) nation)*/
.WhereIf(selectionQuery.DepartmentId != null, t => t.DepartmentId == selectionQuery.DepartmentId)
.WhereIf(selectionQuery.SpecialityId != null, t => t.SpecialityId == selectionQuery.SpecialityId)
.WhereIf(trialConfig.TrialType == TrialType.NoneOfficial, t => t.IsVirtual ==true)
.WhereIf(trialConfig.TrialType != TrialType.NoneOfficial, t => t.IsVirtual == false)
.WhereIf(selectionQuery.HospitalId != null, t => t.HospitalId == selectionQuery.HospitalId)
.WhereIf(selectionQuery.PositionId != null, t => t.PositionId == selectionQuery.PositionId)
.WhereIf(selectionQuery.RankId != null, t => t.RankId == selectionQuery.RankId)
.WhereIf(selectionQuery.ContractorStatus != null, t => t.CooperateStatus == selectionQuery.ContractorStatus )
.WhereIf(selectionQuery.InformationConfirmed != null, t => t.ResumeStatus == selectionQuery.InformationConfirmed)
.WhereIf(selectionQuery.AcceptingNewTrial != null, t => t.AcceptingNewTrial == selectionQuery.AcceptingNewTrial)
.WhereIf(!string.IsNullOrWhiteSpace(selectionQuery.Name), t => t.ChineseName.Contains(selectionQuery.Name) || (t.LastName + t.FirstName).Contains(selectionQuery.Name))
.WhereIf(evaluationCriteriaCount > 0, t => t.TrialExperienceCriteriaList.Count(t => selectionQuery.EvaluationCriteriaIdList.Contains(t.EvaluationCriteriaId)) == evaluationCriteriaCount)
//用户类型 看到简历的范围这里需要确认
//.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ReviewerCoordinator, t => t.UserList.Any(u => u.UserId == _userInfo.Id))
.WhereIf(count > 0, t => t.DoctorDicRelationList.Count(u => guidList.Contains(u.DictionaryId)) == count)
.WhereIf(selectionQuery.EnrollStatus != null && selectionQuery.EnrollStatus == (int)ReviewerEnrollStatus.Yes, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.DoctorReading))
.ProjectTo<SelectionReviewerDTO>(_mapper.ConfigurationProvider);
var result = await query.ToPagedListAsync(selectionQuery.PageIndex, selectionQuery.PageSize, selectionQuery.SortField == string.Empty ? "ReviewerCode" : selectionQuery.SortField, selectionQuery.Asc);
//是否已申请 申请时间 申请人
var doctorStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == selectionQuery.TrialId && x.EnrollStatus == EnrollStatus.HasApplyDownloadResume)
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
result.CurrentPageData.ToList().ForEach(doctor =>
{
//简历申请列表 --处理已经申请的
var doctorState = doctorStateList.FirstOrDefault(t => t.DoctorId == doctor.Id && t.IntoGroupState == (int)EnrollStatus.HasApplyDownloadResume);
if (doctorState != null)
{
doctor.DoctorTrialState = (int)EnrollStatus.HasApplyDownloadResume;
doctor.OptTime = doctorState.OptTime;
doctor.OptUserName = doctorState.OptUserName;
}
});
return result;
}
/// <summary>
/// 获取提交CRO或者CRO审核的Reviewer列表
/// </summary>
/// <summary>
/// 根据状态获取医生列表,入组 相关接口 提交CRO-1 CRO确认-4
/// </summary>
[HttpPost]
public async Task<PageOutput<ConfirmationReviewerDTO>> GetSubmissionOrApprovalReviewerList(
ReviewerSubmissionQueryDTO param)
{
var doctorQuery = _repository.Where<Enroll>(x => x.TrialId == param.TrialId)
//提交CRO 以及下载简历列表
.WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus >= EnrollStatus.HasApplyDownloadResume)
//CRO确认列表 状态为 已提交CRO
.WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus >= EnrollStatus.HasCommittedToCRO)
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
var doctorPageList = await doctorQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == "" ? "Code" : param.SortField, param.Asc);
var enrollStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId)
//提交CRO 以及下载简历列表
.WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus == EnrollStatus.HasCommittedToCRO)
//CRO确认列表 状态为 已提交CRO
.WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus == EnrollStatus.InviteIntoGroup)
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
doctorPageList.CurrentPageData.ToList().ForEach(u =>
{
var opt = enrollStateList.FirstOrDefault(t => t.DoctorId == u.Id);
if (opt != null)
{
u.DoctorTrialState = param.IntoGroupSearchState == 1 ? (int)EnrollStatus.HasCommittedToCRO : (int)EnrollStatus.InviteIntoGroup;
u.OptTime = opt.OptTime;
u.OptUserName = opt.OptUserName;
}
else
{
u.DoctorTrialState = param.IntoGroupSearchState == 1 ? (int)EnrollStatus.HasDownloadResume : (int)EnrollStatus.HasCommittedToCRO;
}
});
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM)
{
//SPM 要看到提交的时间 提交人
var enrollCommitList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId)
//提交CRO 以及下载简历列表
.WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus == EnrollStatus.HasCommittedToCRO)
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
doctorPageList.CurrentPageData.ToList().ForEach(u =>
{
var opt = enrollCommitList.FirstOrDefault(t => t.DoctorId == u.Id);
if (opt != null)
{
u.SubmmitTime = opt.OptTime;
u.SubmmitUserName = opt.OptUserName;
}
});
}
return doctorPageList;
}
//public async Task<PageOutput<ConfirmationReviewerDTO>> GetSPMSubmissionOrApprovalReviewerList(
// ReviewerSubmissionQueryDTO param)
//{
// var doctorQuery = _repository.Where<Enroll>(x => x.TrialId == param.TrialId)
// //提交CRO 以及下载简历列表
// .WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus >= (int)EnrollStatus.HasApplyDownloadResume)
// //CRO确认列表 状态为 已提交CRO
// .WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus >= (int)EnrollStatus.HasCommittedToCRO)
// .ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
// var doctorPageList = await doctorQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == "" ? "Code" : param.SortField, param.Asc);
// var enrollStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId)
// //提交CRO 以及下载简历列表
// .WhereIf(param.IntoGroupSearchState == 1, t => t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO)
// //CRO确认列表 状态为 已提交CRO
// .WhereIf(param.IntoGroupSearchState == 4, t => t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup)
// .ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
// doctorPageList.CurrentPageData.ToList().ForEach(u =>
// {
// var opt = enrollStateList.FirstOrDefault(t => t.DoctorId == u.Id);
// if (opt != null)
// {
// u.DoctorTrialState = param.IntoGroupSearchState == 1 ? (int)EnrollStatus.HasCommittedToCRO : (int)EnrollStatus.InviteIntoGroup;
// u.OptTime = opt.OptTime;
// u.OptUserName = opt.OptUserName;
// }
// });
// return doctorPageList;
//}
/// <summary>
/// 获取项目下医生入组状态列表[Confirmation]
/// </summary>
[HttpPost]
public async Task<PageOutput<ConfirmationReviewerDTO>> GetConfirmationReviewerList(
ReviewerConfirmationQueryDTO param)
{
var doctorQuery = _repository.Where<Enroll>(x => x.TrialId == param.TrialId && x.EnrollStatus >= EnrollStatus.InviteIntoGroup)
.ProjectTo<ConfirmationReviewerDTO>(_mapper.ConfigurationProvider);
var doctorPageList = await doctorQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == "" ? "Code" : param.SortField, param.Asc);
var enrollStateList = await _repository.Where<EnrollDetail>(x => x.TrialId == param.TrialId && x.EnrollStatus > EnrollStatus.InviteIntoGroup)
.ProjectTo<DoctorStateModelDTO>(_mapper.ConfigurationProvider).ToListAsync();
doctorPageList.CurrentPageData.ToList().ForEach(u =>
{
u.DoctorTrialState = (int)EnrollStatus.InviteIntoGroup;
var opt = enrollStateList.FirstOrDefault(t => t.DoctorId == u.Id);
if (opt != null)
{
u.DoctorTrialState = opt.IntoGroupState;
u.OptTime = opt.OptTime;
u.OptUserName = opt.OptUserName;
}
});
return doctorPageList;
}
#endregion
}
}

View File

@ -1,628 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using System.Linq.Expressions;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Reviewer")]
public class DoctorService : BaseService, IDoctorService
{
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Message> _messageRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<DoctorDictionary> _doctorDictionaryRepository;
private readonly IRepository<Attachment> _attachmentRepository;
private readonly IRepository<DoctorCriterionFile> _doctorCriterionFileRepository;
private readonly IRepository<UserDoctor> _userDoctorRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialPaymentPrice> _trialExtRepository;
private readonly IRepository<Vacation> _vacationRepository;
public DoctorService(IRepository<Doctor> doctorInfoRepository,
IRepository<Dictionary> dictionaryRepository,
IRepository<Message> sysMessageRepository, IRepository<Enroll> intoGroupRepository,
IRepository<DoctorDictionary> doctorDictionaryRepository,
IRepository<Attachment> attachmentRepository,
IRepository<DoctorCriterionFile> doctorCriterionFileRepository,
IRepository<UserDoctor> userDoctorRepository,
IRepository<Trial> trialRepository,
IRepository<TrialPaymentPrice> trialExtRepository, IRepository<Vacation> vacationRepository)
{
_doctorRepository = doctorInfoRepository;
_messageRepository = sysMessageRepository;
_enrollRepository = intoGroupRepository;
_doctorDictionaryRepository = doctorDictionaryRepository;
_attachmentRepository = attachmentRepository;
this._doctorCriterionFileRepository = doctorCriterionFileRepository;
_userDoctorRepository = userDoctorRepository;
_trialRepository = trialRepository;
_trialExtRepository = trialExtRepository;
_vacationRepository = vacationRepository;
}
#region 医生基本信息--查询、新增、更新
/// <summary>
/// 添加/更新 医生基本信息 BasicInfo
/// </summary>
[HttpPost]
public async Task<IResponseOutput<DoctorBasicInfoCommand>> AddOrUpdateDoctorBasicInfo(DoctorBasicInfoCommand basicInfoModel)
{
Expression<Func<Doctor, bool>> verifyExp = t => t.Phone == basicInfoModel.Phone || t.EMail == basicInfoModel.EMail;
//---current phone or email number already existed
var verifyPair = new KeyValuePair<Expression<Func<Doctor, bool>>, string>(verifyExp, _localizer["Doctor_DupPhoneOrEmail"]);
if (basicInfoModel.Id == Guid.Empty || basicInfoModel.Id == null)
{
var doctor = _mapper.Map<Doctor>(basicInfoModel);
//验证用户手机号
if (await _doctorRepository.AnyAsync(t => t.Phone == doctor.Phone))
{
//---The current phone number already existed!
return ResponseOutput.NotOk(_localizer["Doctor_DupPhone"], new DoctorBasicInfoCommand());
}
if (await _doctorRepository.AnyAsync(t => t.EMail == doctor.EMail))
{
//---The current email already existed!
return ResponseOutput.NotOk(_localizer["Doctor_DupEmail"], new DoctorBasicInfoCommand());
}
doctor.Code = (await _doctorRepository.MaxAsync(t => t.Code)) + 1;
doctor.ReviewerCode = AppSettings.GetCodeStr(doctor.Code, nameof(Doctor));
doctor.Password = MD5Helper.Md5(doctor.Phone);
//插入中间表
basicInfoModel.TitleIds.ForEach(titleId => doctor.DoctorDicRelationList.Add(new DoctorDictionary() { DoctorId = doctor.Id, KeyName = StaticData.Title, DictionaryId = titleId }));
await _doctorRepository.AddAsync(doctor);
//_doctorRepository.Add(doctor);
//await _repository.AddAsync(new UserDoctor() { DoctorId = doctor.Id, UserId = _userInfo.Id });
//_userDoctorRepository.Add(new UserDoctor() { DoctorId = doctor.Id, UserId = _userInfo.Id });
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, _mapper.Map<DoctorBasicInfoCommand>(doctor));
}
else
{
var updateModel = basicInfoModel;
var phone = updateModel.Phone.Trim();
if ((await _doctorRepository.FirstOrDefaultAsync(t => t.Phone == phone && t.Id != updateModel.Id)) != null)
{
//---The current phone number already existed!
return ResponseOutput.NotOk(_localizer["Doctor_DupPhone"], new DoctorBasicInfoCommand());
}
var email = updateModel.EMail.Trim();
if (await _doctorRepository.AnyAsync(t => t.EMail == email && t.Id != updateModel.Id))
{
//---The current email already existed!
return ResponseOutput.NotOk(_localizer["Doctor_DupEmail"], new DoctorBasicInfoCommand());
}
var doctor = await _doctorRepository.FirstOrDefaultAsync(t => t.Id == updateModel.Id).IfNullThrowException();
//删除中间表 Title对应的记录
await _repository.BatchDeleteAsync<DoctorDictionary>(t => t.DoctorId == updateModel.Id && t.KeyName == StaticData.Title);
var adddata = new List<DoctorDictionary>();
//重新插入新的 Title记录
updateModel.TitleIds.ForEach(titleId => adddata.Add(new DoctorDictionary() { DoctorId = updateModel.Id.Value, KeyName = StaticData.Title, DictionaryId = titleId }));
await _repository.AddRangeAsync(adddata);
_mapper.Map(basicInfoModel, doctor);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, basicInfoModel);
}
}
/// <summary>
///详情、编辑-获取 医生基本信息 BasicInfo
/// </summary>
/// <param name="doctorId">ReviewerID</param>
/// <returns></returns>
[HttpGet("{doctorId:guid}")]
public async Task<DoctorBasicInfoDTO> GetBasicInfo(Guid doctorId)
{
#region 用导航属性直接查询
//SELECT[t].[Id], [t].[Code], [t].[ChineseName], [t].[EMail], [t].[FirstName], [t].[Introduction], [t].[LastName], [t].[Phone], [t].[Sex], [t].[WeChat], [t].[Nation], [t0].[Title], [t0].[TitleCN], [t0].[TitleId], [t0].[ShowOrder], [t0].[Id], [t0].[Id0]
//FROM(
// SELECT TOP(1)[d].[Id], [d].[Code], [d].[ChineseName], [d].[EMail], [d].[FirstName], [d].[Introduction], [d].[LastName], [d].[Phone], [d].[Sex], [d].[WeChat], [d].[Nation]
// FROM[Doctor] AS[d] WITH(NOLOCK)
// WHERE[d].[Id] = @__doctorId_0
//) AS[t]
//LEFT JOIN(
// SELECT[d1].[Value] AS[Title], [d1].[ValueCN] AS[TitleCN], [d0].[DictionaryId] AS[TitleId], [d1].[ShowOrder], [d0].[Id], [d1].[Id] AS[Id0], [d0].[DoctorId]
// FROM [DoctorDictionary] AS [d0] WITH (NOLOCK)
// INNER JOIN[Dictionary] AS [d1] WITH (NOLOCK) ON [d0].[DictionaryId] = [d1].[Id]
// WHERE[d0].[KeyName] = N'Title'
//) AS[t0] ON[t].[Id] = [t0].[DoctorId]
//ORDER BY[t].[Id], [t0].[ShowOrder], [t0].[Id]
//var doctorQueryable = _doctorRepository
// .Find(t => t.Id == doctorId)
// .Select(doctor => new DoctorBasicInfoDTO()
// {
// Id = doctor.Id,
// Code = doctor.Code,
// ChineseName = doctor.ChineseName,
// EMail = doctor.EMail,
// FirstName = doctor.FirstName,
// Introduction = doctor.Introduction,
// LastName = doctor.LastName,
// Phone = doctor.Phone,
// Sex = doctor.Sex,
// WeChat = doctor.WeChat,
// Nation = doctor.Nation,
// //不要分三个属性查询,会做三次左连接,这样 只会一个左连接
// TempObjList = doctor.DoctorDicList.Where(t => t.KeyName == StaticData.Title)
// .Select(t => new TempObj { Title = t.Dictionary.Value, TitleCN = t.Dictionary.ValueCN, TitleId = t.DictionaryId, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).ToList(),
// });
//var doctorBasicInfo = doctorQueryable.FirstOrDefault();
#endregion
var doctorBasicInfo = (await _doctorRepository.Where(t => t.Id == doctorId)
.ProjectTo<DoctorBasicInfoDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
return doctorBasicInfo;
}
#endregion
#region Employment信息--查询和更新
/// <summary>
/// 详情、编辑-获取医生工作信息 Employment
/// </summary>
[HttpGet("{doctorId:Guid}")]
public async Task<EmploymentDTO> GetEmploymentInfo(Guid doctorId)
{
#region init EF select 废弃
//var dic = GetDictionary();
//var employmentQueryable = from doctorItem in _doctorRepository
// .Where(t => t.Id == doctorId)
// join hospitalItem in _hospitalRepository.AsQueryable() on doctorItem.HospitalId equals hospitalItem.Id into g
// from hospital in g.DefaultIfEmpty()
// select new EmploymentDTO()
// {
// Id = doctorItem.Id,
// //部门
// DepartmentId = doctorItem.DepartmentId,
// DepartmentOther = doctorItem.DepartmentOther,
// DepartmentOtherCN = doctorItem.DepartmentOtherCN,
// //医院
// HospitalId = doctorItem.HospitalId,
// PositionId = doctorItem.PositionId,
// PositionOther = doctorItem.PositionOther,
// PositionOtherCN = doctorItem.PositionOtherCN,
// RankId = doctorItem.RankId,
// RankOther = doctorItem.RankOther,
// RankOtherCN = doctorItem.RankOtherCN,
// City = hospital.City,
// Country = hospital.Country,
// UniversityAffiliated = hospital.UniversityAffiliated,
// HospitalName = hospital.HospitalName,
// Province = hospital.Province,
// CityCN = hospital.CityCN,
// CountryCN = hospital.CountryCN,
// UniversityAffiliatedCN = hospital.UniversityAffiliatedCN,
// HospitalNameCN = hospital.HospitalNameCN,
// ProvinceCN = hospital.ProvinceCN
// };
//var employmentInfo = employmentQueryable.FirstOrDefault();
//if (employmentInfo != null)
//{
// //医院信息设置
// if (employmentInfo.HospitalId == Guid.Empty)
// {
// employmentInfo.City = string.Empty;
// employmentInfo.Country = string.Empty;
// employmentInfo.UniversityAffiliated = string.Empty;
// employmentInfo.HospitalName = string.Empty;
// employmentInfo.Province = string.Empty;
// }
// employmentInfo.Department = employmentInfo.DepartmentId == Guid.Empty ? employmentInfo.DepartmentOther : dic.FirstOrDefault(o => o.Id == employmentInfo.DepartmentId)?.Value ?? "";
// employmentInfo.Rank = employmentInfo.RankId == Guid.Empty ? employmentInfo.RankOther : dic.FirstOrDefault(o => o.Id == employmentInfo.RankId)?.Value ?? "";
// employmentInfo.Position = employmentInfo.PositionId == Guid.Empty ? employmentInfo.PositionOther : dic.FirstOrDefault(o => o.Id == employmentInfo.PositionId)?.Value ?? "";
// employmentInfo.DepartmentCN = employmentInfo.DepartmentId == Guid.Empty ? employmentInfo.DepartmentOther : dic.FirstOrDefault(o => o.Id == employmentInfo.DepartmentId)?.ValueCN ?? "";
// employmentInfo.RankCN = employmentInfo.RankId == Guid.Empty ? employmentInfo.RankOther : dic.FirstOrDefault(o => o.Id == employmentInfo.RankId)?.ValueCN ?? "";
// employmentInfo.PositionCN = employmentInfo.PositionId == Guid.Empty ? employmentInfo.PositionOther : dic.FirstOrDefault(o => o.Id == employmentInfo.PositionId)?.ValueCN ?? "";
//}
#endregion
var query = _doctorRepository.Where(t => t.Id == doctorId)
.ProjectTo<EmploymentDTO>(_mapper.ConfigurationProvider);
var employmentInfo = (await query.FirstOrDefaultAsync()).IfNullThrowException();
return employmentInfo;
}
[HttpPost]
public async Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand doctorWorkInfoModel)
{
#region 废弃
//var success = _doctorRepository.Update(d => d.Id == doctorWorkInfoModel.Id, u => new Doctor()
//{
// DepartmentId = doctorWorkInfoModel.DepartmentId,
// DepartmentOther = doctorWorkInfoModel.DepartmentOther,
// DepartmentOtherCN = doctorWorkInfoModel.DepartmentOtherCN,
// SpecialityId = doctorWorkInfoModel.DepartmentId,
// SpecialityOther = doctorWorkInfoModel.DepartmentOther,
// SpecialityOtherCN = doctorWorkInfoModel.DepartmentOtherCN,
// RankId = doctorWorkInfoModel.RankId,
// RankOther = doctorWorkInfoModel.RankOther,
// RankOtherCN = doctorWorkInfoModel.RankOtherCN,
// PositionId = doctorWorkInfoModel.PositionId,
// PositionOther = doctorWorkInfoModel.PositionOther,
// PositionOtherCN = doctorWorkInfoModel.PositionOtherCN,
// HospitalId = doctorWorkInfoModel.HospitalId,
// UpdateTime = DateTime.Now
//});
//var doctor = _doctorRepository.FirstOrDefault(d => d.Id == doctorWorkInfoModel.Id);
//_mapper.Map(doctorWorkInfoModel, doctor);
//var success = _doctorRepository.SaveChanges();
#endregion
var entity = await _repository.InsertOrUpdateAsync<Doctor, EmploymentCommand>(doctorWorkInfoModel, true);
return ResponseOutput.Ok();
}
#endregion
#region 医生技能信息 查询和 更新
[HttpGet, Route("{doctorId:Guid}")]
public async Task<SpecialtyDTO> GetSpecialtyInfo(Guid doctorId)
{
#region 利用导航属性直接查询出来 生成的sql ok 废弃
//var specialtyQueryable = _doctorRepository
// .Where(t => t.Id == doctorId).Include(u => u.DoctorDicRelationList)
// .Select(specialty => new SpecialtyDTO()
// {
// Id = specialty.Id,
// ReadingTypeOther = specialty.ReadingTypeOther,
// ReadingTypeOtherCN = specialty.ReadingTypeOtherCN,
// SubspecialityOther = specialty.SubspecialityOther,
// SubspecialityOtherCN = specialty.SubspecialityOtherCN,
// DictionaryList = specialty.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality)
// .Select(t => new SpecialtyDTO.DoctorDictionaryView() { DictionaryId = t.DictionaryId, Value = t.Dictionary.Value, ValueCN = t.Dictionary.ValueCN, ShowOrder = t.Dictionary.ShowOrder, KeyName = t.Dictionary.KeyName })
// .OrderBy(t => t.ShowOrder).ToList(),
// SpecialityId = specialty.SpecialityId,
// Speciality = specialty.Speciality.Value,
// SpecialityCN = specialty.Speciality.ValueCN,
// SpecialityOther = specialty.SpecialityOther,
// SpecialityOtherCN = specialty.SpecialityOtherCN
// });
//var specialtyInfo = specialtyQueryable.FirstOrDefault();
//return specialtyInfo;
#endregion
var test = await (_doctorRepository.Where(t => t.Id == doctorId)
.ProjectTo<SpecialtyDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
return test;
}
[HttpPost]
public async Task<IResponseOutput> UpdateSpecialtyInfo(SpecialtyCommand specialtyUpdateModel)
{
var doctor = await _doctorRepository.FirstOrDefaultAsync(t => t.Id == specialtyUpdateModel.Id);
if (doctor == null) return Null404NotFound(doctor);
////删除中间表
//_doctorDictionaryRepository.Delete(t =>
// t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.Subspeciality);
//_doctorDictionaryRepository.Delete(t =>
// t.DoctorId == specialtyUpdateModel.Id && t.KeyName == StaticData.ReadingType);
await _repository.BatchDeleteAsync<DoctorDictionary>(t =>
t.DoctorId == specialtyUpdateModel.Id && (t.KeyName == StaticData.Subspeciality || t.KeyName == StaticData.ReadingType));
//重新插入新的
var adddata = new List<DoctorDictionary>();
specialtyUpdateModel.ReadingTypeIds.ForEach(readingTypeId => adddata.Add(
new DoctorDictionary()
{
DoctorId = specialtyUpdateModel.Id,
KeyName = StaticData.ReadingType,
DictionaryId = readingTypeId
}));
specialtyUpdateModel.SubspecialityIds.ForEach(subspecialityId => adddata.Add(
new DoctorDictionary()
{
DoctorId = specialtyUpdateModel.Id,
KeyName = StaticData.Subspeciality,
DictionaryId = subspecialityId
}));
await _repository.AddRangeAsync(adddata);
_mapper.Map(specialtyUpdateModel, doctor);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
#endregion
#region 简历审核
[HttpPost]
public async Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam)
{
var userId = _userInfo.Id;
//判断 合作协议、正式简历 是否有。如果没有,显示提示信息,并且不能保存
var attachmentList = await _attachmentRepository.Where(u => u.DoctorId == auditResumeParam.Id)
.Select(u => u.Type).ToListAsync();
if (auditResumeParam.ResumeStatus == ResumeStatusEnum.Pass && ((!attachmentList.Contains("Resume")) || (!attachmentList.Contains("Consultant Agreement"))))
{
//---Resume & Consultant Agreement must be upload
return ResponseOutput.NotOk(_localizer["Doctor_RequiredDocumentsError"]);
}
var success = await _doctorRepository.BatchUpdateNoTrackingAsync(o => o.Id == auditResumeParam.Id, u => new Doctor()
{
CooperateStatus = auditResumeParam.CooperateStatus,
ResumeStatus = auditResumeParam.ResumeStatus,
AdminComment = auditResumeParam.AdminComment,
ReviewStatus = auditResumeParam.ReviewStatus,
AcceptingNewTrial = auditResumeParam.AcceptingNewTrial,
ActivelyReading = auditResumeParam.ActivelyReading,
IsVirtual = auditResumeParam.IsVirtual,
BlindName = auditResumeParam.BlindName,
BlindNameCN = auditResumeParam.BlindNameCN,
BlindPublications = auditResumeParam.BlindPublications,
AuditTime = DateTime.Now,
AuditUserId = userId
});
if (success)
{
if (!string.IsNullOrWhiteSpace(auditResumeParam.MessageContent))
{
var message = new Message
{
FromUserId = userId,
ToDoctorId = auditResumeParam.Id,
Title = "Resume review results",
Content = auditResumeParam.MessageContent,
HasRead = false,
MessageTime = DateTime.Now
};
await _repository.AddAsync(message);
success = await _repository.SaveChangesAsync();
}
}
return ResponseOutput.Result(success);
}
/// <summary>
/// 添加修改医生标准文件
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AddDoctorCriterionFile(AddDoctorCriterionFileDto inDto)
{
if (await _doctorCriterionFileRepository.AnyAsync(x => inDto.IsEnable && x.DoctorId == inDto.DoctorId && x.FileType == inDto.FileType && x.TrialId==inDto.TrialId &&x.TrialReadingCriterionId==inDto.TrialReadingCriterionId && x.IsEnable && x.CriterionType == inDto.CriterionType && x.Id != inDto.Id))
{
//-----------当前标准已添加过此类型文件
throw new BusinessValidationFailedException(_localizer["Doctor_StandardDuplicateFileTypeError"]);
}
var entity = await _doctorCriterionFileRepository.InsertOrUpdateAsync(inDto);
if (inDto.TrialId != null)
{
entity.Remark = await _trialRepository.Where(t => t.Id == inDto.TrialId).Select(t => t.TrialCode).FirstOrDefaultAsync();
}
await _doctorCriterionFileRepository.SaveChangesAsync();
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 删除医生标准文件
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> DeleteDoctorCriterionFile(DeleteDoctorCriterionFile inDto)
{
var result = await _doctorCriterionFileRepository.DeleteFromQueryAsync(inDto.Id, true);
return ResponseOutput.Ok(result.Id.ToString());
}
/// <summary>
/// 获取医生标准文件
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetDoctorCriterionFileOutDto>> GetDoctorCriterionFile(GetDoctorCriterionFileInDto inDto)
{
var result = await _doctorCriterionFileRepository.Where(x => x.DoctorId == inDto.DoctorId)
.WhereIf(inDto.CriterionType != null, x => x.CriterionType == inDto.CriterionType)
.WhereIf(inDto.FileType != null, x => x.FileType == inDto.FileType)
.ProjectTo<GetDoctorCriterionFileOutDto>(_mapper.ConfigurationProvider)
.ToListAsync();
return result;
}
[HttpGet("{doctorId:guid}")]
public async Task<ResumeConfirmDTO> GetAuditState(Guid doctorId)
{
var doctor = (await _doctorRepository
.ProjectTo<ResumeConfirmDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync(t => t.Id == doctorId)).IfNullThrowException();
doctor.InHoliday = (await _repository.CountAsync<Vacation>(x => x.DoctorId == doctorId && x.EndDate <= DateTime.Now && x.StartDate <= DateTime.Now)) > 0;
return doctor;
}
/// <summary>
/// 获取医生入组信息 正在提交的数量 已同意入组项目个数 正在读的
/// </summary>
[HttpPost, Route("{doctorId:guid}")]
public DoctorEnrollInfoDTO GetDoctorIntoGroupInfo(Guid doctorId)
{
var doctorQueryable =
from doctor in _doctorRepository.Where(t => t.Id == doctorId)
join intoGroupItem in _enrollRepository.AsQueryable() on doctor.Id equals intoGroupItem.DoctorId
into t
from intoGroupItem in t.DefaultIfEmpty()
group intoGroupItem by intoGroupItem.DoctorId
into g
select new DoctorEnrollInfoDTO
{
DoctorId = g.Key,
//Submitted = g.Sum(t =>
// t.EnrollStatus == (int)EnrollStatus.HasCommittedToCRO ? 1 : 0),
//Approved = g.Sum(t =>
// t.EnrollStatus == (int)EnrollStatus.InviteIntoGroup ? 1 : 0),
//Reading = g.Sum(t =>
// t.EnrollStatus == (int)EnrollStatus.DoctorReading ? 1 : 0)
Submitted = g.Count(t =>
t.EnrollStatus == EnrollStatus.HasCommittedToCRO),
Approved = g.Count(t =>
t.EnrollStatus == EnrollStatus.InviteIntoGroup),
Reading = g.Count(t =>
t.EnrollStatus == EnrollStatus.DoctorReading)
};
return doctorQueryable.FirstOrDefault().IfNullThrowException();
}
/// <summary>
/// Get Statement of Work list.[New]
/// </summary>
[HttpGet("{doctorId:guid}")]
public List<SowDTO> GetDoctorSowList(Guid doctorId)
{
var query = from enroll in _enrollRepository.Where(u => u.DoctorId == doctorId && u.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
join trialExt in _trialExtRepository.AsQueryable() on enroll.TrialId equals trialExt.TrialId
join trial in _trialRepository.AsQueryable() on enroll.TrialId equals trial.Id
select new SowDTO
{
FileName = trialExt.SowName,
FilePath = trialExt.SowPath,
TrialCode = trial.TrialCode,
CreateTime = trialExt.CreateTime
};
return query.ToList().Where(u => !string.IsNullOrWhiteSpace(u.FileName)).ToList();
}
/// <summary>
/// Get Ack Statement of Work[New]
/// </summary>
[HttpGet("{doctorId:guid}")]
public List<SowDTO> GetDoctorAckSowList(Guid doctorId)
{
var query = from enroll in _enrollRepository.Where(u => u.DoctorId == doctorId)
join attachment in _attachmentRepository.Where(u => u.DoctorId == doctorId)
on enroll.AttachmentId equals attachment.Id
join trial in _trialRepository.AsQueryable() on enroll.TrialId equals trial.Id
select new SowDTO
{
FileName = attachment.FileName,
FilePath = attachment.Path,
TrialCode = trial.TrialCode,
CreateTime = attachment.CreateTime
};
return query.ToList();
}
#endregion
}
}

View File

@ -1,140 +0,0 @@

using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Reviewer")]
public class EducationService : BaseService, IEducationService
{
private readonly IRepository<Postgraduate> _postgraduateRepository;
private readonly IRepository<Education> _educationRepository;
public EducationService(IRepository<Education> doctorNormalEducationRepository,
IRepository<Postgraduate> doctorContinueLearningRepository)
{
_educationRepository = doctorNormalEducationRepository;
_postgraduateRepository = doctorContinueLearningRepository;
}
/// <summary>
/// 根据医生Id获取医生教育经历和继续学习经历列表
/// </summary>
[HttpGet("{doctorId:Guid}")]
public async Task<DoctorEducationExperienceDTO> GetEducation(Guid doctorId)
{
var educationList = await _educationRepository.Where(o => o.DoctorId == doctorId)
.OrderBy(t => t.CreateTime).ProjectTo<EducationInfoViewModel>(_mapper.ConfigurationProvider).ToListAsync();
var postgraduateList = await _postgraduateRepository.Where(o => o.DoctorId == doctorId)
.OrderBy(t => t.CreateTime).ProjectTo<PostgraduateViewModel>(_mapper.ConfigurationProvider).ToListAsync();
return new DoctorEducationExperienceDTO()
{
EducationList = educationList,
PostgraduateList = postgraduateList
};
}
/// <summary>
/// 新增医生教育经历
/// </summary>
/// <param name="educationInfoViewModel"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateEducationInfo(EducationCommand educationInfoViewModel)
{
if (educationInfoViewModel.Id == Guid.Empty || educationInfoViewModel.Id == null)
{
var doctorEducationInfo = _mapper.Map<Education>(educationInfoViewModel);
switch (educationInfoViewModel.Degree)
{
case StaticData.ReviewerDegree.Bachelor:
doctorEducationInfo.ShowOrder = 1;
break;
case StaticData.ReviewerDegree.Master:
doctorEducationInfo.ShowOrder = 2;
break;
case StaticData.ReviewerDegree.Doctorate:
doctorEducationInfo.ShowOrder = 3;
break;
}
await _educationRepository.AddAsync(doctorEducationInfo);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, doctorEducationInfo.Id.ToString());
}
else
{
var needUpdate = await _educationRepository.FirstOrDefaultAsync(t => t.Id == educationInfoViewModel.Id);
if (needUpdate == null) return Null404NotFound(needUpdate);
_mapper.Map(educationInfoViewModel, needUpdate);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Ok(success);
}
//_educationRepository.Update(needUpdate);
}
[HttpDelete, Route("{doctorId:guid}")]
public async Task<IResponseOutput> DeleteEducationInfo(Guid id)
{
var success = await _educationRepository.BatchDeleteNoTrackingAsync(o => o.Id == id);
return ResponseOutput.Result(success);
}
/// <summary> 添加/更新医生继续学习经历</summary>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand postgraduateViewModel)
{
#region 封装前
//if (postgraduateViewModel.Id == Guid.Empty || postgraduateViewModel.Id == null)
//{
// var doctorContinueLearning = _mapper.Map<Postgraduate>(postgraduateViewModel);
// _postgraduateRepository.Add(doctorContinueLearning);
// var success = _postgraduateRepository.SaveChanges();
// return ResponseOutput.Result(success, doctorContinueLearning.Id.ToString());
//}
//else
//{
// _postgraduateRepository.Update(_mapper.Map<Postgraduate>(postgraduateViewModel));
// var success = _postgraduateRepository.SaveChanges();
// return ResponseOutput.Result(success);
//}
#endregion
var entity = await _repository.InsertOrUpdateAsync<Postgraduate, PostgraduateCommand>(postgraduateViewModel, true);
return ResponseOutput.Ok(entity.Id);
}
/// <summary>
/// 删除医生继续学习经历
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <returns></returns>
[HttpDelete("{doctorId:guid}")]
public async Task<IResponseOutput> DeletePostgraduateInfo(Guid doctorId)
{
var success = await _repository.BatchDeleteAsync<Postgraduate>(o => o.Id == doctorId);
return ResponseOutput.Result(success);
}
}
}

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IAttachmentService
{
Task<IEnumerable<AttachmentDTO>> SaveAttachments(IEnumerable<AttachmentDTO> attachmentList);
Task<IResponseOutput<AttachmentDTO>> AddAttachment(AttachmentDTO attachment);
Task<IResponseOutput> DeleteAttachment(AttachementCommand param);
Task<AttachmentDTO> GetDetailById(Guid attachmentId);
Task<IEnumerable<AttachmentDTO>> GetAttachmentByType(Guid doctorId, string type);
Task<IEnumerable<AttachmentDTO>> GetAttachmentByTypes(Guid doctorId, string[] types);
Task<IEnumerable<AttachmentDTO>> GetAttachments(Guid doctorId);
Task<string> GetDoctorOfficialCV(int language, Guid doctorId);
Task<IResponseOutput> SetOfficial(Guid doctorId, Guid attachmentId, int language);
Task<IResponseOutput> SetLanguage(Guid doctorId, Guid attachmentId, int language);
}
}

View File

@ -1,14 +0,0 @@
using System;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IDoctorAccountService
{
IResponseOutput Register(DoctorAccountRegisterModel doctorAccount);
DoctorAccountDTO Login(DoctorAccountLoginDTO doctorAccount);
IResponseOutput UpdatePassword(DoctorAccountUpdatePasswordCommand doctorAccount);
}
}

View File

@ -1,32 +0,0 @@
using IRaCIS.Application.Contracts;
namespace IRaCIS.Application.Interfaces
{
public interface IDoctorListQueryService
{
/// <summary>
/// 医生多条件查询
/// </summary>
Task<PageOutput<DoctorDTO>> GetDoctorSearchList(DoctorSearchDTO param);
/// <summary>
/// 筛选医生列表
/// </summary>
/// <param name="doctorSearchModel"></param>
/// <returns></returns>
//
Task<PageOutput<SelectionReviewerDTO>> GetSelectionReviewerList(
ReviewerSelectionQueryDTO doctorSearchModel);
/// <summary>
/// //入组 相关接口 提交CRO-1 CRO确认-4
/// </summary>
Task<PageOutput<ConfirmationReviewerDTO>> GetSubmissionOrApprovalReviewerList(
ReviewerSubmissionQueryDTO doctorIntoGroupSearchModel);
//医生确认状态列表
Task<PageOutput<ConfirmationReviewerDTO>> GetConfirmationReviewerList(
ReviewerConfirmationQueryDTO trialIdPageModel);
}
}

View File

@ -1,74 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IDoctorService
{
#region 医生 基本信息
/// <summary>
/// 基本信息详情展示、编辑使用
/// </summary>
/// <param name="doctorId"></param>
/// <returns></returns>
Task<DoctorBasicInfoDTO> GetBasicInfo(Guid doctorId);
/// <summary>
/// 添加医生基本信息
/// </summary>
/// <param name="addBasicInfoParam"></param>
/// <returns></returns>
Task<IResponseOutput<DoctorBasicInfoCommand>> AddOrUpdateDoctorBasicInfo(DoctorBasicInfoCommand addBasicInfoParam);
#endregion
#region 医生 工作信息
/// <summary>
/// 获取医生 工作信息
/// </summary>
/// <param name="doctorId"></param>
/// <returns></returns>
Task<EmploymentDTO> GetEmploymentInfo(Guid doctorId);
/// <summary>
/// 更新医生 工作信息
/// </summary>
/// <param name="updateDoctorWorkInfoViewModel"></param>
/// <returns></returns>
Task<IResponseOutput> UpdateEmploymentInfo(EmploymentCommand updateDoctorWorkInfoViewModel);
#endregion
/// <summary>
/// 获取医生技能信息
/// </summary>
Task<SpecialtyDTO> GetSpecialtyInfo(Guid doctorId);
/// <summary>
/// 更新医生技能信息
/// </summary>
Task<IResponseOutput> UpdateSpecialtyInfo(SpecialtyCommand specialtyUpdateModel);
/// <summary>
/// 获取医生 审核状态
/// </summary>
Task<ResumeConfirmDTO> GetAuditState(Guid doctorId);
/// <summary>
/// 审核简历 和合作关系
/// </summary>
Task<IResponseOutput> UpdateAuditResume(ResumeConfirmCommand auditResumeParam);
/// <summary> 医生详情 入组信息 </summary>
DoctorEnrollInfoDTO GetDoctorIntoGroupInfo(Guid doctorId);
/// <summary> 获取医生参与项目的Sow协议 </summary>
List<SowDTO> GetDoctorSowList(Guid doctorId);
/// <summary> 获取医生入组的 ack Sow </summary>
List<SowDTO> GetDoctorAckSowList(Guid doctorId);
}
}

View File

@ -1,26 +0,0 @@
using System;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IEducationService
{
Task<DoctorEducationExperienceDTO> GetEducation(Guid doctorId);
#region 教育经历
Task<IResponseOutput> AddOrUpdateEducationInfo(EducationCommand doctorEducationInfoViewModel);
Task<IResponseOutput> DeleteEducationInfo(Guid doctorId);
#endregion
#region 继续教育经历
Task<IResponseOutput> AddOrUpdatePostgraduateInfo(PostgraduateCommand doctorContinueLearningViewModel);
Task<IResponseOutput> DeletePostgraduateInfo(Guid doctorId);
#endregion
}
}

View File

@ -1,13 +0,0 @@
using System;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IResearchPublicationService
{
Task<ResearchPublicationDTO> GetResearchPublication(Guid doctorId);
Task<IResponseOutput> AddOrUpdateResearchPublication(ResearchPublicationDTO param);
}
}

View File

@ -1,15 +0,0 @@
using System;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface ITrialExperienceService
{
Task<TrialExperienceModel> GetTrialExperience(Guid doctorId);
Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand model);
Task<IResponseOutput> DeleteTrialExperience(Guid id);
Task<IResponseOutput> UpdateGcpExperience(GCPExperienceCommand model);
Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand updateOtherClinicalExperience);
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IVacationService
{
Task<IResponseOutput> AddOrUpdateVacation(VacationCommand vacationViewModel);
Task<IResponseOutput> DeleteVacation(Guid id);
Task<PageOutput<VacationCommand>> GetVacationList(Guid doctorId, int pageIndex, int pageSize);
/// <summary> 判断当前时间是否在休假 </summary>
Task<IResponseOutput> OnVacation(Guid reviewerId);
}
}

View File

@ -1,41 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Reviewer")]
public class ResearchPublicationService : BaseService, IResearchPublicationService
{
private readonly IRepository<ResearchPublication> researchPublicationRepository;
public ResearchPublicationService(IRepository<ResearchPublication> _researchPublicationRepository)
{
researchPublicationRepository = _researchPublicationRepository;
}
/// <summary>
/// 查询-医生科学研究信息
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <returns></returns>
[HttpGet("{doctorId:guid}")]
public async Task<ResearchPublicationDTO> GetResearchPublication(Guid doctorId)
{
var doctorScientificResearchInfo = await researchPublicationRepository.Where(o => o.DoctorId == doctorId)
.ProjectTo<ResearchPublicationDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return doctorScientificResearchInfo;
}
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateResearchPublication(ResearchPublicationDTO param)
{
var entity = await _repository.InsertOrUpdateAsync<ResearchPublication, ResearchPublicationDTO>(param, true);
return ResponseOutput.Ok(entity.Id);
}
}
}

View File

@ -1,179 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Reviewer")]
public class TrialExperienceService : BaseService, ITrialExperienceService
{
private readonly IRepository<TrialExperience> _trialExperienceRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Attachment> _attachmentRepository;
private readonly IRepository<TrialExperienceCriteria> _trialExperienceCriteriaRepository;
public TrialExperienceService(IRepository<TrialExperience> trialExperienceRepository, IRepository<Doctor> doctorRepository, IRepository<Attachment> attachmentRepository,
IRepository<TrialExperienceCriteria> trialExperienceCriteriaRepository)
{
_trialExperienceRepository = trialExperienceRepository;
_doctorRepository = doctorRepository;
_attachmentRepository = attachmentRepository;
_trialExperienceCriteriaRepository = trialExperienceCriteriaRepository;
}
/// <summary>
/// 根据医生Id获取临床试验经历 界面所有数据
/// </summary>
[HttpGet("{doctorId:guid}")]
public async Task<TrialExperienceModel> GetTrialExperience(Guid doctorId)
{
var trialExperience = new TrialExperienceModel();
var doctor = await _doctorRepository.Where(o => o.Id == doctorId)
.ProjectTo<TrialExperienceModel>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
trialExperience.ClinicalTrialExperienceList = await GetTrialExperienceList(doctorId);
if (doctor != null)
{
trialExperience.GCP = doctor.GCP;
trialExperience.Id = doctor.Id;
trialExperience.OtherClinicalExperience = doctor.OtherClinicalExperience ?? "";
trialExperience.OtherClinicalExperienceCN = doctor.OtherClinicalExperienceCN ?? "";
var attachment = await _attachmentRepository.FirstOrDefaultAsync(t => t.Id == doctor.GCPId);
if (attachment != null)
{
trialExperience.ExpiryDateStr = attachment.ExpiryDate == null ? "" : attachment.ExpiryDate.Value.ToString("yyyy-MM-dd HH:mm");
trialExperience.Path = attachment.Path;
trialExperience.GCPFullPath = attachment.Path + "?access_token=" + _userInfo.UserToken;
trialExperience.Type = attachment.Type;
trialExperience.FileName = attachment.FileName;
trialExperience.GCPId = attachment.Id;
}
}
return trialExperience;
}
private async Task<List<TrialExperienceListDTO>> GetTrialExperienceList(Guid doctorId)
{
var doctorClinicalTrialExperienceList = await _trialExperienceRepository.Where(o => o.DoctorId == doctorId).OrderBy(t => t.CreateTime)
.ProjectTo<TrialExperienceListDTO>(_mapper.ConfigurationProvider).ToListAsync();
return doctorClinicalTrialExperienceList;
}
/// <summary> 添加或更新医生临床经验列表项</summary>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand trialExperienceViewModel)
{
if (trialExperienceViewModel.Id == Guid.Empty || trialExperienceViewModel.Id == null)
{
var trialExperience =
_mapper.Map<TrialExperience>(trialExperienceViewModel);
trialExperience = await _repository.AddAsync(trialExperience);
List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
{
DoctorId = trialExperienceViewModel.DoctorId,
//EvaluationCriteria = t.EvaluationCriteria,
EvaluationCriteriaId = t,
TrialExperienceId = trialExperience.Id
}));
await _repository.AddRangeAsync(criteriaList);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, trialExperience.Id);
}
else
{
var needUpdate = await _trialExperienceRepository.FirstOrDefaultAsync(t => t.Id == trialExperienceViewModel.Id);
if (needUpdate == null) return Null404NotFound(needUpdate);
_mapper.Map(trialExperienceViewModel, needUpdate);
await _repository.UpdateAsync(needUpdate);
await _repository.BatchDeleteAsync<TrialExperienceCriteria>(t => t.TrialExperienceId == needUpdate.Id);
List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
{
DoctorId = trialExperienceViewModel.DoctorId,
EvaluationCriteriaId = t,
TrialExperienceId = needUpdate.Id
}));
await _repository.AddRangeAsync<TrialExperienceCriteria>(criteriaList);
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, trialExperienceViewModel.Id);
}
}
/// <summary>
/// 删除临床经验
/// </summary>
[HttpDelete, Route("{doctorId:guid}")]
public async Task<IResponseOutput> DeleteTrialExperience(Guid doctorId)
{
var success = await _repository.BatchDeleteAsync<TrialExperience>(o => o.Id == doctorId);
return ResponseOutput.Result(success);
}
/// <summary>
/// 更新-GCP和其他临床经验
/// </summary>
/// <param name="updateGCPExperienceParam"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UpdateGcpExperience(GCPExperienceCommand updateGCPExperienceParam)
{
//_attachmentRepository.Delete(t => t.DoctorId == updateGCPExperienceParam.Id && t.Type == StaticData.GCP);
var successs = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor()
{
GCP = updateGCPExperienceParam.GCP,
GCPId = updateGCPExperienceParam.GCP==0&&updateGCPExperienceParam.GCPId==null?Guid.Empty: updateGCPExperienceParam.GCPId!.Value
});
if (updateGCPExperienceParam.GCP == 0 && updateGCPExperienceParam.GCPId != null)
{
await _repository.BatchDeleteAsync<Attachment>(a => a.Id == updateGCPExperienceParam.GCPId);
}
return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString());
}
/// <summary>
/// 更新其他技能经验
/// </summary>
[HttpPost]
public async Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand updateOtherClinicalExperience)
{
var success = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateOtherClinicalExperience.DoctorId, u => new Doctor()
{
OtherClinicalExperience = updateOtherClinicalExperience.OtherClinicalExperience ?? string.Empty,
OtherClinicalExperienceCN = updateOtherClinicalExperience.OtherClinicalExperienceCN ?? string.Empty
});
return ResponseOutput.Result(success);
}
}
}

View File

@ -1,88 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Reviewer")]
public class VacationService : BaseService, IVacationService
{
private readonly IRepository<Vacation> _vacationRepository;
public VacationService(IRepository<Vacation> vacationRepository)
{
_vacationRepository = vacationRepository;
}
/// <summary>
/// 添加休假时间段
/// </summary>
/// <param name="param">Status不传</param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateVacation(VacationCommand param)
{
if (param.Id == Guid.Empty|| param.Id ==null)
{
var result = await _vacationRepository.AddAsync(_mapper.Map<Vacation>(param));
var success = await _repository.SaveChangesAsync();
return ResponseOutput.Result(success, result.Id);
}
else
{
var success = await _vacationRepository.BatchUpdateNoTrackingAsync(u => u.Id == param.Id,
h => new Vacation
{
StartDate = param.StartDate,
EndDate = param.EndDate
});
return ResponseOutput.Result(success);
}
}
/// <summary>
/// 删除休假时间段
/// </summary>
/// <param name="holidayId">记录Id</param>
/// <returns></returns>
[HttpDelete("{holidayId:guid}")]
public async Task<IResponseOutput> DeleteVacation(Guid holidayId)
{
var success = await _vacationRepository.BatchDeleteNoTrackingAsync(u => u.Id == holidayId);
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取休假时间段列表
/// </summary>
/// <returns></returns>
[HttpGet("{doctorId:guid}/{pageIndex:int}/{pageSize:int}")]
public async Task<PageOutput<VacationCommand>> GetVacationList(Guid doctorId, int pageIndex, int pageSize)
{
var query = _vacationRepository.Where(u => u.DoctorId == doctorId)
.ProjectTo<VacationCommand>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(pageIndex, pageSize, "StartDate");
}
[NonDynamicMethod]
public async Task<IResponseOutput> OnVacation(Guid doctorId)
{
var count = await _vacationRepository.CountAsync(u => u.DoctorId == doctorId && u.EndDate >= DateTime.Now && u.StartDate <= DateTime.Now);
return ResponseOutput.Result(count > 0);
}
}
}

View File

@ -1,159 +0,0 @@
using AutoMapper;
using AutoMapper.EquivalencyExpression;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Service
{
public class DoctorConfig : Profile
{
public DoctorConfig()
{
#region reviewer
//基本信息 工作信息 添加时转换使用
CreateMap<DoctorBasicInfoCommand, Doctor>().EqualityComparison((odto, o) => odto.Id == o.Id);
//学习经历 添加时转换使用
CreateMap<EducationCommand, Education>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<PostgraduateCommand, Postgraduate>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<ResearchPublicationDTO, ResearchPublication>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<TrialExperienceCommand, TrialExperience>().EqualityComparison((odto, o) => odto.Id == o.Id);
//医生账户
CreateMap<DoctorAccountLoginDTO, Doctor>();
CreateMap<DoctorAccountRegisterModel, Doctor>();
CreateMap<VacationCommand, Vacation>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<AttachmentDTO, Attachment>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<ReviewerAckDTO, Attachment>().EqualityComparison((odto, o) => odto.Id == o.Id);
CreateMap<AddDoctorCriterionFileDto, DoctorCriterionFile>();
CreateMap<DoctorCriterionFile, GetDoctorCriterionFileOutDto>();
CreateMap<Doctor, DoctorBasicInfoCommand>();
CreateMap<Education, EducationInfoViewModel>();
CreateMap<Vacation, VacationCommand>();
CreateMap<Education, EducationInfoViewModel>();
CreateMap<ResearchPublication, ResearchPublicationDTO>();
CreateMap<Postgraduate, PostgraduateViewModel>();
CreateMap<Attachment, AttachmentDTO>();
CreateMap<Doctor, ResumeConfirmDTO>();
CreateMap<Doctor, DoctorSelectDTO>();
CreateMap<Doctor, TrialExperienceModel>();
CreateMap<TrialExperience, TrialExperienceCommand>();
CreateMap<Doctor, DoctorBasicInfo>();
#endregion
CreateMap<Dictionary, KeyNameType>();
CreateMap<Dictionary, DicViewModelDTO>();
CreateMap<AddOrUpdateDicDTO, Dictionary>().ReverseMap();
//医生列表、项目显示列表模型转换
CreateMap<DoctorDTO, SelectionReviewerDTO>();
CreateMap<User, UserBasicInfo>()
.ForMember(d => d.UserTypeShortName, u => u.MapFrom(t => t.UserTypeRole.UserTypeShortName))
.ForMember(d => d.Code, u => u.MapFrom(t => t.UserCode))
.ForMember(d => d.PermissionStr, u => u.MapFrom(t => t.UserTypeRole.PermissionStr))
.ForMember(d => d.RealName, u => u.MapFrom(user => string.IsNullOrEmpty(user.FirstName) ? user.LastName : user.LastName + " / " + user.FirstName));
CreateMap<TrialExperience, TrialExperienceListDTO>()
.ForMember(d => d.Phase, u => u.MapFrom(t => t.Phase.Value))
.ForMember(d => d.EvaluationCriteriaList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteria.Value)))
.ForMember(d => d.EvaluationCriteriaIdList, u => u.MapFrom(t => t.ExperienceCriteriaList.Select(t => t.EvaluationCriteriaId)));
CreateMap<Doctor, UserBasicInfo>()
.ForMember(d => d.Code, u => u.MapFrom(t => t.ReviewerCode))
.ForMember(d => d.RealName, u => u.MapFrom(t => t.ChineseName))
.ForMember(d => d.IsReviewer, u => u.MapFrom(t => true))
.ForMember(d => d.UserName, u => u.MapFrom(doctor => doctor.LastName + " / " + doctor.FirstName));
#region 医生基本信息
CreateMap<Doctor, SelectionReviewerDTO>();
CreateMap<Doctor, DoctorDTO>().IncludeMembers(t => t.Hospital).Include<Doctor, SelectionReviewerDTO>()
.ForMember(d => d.AccountUserName, u => u.MapFrom(s => s.EnrollList.Where(t=>t.DoctorUserId!=null).Select(c=>c.DoctorUser.UserName).FirstOrDefault()))
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
.ForMember(d => d.DepartmentCN, u => u.MapFrom(s => s.Department.ValueCN))
.ForMember(d => d.Position, u => u.MapFrom(s => s.Position.Value))
.ForMember(d => d.PositionCN, u => u.MapFrom(s => s.Position.ValueCN))
.ForMember(d => d.Rank, u => u.MapFrom(s => s.Rank.Value))
.ForMember(d => d.RankCN, u => u.MapFrom(s => s.Rank.ValueCN))
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Speciality.Value))
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Speciality.ValueCN))
.ForMember(d => d.HasResume, u => u.MapFrom(s => s.AttachmentList.Any(u => u.Type == "Resume" && u.IsOfficial)))
.ForMember(d => d.Submitted, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == EnrollStatus.HasCommittedToCRO)))
.ForMember(d => d.Approved, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == EnrollStatus.InviteIntoGroup)))
.ForMember(d => d.Reading, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == EnrollStatus.DoctorReading)))
.ForMember(d => d.Finished, u => u.MapFrom(s => s.EnrollList.Count(t => t.EnrollStatus == EnrollStatus.Finished)))
.ForMember(d => d.Reconfirmed, u => u.MapFrom(s => s.ReviewStatus == ReviewerInformationConfirmStatus.ConfirmPass))
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
CreateMap<Hospital, DoctorDTO>();
CreateMap<EmploymentCommand, Doctor>();
//这样会左连接三次
// CreateMap<Doctor, DoctorBasicInfoDTO>()
//.ForMember(d => d.TitleCNList, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
//.Select(t => new { TitleCN = t.Dictionary.ValueCN, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.TitleCN)))
// .ForMember(d => d.TitleList, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
//.Select(t => new { Title = t.Dictionary.Value, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.Title)))
// .ForMember(d => d.TitleIds, u => u.MapFrom(s => s.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title)
//.Select(t => new { TitleId = t.Dictionary.Id, ShowOrder = t.Dictionary.ShowOrder }).OrderBy(k => k.ShowOrder).Select(t => t.TitleId)));
//这样只会查询一次
CreateMap<Doctor, DoctorBasicInfoDTO>()
.ForMember(o => o.DoctorDicViewDtos, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.Title).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
CreateMap<Dictionary, DicView>()
.ForMember(t=>t.ParentCode,u=>u.MapFrom(c=>c.Parent.Code));
//CreateMap<DoctorDictionary, DicView>();
CreateMap<Doctor, SpecialtyDTO>()
.ForMember(o => o.Speciality, t => t.MapFrom(u => u.Speciality.Value))
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)));
CreateMap<SpecialtyCommand, Doctor>();
//医生职业信息
CreateMap<Doctor, EmploymentDTO>().IncludeMembers(t => t.Hospital)
.ForMember(d => d.Department, u => u.MapFrom(s => s.Department.Value))
.ForMember(d => d.DepartmentCN, u => u.MapFrom(s => s.Department.ValueCN))
.ForMember(d => d.Position, u => u.MapFrom(s => s.Position.Value))
.ForMember(d => d.PositionCN, u => u.MapFrom(s => s.Position.ValueCN))
.ForMember(d => d.Rank, u => u.MapFrom(s => s.Rank.Value))
.ForMember(d => d.RankCN, u => u.MapFrom(s => s.Rank.ValueCN));
CreateMap<Hospital, EmploymentDTO>();
CreateMap<EnrollDetail, DoctorStateModelDTO>()
.ForMember(d => d.IntoGroupState, u => u.MapFrom(s => s.EnrollStatus))
.ForMember(d => d.OptTime, u => u.MapFrom(s => s.CreateTime))
.ForMember(d => d.OptUserName, u => u.MapFrom(s => s.CreateUser.UserName));
CreateMap<Enroll, ConfirmationReviewerDTO>().IncludeMembers(t => t.Doctor, t => t.Doctor.Hospital)
.ForMember(o => o.DictionaryList, t => t.MapFrom(u => u.Doctor.DoctorDicRelationList.Where(t => t.KeyName == StaticData.ReadingType || t.KeyName == StaticData.Subspeciality).Select(t => t.Dictionary).OrderBy(t => t.ShowOrder)))
.ForMember(d => d.Speciality, u => u.MapFrom(s => s.Doctor.Speciality.Value))
.ForMember(d => d.SpecialityCN, u => u.MapFrom(s => s.Doctor.Speciality.ValueCN))
.ForMember(d => d.Id, u => u.MapFrom(s => s.Doctor.Id))
.ForMember(d => d.Code, u => u.MapFrom(s => s.DoctorUser.UserName))
;
CreateMap<Doctor, ConfirmationReviewerDTO>();
CreateMap<Hospital, ConfirmationReviewerDTO>();
#endregion
}
}
}

View File

@ -1,715 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
public class CalculateService :BaseService, ICalculateService
{
private readonly IRepository<Payment> _paymentRepository;
private readonly IRepository<TrialPaymentPrice> _trialPaymentRepository;
private readonly IRepository<ReviewerPayInformation> _doctorPayInfoRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Workload> _doctorWorkloadRepository;
private readonly IRepository<RankPrice> _rankPriceRepository;
private readonly IRepository<PaymentDetail> _paymentDetailRepository;
private readonly IVolumeRewardService _volumeRewardPriceService;
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
private readonly IRepository<PaymentAdjustment> _payAdjustmentRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IMapper _mapper;
public CalculateService(IRepository<Payment> paymentRepository, IRepository<TrialPaymentPrice> trialPaymentPriceRepository,
IRepository<ReviewerPayInformation> reviewerPayInfoRepository,
IRepository<Trial> trialRepository,
IRepository<Doctor> doctorRepository,
IRepository<Workload> workloadRepository,
IRepository<RankPrice> rankPriceRepository,
IRepository<PaymentDetail> paymentDetailRepository,
IVolumeRewardService volumeRewardService,
IRepository<ExchangeRate> exchangeRateRepository,
IRepository<Enroll> EnrollRepository,
IRepository<PaymentAdjustment> paymentAdjustmentRepository, IMapper mapper)
{
_paymentRepository = paymentRepository;
_trialPaymentRepository = trialPaymentPriceRepository;
_doctorPayInfoRepository = reviewerPayInfoRepository;
_trialRepository = trialRepository;
_doctorRepository = doctorRepository;
_doctorWorkloadRepository = workloadRepository;
_rankPriceRepository = rankPriceRepository;
_paymentDetailRepository = paymentDetailRepository;
_volumeRewardPriceService = volumeRewardService;
_exchangeRateRepository = exchangeRateRepository;
_payAdjustmentRepository = paymentAdjustmentRepository;
this._enrollRepository = EnrollRepository;
_mapper = mapper;
}
/// <summary>
/// 获取某个月下的某些医生最终确认的工作量,用于计算月度费用
/// </summary>
private async Task< List<CalculatePaymentDTO>> GetFinalConfirmedWorkloadAndPayPriceList(CalculateDoctorAndMonthDTO calculateFeeParam)
{
Expression<Func<Workload, bool>> workloadLambda = x => true;
DateTime bTime = new DateTime(calculateFeeParam.CalculateMonth.Year, calculateFeeParam.CalculateMonth.Month, 1);
var eTime = bTime.AddMonths(1);
workloadLambda = workloadLambda.And(t =>
t.WorkTime >= bTime && t.WorkTime < eTime);
workloadLambda = workloadLambda.And(t => calculateFeeParam.NeedCalculateReviewers.Contains(t.DoctorId) && t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm);
var workLoadQueryable = from doctor in _doctorRepository.AsQueryable()
join workLoad in _doctorWorkloadRepository.Where(workloadLambda) on
doctor.Id equals workLoad.DoctorId
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
join trialPay in _trialPaymentRepository.AsQueryable() on trial.Id equals trialPay.TrialId
into temp
from trialPay in temp.DefaultIfEmpty()
join doctorPayInfo in _doctorPayInfoRepository.AsQueryable() on doctor.Id equals doctorPayInfo.DoctorId
join rankPrice in _rankPriceRepository.AsQueryable() on doctorPayInfo.RankId equals rankPrice.Id
select new CalculatePaymentDTO()
{
Id = workLoad.Id,
DoctorId = workLoad.DoctorId,
WorkTime = workLoad.WorkTime,
DataFrom = workLoad.DataFrom,
TrialId = workLoad.TrialId,
TrialCode = trial.TrialCode,
Timepoint = workLoad.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H,
Global = workLoad.Global,
Adjudication = workLoad.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H,
Training = workLoad.Training,
RefresherTraining = workLoad.RefresherTraining,
Downtime = workLoad.Downtime,
TrialAdditional = trialPay.TrialAdditional,
PersonalAdditional = doctorPayInfo.Additional,
AdjustmentMultiple = trialPay.AdjustmentMultiple,
TimepointPrice = rankPrice.Timepoint,
TimepointIn24HPrice = rankPrice.TimepointIn24H,
TimepointIn48HPrice = rankPrice.TimepointIn48H,
AdjudicationPrice = rankPrice.Adjudication,
AdjudicationIn24HPrice = rankPrice.AdjudicationIn24H,
AdjudicationIn48HPrice = rankPrice.AdjudicationIn48H,
DowntimePrice = rankPrice.Downtime,
GlobalPrice = rankPrice.Global,
TrainingPrice = rankPrice.Training,
RefresherTrainingPrice = rankPrice.RefresherTraining
};
return await workLoadQueryable.ToListAsync();
}
/// <summary>
/// 计算月度费用并调用AddOrUpdateMonthlyPayment和AddOrUpdateMonthlyPaymentDetail方法
/// 将费用计算的月度数据及详情保存
/// </summary>
[NonDynamicMethod]
public async Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param, string token)
{
var yearMonth = param.CalculateMonth.ToString("yyyy-MM");
var rate = await _exchangeRateRepository.FirstOrDefaultAsync(u => u.YearMonth == yearMonth);
decimal exchangeRate = rate?.Rate ?? 0;
var workLoadAndPayPriceList = await GetFinalConfirmedWorkloadAndPayPriceList(param);
var volumeRewardPriceList = await _volumeRewardPriceService.GetVolumeRewardPriceList();
#region 奖励数据校验
for (int i = 0; i < volumeRewardPriceList.Count; i++)
{
if (i == 0 && volumeRewardPriceList[i].Min != 0)
{
//---Volume reward data error.
return ResponseOutput.NotOk(_localizer["Cal_VolDataErr"]);
}
if (i > 0)
{
if (volumeRewardPriceList[i - 1].Max + 1 != volumeRewardPriceList[i].Min)
//---Volume reward data error.
return ResponseOutput.NotOk(_localizer["Cal_VolDataErr"]);
}
}
#endregion
List<PaymentModel> paymentList = new List<PaymentModel>();
List<ReviewerPaymentUSD> reviewerPaymentUSDList = new List<ReviewerPaymentUSD>();
// 获取所有医生费用 一次从数据库里面全部取出来
var allDoctorList = workLoadAndPayPriceList.Where(x => param.NeedCalculateReviewers.Contains(x.DoctorId)).ToList();
var allDoctorIds = allDoctorList.Select(x => x.DoctorId).Distinct().ToList();
var listTrialId = allDoctorList.Select(x => x.TrialId).Distinct().ToList();
var trialDoctorlist= await (from enroll in _enrollRepository.Where(x=> listTrialId.Contains(x.TrialId)|| allDoctorIds.Contains(x.DoctorId))
join price in _trialPaymentRepository.Where() on enroll.TrialId equals price.TrialId
select new DoctorPrice()
{
IsNewTrial = price.IsNewTrial,
AdjustmentMultiple = enroll.AdjustmentMultiple,
TrialId=enroll.TrialId,
DoctorId = enroll.DoctorId,
Training=enroll.Training,
Adjudication=enroll.Adjudication,
Adjudication24H=enroll.Adjudication24H,
Adjudication48H= enroll.Adjudication48H,
Downtime=enroll.Downtime,
Global=enroll.Global,
RefresherTraining=enroll.RefresherTraining,
Timepoint= enroll.Timepoint,
Timepoint24H=enroll.Timepoint24H,
Timepoint48H=enroll.Timepoint48H,
}).ToListAsync();
foreach (var doctor in param.NeedCalculateReviewers)
{
if (await _paymentRepository.AnyAsync(u => u.DoctorId == doctor && u.YearMonth == yearMonth && u.IsLock))
{
break;
}
List<PaymentDetailCommand> paymentDetailList = new List<PaymentDetailCommand>();
decimal totalNormal = 0;
//计算单个医生费用统,并且插入到统计表
var doctorWorkloadAndPayPriceList = workLoadAndPayPriceList.Where(u => u.DoctorId == doctor).ToList();
//阅片数量 计算奖励费用
int readCount = 0;
int codeOrder = 0;
//这里需要改
foreach (var item in doctorWorkloadAndPayPriceList)
{
var doctordata = trialDoctorlist.Where(x => x.IsNewTrial ?? false && x.Training == item.Training && x.DoctorId == item.DoctorId).FirstOrDefault();
if (doctordata != null)
{
item.Training = doctordata.Training??0;
item.Adjudication = doctordata.Adjudication??0;
item.AdjudicationIn24H = doctordata.Adjudication24H??0;
item.AdjudicationIn48H = doctordata.Adjudication48H??0;
item.Downtime = doctordata.Downtime??0;
item.Global = doctordata.Global??0;
item.RefresherTraining = doctordata.RefresherTraining??0;
item.Timepoint = doctordata.Timepoint??0;
item.TimepointIn24H = doctordata.Timepoint24H??0;
item.TimepointIn48H = doctordata.Timepoint48H??0;
item.PersonalAdditional = 0;
}
++codeOrder;
readCount += (item.Timepoint + item.TimepointIn24H + item.TimepointIn48H
+ item.Adjudication + item.AdjudicationIn24H + item.AdjudicationIn48H);
decimal trainingTotal = item.Training * item.TrainingPrice;
decimal refresherTrainingTotal = item.RefresherTraining * item.RefresherTrainingPrice;
decimal downtimeTotal = item.Downtime * item.DowntimePrice;
//规则定义 global 的价格是Tp和个人附加的一半
decimal globalTotal = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2);
//项目如果没有添加附加数据 默认为0
decimal timePointTotal = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional));
decimal timePointIn24HTotal = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
decimal timePointIn48HTotal = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
decimal adjudicationTotal = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional));
decimal adjudicationIn24HTotal = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
decimal adjudicationIn48HTotal = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional);
totalNormal += (trainingTotal + refresherTrainingTotal + downtimeTotal + globalTotal + timePointTotal + timePointIn24HTotal
+ timePointIn48HTotal + adjudicationTotal + adjudicationIn24HTotal + adjudicationIn48HTotal);
#region 统计明细信息
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Training",
Count = item.Training,
BasePrice = item.TrainingPrice,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 1,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.Training * item.TrainingPrice,
PaymentCNY = item.Training * item.TrainingPrice * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Refresher Training",
Count = item.RefresherTraining,
BasePrice = item.RefresherTrainingPrice,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 2,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.RefresherTraining * item.RefresherTrainingPrice,
PaymentCNY = item.RefresherTraining * item.RefresherTrainingPrice * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Downtime",
Count = item.Downtime,
BasePrice = item.DowntimePrice,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 3,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.Downtime * item.DowntimePrice,
PaymentCNY = item.Downtime * item.DowntimePrice * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Timepoint Regular",
Count = item.Timepoint,
BasePrice = item.TimepointPrice,
PersonalAdditional = doctordata!=null?0: item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.TimepointPrice * (item.AdjustmentMultiple - 1) + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional),
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 4,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)),
PaymentCNY = item.Timepoint * (item.TimepointPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Timepoint 48-Hour",
Count = item.TimepointIn48H,
BasePrice = item.TimepointIn48HPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.TimepointIn48HPrice * (item.AdjustmentMultiple - 1) + 0,//48小时不加项目附加
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 5,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
PaymentCNY = item.TimepointIn48H * (item.TimepointIn48HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Timepoint 24-Hour",
Count = item.TimepointIn24H,
BasePrice = item.TimepointIn24HPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.TimepointIn24HPrice * (item.AdjustmentMultiple - 1) + 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 6,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
PaymentCNY = item.TimepointIn24H * (item.TimepointIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Adjudication Regular",
Count = item.Adjudication,
BasePrice = item.AdjudicationPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.AdjudicationPrice * (item.AdjustmentMultiple - 1) + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional),
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 7,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)),
PaymentCNY = item.Adjudication * (item.AdjudicationPrice * item.AdjustmentMultiple + item.PersonalAdditional + (item.TrialAdditional == null ? 0 : (decimal)item.TrialAdditional)) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Adjudication 48-Hour",
Count = item.AdjudicationIn48H,
BasePrice = item.AdjudicationIn48HPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.AdjudicationIn48HPrice * (item.AdjustmentMultiple - 1) + 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 8,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional + 0),
PaymentCNY = item.AdjudicationIn48H * (item.AdjudicationIn48HPrice * item.AdjustmentMultiple + item.PersonalAdditional + 0) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Adjudication 24-Hour",
Count = item.AdjudicationIn24H,
BasePrice = item.AdjudicationIn24HPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional,
TrialAdditional = doctordata != null ? 0 : item.AdjudicationIn24HPrice * (item.AdjustmentMultiple - 1) + 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 9,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional),
PaymentCNY = item.AdjudicationIn24H * (item.AdjudicationIn24HPrice * item.AdjustmentMultiple + 0 + item.PersonalAdditional) * exchangeRate
});
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = item.TrialCode,
PaymentType = "Global",
Count = item.Global,
BasePrice = item.TimepointPrice / 2,//item.GlobalPrice,
PersonalAdditional = doctordata != null ? 0 : item.PersonalAdditional / 2,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = item.DoctorId,
TrialId = item.TrialId,
ShowTypeOrder = 10,
ShowCodeOrder = codeOrder,
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2),
PaymentCNY = item.Global * (item.TimepointPrice / 2 + item.PersonalAdditional / 2) * exchangeRate
});
#endregion
}
int typeOrder = 0;
if (readCount > 0)
{
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = "Volume Reward",
PaymentType = "Total TP & AD",
Count = readCount,
BasePrice = 0,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = doctor,
TrialId = Guid.Empty,
ShowTypeOrder = typeOrder,
ShowCodeOrder = (++codeOrder),
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = 0,
PaymentCNY = 0
});
foreach (var awardItem in volumeRewardPriceList)
{
++typeOrder;
if ((readCount - awardItem.Min + 1) < 0)
{
break;
}
if (awardItem.Min == 0)
{
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = "Volume Reward",
PaymentType = awardItem.Min + "-" + awardItem.Max,
Count = readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min),
BasePrice = awardItem.Price,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,//result.Data,
DoctorId = doctor,
TrialId = Guid.Empty,
ShowTypeOrder = typeOrder,
ShowCodeOrder = (++codeOrder),
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = (readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min)) * awardItem.Price,
PaymentCNY = (readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min) : (readCount - awardItem.Min)) * awardItem.Price * exchangeRate
});
}
else
{
paymentDetailList.Add(new PaymentDetailCommand
{
TrialCode = "Volume Reward",
PaymentType = awardItem.Min + "-" + awardItem.Max,
Count = readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1),
BasePrice = awardItem.Price,
PersonalAdditional = 0,
TrialAdditional = 0,
PaymentId = Guid.Empty,
DoctorId = doctor,
TrialId = Guid.Empty,
ShowTypeOrder = typeOrder,
ShowCodeOrder = (++codeOrder),
ExchangeRate = exchangeRate,
YearMonth = yearMonth,
PaymentUSD = (readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1)) * awardItem.Price,
PaymentCNY = (readCount >= awardItem.Max ?
(awardItem.Max - awardItem.Min + 1) : (readCount - awardItem.Min + 1)) * awardItem.Price * exchangeRate
});
}
}
}
decimal award = 0;
volumeRewardPriceList = volumeRewardPriceList.OrderBy(u => u.Min).ToList();
var levelTemp = -1; //用来计算属于哪一个挡位
foreach (var awarPriceitem in volumeRewardPriceList)
{
if (awarPriceitem.Min == 0)
{
if (readCount > awarPriceitem.Max)
{
++levelTemp;
award += (awarPriceitem.Max - awarPriceitem.Min) * awarPriceitem.Price;
}
if (awarPriceitem.Min < readCount && readCount < awarPriceitem.Max)
{
++levelTemp;
award += (readCount - awarPriceitem.Min) * awarPriceitem.Price;
break; ;
}
}
else
{
if (readCount > awarPriceitem.Max)
{
++levelTemp;
award += (awarPriceitem.Max - awarPriceitem.Min + 1) * awarPriceitem.Price;
}
if (awarPriceitem.Min < readCount && readCount < awarPriceitem.Max)
{
++levelTemp;
award += (readCount - awarPriceitem.Min + 1) * awarPriceitem.Price;
break; ;
}
}
}
decimal totalUSD = award + totalNormal;//总费用
var result = await AddOrUpdateMonthlyPayment(new PaymentCommand
{
DoctorId = doctor,
Year = param.CalculateMonth.Year,
Month = param.CalculateMonth.Month,
PaymentUSD = totalUSD,
CalculateUser = token,
CalculateTime = DateTime.Now,
ExchangeRate = exchangeRate,
PaymentCNY = exchangeRate * totalUSD,
});
reviewerPaymentUSDList.Add(new ReviewerPaymentUSD { DoctorId = doctor, PaymentUSD = totalUSD, RecordId = result.Data });
foreach (var detail in paymentDetailList)
{
//var data = trialDoctorlist.FirstOrDefault(x => x.DoctorId == detail.DoctorId && x.TrialId == detail.TrialId && x.IsNewTrial == true && (x.AdjustmentMultiple??0) != 0);
//if (data != null)
//{
// detail.BasePrice = data.AdjustmentMultiple??0;
// detail.PersonalAdditional = 0;
// detail.TrialAdditional = 0;
//}
detail.PaymentId = result.Data;
}
await AddOrUpdateMonthlyPaymentDetail(paymentDetailList, result.Data);
await UpdatePaymentAdjustment(doctor, yearMonth);
}
return ResponseOutput.Ok(reviewerPaymentUSDList);
}
// 重新计算调整费用
private async Task UpdatePaymentAdjustment(Guid reviewerId, string yearMonth)
{
var adjustList = await _payAdjustmentRepository.Where(u => u.YearMonth == yearMonth &&
!u.IsLock && u.ReviewerId == reviewerId).ToListAsync();
var needUpdatePayment = adjustList.GroupBy(t => t.ReviewerId).Select(g => new
{
ReviewerId = g.Key,
AdjustCNY = g.Sum(t => t.AdjustmentCNY),
AdjustUSD = g.Sum(t => t.AdjustmentUSD)
});
foreach (var reviewer in needUpdatePayment)
{
await _paymentRepository.BatchUpdateNoTrackingAsync(u => u.YearMonth == yearMonth &&
!u.IsLock && u.DoctorId == reviewer.ReviewerId, t => new Payment()
{
AdjustmentUSD = reviewer.AdjustUSD,
AdjustmentCNY = reviewer.AdjustCNY
});
}
}
/// <summary>
/// 保存费用计算的月度数据
/// </summary>
private async Task<IResponseOutput<Guid>> AddOrUpdateMonthlyPayment(PaymentCommand addOrUpdateModel)
{
var success = false;
var paymentModel = await _paymentRepository.FirstOrDefaultAsync(t =>
t.DoctorId == addOrUpdateModel.DoctorId && t.YearMonth == addOrUpdateModel.YearMonth);
//var taxCNY = GetTax(addOrUpdateModel.PaymentCNY);
//var actuallyPaidCNY = addOrUpdateModel.PaymentCNY - taxCNY;
//var bankTransferCNY = addOrUpdateModel.PaymentCNY - taxCNY;
if (paymentModel == null)
{
var payment = _mapper.Map<Payment>(addOrUpdateModel);
//payment.BankTransferCNY = bankTransferCNY;
//payment.TaxCNY= taxCNY;
//payment.BankTransferCNY = bankTransferCNY;
payment.YearMonthDate = DateTime.Parse(payment.YearMonth);
payment =await _paymentRepository.AddAsync(payment);
success =await _paymentRepository.SaveChangesAsync();
return ResponseOutput.Result(success, payment.Id);
}
else
{
// 如果是 当月计算的工作量费用 和 调整费用都为0则删除该行记录
if (addOrUpdateModel.PaymentUSD == 0 && paymentModel.AdjustmentUSD == 0)
{
success =await _paymentRepository.BatchDeleteNoTrackingAsync(u => u.Id == paymentModel.Id);
//_paymentDetailRepository.Delete(u=>u.PaymentId==paymentModel.Id);
}
else
{
success = await _paymentRepository.BatchUpdateNoTrackingAsync(t => t.Id == paymentModel.Id, u => new Payment()
{
PaymentUSD = addOrUpdateModel.PaymentUSD,
CalculateTime = addOrUpdateModel.CalculateTime,
CalculateUser = addOrUpdateModel.CalculateUser,
//TaxCNY = taxCNY,
//ActuallyPaidCNY = actuallyPaidCNY,
//BankTransferCNY = bankTransferCNY,
PaymentCNY = addOrUpdateModel.PaymentCNY,
ExchangeRate = addOrUpdateModel.ExchangeRate
});
}
return ResponseOutput.Result(success, paymentModel.Id);
}
}
/// <summary>
/// 保存费用计算的月度详情
/// </summary>
private async Task<bool> AddOrUpdateMonthlyPaymentDetail(List<PaymentDetailCommand> addOrUpdateList, Guid paymentId)
{
//var paymentDetailIds = addOrUpdateList.Select(t => t.PaymentId).ToList();
await _paymentDetailRepository.BatchDeleteNoTrackingAsync(t => t.PaymentId == paymentId);
await _paymentDetailRepository.AddRangeAsync(_mapper.Map<List<PaymentDetail>>(addOrUpdateList));
return await _paymentDetailRepository.SaveChangesAsync();
}
/// <summary>
/// 获取待计算费用的Reviewer对应的月份列表
/// </summary>
public async Task<List<CalculateNeededDTO>> GetNeedCalculateReviewerList(Guid reviewerId, string yearMonth)
{
Expression<Func<Payment, bool>> calculateLambda = u => !u.IsLock;
if (reviewerId != Guid.Empty)
{
calculateLambda = calculateLambda.And(u => u.DoctorId == reviewerId);
}
if (!string.IsNullOrWhiteSpace(yearMonth))
{
calculateLambda = calculateLambda.And(u => u.YearMonth == yearMonth);
}
return await _paymentRepository.Where(calculateLambda).ProjectTo<CalculateNeededDTO>(_mapper.ConfigurationProvider).ToListAsync();
}
/// <summary>
/// 查询Reviewer某个月的费用是否被锁定
/// </summary>
public async Task<bool> IsLock(Guid reviewerId, string yearMonth)
{
return await _paymentRepository.AnyAsync(u => u.DoctorId == reviewerId && u.YearMonth == yearMonth && u.IsLock);
}
//public bool ResetMonthlyPayment(Guid reviewerId, Guid trialId, string yearMonth)
//{
// var payment = _paymentRepository.FindSingleOrDefault(u => u.DoctorId == reviewerId && u.YearMonth == yearMonth);
// payment.PaymentCNY = 0;
// payment.PaymentUSD = 0;
// _paymentRepository.Update(payment);
// _paymentDetailRepository.Delete(u=>u.DoctorId==reviewerId && u.TrialId==trial)
//}
}
}

View File

@ -1,37 +0,0 @@
using System;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public class AwardPriceDTO: AwardPriceCalculateDTO
{
public Guid Id { get; set; }
}
public class AwardPriceCalculateDTO
{
public decimal Price { get; set; }
public int Max { get; set; }
public int Min { get; set; }
}
public class AwardPriceCommand
{
//public Guid Id { get; set; }
public decimal Price { get; set; }
public int Min { get; set; }
public int Max { get; set; }
public Guid OptUserId { get; set; }
}
public class AwardPriceQueryDTO : PageInput
{
}
public class ExchangeRateQueryDTO : PageInput
{
public DateTime? SearchMonth { get; set; }
}
}

View File

@ -1,44 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class CalculateNeededDTO
{
public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public string YearMonth { get; set; } = String.Empty;
public bool IsLock { get; set; }
}
public class DoctorPrice
{
public decimal? AdjustmentMultiple { get; set; }
public Guid? DoctorId { get; set; }
public Guid? TrialId { get; set; }
public bool? IsNewTrial { get; set; }
public int? Training { get; set; }
public int? RefresherTraining { get; set; }
public int? Timepoint { get; set; }
public int? Timepoint48H { get; set; }
public int? Timepoint24H { get; set; }
public int? Adjudication { get; set; }
public int? Adjudication48H { get; set; }
public int? Adjudication24H { get; set; }
public int? Global { get; set; }
public int? Downtime { get; set; }
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class ExchangeRateCommand
{
public Guid? Id { get; set; }
public string YearMonth { get; set; }=String.Empty;
public decimal Rate { get; set; }
public DateTime UpdateTime { get; set; }
}
}

View File

@ -1,54 +0,0 @@
using System;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts.Pay
{
public class PaymentAdjustmentCommand
{
public Guid? Id { get; set; }
public Guid ReviewerId { get; set; }
public DateTime YearMonth { get; set; }
public decimal AdjustPaymentUSD { get; set; }
public decimal AdjustPaymentCNY { get; set; }
public string Note { get; set; } = string.Empty;
}
public class PaymentAdjustmentDTO
{
public Guid Id { get; set; }
public Guid ReviewerId { get; set; }
public string YearMonth { get; set; }=String.Empty;
public DateTime YearMonthDate { get; set; }
public bool IsLock { get; set; }
public decimal AdjustPaymentUSD { get; set; }
public decimal AdjustPaymentCNY { get; set; }
public string Note { get; set; } = String.Empty;
}
public class PaymentAdjustmentDetailDTO: PaymentAdjustmentDTO
{
public string ReviewerCode { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string FullName => LastName + " / " + FirstName;
public string ChineseName { get; set; } = String.Empty;
}
public class PaymentAdjustmentQueryDTO:PageInput
{
public string TrialCode { get; set; } = string.Empty;
public string Reviewer { get; set; } = string.Empty;
public DateTime BeginMonth { get; set; }
public DateTime EndMonth { get; set; }
}
public class DoctorSelectDTO
{
public Guid Id { get; set; }
public string Code { get; set; } = string.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string FullName => LastName + " / " + FirstName;
public string ChineseName { get; set; } = String.Empty;
}
}

View File

@ -1,195 +0,0 @@
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts.Pay
{
public class PaymentDetailDTO
{
public Guid Id { get; set; }
public Guid PaymentId { get; set; }
public string YearMonth { get; set; } = String.Empty;
public Guid DoctorId { get; set; }
public Guid TrialId { get; set; }
public string TrialCode { get; set; } = String.Empty;
public string PaymentType { get; set; } = String.Empty;
public int Count { get; set; }
public decimal BasePrice { get; set; }
public decimal PersonalAdditional { get; set; }
public decimal? NewPersonalAdditional { get; set; }
public decimal TrialAdditional { get; set; }
public int ShowTypeOrder { get; set; }
public int ShowCodeOrder { get; set; }
public decimal ExchangeRate { get; set; }
public decimal PaymentUSD { get; set; }
public decimal PaymentCNY { get; set; }
public bool? IsNewTrial { get; set; }
public decimal TotalUnitPrice => BasePrice + PersonalAdditional + TrialAdditional;
public AdjustmentDTO AdjustmentView { get; set; } = new AdjustmentDTO();
}
public class AdjustmentDTO
{
public decimal AdjustPaymentUSD { get; set; }
public decimal AdjustPaymentCNY { get; set; }
public string AdjustType
{
get
{
if (AdjustPaymentUSD > 0)
{
return "+";
}
else if (AdjustPaymentUSD < 0)
{
return "-";
}
else { return string.Empty; }
}
}
public string Note { get; set; } = String.Empty;
}
public class PaymentDetailCommand : PaymentDetailDTO
{
}
public class PayDetailDTO
{
public IEnumerable<PaymentDetailDTO> DetailList { get; set; } = new List<PaymentDetailDTO>();
public DoctorPayInfo DoctorInfo { get; set; } = new DoctorPayInfo();
}
public class LockPaymentDTO
{
public List<Guid> ReviewerIdList { get; set; }=new List<Guid>();
public DateTime Month { get; set; }
public bool IsLock { get; set; } = true;
}
public class DoctorPayInfo
{
public Guid DoctorId { get; set; }
public string ChineseName { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string Phone { get; set; } = String.Empty;
public string PayTitle { get; set; } = String.Empty;
public string Code { get; set; } = String.Empty;
public string YearMonth { get; set; } = String.Empty;
}
public class ReviewerPaymentUSD
{
public Guid RecordId { get; set; }
public Guid DoctorId { get; set; }
public decimal PaymentUSD { get; set; }
}
public class PaymentQueryDTO : PageInput
{
public string Reviewer { get; set; } = String.Empty;
public DateTime BeginMonth { get; set; }
public DateTime EndMonth { get; set; }
public int? Nation { get; set; }
}
public class MonthlyPaymentDTO
{
public Guid ReviewerId { get; set; }
public string ReviewerCode { get; set; } = String.Empty;
public string ChineseName { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string FullName { get; set; } = String.Empty;
public decimal AdjustmentUSD { get; set; }
public decimal AdjustmentCNY { get; set; }
public decimal PaymentUSD { get; set; }
public decimal PaymentCNY { get; set; }
public decimal TotalUSD { get; set; }
public decimal TotalCNY { get; set; }
}
public class VolumeStatisticsDTO
{
public Guid StatisticsId { get; set; }
public string Month { get; set; } = String.Empty;
public decimal VolumeReward { get; set; }
public decimal ExchangeRate { get; set; }
public decimal AdjustmentUSD { get; set; }
public decimal AdjustmentCNY { get; set; }
public decimal PaymentUSD { get; set; }
public decimal PaymentCNY { get; set; }
public decimal TotalCNY => AdjustmentCNY + PaymentCNY;
public decimal TotalUSD => AdjustmentUSD + PaymentUSD;
public List<TrialPaymentDTO> TrialPaymentList = new List<TrialPaymentDTO>();
}
public class TrialPaymentDTO
{
public Guid TrialId { get; set; }
public string TrialCode { get; set; } = String.Empty;
public decimal TrialPayment { get; set; }
}
public class VolumeQueryDTO
{
public DateTime BeginMonth { get; set; }
public DateTime EndMonth { get; set; }
public Guid ReviewerId { get; set; }
}
public class RevenuesDTO
{
public List<string> MissingTrialCodes = new List<string>();
public Guid Id { get; set; }
public string TrialCode { get; set; } = String.Empty;
public Guid TrialId { get; set; }
public string Indication { get; set; } = String.Empty;
public Guid? CroId { get; set; }
public string Cro { get; set; } = string.Empty;
public int Expedited { get; set; }
public string ChineseName { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string ReviewerCode { get; set; } = string.Empty;
public decimal Training { get; set; }
public decimal Downtime { get; set; }
public decimal Timepoint { get; set; }
public decimal TimepointIn24H { get; set; }
public decimal TimepointIn48H { get; set; }
public decimal Adjudication { get; set; }
public decimal AdjudicationIn24H { get; set; }
public decimal AdjudicationIn48H { get; set; }
public decimal Global { get; set; }
public decimal Total { get; set; }
public string YearMonth { get; set; } = String.Empty;
}
}

View File

@ -1,179 +0,0 @@
using System;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts
{
public class PaymentDTO
{
public PageOutput<PaymentModel> CostList { get; set; }=new PageOutput<PaymentModel>();
public decimal ExchangeRate { get; set; }
}
public class PaymentModel
{
public Guid Id { get; set; }
public string RankName { get; set; } = String.Empty;
public Guid DoctorId { get; set; }
public string YearMonth { get; set; } = String.Empty;
public DateTime YearMonthDate { get; set; }
public DateTime? CalculateTime { get; set; }
public string CalculateUser { get; set; } = String.Empty;
//额外信息
public string Code { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string ChineseName { get; set; } = String.Empty;
public string Phone { get; set; } = String.Empty;
public string DoctorNameInBank { get; set; } = String.Empty;
public string IDCard { get; set; } = String.Empty;
public string BankCardNumber { get; set; } = String.Empty;
public string BankName { get; set; } = String.Empty;
public bool IsLock { get; set; } = false;
public decimal ExchangeRate { get; set; }
public decimal PaymentCNY { get; set; }
public decimal AdjustPaymentCNY { get; set; }
public decimal TotalPaymentCNY { get; set; }
public decimal PaymentUSD { get; set; }
public decimal AdjustPaymentUSD { get; set; }
public decimal TotalPaymentUSD { get; set; }
}
public class PaymentCommand
{
public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public string YearMonth => new DateTime(Year, Month, 1).ToString("yyyy-MM");
public int Year { get; set; }
public int Month { get; set; }
public decimal PaymentUSD { get; set; }
public DateTime CalculateTime { get; set; }
public decimal PaymentCNY { get; set; }
public decimal ExchangeRate { get; set; }
public string CalculateUser { get; set; } = String.Empty;
}
public class MonthlyPaymentQueryDTO : PageInput
{
public DateTime StatisticsDate { get; set; }
public string KeyWord { get; set; } = String.Empty;
public int? Nation { get; set; }
}
public class MonthlyPaymentDetailQuery
{
public Guid PaymentId { get; set; }
public Guid ReviewerId { get; set; }
public DateTime YearMonth { get; set; }
}
//public class LaborPaymentQuery
//{
// public Guid PaymentId { get; set; }
// public Guid ReviewerId { get; set; }
// public DateTime YearMonth { get; set; }
//}
public class TrialAnalysisDTO
{
public Guid TrialId { get; set; }
public string Indication { get; set; } = String.Empty;
public string TrialCode { get; set; } = String.Empty;
public string Cro { get; set; } = string.Empty;
public int Expedited { get; set; }
public string Type { get; set; } = String.Empty;
public decimal PaymentUSD { get; set; }
public decimal RevenusUSD { get; set; }
public decimal GrossProfit => RevenusUSD - PaymentUSD;
public decimal GrossProfitMargin
{
get {
if (RevenusUSD == 0)
return 0;
else
{
return GrossProfit / RevenusUSD;
}
}
}
}
public class LaborPayment
{
public string ChineseName { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string ResidentId { get; set; } = String.Empty;
public string Phone { get; set; } = String.Empty;
public string AccountNumber { get; set; } = String.Empty;
public string Bank { get; set; } = String.Empty;
public string YearMonth { get; set; } = String.Empty;
public decimal PaymentCNY { get; set; }
public decimal TaxCNY { get; set; }
public decimal ActuallyPaidCNY { get; set; }
public decimal BankTransferCNY { get; set; }
}
public class ReviewerAnalysisDTO
{
public List<string> MissingTrialCodes = new List<string>();
public string ChineseName { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public Guid ReviewerId { get; set; }
public string ReviewerCode { get; set; } = String.Empty;
public decimal PaymentUSD { get; set; }
public decimal RevenusUSD { get; set; }
public decimal GrossProfit => RevenusUSD - PaymentUSD;
public decimal GrossProfitMargin
{
get {
if (RevenusUSD == 0)
return 0;
else
{
return GrossProfit / RevenusUSD;
}
}
}
}
public class AnalysisQueryDTO
{
public string Reviewer { get; set; } = String.Empty;
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
public int? Nation { get; set; }
}
public class TrialAnalysisQueryDTO
{
public Guid? CroId { get; set; }
public string TrialCode { get; set; } = String.Empty;
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
//public AttendedReviewerType? AttendedReviewerType { get; set; }
}
}

View File

@ -1,50 +0,0 @@
using System;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts
{
public class RankPriceDTO
{
public Guid Id { get; set; }
public string RankName { get; set; } = string.Empty;
public decimal Timepoint { get; set; }
public decimal TimepointIn24H { get; set; }
public decimal TimepointIn48H { get; set; }
public decimal Adjudication { get; set; }
public decimal AdjudicationIn24H { get; set; }
public decimal AdjudicationIn48H { get; set; }
public decimal Global { get; set; }
public decimal Training { get; set; }
public decimal Downtime { get; set; }
public decimal RefresherTraining { get; set; }
public int ShowOrder { get; set; }
}
public class RankDic
{
public Guid Id { get; set; }
public string RankName { get; set; } = string.Empty;
}
public class RankPriceCommand
{
public Guid? Id { get; set; }
public string RankName { get; set; } = string.Empty;
public decimal Timepoint { get; set; }
public decimal TimepointIn24H { get; set; }
public decimal TimepointIn48H { get; set; }
public decimal Adjudication { get; set; }
public decimal AdjudicationIn24H { get; set; }
public decimal AdjudicationIn48H { get; set; }
public decimal Global { get; set; }
public decimal Training { get; set; }
public decimal Downtime { get; set; }
public decimal RefresherTraining { get; set; }
}
public class RankPriceQueryDTO : PageInput
{
}
}

View File

@ -1,40 +0,0 @@
using System;
namespace IRaCIS.Application.Contracts
{
public class ReviewerPayInfoQueryDTO
{
public Guid DoctorId { get; set; }
public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;
public string ChineseName { get; set; } = String.Empty;
public string Code { get; set; } = String.Empty;
public string Phone { get; set; } = String.Empty;
public string DoctorNameInBank { get; set; } = String.Empty;
public string IDCard { get; set; } = String.Empty;
public string BankCardNumber { get; set; } = String.Empty;
public string BankName { get; set; } = String.Empty;
public Guid? RankId { get; set; }
public decimal? Additional { get; set; }
public DateTime? CreateTime { get; set; }
}
public class DoctorPayInfoQueryListDTO : ReviewerPayInfoQueryDTO
{
public string Hospital { get; set; } = String.Empty;
public string RankName { get; set; } = String.Empty;
}
public class ReviewerPayInfoCommand
{
//public Guid Id { get; set; }
public Guid DoctorId { get; set; }
public string DoctorNameInBank { get; set; } = String.Empty;
public string IDCard { get; set; } = String.Empty;
public string BankCardNumber { get; set; } = String.Empty;
public string BankName { get; set; } = String.Empty;
public Guid RankId { get; set; }
public decimal? Additional { get; set; }
}
}

View File

@ -1,46 +0,0 @@
using IRaCIS.Core.Domain.Share;
using System;
namespace IRaCIS.Application.Contracts
{
public class DtoDoctorList
{
public Guid TrialId { get; set; }
public string Name { get; set; }
}
public class TrialPaymentPriceDTO
{
public Guid TrialId { get; set; }
public string TrialCode { get; set; } = String.Empty;
public string Indication { get; set; } = String.Empty;
public string Cro { get; set; } = String.Empty;
public int Expedited { get; set; }
public bool? IsNewTrial { get; set; }
public decimal? TrialAdditional { get; set; }
public DateTime? CreateTime { get; set; }
public string SowName { get; set; } = String.Empty;
public string SowPath { get; set; } = String.Empty;
public string SowFullPath => SowPath;
public decimal AdjustmentMultiple { get; set; } = 1;
public string DoctorsNames{ get; set; }=String.Empty;
public string ReviewMode { get; set; } = String.Empty;
}
public class TrialPaymentPriceCommand
{
public Guid TrialId { get; set; }
public decimal TrialAdditional { get; set; }
public decimal AdjustmentMultiple { get; set; }
public bool? IsNewTrial { get; set; }
}
}

View File

@ -1,37 +0,0 @@
using System;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Contracts
{
public class TrialRevenuesPriceDTO
{
public Guid TrialId { get; set; }
public decimal Timepoint { get; set; }
public decimal TimepointIn24H { get; set; }
public decimal TimepointIn48H { get; set; }
public decimal Adjudication { get; set; }
public decimal AdjudicationIn24H { get; set; }
public decimal AdjudicationIn48H { get; set; }
public decimal RefresherTraining { get; set; }
public decimal Global { get; set; }
public decimal Training { get; set; }
public decimal Downtime { get; set; }
}
public class TrialRevenuesPriceDetialDTO : TrialRevenuesPriceDTO
{
public Guid Id { get; set; }
public string TrialCode { get; set; } = String.Empty;
public string Indication { get; set; } = string.Empty;
public int Expedited { get; set; }
public string ReviewMode { get; set; } = String.Empty;
public string Cro { get; set; } = String.Empty;
}
public class TrialRevenuesPriceQueryDTO : PageInput
{
public string KeyWord { get; set; } = String.Empty;
public Guid? CroId { get; set; }
}
}

View File

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.Contracts
{
public class RevenusVerifyQueryDTO
{
public DateTime BeginDate { get; set; } = DateTime.Now;
public DateTime EndDate { get; set; } = DateTime.Now;
}
public class AnalysisVerifyQueryDTO
{
public DateTime BeginDate { get; set; } = DateTime.Now;
public DateTime EndDate { get; set; } = DateTime.Now;
}
public class AnalysisNeedLockDTO
{
public string YearMonth { get; set; } = string.Empty;
public string ReviewerCode { get; set; } = string.Empty;
public string ReviewerName { get; set; } = string.Empty;
public string ReviewerNameCN { get; set; } = string.Empty;
}
public class AnalysisVerifyResultDTO
{
public List<MonthlyResult> MonthVerifyResult = new List<MonthlyResult>();
public List<RevenusVerifyDTO> RevenuesVerifyList = new List<RevenusVerifyDTO>();
}
public class MonthlyResult
{
public string YearMonth { get; set; } = string.Empty;
public List<string> ReviewerNameList = new List<string>();
public List<string> ReviewerNameCNList = new List<string>();
public List<string> ReviewerCodeList = new List<string>();
}
public class RevenusVerifyDTO
{
public string TrialCode { get; set; } = string.Empty;
public bool Training { get; set; } = false;
public bool Downtime { get; set; } = false;
public bool Global { get; set; } = false;
public bool Timepoint { get; set; } = false;
public bool TimepointIn24H { get; set; } = false;
public bool TimepointIn48H { get; set; } = false;
public bool Adjudication { get; set; } = false;
public bool AdjudicationIn24H { get; set; } = false;
public bool AdjudicationIn48H { get; set; } = false;
}
}

View File

@ -1,117 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Financial")]
public class ExchangeRateService : BaseService, IExchangeRateService
{
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
private readonly IRepository<Payment> _paymentRepository;
public ExchangeRateService(IRepository<ExchangeRate> exchangeRateRepository, IRepository<Payment> paymentRepository)
{
_exchangeRateRepository = exchangeRateRepository;
_paymentRepository = paymentRepository;
}
[NonDynamicMethod]
public async Task<IResponseOutput> AddOrUpdateExchangeRate(ExchangeRateCommand model)
{
if (model.Id == Guid.Empty || model.Id == null)
{
var existItem = await _exchangeRateRepository.FirstOrDefaultAsync(u => u.YearMonth == model.YearMonth);
if (existItem != null)
{
//---The exchange rate of the same month already existed.
return ResponseOutput.NotOk(_localizer["ExR_SameMthExist"]);
}
var rate = _mapper.Map<ExchangeRate>(model);
rate = await _exchangeRateRepository.AddAsync(rate);
if (await _exchangeRateRepository.SaveChangesAsync())
{
return ResponseOutput.Ok(rate.Id.ToString());
}
else
{
return ResponseOutput.NotOk();
}
}
else
{
var success = await _exchangeRateRepository.BatchUpdateNoTrackingAsync(t => t.Id == model.Id, u => new ExchangeRate()
{
//YearMonth = model.YearMonth,
Rate = model.Rate,
UpdateTime = DateTime.Now
});
return ResponseOutput.Result(success);
}
}
/// <summary>
/// 根据记录Id删除汇率记录
/// </summary>
/// <param name="id">汇率记录Id</param>
[HttpDelete("{id:guid}")]
public async Task<IResponseOutput> DeleteExchangeRate(Guid id)
{
var monthInfo = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.Id == id);
if (await _paymentRepository.AnyAsync(t => t.YearMonth == monthInfo.YearMonth))
{
//---The exchange rate has been used in monthly payment
return ResponseOutput.NotOk(_localizer["ExR_MthPymtRate"]);
}
var success = await _exchangeRateRepository.BatchDeleteNoTrackingAsync(t => t.Id == id);
return ResponseOutput.Ok(success);
}
[NonDynamicMethod]
public async Task<decimal> GetExchangeRateByMonth(string month)
{
//var rate = _exchangeRateRepository.FindSingleOrDefault(u => u.YearMonth.Equals(month));
//if (rate == null)
//{
// return 0;
//}
//return rate.Rate;
var rate = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.YearMonth == month);
if (rate == null)
{
return 0;
}
return rate.Rate;
}
[HttpPost]
public async Task<PageOutput<ExchangeRateCommand>> GetExchangeRateList(ExchangeRateQueryDTO queryParam)
{
var yearMonth = queryParam.SearchMonth?.ToString("yyyy-MM");
var exchangeRateQueryable = _exchangeRateRepository.AsQueryable()
.WhereIf(queryParam.SearchMonth != null, o => o.YearMonth == yearMonth)
.ProjectTo<ExchangeRateCommand>(_mapper.ConfigurationProvider);
return await exchangeRateQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "YearMonth", false);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
using IRaCIS.Application.Contracts;
using System;
using System.Collections.Generic;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface ICalculateService
{
Task<IResponseOutput> CalculateMonthlyPayment(CalculateDoctorAndMonthDTO param, string token);
//IResponseOutput LockMonthlyPayment(LockPaymentDTO param);
Task<List<CalculateNeededDTO>> GetNeedCalculateReviewerList(Guid reviewerId, string yearMonth);
Task<bool> IsLock(Guid reviewerId, string yearMonth);
//bool ResetMonthlyPayment(Guid reviewerId, Guid trialId,string yearMonth);
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IReviewerPayInfoService
{
Task<IResponseOutput> AddOrUpdateReviewerPayInfo(ReviewerPayInfoCommand addOrUpdateModel, Guid userId);
Task<PageOutput<DoctorPayInfoQueryListDTO>> GetReviewerPayInfoList(DoctorPaymentInfoQueryDTO queryParam);
Task<DoctorPayInfoQueryListDTO> GetReviewerPayInfo(Guid doctorId);
Task<List<Guid>> GetReviewerIdByRankId(Guid rankId);
}
}

View File

@ -1,15 +0,0 @@
using IRaCIS.Application.Contracts;
using System;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IExchangeRateService
{
Task<IResponseOutput> AddOrUpdateExchangeRate(ExchangeRateCommand model);
Task<decimal> GetExchangeRateByMonth(string month);
Task<PageOutput<ExchangeRateCommand>> GetExchangeRateList(ExchangeRateQueryDTO queryParam);
Task<IResponseOutput> DeleteExchangeRate(Guid id);
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IPaymentAdjustmentService
{
Task<PageOutput<PaymentAdjustmentDetailDTO>> GetPaymentAdjustmentList(PaymentAdjustmentQueryDTO queryParam);
Task<IResponseOutput> AddOrUpdatePaymentAdjustment(PaymentAdjustmentCommand addOrUpdateModel);
Task<IResponseOutput> DeletePaymentAdjustment(Guid id);
Task CalculateCNY(string yearMonth, decimal rate);
Task<List<DoctorSelectDTO>> GetReviewerSelectList();
}
}

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IPaymentService
{
Task<IResponseOutput> LockMonthlyPayment(LockPaymentDTO param);
Task<PageOutput<PaymentModel>> GetMonthlyPaymentList(MonthlyPaymentQueryDTO queryParam);
Task<PayDetailDTO> GetMonthlyPaymentDetailList(Guid PaymentId, Guid doctorId, DateTime yearMonth);
Task<List<LaborPayment>> GetLaborPaymentList(List<Guid> paymentId);
//导出多个医生的付费详细
Task<List<PayDetailDTO>> GetReviewersMonthlyPaymentDetail(List<MonthlyPaymentDetailQuery> manyReviewers);
Task<PageOutput<MonthlyPaymentDTO>> GetPaymentHistoryList(PaymentQueryDTO param);
Task<List<VolumeStatisticsDTO>> GetPaymentHistoryDetailList(VolumeQueryDTO param);
Task<PageOutput<RevenuesDTO>> GetRevenuesStatistics(StatisticsQueryDTO param);
Task<List<TrialAnalysisDTO>> GetTrialAnalysisList(TrialAnalysisQueryDTO param);
Task<List<ReviewerAnalysisDTO>> GetReviewerAnalysisList(AnalysisQueryDTO param);
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IRankPriceService
{
Task<IResponseOutput> AddOrUpdateRankPrice(RankPriceCommand addOrUpdateModel, Guid userId);
Task<PageOutput<RankPriceDTO>> GetRankPriceList(RankPriceQueryDTO queryParam);
Task<IResponseOutput> DeleteRankPrice( Guid id);
Task<List<RankDic>> GetRankDic();
}
}

View File

@ -1,21 +0,0 @@
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface ITrialPaymentPriceService
{
Task<IResponseOutput> AddOrUpdateTrialPaymentPrice(TrialPaymentPriceCommand addOrUpdateModel);//新增也不需要返回IdTrialId 也是唯一
Task<PageOutput<TrialPaymentPriceDTO>> GetTrialPaymentPriceList(TrialPaymentPriceQueryDTO queryParam);
/// <summary>
/// 上传入组后的Ack-SOW
/// </summary>
Task<IResponseOutput> UploadTrialSOW( TrialSOWPathDTO trialSowPath);
Task<IResponseOutput> DeleteTrialSOW( DeleteSowPathDTO trialSowPath);
}
}

View File

@ -1,14 +0,0 @@
using IRaCIS.Application.Contracts;
using System;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface ITrialRevenuesPriceService
{
Task<IResponseOutput> AddOrUpdateTrialRevenuesPrice(TrialRevenuesPriceDTO model);
Task<bool> DeleteTrialCost(Guid Id);
Task<PageOutput<TrialRevenuesPriceDetialDTO>> GetTrialRevenuesPriceList(TrialRevenuesPriceQueryDTO param);
}
}

View File

@ -1,17 +0,0 @@

using IRaCIS.Core.Application.Contracts;
using System.Collections.Generic;
namespace IRaCIS.Application.Interfaces
{
public interface ITrialRevenuesPriceVerificationService
{
//List<RevenusVerifyDTO> GetRevenuesVerifyResultList(RevenusVerifyQueryDTO param);
Task<AnalysisVerifyResultDTO> GetAnalysisVerifyList(RevenusVerifyQueryDTO param);
Task<List<RevenusVerifyDTO>> GetRevenuesVerifyList(RevenusVerifyQueryDTO param);
}
}

View File

@ -1,12 +0,0 @@
using System.Collections.Generic;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface IVolumeRewardService
{
Task<IResponseOutput> AddOrUpdateVolumeRewardPriceList(IEnumerable<AwardPriceCommand> addOrUpdateModels);
Task<PageOutput<AwardPriceDTO>> GetVolumeRewardPriceList(AwardPriceQueryDTO queryParam);
Task<List<AwardPriceCalculateDTO>> GetVolumeRewardPriceList();
}
}

View File

@ -1,314 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Financial")]
public class PaymentAdjustmentService : BaseService, IPaymentAdjustmentService
{
private readonly IRepository<PaymentAdjustment> _payAdjustmentRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<ExchangeRate> _exchangeRateRepository;
private readonly IRepository<Payment> _paymentRepository;
public PaymentAdjustmentService(IRepository<PaymentAdjustment> costAdjustmentRepository, IRepository<Doctor> doctorRepository,
IRepository<ExchangeRate> exchangeRateRepository, IRepository<Payment> paymentRepository, IMapper mapper)
{
_payAdjustmentRepository = costAdjustmentRepository;
_doctorRepository = doctorRepository;
_exchangeRateRepository = exchangeRateRepository;
_paymentRepository = paymentRepository;
}
/// <summary>
/// 添加或更新费用调整[AUTH]
/// </summary>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdatePaymentAdjustment(PaymentAdjustmentCommand addOrUpdateModel)
{
var yearMonthDate = new DateTime(addOrUpdateModel.YearMonth.Year, addOrUpdateModel.YearMonth.Month, 1);
var yearMonth = addOrUpdateModel.YearMonth.ToString("yyyy-MM");
var payment = await _paymentRepository.FirstOrDefaultAsync(u => u.DoctorId == addOrUpdateModel.ReviewerId
&& u.YearMonth == yearMonth);
//判断付费表中是否有记录
if (payment == null)
{
//没有 添加仅有的调整费用记录
payment = new Payment
{
DoctorId = addOrUpdateModel.ReviewerId,
YearMonth = yearMonth,
YearMonthDate = yearMonthDate,
PaymentCNY = 0,
PaymentUSD = 0,
AdjustmentCNY = 0,
AdjustmentUSD = 0
};
await _paymentRepository.AddAsync(payment);
await _paymentRepository.SaveChangesAsync();
}
else
{
if (payment.IsLock)
{
//---Doctor payment has confirmed lock
return ResponseOutput.NotOk(_localizer["PayAdj_DocPymtLock"]);
}
}
var exchangeRate = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.YearMonth == yearMonth);
if (addOrUpdateModel.Id == Guid.Empty || addOrUpdateModel.Id == null)
{
var costAdjustment = _mapper.Map<PaymentAdjustment>(addOrUpdateModel);
//视图模型和领域模型没对应 重新赋值
costAdjustment.ExchangeRate = exchangeRate?.Rate ?? 0;
costAdjustment.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
costAdjustment.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
await _payAdjustmentRepository.AddAsync(costAdjustment);
//添加的时候,每个月调整汇总费用 需要加上本次调整的费用
payment.AdjustmentCNY += costAdjustment.AdjustmentCNY;
payment.AdjustmentUSD += costAdjustment.AdjustmentUSD;
//await _paymentRepository.UpdateAsync(payment);
await _paymentRepository.UpdateAsync(payment, u => new Payment()
{
AdjustmentCNY = payment.AdjustmentCNY + costAdjustment.AdjustmentCNY,
AdjustmentUSD = payment.AdjustmentUSD + costAdjustment.AdjustmentUSD
});
await _payAdjustmentRepository.SaveChangesAsync();
return ResponseOutput.Ok(costAdjustment.Id.ToString());
}
else
{
// 更新的时候,先查出来,更新前的调整费用数据
var paymentAdjust = await _payAdjustmentRepository.FirstOrDefaultAsync(t => t.Id == addOrUpdateModel.Id);
_mapper.Map(addOrUpdateModel, paymentAdjust);
paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0;
paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
//await _payAdjustmentRepository.UpdateAsync(paymentAdjust);
var success = await _payAdjustmentRepository.SaveChangesAsync();
if (success)
{
var adjustmentList = await _payAdjustmentRepository.Where(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth).ToListAsync();
await _paymentRepository.UpdateAsync(payment, u => new Payment()
{
AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY),
AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD)
});
//payment.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY);
//payment.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD);
//await _paymentRepository.UpdateAsync(payment);
await _paymentRepository.SaveChangesAsync();
}
//查询得到历史汇总
return ResponseOutput.Ok(success);
#region 逻辑存在错误 问题待查
//// 更新的时候,先查出来,更新前的调整费用数据
//var paymentAdjust = _payAdjustmentRepository.FindSingleOrDefault(t => t.Id == addOrUpdateModel.Id);
////减去数据库本条记录的值
//payment.AdjustmentCNY = -paymentAdjust.AdjustmentCNY;
//payment.AdjustmentUSD = -paymentAdjust.AdjustmentUSD;
//_mapper.Map(addOrUpdateModel, paymentAdjust);
//paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0;
//paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD;
//paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0);
//_payAdjustmentRepository.Update(paymentAdjust);
////查询得到历史汇总
//var adjustment = _payAdjustmentRepository.Find(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth)
// .GroupBy(u => new { u.ReviewerId, u.YearMonth }).Select(g => new
// {
// AdjustCNY = g.Sum(t => t.AdjustmentCNY),
// AdjustUSD = g.Sum(t => t.AdjustmentUSD)
// }).FirstOrDefault();
////最终的值 等于历史汇总 减去更新前的加上当前更新的值
//payment.AdjustmentCNY += (adjustment.AdjustCNY + paymentAdjust.AdjustmentCNY);
//payment.AdjustmentUSD += (adjustment.AdjustUSD + paymentAdjust.AdjustmentUSD);
//_paymentRepository.Update(payment);
//var success = _payAdjustmentRepository.SaveChanges();
//return ResponseOutput.Result(success, success ? string.Empty : StaticData.UpdateFailed);
#endregion
}
}
/// <summary>
/// 删除费用调整记录
/// </summary>
[HttpDelete("{id:guid}")]
public async Task<IResponseOutput> DeletePaymentAdjustment(Guid id)
{
var adjustPayment = await _payAdjustmentRepository.FirstOrDefaultAsync(u => u.Id == id);
await _payAdjustmentRepository.DeleteAsync(new PaymentAdjustment() { Id = id });
var success = await _payAdjustmentRepository.SaveChangesAsync();
if (success)
{
var adjustmentList = await _payAdjustmentRepository.Where(u =>
u.ReviewerId == adjustPayment.ReviewerId && u.YearMonth == adjustPayment.YearMonth).ToListAsync();
var monthPay = await _paymentRepository.FirstOrDefaultAsync(t =>
t.DoctorId == adjustPayment.ReviewerId && t.YearMonth == adjustPayment.YearMonth);
await _paymentRepository.UpdateAsync(monthPay, u => new Payment()
{
AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY),
AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD)
});
//monthPay.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY);
//monthPay.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD);
//await _paymentRepository.UpdateAsync(monthPay);
await _paymentRepository.SaveChangesAsync();
}
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取费用调整列表
/// </summary>
[HttpPost]
public async Task<PageOutput<PaymentAdjustmentDetailDTO>> GetPaymentAdjustmentList(PaymentAdjustmentQueryDTO queryParam)
{
var beginYearMonth = queryParam.BeginMonth.AddDays(1 - queryParam.BeginMonth.Day);
var endYearMonth = queryParam.EndMonth.AddDays(1 - queryParam.EndMonth.Day).AddMonths(1).AddDays(-1);
var costAdjustmentQueryable = from costAdjustment in _payAdjustmentRepository
.Where(t => t.YearMonthDate >= beginYearMonth && t.YearMonthDate <= endYearMonth)
join doctor in _doctorRepository.AsQueryable().
WhereIf(!string.IsNullOrWhiteSpace(queryParam.Reviewer),
u => u.ChineseName.Contains(queryParam.Reviewer) ||
(u.LastName + u.FirstName).Contains(queryParam.Reviewer) ||
u.ReviewerCode.Contains(queryParam.Reviewer))
on costAdjustment.ReviewerId equals doctor.Id
select new PaymentAdjustmentDetailDTO()
{
AdjustPaymentCNY = costAdjustment.AdjustmentCNY,
AdjustPaymentUSD = costAdjustment.AdjustmentUSD,
IsLock = costAdjustment.IsLock,
Id = costAdjustment.Id,
YearMonth = costAdjustment.YearMonth,
YearMonthDate = costAdjustment.YearMonthDate,
Note = costAdjustment.Note,
ReviewerId = costAdjustment.ReviewerId,
ReviewerCode = doctor.ReviewerCode,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
ChineseName = doctor.ChineseName
};
return await costAdjustmentQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrWhiteSpace(queryParam.SortField) ? "YearMonthDate" : queryParam.SortField, queryParam.Asc);
}
public async Task<List<DoctorSelectDTO>> GetReviewerSelectList()
{
return await _doctorRepository.Where(t => t.CooperateStatus == ContractorStatusEnum.Cooperation && t.ResumeStatus == ResumeStatusEnum.Pass).ProjectTo<DoctorSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
}
[NonDynamicMethod]
public async Task CalculateCNY(string yearMonth, decimal rate)
{
//如果是double 不会保留两位小数
await _payAdjustmentRepository.BatchUpdateNoTrackingAsync(u => u.YearMonth == yearMonth &&
!u.IsLock, t => new PaymentAdjustment
{
AdjustmentCNY = t.AdjustmentUSD * rate,
ExchangeRate = rate,
UpdateTime = DateTime.Now
});
var adjustList = await _payAdjustmentRepository.Where(u => u.YearMonth == yearMonth &&
!u.IsLock).ToListAsync();
var needUpdatePayment = adjustList.GroupBy(t => t.ReviewerId).Select(g => new
{
ReviewerId = g.Key,
AdjustCNY = g.Sum(t => t.AdjustmentCNY),
AdjustUSD = g.Sum(t => t.AdjustmentUSD)
});
foreach (var reviewer in needUpdatePayment)
{
await _paymentRepository.BatchUpdateNoTrackingAsync(u => u.YearMonth == yearMonth &&
!u.IsLock && u.DoctorId == reviewer.ReviewerId, t => new Payment()
{
AdjustmentUSD = reviewer.AdjustUSD,
AdjustmentCNY = reviewer.AdjustCNY
});
}
}
}
}

View File

@ -1,105 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Financial")]
public class RankPriceService : BaseService, IRankPriceService
{
private readonly IRepository<RankPrice> _rankPriceRepository;
private readonly IRepository<ReviewerPayInformation> _reviewerPayInfoRepository;
public RankPriceService(IRepository<RankPrice> rankPriceRepository, IRepository<ReviewerPayInformation> reviewerPayInfoRepository,IMapper mapper)
{
_rankPriceRepository = rankPriceRepository;
_reviewerPayInfoRepository = reviewerPayInfoRepository;
}
[NonDynamicMethod]
public async Task<IResponseOutput> AddOrUpdateRankPrice(RankPriceCommand addOrUpdateModel, Guid userId)
{
if (addOrUpdateModel.Id == Guid.Empty|| addOrUpdateModel.Id ==null)
{
var rankPrice = _mapper.Map<RankPrice>(addOrUpdateModel);
rankPrice = await _rankPriceRepository.AddAsync(rankPrice);
if (await _rankPriceRepository.SaveChangesAsync())
{
return ResponseOutput.Ok(rankPrice.Id.ToString());
}
else
{
return ResponseOutput.NotOk();
}
}
else
{
var success =await _rankPriceRepository.BatchUpdateNoTrackingAsync(t => t.Id == addOrUpdateModel.Id, u => new RankPrice()
{
UpdateUserId = userId,
UpdateTime = DateTime.Now,
RefresherTraining=addOrUpdateModel.RefresherTraining,
RankName = addOrUpdateModel.RankName,
Timepoint = addOrUpdateModel.Timepoint,
TimepointIn24H = addOrUpdateModel.TimepointIn24H,
TimepointIn48H = addOrUpdateModel.TimepointIn48H,
Adjudication = addOrUpdateModel.Adjudication,
AdjudicationIn24H = addOrUpdateModel.AdjudicationIn24H,
AdjudicationIn48H = addOrUpdateModel.AdjudicationIn48H,
Global = addOrUpdateModel.Global,
Training = addOrUpdateModel.Training,
Downtime = addOrUpdateModel.Downtime
});
return ResponseOutput.Result(success);
}
}
[HttpDelete("{id:guid}")]
public async Task<IResponseOutput> DeleteRankPrice(Guid id)
{
if (await _reviewerPayInfoRepository.AnyAsync(t => t.RankId == id))
{
//---This title has been used by reviewer payment information
return ResponseOutput.NotOk(_localizer["RP_TitleUsedByRev"]);
}
var success = await _rankPriceRepository.BatchDeleteNoTrackingAsync(t => t.Id == id);
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取职称单价列表
/// </summary>
[HttpPost]
public async Task<PageOutput<RankPriceDTO>> GetRankPriceList(RankPriceQueryDTO queryParam)
{
var rankPriceQueryable = _rankPriceRepository.ProjectTo<RankPriceDTO>(_mapper.ConfigurationProvider);
return await rankPriceQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "ShowOrder", queryParam.Asc);
}
public async Task<List<RankDic>> GetRankDic()
{
var rankQueryable = _rankPriceRepository.ProjectTo<RankDic>(_mapper.ConfigurationProvider);
return await rankQueryable.ToListAsync();
}
}
}

View File

@ -1,144 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using System.Linq.Expressions;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Financial")]
public class ReviewerPayInfoService : BaseService, IReviewerPayInfoService
{
private readonly IRepository<ReviewerPayInformation> _doctorPayInfoRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<RankPrice> _rankPriceRepository;
private readonly IRepository<Hospital> _hospitalRepository;
public ReviewerPayInfoService(IRepository<Doctor> doctorRepository, IRepository<ReviewerPayInformation> doctorPayInfoRepository,
IRepository<RankPrice> rankPriceRepository, IRepository<Hospital> hospitalRepository, IMapper mapper)
{
_doctorPayInfoRepository = doctorPayInfoRepository;
_doctorRepository = doctorRepository;
_rankPriceRepository = rankPriceRepository;
_hospitalRepository = hospitalRepository;
}
[NonDynamicMethod]
public async Task<IResponseOutput> AddOrUpdateReviewerPayInfo(ReviewerPayInfoCommand addOrUpdateModel, Guid userId)
{
var success = false;
var doctorPayInfoExistedItem = await _doctorPayInfoRepository.FirstOrDefaultAsync(u => u.DoctorId == addOrUpdateModel.DoctorId);
if (doctorPayInfoExistedItem == null)//insert
{
await _doctorPayInfoRepository.InsertFromDTOAsync(addOrUpdateModel);
}
else//update
{
await _doctorPayInfoRepository.UpdateFromDTOAsync(addOrUpdateModel);
}
success = await _doctorPayInfoRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取医生支付信息列表
/// </summary>
[HttpPost]
public async Task<PageOutput<DoctorPayInfoQueryListDTO>> GetReviewerPayInfoList(DoctorPaymentInfoQueryDTO queryParam)
{
var doctorQueryable = from doctor in _doctorRepository.AsQueryable()
.WhereIf(queryParam.HospitalId != null, o => o.HospitalId == queryParam.HospitalId)
.WhereIf(!string.IsNullOrEmpty(queryParam.SearchName),
u => u.ChineseName.Contains(queryParam.SearchName)|| (u.LastName+ u.FirstName).Contains(queryParam.SearchName))
join hospitalItem in _hospitalRepository.AsQueryable() on doctor.HospitalId equals hospitalItem.Id into gt
from hospital in gt.DefaultIfEmpty()
join trialPayInfo in _doctorPayInfoRepository.Where()
on doctor.Id equals trialPayInfo.DoctorId into payInfo
from doctorPayInfo in payInfo.DefaultIfEmpty()
join rankPrice in _rankPriceRepository.Where()
on doctorPayInfo.RankId equals rankPrice.Id into rankPriceInfo
from rankPrice in rankPriceInfo.DefaultIfEmpty()
select new DoctorPayInfoQueryListDTO
{
//Id = doctorPayInfo.Id,
DoctorId = doctor.Id,
Code = doctor.ReviewerCode,
LastName = doctor.LastName,
FirstName = doctor.FirstName,
ChineseName = doctor.ChineseName,
Phone = doctor.Phone,
DoctorNameInBank = doctorPayInfo.DoctorNameInBank,
IDCard = doctorPayInfo.IDCard,
BankCardNumber = doctorPayInfo.BankCardNumber,
BankName = doctorPayInfo.BankName,
RankId = doctorPayInfo.RankId,
RankName = rankPrice.RankName,
Additional = doctorPayInfo.Additional,
Hospital = hospital.HospitalName,
CreateTime = doctor.CreateTime
};
return await doctorQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "Code", queryParam.Asc);
}
/// <summary>
/// 根据医生Id获取支付信息
/// </summary>
/// <param name="doctorId">医生Id</param>
/// <returns></returns>
[HttpGet("{doctorId:guid}")]
public async Task<DoctorPayInfoQueryListDTO> GetReviewerPayInfo(Guid doctorId)
{
var doctorQueryable = from doctor in _doctorRepository.Where(u => u.Id == doctorId)
join trialPayInfo in _doctorPayInfoRepository.Where()
on doctor.Id equals trialPayInfo.DoctorId into payInfo
from doctorPayInfo in payInfo.DefaultIfEmpty()
join rankPrice in _rankPriceRepository.Where()
on doctorPayInfo.RankId equals rankPrice.Id into rankPriceInfo
from rankPrice in rankPriceInfo.DefaultIfEmpty()
select new DoctorPayInfoQueryListDTO
{
//Id = doctorPayInfo.Id,
DoctorId = doctor.Id,
Code = doctor.ReviewerCode,
LastName = doctor.LastName,
FirstName = doctor.FirstName,
ChineseName = doctor.ChineseName,
Phone = doctor.Phone,
DoctorNameInBank = doctorPayInfo.DoctorNameInBank,
IDCard = doctorPayInfo.IDCard,
BankCardNumber = doctorPayInfo.BankCardNumber,
BankName = doctorPayInfo.BankName,
RankId = doctorPayInfo.RankId,
RankName = rankPrice.RankName,
Additional = doctorPayInfo.Additional,
CreateTime = doctor.CreateTime
};
return (await doctorQueryable.FirstOrDefaultAsync()).IfNullThrowException();
}
/// <summary>
/// 根据rankId 获取ReviewerId用于当Rank的单价信息改变时触发费用计算
/// </summary>
/// <param name="rankId"></param>
/// <returns></returns>
public async Task<List<Guid>> GetReviewerIdByRankId(Guid rankId)
{
return await _doctorPayInfoRepository.Where(u => u.RankId == rankId).Select(u => u.DoctorId).ToListAsync();
}
}
}

View File

@ -1,188 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Financial")]
public class TrialPaymentPriceService : BaseService, ITrialPaymentPriceService
{
private readonly IRepository<TrialPaymentPrice> _trialExtRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<CRO> _croRepository;
private readonly IRepository<Trial> _trialRepository;
public TrialPaymentPriceService(IRepository<Trial> trialRepository, IRepository<TrialPaymentPrice> trialExtRepository,
IRepository<Enroll> enrollRepository,
IRepository<Doctor> doctorRepository,
IRepository<CRO> croCompanyRepository, IMapper mapper)
{
_trialExtRepository = trialExtRepository;
_croRepository = croCompanyRepository;
_enrollRepository = enrollRepository;
_doctorRepository = doctorRepository;
_trialRepository = trialRepository;
}
/// <summary>
/// 添加或更新项目支付价格信息
/// </summary>
[NonDynamicMethod]
public async Task<IResponseOutput> AddOrUpdateTrialPaymentPrice(TrialPaymentPriceCommand addOrUpdateModel)
{
var trialExistedItem = await _trialExtRepository.FirstOrDefaultAsync(u => u.TrialId == addOrUpdateModel.TrialId);
if (trialExistedItem == null)//insert
{
await _trialExtRepository.InsertFromDTOAsync(addOrUpdateModel);
}
else//update
{
await _trialExtRepository.UpdateFromDTOAsync(addOrUpdateModel);
}
var success = await _trialExtRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
[HttpPost]
public async Task<IResponseOutput> UploadTrialSOW(TrialSOWPathDTO trialSowPath)
{
var trialPaymentPrice = await _trialExtRepository.FirstOrDefaultAsync(u => u.TrialId == trialSowPath.TrialId);
if (trialPaymentPrice == null)//添加
{
await _trialExtRepository.InsertFromDTOAsync(trialSowPath);
}
else//更新
{
await _trialExtRepository.UpdateFromDTOAsync(trialSowPath);
}
var success = await _trialExtRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
[HttpPost]
public async Task<IResponseOutput> DeleteTrialSOW(DeleteSowPathDTO trialSowPath)
{
var success = await _trialExtRepository.BatchUpdateNoTrackingAsync(u => u.TrialId == trialSowPath.TrialId, s => new TrialPaymentPrice
{
SowPath = "",
SowName = "",
UpdateTime = DateTime.Now,
UpdateUserId = _userInfo.Id
});
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取项目支付价格信息列表
/// </summary>
[HttpPost]
public async Task<PageOutput<TrialPaymentPriceDTO>> GetTrialPaymentPriceList(TrialPaymentPriceQueryDTO queryParam)
{
#region hwt
//var trialQueryable = from trial in _trialRepository.AsQueryable()
// .WhereIf(queryParam.CroId != null, o => o.CROId == queryParam.CroId)
// .WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.TrialCode.Contains(queryParam.KeyWord) || o.Indication.Contains(queryParam.KeyWord))
// join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into CRO
// from croInfo in CRO.DefaultIfEmpty()
// join trialExt in _trialExtRepository.Where()
// on trial.Id equals trialExt.TrialId into trialInfo
// from trialExt in trialInfo.DefaultIfEmpty()
// select new TrialPaymentPriceDTO
// {
// //Id = trialExt.Id ,
// IsNewTrial = trialExt.IsNewTrial,
// TrialId = trial.Id,
// TrialCode = trial.TrialCode,
// Cro = croInfo.CROName,
// Indication = trial.Indication,
// Expedited = trial.Expedited,
// TrialAdditional = trialExt.TrialAdditional,
// AdjustmentMultiple = trialExt.AdjustmentMultiple,
// SowName = trialExt.SowName,
// SowPath = trialExt.SowPath,
// CreateTime = trial.CreateTime,
// };
//var namelist = (from enroll in _enrollRepository.AsQueryable()
// join doctor in _doctorRepository.Where() on enroll.DoctorId equals doctor.Id
// select new DtoDoctorList()
// {
// TrialId = enroll.TrialId,
// Name = doctor.ChineseName
// }).ToList().GroupBy(x => new { x.TrialId },
//(key, lst) => new DtoDoctorList
//{
// TrialId = key.TrialId,
// Name = string.Join(',', lst.Select(x => x.Name))
//});
//var returndata = trialQueryable.ToPagedList(queryParam.PageIndex, queryParam.PageSize, "CreateTime", queryParam.Asc);
//returndata.CurrentPageData.ForEach(x => {
// x.DoctorsNames = namelist.Where(y => y.TrialId == x.TrialId).Select(y => y.Name).FirstOrDefault() ?? string.Empty;
//});
//return returndata;
#endregion
#region byzhouhang 方式一
//var trialQueryable = _trialExtRepository.Where(t => t.Trial.IsDeleted == false)
// .WhereIf(queryParam.CroId != null, o => o.Trial.CROId == queryParam.CroId)
// .WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.Trial.TrialCode.Contains(queryParam.KeyWord) || o.Trial.Indication.Contains(queryParam.KeyWord))
// .Select(trialExt => new TrialPaymentPriceDTO()
// {
// TrialCode = trialExt.Trial.TrialCode,
// Cro = trialExt.Trial.CRO.CROName,
// Indication = trialExt.Trial.Indication,
// Expedited = trialExt.Trial.Expedited,
// TrialId = trialExt.TrialId,
// IsNewTrial = trialExt.IsNewTrial,
// SowName = trialExt.SowName,
// SowPath = trialExt.SowPath,
// TrialAdditional = trialExt.TrialAdditional,
// AdjustmentMultiple = trialExt.AdjustmentMultiple,
// CreateTime = trialExt.CreateTime,
// DoctorsNames = string.Join(',', trialExt.Trial.EnrollList.Select(t => t.Doctor.ChineseName))
// });
//return trialQueryable.ToPagedList(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrEmpty(queryParam.SortField) ? "CreateTime" : queryParam.SortField, queryParam.Asc);
#endregion
#region byzhouhang 方式二
var trialQueryable2 = _trialExtRepository.Where(t => t.Trial.IsDeleted == false)
.WhereIf(queryParam.CroId != null, o => o.Trial.CROId == queryParam.CroId)
.WhereIf(!string.IsNullOrEmpty(queryParam.KeyWord), o => o.Trial.TrialCode.Contains(queryParam.KeyWord) || o.Trial.Indication.Contains(queryParam.KeyWord))
.ProjectTo<TrialPaymentPriceDTO>(_mapper.ConfigurationProvider);
return await trialQueryable2.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrEmpty(queryParam.SortField) ? "CreateTime" : queryParam.SortField, queryParam.Asc);
#endregion
}
}
}

View File

@ -1,152 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using System.Linq.Expressions;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Financial")]
public class TrialRevenuesPriceService : BaseService, ITrialRevenuesPriceService
{
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialRevenuesPrice> _trialRevenuesPriceRepository;
private readonly IRepository<CRO> _croRepository;
private readonly IRepository<Dictionary> _dictionaryRepository;
private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;
public TrialRevenuesPriceService(IRepository<Trial> trialRepository, IRepository<TrialRevenuesPrice> trialCostRepository, IRepository<CRO> croCompanyRepository, IRepository<Dictionary> dictionaryRepository, IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository, IMapper mapper)
{
_trialRepository = trialRepository;
_trialRevenuesPriceRepository = trialCostRepository;
_croRepository = croCompanyRepository;
_dictionaryRepository = dictionaryRepository;
_trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;
}
public async Task<IResponseOutput> AddOrUpdateTrialRevenuesPrice(TrialRevenuesPriceDTO model)
{
var count = model.Timepoint +
model.TimepointIn24H +
model.TimepointIn48H +
model.Adjudication +
model.AdjudicationIn24H +
model.AdjudicationIn48H +
model.Downtime +
model.Global +
model.Training;
if (count <= 0)
{
//---Please add meaningful data
return ResponseOutput.NotOk(_localizer["TRP_AddMeaningful"]);
}
var trialExistedItem = await _trialRevenuesPriceRepository.FirstOrDefaultAsync(u => u.TrialId == model.TrialId);
if (trialExistedItem == null)//insert
{
var trialCost = _mapper.Map<TrialRevenuesPrice>(model);
await _trialRevenuesPriceRepository.AddAsync(trialCost);
var success = await _trialRevenuesPriceRepository.SaveChangesAsync();
return ResponseOutput.Result(success, trialCost.Id.ToString());
}
else//update
{
//var trialRevenuesPrice = (await _trialRevenuesPriceRepository.AsQueryable().FirstOrDefaultAsync(u => u.TrialId == model.TrialId)).IfNullThrowException();
await _trialRevenuesPriceRepository.UpdateFromDTOAsync(model);
// 完善价格的 将对应的列设置为true 变更为有价格了
var aaa = await _trialRevenuesPriceVerificationRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == model.TrialId, u => new TrialRevenuesPriceVerification()
{
//有价格 则设置为true 否则 该列不变
Timepoint = model.Timepoint > 0 || u.Timepoint,
TimepointIn24H = model.TimepointIn24H > 0 || u.TimepointIn24H,
TimepointIn48H = model.TimepointIn48H > 0 || u.TimepointIn48H,
Adjudication = model.Adjudication > 0 || u.Adjudication,
AdjudicationIn24H =
model.AdjudicationIn24H > 0 || u.AdjudicationIn24H,
AdjudicationIn48H =
model.AdjudicationIn48H > 0 || u.AdjudicationIn48H,
Global = model.Global > 0 || u.Global,
Downtime = model.Downtime > 0 || u.Downtime,
Training = model.Training > 0 || u.Training,
RefresherTraining = model.RefresherTraining > 0 || u.RefresherTraining,
});
//删除所有有价格的记录 为true 表示有价格或者不需要价格 缺价格的为false
await _trialRevenuesPriceVerificationRepository.BatchDeleteNoTrackingAsync(t => t.TrialId == model.TrialId &&
t.Timepoint&&
t.TimepointIn24H&&
t.TimepointIn48H &&
t.Adjudication &&
t.AdjudicationIn24H &&
t.AdjudicationIn48H &&
t.Global &&
t.Training &&t.RefresherTraining);
var success = await _trialRevenuesPriceRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
}
[NonDynamicMethod]
public async Task<bool> DeleteTrialCost(Guid id)
{
return await _trialRevenuesPriceRepository.BatchDeleteNoTrackingAsync(u => u.Id == id);
}
/// <summary>
/// 获取项目收入费用信息列表[New]
/// </summary>
[HttpPost]
public async Task<PageOutput<TrialRevenuesPriceDetialDTO>> GetTrialRevenuesPriceList(TrialRevenuesPriceQueryDTO queryParam)
{
var trialQueryable = from trial in _trialRepository.AsQueryable()
.Where(u => u.TrialCode.Contains(queryParam.KeyWord)|| u.Indication.Contains(queryParam.KeyWord))
.WhereIf(queryParam.CroId != null, o => o.CROId == queryParam.CroId)
join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into CRO
from croInfo in CRO.DefaultIfEmpty()
join dic in _dictionaryRepository.AsQueryable() on trial.ReviewModeId equals dic.Id into dict
from dic in dict.DefaultIfEmpty()
join trialCost in _trialRevenuesPriceRepository.AsQueryable()
on trial.Id equals trialCost.TrialId into trialInfo
from trialCostItem in trialInfo.DefaultIfEmpty()
select new TrialRevenuesPriceDetialDTO
{
Id = trialCostItem == null ? Guid.Empty : trialCostItem.Id,
TrialId = trial.Id,
TrialCode = trial.TrialCode,
Indication = trial.Indication,
Cro = croInfo == null ? string.Empty : croInfo.CROName,
ReviewMode = dic == null ? string.Empty : dic.Value,
Timepoint = trialCostItem == null ? 0 : trialCostItem.Timepoint,
TimepointIn24H = trialCostItem == null ? 0 : trialCostItem.TimepointIn24H,
TimepointIn48H = trialCostItem == null ? 0 : trialCostItem.TimepointIn48H,
Adjudication = trialCostItem == null ? 0 : trialCostItem.Adjudication,
AdjudicationIn24H = trialCostItem == null ? 0 : trialCostItem.AdjudicationIn24H,
AdjudicationIn48H = trialCostItem == null ? 0 : trialCostItem.AdjudicationIn48H,
Downtime = trialCostItem == null ? 0 : trialCostItem.Downtime,
Global = trialCostItem == null ? 0 : trialCostItem.Global,
Training = trialCostItem == null ? 0 : trialCostItem.Training,
RefresherTraining= trialCostItem == null ? 0 : trialCostItem.RefresherTraining,
Expedited = trial.Expedited
};
return await trialQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "TrialCode", queryParam.Asc);
}
}
}

View File

@ -1,197 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Domain.Models;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Contracts;
namespace IRaCIS.Core.Application.Services
{
/// <summary>
/// Financial---项目收入价格验证
/// </summary>
[ ApiExplorerSettings(GroupName = "Financial")]
public class TrialRevenuesPriceVerificationService : BaseService, ITrialRevenuesPriceVerificationService
{
private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Payment> _paymentRepository;
public TrialRevenuesPriceVerificationService(IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository,
IRepository<Trial> trialRepository,IRepository<Doctor> doctorRepository,IRepository<Payment> paymentRepository)
{
_trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;
_trialRepository = trialRepository;
_doctorRepository = doctorRepository;
_paymentRepository = paymentRepository;
}
[HttpPost]
public async Task<AnalysisVerifyResultDTO> GetAnalysisVerifyList(RevenusVerifyQueryDTO param)
{
AnalysisVerifyResultDTO result=new AnalysisVerifyResultDTO();
result.RevenuesVerifyList = await GetRevenuesVerifyList(param);
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
eDate = eDate.AddMonths(1).AddSeconds(-1);
Expression<Func<Payment, bool>> paymentLambda = x => x.YearMonthDate >= bDate && x.YearMonthDate <= eDate&&!x.IsLock;
var query = from payment in _paymentRepository.Where(paymentLambda)
join doctor in _doctorRepository.AsQueryable() on payment.DoctorId equals doctor.Id
select new AnalysisNeedLockDTO()
{
YearMonth = payment.YearMonth,
ReviewerCode = doctor.ReviewerCode,
ReviewerName = doctor.LastName + " / " + doctor.FirstName,
ReviewerNameCN = doctor.ChineseName
};
result.MonthVerifyResult = (await query.ToListAsync()).GroupBy(t => t.YearMonth).Select(g => new MonthlyResult
{
YearMonth = g.Key,
ReviewerNameList = g.Select(t => t.ReviewerName).ToList(),
ReviewerNameCNList = g.Select(t => t.ReviewerNameCN).ToList(),
ReviewerCodeList = g.Select(t => t.ReviewerCode).ToList()
}).OrderBy(t=>t.YearMonth).ToList();
return result;
}
[HttpPost]
public async Task<List<RevenusVerifyDTO>> GetRevenuesVerifyList(RevenusVerifyQueryDTO param)
{
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
Expression<Func<TrialRevenuesPriceVerification, bool>> trialRevenuesPriceVerificationLambda = x => x.WorkLoadDate >= bDate && x.WorkLoadDate <= eDate;
var query = (from trialVerify in _trialRevenuesPriceVerificationRepository.Where(trialRevenuesPriceVerificationLambda)
join trail in _trialRepository.AsQueryable() on trialVerify.TrialId equals trail.Id
select new RevenusVerifyDTO
{
TrialCode = trail.TrialCode,
Timepoint = trialVerify.Timepoint,
TimepointIn24H = trialVerify.TimepointIn24H,
TimepointIn48H = trialVerify.TimepointIn48H,
Adjudication = trialVerify.Adjudication,
AdjudicationIn24H = trialVerify.AdjudicationIn24H,
AdjudicationIn48H = trialVerify.AdjudicationIn48H,
Global = trialVerify.Global,
Downtime = trialVerify.Downtime,
Training = trialVerify.Training
}).Distinct();
return await query.ToListAsync();
}
//废弃
[Obsolete]
public async Task<List<RevenusVerifyDTO>> GetRevenuesVerifyResultList(RevenusVerifyQueryDTO param)
{
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
Expression<Func<TrialRevenuesPriceVerification, bool>> trialRevenuesPriceVerificationLambda = x => x.WorkLoadDate >= bDate && x.WorkLoadDate <= eDate;
var query = (from trialVerify in _trialRevenuesPriceVerificationRepository.Where(trialRevenuesPriceVerificationLambda)
join trail in _trialRepository.AsQueryable() on trialVerify.TrialId equals trail.Id
select new RevenusVerifyDTO
{
TrialCode = trail.TrialCode,
Timepoint = trialVerify.Timepoint,
TimepointIn24H = trialVerify.TimepointIn24H,
TimepointIn48H = trialVerify.TimepointIn48H,
Adjudication = trialVerify.Adjudication,
AdjudicationIn24H = trialVerify.AdjudicationIn24H,
AdjudicationIn48H = trialVerify.AdjudicationIn48H,
Global = trialVerify.Global,
Downtime = trialVerify.Downtime,
Training = trialVerify.Training
}).Distinct();
return await query.ToListAsync();
#region 提示 old
//query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
// select new RevenusVerifyDTO()
// {
// ReviewerCode = reviewer.Code,
// TrialCode = trail.Code,
// YearMonth = trialVerify.YearMonth
// };
////0是Detail 1是按照项目 2是按照人 3按照月份
//if (param.StatType == 0)
//{
// query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
// select new RevenusVerifyDTO()
// {
// ReviewerCode = reviewer.Code,
// TrialCode = trail.Code,
// YearMonth = trialVerify.YearMonth
// };
//}
//else if (param.StatType == 1)
//{
// query = (from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
// select new RevenusVerifyDTO()
// {
// ReviewerCode = "",
// TrialCode = trail.Code,
// YearMonth = ""
// }).Distinct();
//}
//else if (param.StatType == 2)
//{
// query = (from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
// select new RevenusVerifyDTO()
// {
// ReviewerCode = reviewer.Code,
// TrialCode = trail.Code,
// YearMonth = ""
// }).Distinct();
//}
//else
//{
// query = from trialVerify in _trialRevenuesPriceVerificationRepository.GetAll()
// join trail in _trialRepository.GetAll() on trialVerify.TrialId equals trail.Id
// join reviewer in _doctorRepository.GetAll() on trialVerify.ReviewerId equals reviewer.Id
// select new RevenusVerifyDTO()
// {
// ReviewerCode = reviewer.Code,
// TrialCode = trail.Code,
// YearMonth = trialVerify.YearMonth
// };
//}
#endregion
}
}
}

View File

@ -1,61 +0,0 @@
using AutoMapper;
using AutoMapper.QueryableExtensions;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Financial")]
public class VolumeRewardService : BaseService, IVolumeRewardService
{
private readonly IRepository<VolumeReward> _volumeRewardRepository;
public VolumeRewardService(IRepository<VolumeReward> volumeRewardRepository,IMapper mapper)
{
_volumeRewardRepository = volumeRewardRepository;
}
/// <summary>
/// 批量添加或更新奖励费用单价
/// </summary>
[NonDynamicMethod]
public async Task<IResponseOutput> AddOrUpdateVolumeRewardPriceList(IEnumerable<AwardPriceCommand> addOrUpdateModel)
{
await _volumeRewardRepository.BatchDeleteNoTrackingAsync(t => t.Id != Guid.Empty);
var temp = _mapper.Map<List<VolumeReward>>(addOrUpdateModel);
await _volumeRewardRepository.AddRangeAsync(temp);
var success = await _volumeRewardRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取所有奖励单价列表-用于计算时,一次性获取所有
/// </summary>
[NonDynamicMethod]
public async Task<List<AwardPriceCalculateDTO>> GetVolumeRewardPriceList()
{
return await _volumeRewardRepository.ProjectTo<AwardPriceCalculateDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.Min).ToListAsync();
}
/// <summary>
/// 分页获取奖励单价列表
/// </summary>
[HttpPost]
public async Task<PageOutput<AwardPriceDTO>> GetVolumeRewardPriceList(AwardPriceQueryDTO queryParam)
{
var awardPriceQueryable = _volumeRewardRepository.ProjectTo<AwardPriceDTO>(_mapper.ConfigurationProvider);
return await awardPriceQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, "Min");
}
}
}

View File

@ -1,62 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Core.Application.Service
{
public class FinancialConfig : Profile
{
public FinancialConfig()
{
CreateMap<PaymentAdjustmentCommand, PaymentAdjustment>()
.ForMember(t => t.YearMonthDate, u => u.MapFrom(t => t.YearMonth))
.ForMember(t => t.YearMonth, u => u.MapFrom(t => t.YearMonth.ToString("yyyy-MM")));
CreateMap<TrialPaymentPriceCommand, TrialPaymentPrice>();
CreateMap<ReviewerPayInfoCommand, ReviewerPayInformation>();
CreateMap<RankPriceCommand, RankPrice>();
CreateMap<AwardPriceCommand, VolumeReward>();
CreateMap<PaymentCommand, Payment>();
CreateMap<PaymentDetailCommand, PaymentDetail>();
CreateMap<ExchangeRateCommand, ExchangeRate>();
CreateMap<AwardPriceCommand, VolumeReward>();
CreateMap<TrialRevenuesPriceDTO, TrialRevenuesPrice>();
CreateMap<TrialSOWPathDTO, TrialPaymentPrice>();
CreateMap<RankPrice, RankPriceDTO>();
CreateMap<VolumeReward, AwardPriceDTO>();
CreateMap<RankPrice, RankDic>();
CreateMap<ExchangeRate, ExchangeRateCommand>();
CreateMap<Payment, CalculateNeededDTO>();
CreateMap<VolumeReward, AwardPriceCalculateDTO>();
CreateMap<PaymentDetail, PaymentDetailDTO>();
CreateMap<TrialPaymentPrice, TrialSOWPathDTO>();
CreateMap<TrialPaymentPrice, TrialPaymentPriceDTO>()
.ForMember(t => t.TrialCode, u => u.MapFrom(t => t.Trial.Code))
.ForMember(t => t.ReviewMode, u => u.MapFrom(t => t.Trial.ReviewMode.Value))
.ForMember(t => t.Cro, u => u.MapFrom(t => t.Trial.CRO.CROName))
.ForMember(t => t.Indication, u => u.MapFrom(t => t.Trial.Indication))
.ForMember(t => t.Expedited, u => u.MapFrom(t => t.Trial.Expedited))
.ForMember(t => t.DoctorsNames, u => u.MapFrom(t => string.Join(',', t.Trial.EnrollList.Select(t => t.Doctor.ChineseName))))
;
}
}
}

View File

@ -10,12 +10,11 @@ namespace IRaCIS.Application.Services
public class HospitalService : BaseService, IHospitalService
{
private readonly IRepository<Hospital> _hospitalRepository;
private readonly IRepository<Doctor> _doctorRepository;
public HospitalService(IRepository<Hospital> hospitalRepository, IRepository<Doctor> doctorRepository)
public HospitalService(IRepository<Hospital> hospitalRepository )
{
_hospitalRepository = hospitalRepository;
this._doctorRepository = doctorRepository;
}
/// <summary> 获取所有医院列表 </summary>
@ -55,11 +54,7 @@ namespace IRaCIS.Application.Services
[HttpDelete("{hospitalId:guid}")]
public async Task<IResponseOutput> DeleteHospital(Guid hospitalId)
{
if (await _doctorRepository.AnyAsync(t => t.Id == hospitalId))
{
//---该医院下已经注册有医生,不可以删除。
return ResponseOutput.NotOk(_localizer["Hospital_HasDoctors"]);
}
//if (_userRepository.Find().Any(t => t.OrganizationId == hospitalId))
//{
// return ResponseOutput.NotOk("该医院下存在用户,暂时无法删除。");

View File

@ -21,7 +21,6 @@ namespace IRaCIS.Application.Services
private readonly IRepository<User> _userRepository;
private readonly IMailVerificationService _mailVerificationService;
private readonly IRepository<VerificationCode> _verificationCodeRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<TrialUser> _userTrialRepository;
private readonly IRepository<UserLog> _userLogRepository;
@ -35,7 +34,6 @@ namespace IRaCIS.Application.Services
IMailVerificationService mailVerificationService,
IRepository<VerificationCode> verificationCodeRepository,
IRepository<Doctor> doctorRepository,
IMemoryCache cache,
IRepository<TrialUser> userTrialRepository,
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
@ -49,7 +47,7 @@ namespace IRaCIS.Application.Services
_userRepository = userRepository;
_mailVerificationService = mailVerificationService;
_verificationCodeRepository = verificationCodeRepository;
_doctorRepository = doctorRepository;
_userTrialRepository = userTrialRepository;
_userLogRepository = userLogRepository;
}

View File

@ -10,54 +10,8 @@ using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Core.Application.ViewModel
{
/// <summary> SubjectCriteriaEvaluationVisitFilterView 列表视图模型 </summary>
public class SubjectCriteriaEvaluationVisitFilterView
{
public DateTime? CreateTime { get; set; }
public Guid? CreateUserId { get; set; }
public Guid? UpdateUserId { get; set; }
public DateTime? UpdateTime { get; set; }
public Guid? Id { get; set; }
public Guid TrialId { get; set; }
public Guid SubjectId { get; set; }
public Guid SiteId { get; set; }
public string SubjectCode { get; set; }
public Guid TrialReadingCriterionId { get; set; }
public Guid SubjectVisitId { get; set; }
public ImageFilterState? ImageFilterState { get; set; }
public ImageDeterminationResultState? ImageDeterminationResultState { get; set; }
public bool? IsGeneratedTask { get; set; }
public decimal VisitNum { get; set; }
public string VisitName { get; set; }
public DateTime? EarliestScanDate { get; set; }
public DateTime? LatestScanDate { get; set; }
}
///<summary>SubjectCriteriaEvaluationVisitFilterQuery 列表查询参数模型</summary>
public class SubjectCriteriaEvaluationVisitFilterQuery
{
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
[NotDefault]
public Guid SubjectId { get; set; }
public ImageFilterState? ImageFilterState { get; set; }
public ImageDeterminationResultState? ImageDeterminationResultState { get; set; }
public bool? IsGeneratedTask { get; set; }
}
public class HaveGeneratedTaskQuery : PageInput
{

View File

@ -1,25 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2023-03-17 11:58:54
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application.Interfaces
{
/// <summary>
/// ISubjectCriteriaEvaluationService
/// </summary>
public interface ISubjectCriteriaEvaluationService
{
//Task<PageOutput<SubjectCriteriaEvaluationView>> GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery);
//Task<IResponseOutput> AddOrUpdateSubjectCriteriaEvaluation(SubjectCriteriaEvaluationAddOrEdit addOrEditSubjectCriteriaEvaluation);
//Task<IResponseOutput> DeleteSubjectCriteriaEvaluation(Guid subjectCriteriaEvaluationId);
Task AutoSubjectCriteriaEvaluationVisitFilter(Guid subjectId, Guid subjectVisitId, Guid trialReadingCriterionId);
}
}

View File

@ -1,776 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2023-03-17 11:58:57
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Contracts.DTO;
using System.Linq;
using System.Linq.Dynamic.Core;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Contracts;
using DocumentFormat.OpenXml.Spreadsheet;
using Panda.DynamicWebApi.Attributes;
using IRaCIS.Core.Domain.Share.Reading;
using System.Runtime.InteropServices;
using DocumentFormat.OpenXml.Bibliography;
using System.Linq.Expressions;
using MathNet.Numerics.Statistics.Mcmc;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// SubjectCriteriaEvaluationService
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class SubjectCriteriaEvaluationService : BaseService, ISubjectCriteriaEvaluationService
{
private readonly IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitFilter> _subjectCriteriaEvaluationVisitFilterRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
private readonly IRepository<ReadingQuestionTrial> _trialReadingQuestionRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IVisitTaskHelpeService _IVisitTaskHelpeService;
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;
public SubjectCriteriaEvaluationService(IRepository<SubjectCriteriaEvaluation> subjectCriteriaEvaluationRepository, IRepository<Subject> subjectRepository,
IRepository<SubjectCriteriaEvaluationVisitFilter> subjectCriteriaEvaluationVisitFilterRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<SubjectCriteriaEvaluationVisitStudyFilter> subjectCriteriaEvaluationVisitStudyFilterRepository,
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IVisitTaskHelpeService IVisitTaskHelpeService, IRepository<ReadingQuestionTrial> trialReadingQuestionRepository, IRepository<VisitTask> visitTaskRepository, IRepository<TaskMedicalReview> taskMedicalReviewRepository, IRepository<VisitTaskReReading> visitTaskReReadingRepository)
{
_subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository;
_subjectRepository = subjectRepository;
_subjectCriteriaEvaluationVisitFilterRepository = subjectCriteriaEvaluationVisitFilterRepository;
_subjectVisitRepository = subjectVisitRepository;
_subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository;
_trialReadingCriterionRepository = trialReadingCriterionRepository;
_IVisitTaskHelpeService = IVisitTaskHelpeService;
_trialReadingQuestionRepository = trialReadingQuestionRepository;
_visitTaskRepository = visitTaskRepository;
_taskMedicalReviewRepository = taskMedicalReviewRepository;
_visitTaskReReadingRepository = visitTaskReReadingRepository;
}
/// <summary>
/// subject 某标准 是否评估列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput<PageOutput<SubjectCriteriaEvaluationView>> > GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery)
{
var trialReadingCritionList = _trialReadingCriterionRepository.Where(t => t.TrialId == inQuery.TrialId).ToList();
var resultTrialReadingCriterionId = Guid.Empty;
var resultTrialReadingCriterion = trialReadingCritionList.First();
var curentCriterionType = CriterionType.NoCriterion;
//BM 需要找基线 两个人做的结果
if (trialReadingCritionList.First(t => t.Id == inQuery.TrialReadingCriterionId).CriterionType == CriterionType.RECIST1Pointt1_MB)
{
resultTrialReadingCriterion = trialReadingCritionList.First(t => t.CriterionType == CriterionType.RECIST1Point1);
resultTrialReadingCriterionId = resultTrialReadingCriterion.Id;
curentCriterionType = CriterionType.RECIST1Pointt1_MB;
}
var addtionalQustionInfoList = _trialReadingQuestionRepository.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && t.IsAdditional == true && t.Type != "group").IgnoreQueryFilters().Select(t => new
{
QuestionId = t.Id,
t.QuestionEnName,
t.QuestionName
}).ToList();
var questionIdList = addtionalQustionInfoList.Select(t => t.QuestionId).ToList();
var subjectCriteriaEvaluationQueryable = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(inQuery.SubjectStatus != null, t => t.Status == inQuery.SubjectStatus)
join subjectCriteriaEvaluation in _subjectCriteriaEvaluationRepository
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
on subject.Id equals subjectCriteriaEvaluation.SubjectId into d
from subjectCriteriaEvaluation in d.DefaultIfEmpty()
select new SubjectCriteriaEvaluationView()
{
SubjectCode = subject.Code,
SubjectId = subject.Id,
SubjectStatus = subject.Status,
TrialSiteCode = subject.TrialSite.TrialSiteCode,
Id = subjectCriteriaEvaluation.Id,
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
IsImageFiltering = subject.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId== inQuery.TrialReadingCriterionId
&& t.ImageFilterState == ImageFilterState.None),
IsJoinEvaluation = subjectCriteriaEvaluation.IsJoinEvaluation,
ReadingEvaluationList = subject.ReadingTaskQuestionAnswerList.AsQueryable().IgnoreQueryFilters()
.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId &&
questionIdList.Contains(t.ReadingQuestionTrialId)
&& t.VisitTask.TaskState == TaskState.Effect)
.Select(u => new EvaluationInfo()
{
QuestionId = u.ReadingQuestionTrialId,
Answer = u.Answer,
ArmEnum = u.VisitTask.ArmEnum,
FinalTranslateDictionaryCode = u.ReadingQuestionTrial.DictionaryCode
}).ToList()
};
var pageList = await subjectCriteriaEvaluationQueryable
.WhereIf(inQuery.IsImageFiltering != null, t => t.IsImageFiltering == inQuery.IsImageFiltering)
.WhereIf(inQuery.IsJoinEvaluation != null, t => t.IsJoinEvaluation == inQuery.IsJoinEvaluation)
.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(SubjectCriteriaEvaluationView.SubjectCode) : inQuery.SortField, inQuery.Asc);
foreach (var item in pageList.CurrentPageData)
{
switch (curentCriterionType)
{
case CriterionType.RECIST1Pointt1_MB:
if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Double)
{
if (item.ReadingEvaluationList.Count == 2)
{
if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
{
item.FinalEvaluationList.Add(new EvaluationInfo()
{
QuestionId = item.ReadingEvaluationList.First().QuestionId,
Answer = ((int)BrainMetastasisResult.Yes).ToString(),
FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
});
}
else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
{
item.FinalEvaluationList.Add(new EvaluationInfo()
{
QuestionId = item.ReadingEvaluationList.First().QuestionId,
Answer = ((int)BrainMetastasisResult.No).ToString(),
FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
});
}
else if (item.ReadingEvaluationList.First().Answer != item.ReadingEvaluationList.Last().Answer && item.ReadingEvaluationList.Any(t => t.Answer == 1.ToString()))
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Maybe).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
else
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
}
else
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
}
else if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Single)
{
if (item.ReadingEvaluationList.Count == 1)
{
if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Yes).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.No).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
else
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
}
else
{
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
}
}
else
{
}
break;
default:
break;
}
}
return ResponseOutput.Ok (pageList, addtionalQustionInfoList);
}
/// <summary>
/// 添加 编辑 是否参与评估
/// </summary>
/// <param name="addOrEditSubjectCriteriaEvaluationList"></param>
/// <returns></returns>
[UnitOfWork]
public async Task<IResponseOutput> BatchAddOrUpdateSubjectCriteriaEvaluation(List<SubjectCriteriaEvaluationAddOrEdit> addOrEditSubjectCriteriaEvaluationList)
{
// 在此处拷贝automapper 映射
foreach (var addOrEditSubjectCriteriaEvaluation in addOrEditSubjectCriteriaEvaluationList)
{
if (addOrEditSubjectCriteriaEvaluation.Id == null)
{
var entity = await _subjectCriteriaEvaluationRepository.InsertFromDTOAsync(addOrEditSubjectCriteriaEvaluation);
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
{
//找到一致性核查通过的访视 并且没有 自动影像筛选的数据
var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed
&& !t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).Select(t => t.Id)
.ToListAsync();
foreach (var subjectVisitId in subjectVisitIdList)
{
await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
}
}
}
//编辑
else
{
//参与评估
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
{
var dbBeforeEntity = await _subjectCriteriaEvaluationRepository.UpdateFromDTOAsync(addOrEditSubjectCriteriaEvaluation);
//从不评估 改为评估
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation != dbBeforeEntity.IsJoinEvaluation)
{
//找到一致性核查通过的访视 并且没有 自动影像筛选的数据
var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed &&
!t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).
Select(t => t.Id).ToListAsync();
foreach (var subjectVisitId in subjectVisitIdList)
{
await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
}
}
//未修改 不做任何操作
}
//不参与评估
else
{
//删除该Subject 该标准访视的所有 访视筛选记录数据
await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectVisit.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
}
}
}
await _subjectCriteriaEvaluationRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 自动访视筛选 (针对单一访视,重新筛选一遍,可能不存在该接口,仅仅留存)
/// </summary>
/// <returns></returns>
[NonDynamicMethod]
public async Task AutoSubjectCriteriaEvaluationVisitFilter(Guid subjectId, Guid subjectVisitId, Guid trialReadingCriterionId)
{
if ((await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId)).CriterionType == CriterionType.RECIST1Pointt1_MB)
{
//如果所有访视 的所有序列部位都是脑部 那么自动筛选通过,同时需要插入序列的筛选记录
//找到该方式的所有序列
var list = await _repository.Where<DicomSeries>(t => t.SubjectVisitId == subjectVisitId && t.SubjectId == subjectId).Select(t => new { SeriesId = t.Id, t.StudyId, t.BodyPartForEdit }).ToListAsync();
////已经自动筛选过
//if (await _subjectCriteriaEvaluationVisitFilterRepository.AnyAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId))
//{
// await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
// await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
//}
var existEntity = await _subjectCriteriaEvaluationVisitFilterRepository.FirstOrDefaultAsync(t => t.SubjectId == subjectId && t.SubjectVisitId == subjectVisitId && t.TrialReadingCriterionId == trialReadingCriterionId);
//已经自动筛选过
if (existEntity != null)
{
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
}
//有不是脑部的序列
if (list.Any(t => t.BodyPartForEdit != "脑部"))
{
if (existEntity == null)
{
var addItem = new SubjectCriteriaEvaluationVisitFilter
{
SubjectVisitId = subjectVisitId,
SubjectId = subjectId,
ImageDeterminationResultState = ImageDeterminationResultState.None,
ImageFilterState = ImageFilterState.None,
TrialReadingCriterionId = trialReadingCriterionId
};
var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);
}
else
{
existEntity.ImageDeterminationResultState = ImageDeterminationResultState.None;
existEntity.ImageFilterState = ImageFilterState.None;
}
}
//都是脑部的序列
else
{
if (existEntity == null)
{
var addItem = new SubjectCriteriaEvaluationVisitFilter
{
SubjectVisitId = subjectVisitId,
SubjectId = subjectId,
ImageDeterminationResultState = ImageDeterminationResultState.Passed,
ImageFilterState = ImageFilterState.Finished,
TrialReadingCriterionId = trialReadingCriterionId,
IsGeneratedTask = true
};
var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);
}
else
{
existEntity.ImageDeterminationResultState = ImageDeterminationResultState.Passed;
existEntity.ImageFilterState = ImageFilterState.Finished;
}
foreach (var item in list)
{
await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitStudyFilter { SubjectVisitId = subjectVisitId, SeriesId = item.SeriesId, TrialReadingCriterionId = trialReadingCriterionId, StudyId = item.StudyId, IsConfirmed = true, IsReading = true });
}
//自动生成任务
var trialId = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.TrialId).FirstOrDefault();
await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(trialId, trialReadingCriterionId, true, new List<Guid>() { subjectVisitId });
}
}
await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();
}
/// <summary>
/// 评估访视筛选列表(一致性核查通过的访视都会出现 根据条件筛选)
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<SubjectCriteriaEvaluationVisitFilterView>> GetSubjectCriteriaEvaluationVisitFilterList(SubjectCriteriaEvaluationVisitFilterQuery inQuery)
{
var subjectCriteriaEvaluationVisitFilterQueryable = from subjectVisit in _subjectVisitRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.CheckState == CheckStateEnum.CVPassed)
join subjectCriteriaEvaluationVisitFilter in _subjectCriteriaEvaluationVisitFilterRepository
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState)
.WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState)
.WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask)
on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId
//into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty()
select new SubjectCriteriaEvaluationVisitFilterView()
{
VisitName = subjectVisit.VisitName,
VisitNum = subjectVisit.VisitNum,
SubjectVisitId = subjectVisit.Id,
TrialId = subjectVisit.TrialId,
SubjectId = subjectVisit.SubjectId,
SubjectCode = subjectVisit.Subject.Code,
SiteId = subjectVisit.SiteId,
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
LatestScanDate = subjectVisit.LatestScanDate,
EarliestScanDate = subjectVisit.LatestScanDate,
ImageDeterminationResultState = subjectCriteriaEvaluationVisitFilter.ImageDeterminationResultState,
ImageFilterState = subjectCriteriaEvaluationVisitFilter.ImageFilterState,
IsGeneratedTask = subjectCriteriaEvaluationVisitFilter.IsGeneratedTask,
Id = subjectCriteriaEvaluationVisitFilter.Id,
CreateTime = subjectCriteriaEvaluationVisitFilter.CreateTime,
CreateUserId = subjectCriteriaEvaluationVisitFilter.CreateUserId,
UpdateTime = subjectCriteriaEvaluationVisitFilter.UpdateTime,
UpdateUserId = subjectCriteriaEvaluationVisitFilter.UpdateUserId,
};
return await subjectCriteriaEvaluationVisitFilterQueryable.OrderBy(t => t.VisitNum).ToListAsync();
}
/// <summary>
/// 已生成任务列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<HaveGeneratedTaskDto>> GetHaveGeneratedTaskList(HaveGeneratedTaskQuery inQuery)
{
var list = await _repository.Where<VisitTask>(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectId == inQuery.SubjectId && t.TaskState == TaskState.Effect).OrderBy(t => t.VisitTaskNum)
.ProjectTo<HaveGeneratedTaskDto>(_mapper.ConfigurationProvider).ToListAsync();
return list;
}
/// <summary>
/// 批量勾选 生成该标准的任务
/// </summary>
/// <returns></returns>
[UnitOfWork]
public async Task<IResponseOutput> BatchGenerateTask(BatchGenerateTaskCommand batchGenerateTaskCommand)
{
var trakingList= await _subjectCriteriaEvaluationVisitFilterRepository.Where(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
&& t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
&& batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId),true).ToListAsync();
foreach (var item in trakingList)
{
item.IsGeneratedTask = true;
}
//await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
//&& t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
//&& batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId), u => new SubjectCriteriaEvaluationVisitFilter { IsGeneratedTask = true });
//自动生成任务
var idList = batchGenerateTaskCommand.SubjectVisitIdList.Select(t => (Guid?)t).ToList();
//存在任务的访视
var haveGenerateVisitIdList = await _repository.Where<VisitTask>(t => idList.Contains(t.SourceSubjectVisitId) && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId && t.TaskState == TaskState.Effect)
.Select(t => t.SourceSubjectVisitId).ToListAsync();
var generateVisitIdList = idList.Except(haveGenerateVisitIdList);
await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(batchGenerateTaskCommand.TrialId, batchGenerateTaskCommand.TrialReadingCriterionId, true, generateVisitIdList.Select(t => (Guid)t).ToList());
await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 获取dicom 访视检查列表 (序列的 Id CreateTime 是否为空 代表了记录是否创建、IsConfirmed 代表 保存 确认)
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<SelctStudySeriesView> GetVisitStudyAndSeriesList(VisitStudyAndSeriesQuery inQuery)
{
var studyList = await _repository.Where<DicomStudy>(s => s.SubjectVisitId == inQuery.SubjectVisitId).ProjectTo<SelectStudyView>(_mapper.ConfigurationProvider).ToListAsync();
var studyIds = studyList.Select(t => t.StudyId).ToList();
var query = from series in _repository.Where<DicomSeries>(t => studyIds.Contains(t.StudyId))
join visitStudyFilter in _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectVisitId == inQuery.SubjectVisitId) on series.Id equals visitStudyFilter.SeriesId into d
from visitStudyFilter in d.DefaultIfEmpty()
select new SelectSeriesView()
{
Description = series.Description,
BodyPartExamined = series.BodyPartExamined,
BodyPartForEdit = series.BodyPartForEdit,
Modality = series.Modality,
SeriesInstanceUid = series.SeriesInstanceUid,
StudyCode = series.DicomStudy.StudyCode,
SeriesNumber = series.SeriesNumber,
SeriesTime = series.SeriesTime,
InstanceCount = series.InstanceCount,
StudyTime = series.DicomStudy.StudyTime,
StudyId = series.StudyId,
SeriesId = series.Id,
SubjectVisitId = series.SubjectVisitId,
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
IsReading = visitStudyFilter.IsReading,
Id = visitStudyFilter.Id,
CreateTime = visitStudyFilter.CreateTime,
IsConfirmed = visitStudyFilter.IsConfirmed,
};
var seriesList = query.ToList();
return new SelctStudySeriesView { StudyList = studyList, SeriesList = seriesList };
}
/// <summary>
/// 批量保存或者确认 选择的序列
/// </summary>
/// <returns></returns>
public async Task<IResponseOutput> BatchAddSubjectCriteriaEvaluationVisitStudyFilter(List<SubjectCriteriaEvaluationVisitStudyFilterAddOrEdit> batchList)
{
var ids = batchList.Where(t => t.Id != null).Select(t => t.Id).ToList();
#region 稽查修改前
//await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => ids.Contains(t.Id));
//await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));
#endregion
#region 查询再更新
if (ids.Count > 0)
{
var list = await _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => ids.Contains(t.Id), true).ToListAsync();
foreach (var item in list)
{
item.IsReading = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsReading ?? item.IsReading;
item.IsConfirmed = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsConfirmed ?? item.IsConfirmed;
}
}
else
{
await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));
}
#endregion
var first = batchList.First();
if (batchList.Count(t => t.IsReading == true) >= 0 && batchList.All(t => t.IsConfirmed == false))
{
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Filtering });
}
if (batchList.All(t => t.IsConfirmed == true))
{
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Finished });
}
await _subjectCriteriaEvaluationVisitStudyFilterRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 附加评估标准 PM 退回某一访视 影响任务列表
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<InfluenceTaskInfo>, object)> GetCriteriaVisitBackInfluenceTaskList(CriteriaVisitBackCommand command)
{
var isIRAppyTaskInfluenced = false;
var filterExpression = await GetTaskExpressionAsync(command);
var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);
if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
t.OriginalReReadingTask.VisitTaskNum >= subjectVisit.VisitNum && t.OriginalReReadingTask.SubjectId == subjectVisit.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == command.TrialReadingCriterionId))
{
isIRAppyTaskInfluenced = true;
}
var list = await _visitTaskRepository.Where(filterExpression)
.OrderBy(t => t.VisitTaskNum).ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();
foreach (var influenceTask in list)
{
//重阅重置或者失效
influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon;
}
return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced });
}
private async Task<Expression<Func<VisitTask, bool>>> GetTaskExpressionAsync(CriteriaVisitBackCommand command)
{
var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId);
//仅仅影响该标准自己的任务
Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated
&& t.TrialReadingCriterionId == command.TrialReadingCriterionId;
//有序
if (criterionConfig.IsReadingTaskViewInOrder)
{
filterExpression = filterExpression.And(t => t.VisitTaskNum >= subjectVisit.VisitNum);
}
else
{
filterExpression = filterExpression.And(t => t.VisitTaskNum == subjectVisit.VisitNum);
}
return filterExpression;
}
/// <summary>
/// 退回任务
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task ConfirmBackCriteriaVisitTask(CriteriaVisitBackCommand command)
{
var filterExpression = await GetTaskExpressionAsync(command);
var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();
var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);
foreach (var influenceTask in influenceTaskList)
{
if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
{
influenceTask.TaskState = TaskState.HaveReturned;
}
else
{
influenceTask.TaskState = TaskState.Adbandon;
}
}
var taskIdList = influenceTaskList.Select(t => t.Id).ToList();
var subjectVisitIdLsit = influenceTaskList.Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId).ToList();
if (subjectVisitIdLsit.Count == 0)
{
subjectVisitIdLsit.Add(command.SubjectVisitId);
}
//医学审核任务失效
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });
//将筛选的访视 序列状态重置
//当前申请影像回退的访视 筛选状态重置,任务生成状态重置
var otherVisitIdList = subjectVisitIdLsit.Where(t => t != command.SubjectVisitId).ToList();
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.SubjectVisitId == command.SubjectVisitId,
t => new SubjectCriteriaEvaluationVisitFilter()
{
ImageFilterState = ImageFilterState.None,
ImageDeterminationResultState = ImageDeterminationResultState.None,
IsGeneratedTask = false
});
//删除序列数据
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectVisitId == command.SubjectVisitId);
//BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配)
await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId),
t => new SubjectCriteriaEvaluationVisitFilter()
{
IsGeneratedTask = false
});
await _visitTaskRepository.SaveChangesAsync();
}
}
}

View File

@ -303,11 +303,7 @@ namespace IRaCIS.Core.Application.Service
// .ForMember(d => d.SubjectStatus, u => u.MapFrom(s => s.subject.Status));
CreateMap<SubjectCriteriaEvaluationAddOrEdit, SubjectCriteriaEvaluation>().ReverseMap();
CreateMap<SubjectCriteriaEvaluation, SubjectCriteriaEvaluationView>().ReverseMap();
CreateMap<SubjectCriteriaEvaluationVisitFilter, SubjectCriteriaEvaluationVisitFilterAddOrEdit>().ReverseMap();
CreateMap<SubjectCriteriaEvaluationVisitStudyFilterAddOrEdit, SubjectCriteriaEvaluationVisitStudyFilter>().ReverseMap();
CreateMap<DicomStudy, SelectStudyView>()
.ForMember(o => o.UploadedTime, t => t.MapFrom(u => u.CreateTime))

View File

@ -28,14 +28,12 @@ namespace IRaCIS.Core.Application.Contracts
private readonly IRepository<TrialSiteUserSurvey> _trialSiteUserSurveyRepository;
private readonly IRepository<User> _userRepository;
private readonly IRepository<TrialSite> _trialSiteRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<TrialUser> _trialUserRepository;
private readonly ITokenService _tokenService;
private readonly IMailVerificationService _mailVerificationService;
public TrialSiteSurveyService(IRepository<TrialSiteSurvey> trialSiteSurveyRepository, IRepository<TrialUser> trialUserRepository, IRepository<TrialSiteUserSurvey> trialSiteUserSurveyRepository,
IRepository<User> userRepository, IRepository<TrialSite> trialSiteRepository,
IRepository<Doctor> doctorRepository,
ITokenService tokenService,
IMailVerificationService mailVerificationService)
{
@ -44,7 +42,6 @@ namespace IRaCIS.Core.Application.Contracts
_userRepository = userRepository;
_trialUserRepository = trialUserRepository;
_trialSiteRepository = trialSiteRepository;
this._doctorRepository = doctorRepository;
_tokenService = tokenService;
_mailVerificationService = mailVerificationService;
}
@ -86,11 +83,6 @@ namespace IRaCIS.Core.Application.Contracts
var verificationRecord = await _repository.GetQueryable<VerificationCode>().OrderByDescending(x => x.ExpirationTime).Where(t => (t.EmailOrPhone == inDto.EmailOrPhone) && t.Code == inDto.VerificationCode && t.CodeType == VerifyType.Email).FirstOrDefaultAsync();
VerifyEmialGetDoctorInfoOutDto result = new VerifyEmialGetDoctorInfoOutDto();
var doctorInfo = await _doctorRepository.Where(x => x.EMail == inDto.EmailOrPhone).FirstOrDefaultAsync();
result.DoctorId = doctorInfo == null ? null : doctorInfo.Id;
result.ReviewStatus = doctorInfo == null ? null : doctorInfo.ReviewStatus;
//检查数据库是否存在该验证码
if (verificationRecord == null)
{

View File

@ -7,37 +7,12 @@ namespace IRaCIS.Application.Interfaces
{
public interface IStatisticsService
{
Task<PageOutput<WorkloadByTrialAndReviewerDTO>> GetWorkloadByTrialAndReviewer(StatisticsWorkloadQueryParam param);
PageOutput<EnrollStatByTrialDTO> GetEnrollStatByTrial(EnrollStatByTrialQueryDTO param);
PageOutput<UserParticipateTrialStat> GetParticipateTrialStat(ParticipateQueryDto param);
List<UserParticipateTrialDetail> GetParticipateTrialList(Guid userId);
#region Dashboard 数据统计
/// <summary> 按类型统计读片数量 </summary>
ReadingDataDTO GetReadingDataByType();
/// <summary> 按月份统计读片数量 </summary>
List<ReadingDataMonthDTO> GetReadingDataByMonth(int monthCount);
/// <summary> 读片数量排行 </summary>
List<ReadingDataRankDTO> GetReadingDataRank(int topCount);
/// <summary> 按Position统计 Reviewers 数量 </summary>
List<RankReviewersDTO> GetReviewersByRank();
///<summary> 每月入组人次 </summary>
List<EnrollQuartDataDTO> GetEnrollDataByQuarter(int quarterCount, int monthCount);
///<summary> 参与项目数排行 </summary>
List<TrialDataRankDTO> GetTrialCountRank(int topCount);
///<summary> 最新工作量 (已确定的)</summary>
List<LatestWorkLoadDTO> GetLatestWorkLoadList( int searchCount);
#endregion
Task<PageOutput<EnrollStatByReviewerDTO>> GetEnrollStatByReviewer(EnrollStatByReviewerQueryDTO enrollTrialStatisticsQueryParam);
}
}

View File

@ -14,380 +14,39 @@ namespace IRaCIS.Application.Services
[ApiExplorerSettings(GroupName = "Dashboard&Statistics")]
public class StatisticsService : BaseService, IStatisticsService
{
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<Workload> _workloadRepository;
private readonly IRepository<CRO> _croCompanyRepository;
private readonly IRepository<Dictionary> _dictionaryRepository;
private readonly IRepository<Hospital> _hospitalRepository;
private readonly IRepository<EnrollDetail> _enrollDetailRepository;
private readonly IRepository<User> _userRepository;
private readonly IRepository<TrialUser> _userTrialRepository;
public StatisticsService(IRepository<Doctor> doctorRepository, IRepository<Trial> trialRepository,
IRepository<Enroll> intoGroupRepository, IRepository<Workload> workloadRepository,
public StatisticsService( IRepository<Trial> trialRepository,
IRepository<CRO> croCompanyRepository,
IRepository<Dictionary> dictionaryRepository,
IRepository<Hospital> hospitalRepository,
IRepository<EnrollDetail> enrollDetailRepository, IRepository<User> userRepository,
IRepository<User> userRepository,
IRepository<TrialUser> userTrialRepository)
{
_doctorRepository = doctorRepository;
_trialRepository = trialRepository;
_enrollRepository = intoGroupRepository;
_workloadRepository = workloadRepository;
_croCompanyRepository = croCompanyRepository;
_dictionaryRepository = dictionaryRepository;
_hospitalRepository = hospitalRepository;
_enrollDetailRepository = enrollDetailRepository;
_userRepository = userRepository;
_userTrialRepository = userTrialRepository;
}
/// <summary> 根据项目和医生,分页获取工作量统计[New] </summary>
[HttpPost]
public async Task<PageOutput<WorkloadByTrialAndReviewerDTO>> GetWorkloadByTrialAndReviewer(
StatisticsWorkloadQueryParam param)
{
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, param.BeginDate.Day);
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, param.EndDate.Day);
eDate = eDate.AddDays(1);
Expression<Func<Workload, bool>> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm;
workloadLambda = workloadLambda.And(x => x.WorkTime >= bDate && x.WorkTime < eDate);
Expression<Func<Trial, bool>> trialLambda = x => true;
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) //超级管理员按照条件查询所有
{
if (param.CroId != null)
{
trialLambda = trialLambda.And(u => u.CROId == param.CroId);
}
}
else //不管是精鼎的pm还是我们的pm 还是运维人员 只能看到自己参与项目的统计
{
List<Guid> trialIdList = _userTrialRepository.Where(u => u.UserId == _userInfo.Id).Select(u => u.TrialId).ToList();
trialLambda = trialLambda.And(u => trialIdList.Contains(u.Id));
}
if (!string.IsNullOrWhiteSpace(param.TrialCode))
{
trialLambda = trialLambda.And(u => u.TrialCode.Contains(param.TrialCode));
}
Expression<Func<Doctor, bool>> doctorLambda = x => true;
if (!string.IsNullOrWhiteSpace(param.Reviewer))
{
var reviewer = param.Reviewer.Trim();
doctorLambda = doctorLambda.And(u => u.ChineseName.Contains(reviewer)
|| u.FirstName.Contains(reviewer)
|| u.LastName.Contains(reviewer)
|| u.ReviewerCode.Contains(reviewer)
);
}
if (Guid.Empty != param.HospitalId && param.HospitalId != null)
{
doctorLambda = doctorLambda.And(u => u.HospitalId == param.HospitalId);
}
var workloadQuery = from workLoad in _workloadRepository.Where(workloadLambda)
join trial in _trialRepository.Where(trialLambda) on workLoad.TrialId equals trial.Id
join doctor in _doctorRepository.Where(doctorLambda) on workLoad.DoctorId equals doctor.Id
group workLoad by new { workLoad.DoctorId, workLoad.TrialId } into gWorkLoad
select new
{
DoctorId = gWorkLoad.Key.DoctorId,
TrialId = gWorkLoad.Key.TrialId,
Downtime = gWorkLoad.Sum(t => t.Downtime),
Training = gWorkLoad.Sum(t => t.Training),
Timepoint = gWorkLoad.Sum(t => t.Timepoint),
TimepointIn24H = gWorkLoad.Sum(t => t.TimepointIn24H),
TimepointIn48H = gWorkLoad.Sum(t => t.TimepointIn48H),
Global = gWorkLoad.Sum(t => t.Global),
Adjudication = gWorkLoad.Sum(t => t.Adjudication),
AdjudicationIn24H = gWorkLoad.Sum(t => t.AdjudicationIn24H),
AdjudicationIn48H = gWorkLoad.Sum(t => t.AdjudicationIn48H),
RefresherTraining = gWorkLoad.Sum(t => t.RefresherTraining),
};
var query = from w in workloadQuery
join trial in _trialRepository.Where(trialLambda) on w.TrialId equals trial.Id into t
from trialItem in t.DefaultIfEmpty()
join doctor in _doctorRepository.Where(doctorLambda) on w.DoctorId equals doctor.Id into tt
from doctorItem in tt.DefaultIfEmpty()
join cro in _croCompanyRepository.AsQueryable() on trialItem.CROId equals cro.Id into ttt
from croItem in ttt.DefaultIfEmpty()
select new WorkloadByTrialAndReviewerDTO
{
Id = Guid.NewGuid(),
TrialId = trialItem.Id,
Indication = trialItem.Indication,
TrialCode = trialItem.TrialCode,
CroId = trialItem.CROId,
Cro = croItem.CROName,
ReviewerCode = doctorItem.ReviewerCode,
ChineseName = doctorItem.ChineseName,
FirstName = doctorItem.FirstName,
LastName = doctorItem.LastName,
FullName = doctorItem.FullName,
Training = w.Training,
Timepoint = w.Timepoint,
TimepointIn24H = w.TimepointIn24H,
TimepointIn48H = w.TimepointIn48H,
Adjudication = w.Adjudication,
AdjudicationIn24H = w.AdjudicationIn24H,
AdjudicationIn48H = w.AdjudicationIn48H,
Global = w.Global,
Downtime = w.Downtime,
RefresherTraining = w.RefresherTraining,
PersonalTotal = w.Timepoint + w.TimepointIn24H + w.TimepointIn48H + w.Adjudication + w.AdjudicationIn24H +
w.AdjudicationIn48H + w.Global
};
return await query.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "ReviewerCode" : param.SortField, param.Asc);
//var propName = param.SortField == "" ? "ReviewerCode" : param.SortField;
//query = param.Asc
// ? query.OrderBy(propName).ThenBy(t => t.TrialCode).ThenBy(u => u.ReviewerCode)
// : query.OrderByDescending(propName).ThenBy(t => t.TrialCode).ThenBy(u => u.ReviewerCode);
//if (propName == "FirstName" || propName == "LastName")
//{
// query = param.Asc
// ? query.OrderBy(t => t.LastName).ThenBy(t => t.FirstName)
// : query.OrderByDescending(t => t.LastName).ThenBy(t => t.FirstName);
//}
//var count = query.Count();
//query = query
// .Skip((param.PageIndex - 1) * param.PageSize)
// .Take(param.PageSize);
//var doctorViewList = query.ToList();
//return new PageOutput<WorkloadByTrialAndReviewerDTO>(param.PageIndex, param.PageSize, count, doctorViewList);
}
/// <summary> 项目入组 医生维度统计[New] </summary>
[HttpPost]
public async Task<PageOutput<EnrollStatByReviewerDTO>> GetEnrollStatByReviewer(EnrollStatByReviewerQueryDTO param)
{
var bDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
var eDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
eDate = eDate.AddMonths(1);
Expression<Func<Enroll, bool>> enrollLambda = x => true;
enrollLambda = enrollLambda.And(x => x.EnrollTime >= bDate && x.EnrollTime < eDate);
Expression<Func<Hospital, bool>> hospitalLambda = x => true;
if (Guid.Empty != param.HospitalId && param.HospitalId != null)
{
hospitalLambda = hospitalLambda.And(u => u.Id == param.HospitalId);
}
Expression<Func<Doctor, bool>> doctorLambda = x => true;
if (!string.IsNullOrWhiteSpace(param.Reviewer))
{
var reviewer = param.Reviewer.Trim();
doctorLambda = doctorLambda.And(u => u.ChineseName.Contains(reviewer)
|| u.FirstName.Contains(reviewer)
|| u.LastName.Contains(reviewer)
|| u.ReviewerCode.Contains(reviewer)
);
}
var enrollQueryable =
from enroll in _enrollRepository.Where(enrollLambda)
group enroll by new { enroll.DoctorId }
into g
select new
{
DoctorId = g.Key.DoctorId,
Submitted = g.Sum(t =>
t.EnrollStatus == EnrollStatus.HasCommittedToCRO ? 1 : 0),
Approved = g.Sum(t =>
t.EnrollStatus == EnrollStatus.InviteIntoGroup ? 1 : 0),
Reading = g.Sum(t =>
t.EnrollStatus == EnrollStatus.DoctorReading ? 1 : 0),
Finished = g.Sum(t =>
t.EnrollStatus >= EnrollStatus.Finished ? 1 : 0),
};
var query = from w in enrollQueryable
join doctor in _doctorRepository.Where(doctorLambda) on w.DoctorId equals doctor.Id
join hospital in _hospitalRepository.Where(hospitalLambda) on doctor.HospitalId equals hospital.Id
select new EnrollStatByReviewerDTO
{
Id = Guid.NewGuid(),
Hospital = hospital.HospitalName,
ReviewerCode = doctor.ReviewerCode,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
FullName = doctor.FullName,
Pending = w.Submitted,
Approved = w.Approved,
Reading = w.Reading,
Finished = w.Finished,
Total = w.Submitted + w.Approved + w.Reading + w.Finished
};
var pageData = await query.ToPagedListAsync(param.PageIndex, param.PageIndex, param.SortField == "" ? "ReviewerCode" : param.SortField, param.Asc);
if (param.SortField == "EntryRate")
{
pageData.CurrentPageData.OrderBy(t => t.EntryRate);
}
return pageData;
//var count = query.Count();
//query = query
// .Skip((param.PageIndex - 1) * param.PageSize)
// .Take(param.PageSize);
//var list = query.ToList();
//if (param.SortField == "EntryRate")
//{
// list = param.Asc
// ? list.OrderBy(t => t.EntryRate).ToList()
// : list.OrderByDescending(t => t.EntryRate).ToList();
//}
//return new PageOutput<EnrollStatByReviewerDTO>(param.PageIndex, param.PageSize, count, list);
}
[HttpPost]
public PageOutput<EnrollStatByTrialDTO> GetEnrollStatByTrial(EnrollStatByTrialQueryDTO param)
{
#region 筛选条件
Expression<Func<Trial, bool>> trialLambda = x => true;
if (param.Expedited != null)
{
trialLambda = trialLambda.And(o => o.Expedited == param.Expedited);
}
if (!string.IsNullOrEmpty(param.TrialCode))
{
var code = param.TrialCode.Trim();
trialLambda = trialLambda.And(o => o.TrialCode.Contains(code));
}
if (!string.IsNullOrWhiteSpace(param.Indication))
{
var indication = param.Indication.Trim();
trialLambda = trialLambda.And(o => o.Indication.Contains(indication));
}
if (param.CROId != null)
{
trialLambda = trialLambda.And(o => o.CROId == param.CROId);
}
if (param.BeginDate != null && param.EndDate != null)
{
var bDate = new DateTime(param.BeginDate.Value.Year, param.BeginDate.Value.Month, param.BeginDate.Value.Day);
var eDate = new DateTime(param.EndDate.Value.Year, param.EndDate.Value.Month, param.BeginDate.Value.Day);
eDate = eDate.AddMonths(1);
trialLambda = trialLambda.And(o => o.CreateTime >= bDate && o.CreateTime < eDate);
}
#endregion
var trialEnrollStatQuery = _enrollRepository.AsQueryable()
.Where(t => t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup).GroupBy(t => t.TrialId).Select(g => new
{
TrialId = g.Key,
EnrollCount = g.Count()
});
var trialQuery = from trial in _trialRepository.Where(trialLambda)
join cro in _croCompanyRepository.AsQueryable() on trial.CROId equals cro.Id into t
from cro in t.DefaultIfEmpty()
join trialEnroll in trialEnrollStatQuery on trial.Id equals trialEnroll.TrialId
select new EnrollStatByTrialDTO
{
TrialId = trial.Id,
Cro = cro != null ? cro.CROName : "",
Expedited = trial.Expedited,
Indication = trial.Indication,
TrialCode = trial.TrialCode,
EnrollCount = trialEnroll.EnrollCount,
CreateTime = trial.CreateTime
};
var propName = param.SortField == "" ? "TrialCode" : param.SortField;
trialQuery = param.Asc
? trialQuery.OrderBy(propName)
: trialQuery.OrderBy(propName + " desc");
var count = trialQuery.Count();
trialQuery = trialQuery
.Skip((param.PageIndex - 1) * param.PageSize)
.Take(param.PageSize);
var trialList = trialQuery.ToList();
var trialIds = trialList.Select(t => t.TrialId).ToList();
var enrollReviewerQuery = from enroll in _enrollRepository.AsQueryable()
.Where(t => t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup && trialIds.Contains(t.TrialId))
join reviewer in _doctorRepository.AsQueryable() on enroll.DoctorId equals reviewer.Id
select new
{
TrialId = enroll.TrialId,
NameCN = reviewer.ChineseName,
Name = reviewer.LastName + " / " + reviewer.FirstName
};
var enrollReviewerByTrialList = enrollReviewerQuery.ToList().GroupBy(t => t.TrialId).Select(g => new
{
TrialId = g.Key,
ReviewerNameCNList = g.Select(t => t.NameCN).ToList(),
ReviewerNameList = g.Select(t => t.Name).ToList()
}).ToList();
trialList.ForEach(t =>
{
var trialDoctors = enrollReviewerByTrialList.FirstOrDefault(u => u.TrialId == t.TrialId);
if (trialDoctors != null)
{
t.ReviewerNameCNList = trialDoctors.ReviewerNameCNList;
t.ReviewerNameList = trialDoctors.ReviewerNameList;
}
});
return new PageOutput<EnrollStatByTrialDTO>(param.PageIndex, param.PageSize, count, trialList);
}
/// <summary> 用户参与项目 统计[New] </summary>
[HttpPost]
@ -497,355 +156,8 @@ namespace IRaCIS.Application.Services
#region Dashboard 数据统计
/// <summary> 读片数分类统计[New] </summary>
public ReadingDataDTO GetReadingDataByType()
{
int tp = 0; int ad = 0; int g = 0;
var finalConfirmWorkload = _workloadRepository.Where(u => u.DataFrom == (int)WorkLoadFromStatus.FinalConfirm).ToList();
foreach (var item in finalConfirmWorkload)
{
tp += (item.Timepoint + item.TimepointIn24H + item.TimepointIn48H);
ad += (item.Adjudication + item.AdjudicationIn24H + item.AdjudicationIn48H);
g += item.Global;
}
return new ReadingDataDTO
{
Timepoint = tp,
Adjudication = ad,
Global = g
};
}
/// <summary> 获取最近几个月份的数据[New] </summary>
[HttpGet, Route("{monthCount:int}")]
public List<ReadingDataMonthDTO> GetReadingDataByMonth(int monthCount)
{
DateTime now = DateTime.Now.AddMonths(-1);
DateTime eTime = new DateTime(now.Year, now.Month, 20);
DateTime now6 = now.AddMonths(-1 * (monthCount - 1));
DateTime bTime = new DateTime(now.AddMonths(-(monthCount - 1)).Year,
now.AddMonths(-(monthCount - 1)).Month, 1, 0, 0, 0, 0);
var query = from workload in _workloadRepository
.Where(u => u.DataFrom == (int)WorkLoadFromStatus.FinalConfirm &&
u.WorkTime >= bTime && u.WorkTime < eTime)
group workload by workload.YearMonth
into gWorkLoad
select new ReadingDataMonthDTO
{
Month = gWorkLoad.Key,
Timepoint = gWorkLoad.Sum(t => t.Timepoint) + gWorkLoad.Sum(t => t.TimepointIn24H)
+ gWorkLoad.Sum(t => t.TimepointIn48H),
Adjudication = gWorkLoad.Sum(t => t.Adjudication) + gWorkLoad.Sum(t => t.AdjudicationIn24H)
+ gWorkLoad.Sum(t => t.AdjudicationIn48H),
Global = gWorkLoad.Sum(t => t.Global)
};
var workloadList = query.OrderByDescending(u => u.Month).ToList();
List<ReadingDataMonthDTO> result = new List<ReadingDataMonthDTO>();
for (int i = 0; i < monthCount; i++)
{
var tempTime = now.AddMonths(-1 * i);
var existedItem = workloadList.Find(u => u.Month ==
(tempTime.Year + "-" + tempTime.Month.ToString().PadLeft(2, '0')));
if (existedItem != null)
{
result.Add(new ReadingDataMonthDTO
{
Month = existedItem.Month,
Timepoint = existedItem.Timepoint,
Adjudication = existedItem.Adjudication,
Global = existedItem.Global
});
}
else
{
result.Add(new ReadingDataMonthDTO
{
Month = tempTime.Year + "-" + tempTime.Month.ToString().PadLeft(2, '0'),
Timepoint = 0,
Adjudication = 0,
Global = 0
});
}
}
return result;
}
/// <summary> 读片数量排行前几的数据[New] </summary>
[HttpGet("{topCount:int}")]
public List<ReadingDataRankDTO> GetReadingDataRank(int topCount)
{
var query = from workload in _workloadRepository
.Where(u => u.DataFrom == (int)WorkLoadFromStatus.FinalConfirm)
group workload by workload.DoctorId
into gWorkLoad
select new ReadingDataRankDTO
{
TotalReadingCount = gWorkLoad.Sum(t => t.Timepoint) + gWorkLoad.Sum(t => t.TimepointIn24H)
+ gWorkLoad.Sum(t => t.TimepointIn48H) + gWorkLoad.Sum(t => t.Adjudication) + gWorkLoad.Sum(t => t.AdjudicationIn24H)
+ gWorkLoad.Sum(t => t.AdjudicationIn48H) + gWorkLoad.Sum(t => t.Global),
ReviewerId = gWorkLoad.Key,
Timepoint = gWorkLoad.Sum(t => t.Timepoint) + gWorkLoad.Sum(t => t.TimepointIn24H)
+ gWorkLoad.Sum(t => t.TimepointIn48H),
Adjudication = gWorkLoad.Sum(t => t.Adjudication) + gWorkLoad.Sum(t => t.AdjudicationIn24H)
+ gWorkLoad.Sum(t => t.AdjudicationIn48H),
Global = gWorkLoad.Sum(t => t.Global)
};
var workloadList = query.OrderByDescending(u => u.TotalReadingCount).Take(topCount).ToList();
var reviewerList = from w in workloadList
join doctor in _doctorRepository.Where() on w.ReviewerId equals doctor.Id into tt
from doctorItem in tt.DefaultIfEmpty()
select new ReadingDataRankDTO
{
TotalReadingCount = w.TotalReadingCount,
ReviewerId = w.ReviewerId,
Timepoint = w.Timepoint,
Adjudication = w.Adjudication,
Global = w.Global,
ReviewerCode = doctorItem.ReviewerCode,
FirstName = doctorItem.FirstName,
LastName = doctorItem.LastName,
ChineseName = doctorItem.ChineseName
};
return reviewerList.ToList();
}
/// <summary> 按Rank统计Reviewer 数量[New] </summary>
public List<RankReviewersDTO> GetReviewersByRank()
{
var query = from q in (from reviewer in _doctorRepository.AsQueryable()
//.Find(u => u.ReviewStatus == 1 && u.CooperateStatus == 1)
group reviewer by reviewer.RankId
into gReviewer
select new
{
RankId = gReviewer.Key,
ReviewerCount = gReviewer.Count()
})
join dic in _dictionaryRepository.Where() on q.RankId equals dic.Id into tt
from dicItem in tt.DefaultIfEmpty()
select new RankReviewersDTO
{
RankId = q.RankId,
ReviewerCount = q.ReviewerCount,
RankName = dicItem == null ? "Other" : dicItem.Value
};
var rankList = query.ToList();
var staffList = rankList.Where(u => u.RankName == "Staff" || u.RankName == "Other");
int staffCount = 0;
foreach (var item in staffList)
{
staffCount += item.ReviewerCount;
}
rankList.RemoveAll(u => u.RankName == "Staff" || u.RankName == "Other");
rankList.Add(new RankReviewersDTO { RankId = Guid.NewGuid(), RankName = "Staff", ReviewerCount = staffCount });
return rankList;
}
///<summary> 最近几个季度入组人次[New] type==0 按照月份 </summary>
[HttpGet("{type:int}/{count:int}")]
public List<EnrollQuartDataDTO> GetEnrollDataByQuarter(int type, int count)
{
//等于0按照月份 否则按照季度
if (type != 0)
{
var quarterCount = count;
var year = DateTime.Now.AddMonths(-(quarterCount - 1) * 3 - DateTime.Now.Month % 3 + 1).Year;
var month = DateTime.Now.AddMonths(-(quarterCount - 1) * 3 - DateTime.Now.Month % 3 + 1).Month;
var beginMonth = new DateTime(year, month, 1);
var endMonth = DateTime.Now;
var querySql = from enrollDetail in _enrollDetailRepository.Where(t =>
t.CreateTime > beginMonth && t.CreateTime < endMonth &&
t.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
select new
{
OptTime = enrollDetail.CreateTime,
Year = enrollDetail.CreateTime.Year,
Month = enrollDetail.CreateTime.Month,
};
var result = querySql.GroupBy(t => new { t.Year, t.Month }).Select(s => new EnrollDataDTO
{
Year = s.Key.Year,
Month = s.Key.Month,
EnrollCount = s.Count()
}).ToList();
#region 填充数据
List<EnrollDataDTO> returnList = new List<EnrollDataDTO>();
for (int i = 0; i < DateTime.Now.Month % 3 + (quarterCount - 1) * 3; i++)
{
var tempTime = DateTime.Now.AddMonths(-1 * i);
var existedItem = result.FirstOrDefault(u => u.YearMonth == tempTime.ToString("yyyy-MM"));
if (existedItem != null)
{
returnList.Add(new EnrollDataDTO
{
Month = existedItem.Month,
Year = existedItem.Year,
EnrollCount = existedItem.EnrollCount
});
}
else
{
returnList.Add(new EnrollDataDTO
{
Month = tempTime.Month,
Year = tempTime.Year,
EnrollCount = 0
});
}
}
#endregion
var returnResult = returnList.GroupBy(t => t.QuarterStr).Select(u => new EnrollQuartDataDTO()
{
ViewStr = u.Key,
EnrollCount = u.Sum(t => t.EnrollCount)
}).ToList();
return returnResult;
}
else
{
var year = DateTime.Now.AddMonths(-(count - 1)).Year;
var month = DateTime.Now.AddMonths(-(count - 1)).Month;
var beginMonth = new DateTime(year, month, 1);
var endMonth = DateTime.Now;
var querySql = from enrollDetail in _enrollDetailRepository.Where(t =>
t.CreateTime > beginMonth && t.CreateTime < endMonth &&
t.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
select new
{
OptTime = enrollDetail.CreateTime,
Year = enrollDetail.CreateTime.Year,
Month = enrollDetail.CreateTime.Month,
};
var result = querySql.GroupBy(t => new { t.Year, t.Month }).Select(s => new EnrollDataDTO
{
Year = s.Key.Year,
Month = s.Key.Month,
EnrollCount = s.Count()
}).ToList();
#region 填充数据
List<EnrollDataDTO> returnList = new List<EnrollDataDTO>();
for (int i = 0; i < count; i++)
{
var tempTime = DateTime.Now.AddMonths(-1 * i);
var existedItem = result.FirstOrDefault(u => u.YearMonth == tempTime.ToString("yyyy-MM"));
if (existedItem != null)
{
returnList.Add(new EnrollDataDTO
{
Month = existedItem.Month,
Year = existedItem.Year,
EnrollCount = existedItem.EnrollCount
});
}
else
{
returnList.Add(new EnrollDataDTO
{
Month = tempTime.Month,
Year = tempTime.Year,
EnrollCount = 0
});
}
}
#endregion
var returnResult = returnList.GroupBy(t => t.YearMonth).Select(u => new EnrollQuartDataDTO()
{
ViewStr = u.Key,
EnrollCount = u.Sum(t => t.EnrollCount)
}).ToList();
return returnResult;
}
}
///<summary> 参与项目数排行 [New] </summary>
[HttpGet("{topCount:int}")]
public List<TrialDataRankDTO> GetTrialCountRank(int topCount)
{
var queryList = (from enrollDetail in _enrollDetailRepository.Where(t =>
t.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
group enrollDetail by enrollDetail.DoctorId
into g
select new
{
ReviewerId = g.Key,
TrialCount = g.Count()
}).OrderByDescending(u => u.TrialCount).Take(topCount).ToList();
var trialDataRank = from stat in queryList
join doctor in _doctorRepository.AsQueryable() on stat.ReviewerId equals doctor.Id
select new TrialDataRankDTO()
{
TrialCount = stat.TrialCount,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
ReviewerId = doctor.Id,
ReviewerCode = doctor.ReviewerCode
};
return trialDataRank.ToList();
}
///<summary> 最新工作量 (已确定的)[New] </summary>
[HttpGet("{searchCount:int}")]
public List<LatestWorkLoadDTO> GetLatestWorkLoadList(int searchCount)
{
var workloadList = _workloadRepository.AsQueryable()
.Where(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm &&
(t.Adjudication + t.AdjudicationIn24H + t.AdjudicationIn48H) > 0 &&
(t.Timepoint + t.TimepointIn24H + t.TimepointIn48H) > 0)
.OrderByDescending(t => t.CreateTime).Take(searchCount).ToList();
var reviewerList = from w in workloadList
join doctor in _doctorRepository.Where() on w.DoctorId equals doctor.Id into tt
from doctorItem in tt.DefaultIfEmpty()
join trial in _trialRepository.AsQueryable() on w.TrialId equals trial.Id into cc
from trialItem in cc.DefaultIfEmpty()
select new LatestWorkLoadDTO
{
ReviewerId = w.DoctorId,
Timepoint = w.Timepoint + w.TimepointIn48H + w.TimepointIn24H,
Adjudication = w.Adjudication + w.AdjudicationIn48H + w.AdjudicationIn24H,
Global = w.Global,
ReviewerCode = doctorItem.ReviewerCode,
FirstName = doctorItem.FirstName,
LastName = doctorItem.LastName,
ChineseName = doctorItem.ChineseName,
TrialCode = trialItem.TrialCode
};
return reviewerList.ToList();
}
#endregion
}

View File

@ -10,14 +10,11 @@ namespace IRaCIS.Application.Interfaces
Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand trialAddModel);
Task<IResponseOutput> DeleteTrial(Guid trialId);
Task<PageOutput<TrialDetailDTO>> GetReviewerTrialListByEnrollmentStatus(TrialByStatusQueryDTO param);
Task<List<Guid>> GetTrialEnrollmentReviewerIds(Guid trialId);
Task<int> GetTrialExpeditedState(Guid trialId);
Task<TrialDetailDTO> GetTrialInfoAndLockState(Guid projectId);
Task<TrialAndTrialStateVieModel> GetTrialInfoAndMaxTrialState(Guid trialId);
Task<PageOutput<TrialDetailDTO>> GetTrialList(TrialQueryDTO searchParam);
Task<PageOutput<TrialDetailDTO>> GetTrialListByReviewer(ReviewerTrialQueryDTO searchModel);
Task<int> GetTrialMaxState(Guid trialId);
Task<IResponseOutput> UpdateEnrollStatus(Guid trialId, EnrollStatus status);
}
}

View File

@ -262,40 +262,6 @@ namespace IRaCIS.Core.Application
}
/// <summary>
///PM 阅片人筛选 -- PM APM 待办
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_enrollRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> vvv
[HttpPost]
public async Task<IResponseOutput<PageOutput<ReviewerSelectToBeDoneDto>>> GetPM_ReviewerSelectToBeDoneList(ReviewerSelectToBeDoneQuery inQuery
, [FromServices] IRepository<Enroll> _enrollRepository,
[FromServices] IRepository<Trial> _trialRepository)
{
var query = _trialRepository
.Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Select(t => new ReviewerSelectToBeDoneDto()
{
TrialId = t.Id,
ResearchProgramNo = t.ResearchProgramNo,
ExperimentName = t.ExperimentName,
TrialCode = t.TrialCode,
IsUrgent = t.IsUrgent || t.IsSubjectExpeditedView,
ToBeApprovalCount = t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.InviteIntoGroup).Count()
}).Where(x => x.ToBeApprovalCount > 0);
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ReviewerSelectToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeApprovalCount = await _enrollRepository.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).CountAsync();
return ResponseOutput.Ok(result, new { ToBeApprovalCount = toBeApprovalCount }); ;
}
/// <summary>
/// 获取PM核对临床数据
@ -339,39 +305,6 @@ namespace IRaCIS.Core.Application
#region SPM CPM 待办
/// <summary>
///SPM 阅片人筛选
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_enrollRepository"></param>
/// <param name="_trialRepository"></param>
/// <returns></returns> vvv
[HttpPost]
public async Task<IResponseOutput<PageOutput<ReviewerSelectToBeDoneDto>>> GetSPM_ReviewerSelectToBeDoneList(ReviewerSelectToBeDoneQuery inQuery
, [FromServices] IRepository<Enroll> _enrollRepository,
[FromServices] IRepository<Trial> _trialRepository)
{
var query = _trialRepository
.Where(t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Select(t => new ReviewerSelectToBeDoneDto()
{
TrialId = t.Id,
ResearchProgramNo = t.ResearchProgramNo,
ExperimentName = t.ExperimentName,
TrialCode = t.TrialCode,
IsUrgent = t.IsUrgent || t.IsSubjectExpeditedView,
ToBeApprovalCount = t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count()
}).Where(x => x.ToBeApprovalCount > 0) ;
var result = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? nameof(ReviewerSelectToBeDoneDto.TrialId) : inQuery.SortField, inQuery.Asc);
var toBeApprovalCount = await _enrollRepository.Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).CountAsync();
return ResponseOutput.Ok(result, new { TotalToBeApprovalCount = toBeApprovalCount }); ;
}
/// <summary>
/// SPM 重阅审批
@ -811,7 +744,7 @@ namespace IRaCIS.Core.Application
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//前序 不存在 未生成任务的访视
.Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
//.Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.Count(t => t.IsUrgent),
@ -822,7 +755,7 @@ namespace IRaCIS.Core.Application
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//前序 不存在 未生成任务的访视
//.WhereIf(g.Key.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))
.Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
//.Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.Count(),
@ -911,8 +844,6 @@ namespace IRaCIS.Core.Application
.Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//前序 不存在 未生成任务的访视
.Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
.Count();
@ -1150,15 +1081,7 @@ namespace IRaCIS.Core.Application
FullName = t.User.FullName,
UserType = t.User.UserTypeEnum,
//SPM 阅片人筛选
ReviewerSelect_SPM_ToBeApprovalCount =
(t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM) ?
t.Trial.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count() : 0,
//PM 阅片人确认
ReviewerSelect_PM_ToBeConfirmCount =
(t.User.UserTypeEnum == UserTypeEnum.APM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager) ?
t.Trial.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.InviteIntoGroup).Count() : 0,
//CRC 重传 --区分人
ImageUpload_CRC_ToBeReUploadCount =
@ -1227,7 +1150,7 @@ namespace IRaCIS.Core.Application
// 前序 不存在 未一致性核查未通过的
.Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
//前序 不存在 未生成任务的访视
.Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)
.Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).Count() : 0,

View File

@ -37,7 +37,6 @@ namespace IRaCIS.Core.Application
private readonly IRepository<ReadingCriterionPage> _readingCriterionPageRepository;
private readonly IEasyCachingProvider _provider;
private readonly IOrganInfoService _iOrganInfoService;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository;
private readonly IReadingQuestionService iReadingQuestionService;
@ -60,7 +59,7 @@ namespace IRaCIS.Core.Application
IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystemRepository,
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
IRepository<ReadingCriterionPage> readingCriterionPageRepository,
IRepository<TaskAllocationRule> taskAllocationRuleRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IReadingQuestionService iReadingQuestionService,
@ -77,7 +76,7 @@ namespace IRaCIS.Core.Application
{
_trialCriterionAdditionalAssessmentTypeRepository = trialCriterionAdditionalAssessmentTypeRepository;
_trialRepository = trialRepository;
_taskAllocationRuleRepository = taskAllocationRuleRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._readingTrialCriterionDictionaryRepository = readingTrialCriterionDictionaryRepository;
this.iReadingQuestionService = iReadingQuestionService;
@ -1151,10 +1150,6 @@ namespace IRaCIS.Core.Application
//Paused、 添加工总量 算医生读片中
if (trialStatusStr.Contains(StaticData.TrialState.TrialCompleted))
{
await _repository.BatchUpdateAsync<Enroll>(u => u.TrialId == trialId, e => new Enroll
{
EnrollStatus = EnrollStatus.Finished
});
await _trialRepository.BatchUpdateNoTrackingAsync(u => u.Id == trialId, s => new Trial { TrialFinishedTime = DateTime.Now });

View File

@ -123,11 +123,7 @@ namespace IRaCIS.Application.Services
}
[NonDynamicMethod]
public async Task<int> GetTrialMaxState(Guid trialId)
{
return await _repository.Where<EnrollDetail>(t => t.TrialId == trialId).MaxAsync(u => (int?)u.EnrollStatus) ?? 0;
}
[HttpGet("{trialId:guid}")]
public async Task<TrialAndTrialStateVieModel> GetTrialInfoAndMaxTrialState(Guid trialId)
@ -135,7 +131,7 @@ namespace IRaCIS.Application.Services
return new TrialAndTrialStateVieModel()
{
TrialView = await GetTrialInfoAndLockState(trialId),
TrialMaxState = await GetTrialMaxState(trialId)
};
}
@ -211,8 +207,7 @@ namespace IRaCIS.Application.Services
//添加运维人员PM
await _repository.AddAsync(new TrialUser() { TrialId = trial.Id, UserId = _userInfo.Id, JoinTime = DateTime.Now });
// 添加扩展信息表记录
await _repository.AddAsync(new TrialPaymentPrice() { TrialId = trial.Id });
//添加访视
await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true });
@ -260,7 +255,7 @@ namespace IRaCIS.Application.Services
if (updateModel.Expedited != trial.Expedited && updateModel.Expedited != null)
{
TrialExpeditedChange = true;
await TrialExpeditedStatusChange(trial.Id, trial.Expedited, (int)updateModel.Expedited);
}
_mapper.Map(updateModel, trial);
@ -274,104 +269,7 @@ namespace IRaCIS.Application.Services
}
// TODO: 需要优化,嵌套两层 switch case
[NonDynamicMethod]
private async Task TrialExpeditedStatusChange(Guid trialId, int oldState, int newState)
{
switch (oldState)
{
case (int)TrialExpedited.None:
switch (newState)
{
case (int)TrialExpedited.ExpeditedIn24H:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn24H = u.Timepoint,
AdjudicationIn24H = u.Adjudication,
Timepoint = 0,
Adjudication = 0
});
break;
case (int)TrialExpedited.ExpeditedIn48H:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn48H = u.Timepoint,
AdjudicationIn48H = u.Adjudication,
Timepoint = 0,
Adjudication = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// Timepoint = 0,
// Adjudication = 0
//});
break;
case (int)TrialExpedited.ExpeditedIn24H:
switch (newState)
{
case (int)TrialExpedited.None:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
Timepoint = u.TimepointIn24H,
Adjudication = u.AdjudicationIn24H,
TimepointIn24H = 0,
AdjudicationIn24H = 0
});
break;
case (int)TrialExpedited.ExpeditedIn48H:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn48H = u.TimepointIn24H,
AdjudicationIn48H = u.AdjudicationIn24H,
TimepointIn24H = 0,
AdjudicationIn24H = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// TimepointIn24H = 0,
// AdjudicationIn24H = 0
//});
break;
case (int)TrialExpedited.ExpeditedIn48H:
switch (newState)
{
case (int)TrialExpedited.None:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
Timepoint = u.TimepointIn48H,
Adjudication = u.AdjudicationIn48H,
TimepointIn48H = 0,
AdjudicationIn48H = 0
});
break;
case (int)TrialExpedited.ExpeditedIn24H:
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
{
TimepointIn24H = u.TimepointIn48H,
AdjudicationIn24H = u.AdjudicationIn48H,
TimepointIn48H = 0,
AdjudicationIn48H = 0
});
break;
}
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
//{
// TimepointIn48H = 0,
// AdjudicationIn48H = 0
//});
break;
}
}
@ -427,8 +325,7 @@ namespace IRaCIS.Application.Services
//}
#endregion
await _repository.BatchDeleteAsync<WorkloadDetail>(o => o.Workload.TrialId == trialId);
await _repository.BatchDeleteAsync<Workload>(o => o.TrialId == trialId);
await _repository.BatchDeleteAsync<CheckChallengeDialog>(o => o.SubjectVisit.TrialId == trialId);
await _repository.BatchDeleteAsync<ClinicalDataTrialSet>(o => o.TrialId == trialId);
@ -439,16 +336,13 @@ namespace IRaCIS.Application.Services
await _repository.BatchDeleteAsync<StudyMonitor>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<DicomSeries>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<DicomInstance>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<EnrollReadingCategory>(t => t.Enroll.TrialId == trialId);
await _repository.BatchDeleteAsync<Enroll>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<EnrollDetail>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<NoneDicomStudyFile>(t => t.NoneDicomStudy.TrialId == trialId);
await _repository.BatchDeleteAsync<NoneDicomStudy>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<OrganTrialInfo>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<PaymentAdjustment>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<PaymentDetail>(t => t.TrialId == trialId);
@ -490,20 +384,18 @@ namespace IRaCIS.Application.Services
await _repository.BatchDeleteAsync<ReadModule>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<ReadingTaskQuestionAnswer>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<SubjectCanceDoctor>(t => t.Subject.TrialId == trialId);
await _repository.BatchDeleteAsync<SubjectUser>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<Subject>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TaskAllocationRule>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TaskConsistentRule>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TaskInfluence>(t => t.InfluenceTask.TrialId == trialId);
await _repository.BatchDeleteAsync<TaskMedicalReview>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TaskMedicalReviewRule>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialPaymentPrice>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId);
@ -524,14 +416,11 @@ namespace IRaCIS.Application.Services
await _repository.BatchDeleteAsync<TrialExternalUser>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialPaymentPrice>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialQCQuestion>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialQCQuestionAnswer>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialRevenuesPrice>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialRevenuesPriceVerification>(t => t.TrialId == trialId);
@ -601,83 +490,18 @@ namespace IRaCIS.Application.Services
return ResponseOutput.Ok();
}
[HttpPost]
public async Task<PageOutput<TrialDetailDTO>> GetReviewerTrialListByEnrollmentStatus(TrialByStatusQueryDTO param)
{
var query = _trialRepository.AsQueryable()
.WhereIf(param.Status == 5, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO))
.WhereIf(param.Status == 8, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.InviteIntoGroup))
.WhereIf(param.Status == 10, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.DoctorReading))
.WhereIf(param.Status == 14, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.Finished))
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id });
return await query.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "CreateTime" : param.SortField, param.Asc);
}
/// <summary>
/// 根据项目Id 获取医生Id用于触发计算费用
/// </summary>
public async Task<List<Guid>> GetTrialEnrollmentReviewerIds(Guid trialId)
{
return await _repository.Where<Enroll>(u => u.TrialId == trialId &&
u.EnrollStatus >= EnrollStatus.DoctorReading).Select(u => u.DoctorId).Distinct().ToListAsync();
}
#region 医生用户接口
/// <summary> 分页获取医生参与的临床实验项目列表(查询条件)</summary>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialDetailDTO>> GetTrialListByReviewer(ReviewerTrialQueryDTO searchModel)
{
var query = _trialRepository
.WhereIf(searchModel.EnrollStatus != null, o => (int)searchModel.EnrollStatus! == 10 ?
o.EnrollList.Any(o => o.EnrollStatus >= EnrollStatus.ConfirmIntoGroup && o.EnrollStatus <= EnrollStatus.DoctorReading && o.DoctorId == _userInfo.Id) :
o.EnrollList.Any(o => o.EnrollStatus == searchModel.EnrollStatus && o.DoctorId == _userInfo.Id))
.WhereIf(searchModel.Expedited != null, o => o.Expedited == searchModel.Expedited)
.WhereIf(!string.IsNullOrEmpty(searchModel.Code), o => o.TrialCode.Contains(searchModel.Code))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Indication), o => o.Indication.Contains(searchModel.Indication))
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id });
return await query.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "CreateTime" : searchModel.SortField, searchModel.Asc);
}
/// <summary>
/// 医生确认入组或拒绝入组
/// </summary>
/// <param name="trialId">项目Id</param>
/// <param name="status">9-拒绝入组10-确认入组</param>
/// <returns></returns>
[HttpPost("{trialId:guid}/{status:int}")]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> UpdateEnrollStatus(Guid trialId, EnrollStatus status)
{
await _repository.AddAsync(new EnrollDetail()
{
DoctorId = _userInfo.Id,
TrialId = trialId,
EnrollStatus = status,
OptUserType = (int)SystemUserType.DoctorUser,
});
return ResponseOutput.Result(await _repository.BatchUpdateAsync<Enroll>(u => u.TrialId == trialId && u.DoctorId == _userInfo.Id, e => new Enroll
{
EnrollStatus = status
}));
}
#endregion

View File

@ -75,7 +75,7 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.CRO, u => u.MapFrom(s => s.CRO.CROName))
.ForMember(d => d.ReviewMode, u => u.MapFrom(s => s.ReviewMode.MappedValue))
//.ForMember(d => d.ReviewType, u => u.MapFrom(s => s.ReviewType.Value))
.ForMember(d => d.IsLocked, u => u.MapFrom(s => s.WorkloadList.Any(u => u.DataFrom == (int)WorkLoadFromStatus.FinalConfirm)))
//.ForMember(d => d.SiteCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.TrialSiteUserList.Count(k => k.UserId == userId) : s.TrialSiteList.Count()))
//.ForMember(d => d.StudyCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.StudyList.Count(t => t.TrialSite.CRCUserList.Any(t => t.UserId == userId)) : s.StudyList.Count()))
//.ForMember(d => d.SubjectCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.SubjectList.Count(t => t.TrialSite.CRCUserList.Any(t => t.UserId == userId)) : s.SubjectList.Count()))

View File

@ -37,7 +37,6 @@ namespace IRaCIS.Core.Application.Service
CreateMap<Enroll, ReviewerSelectToBeDoneDto>();
CreateMap<VisitTask, ReReadingApprovalToBeDoneDto>();

View File

@ -32,7 +32,6 @@ namespace IRaCIS.Core.Application.Services
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository;
public SubjectVisitService(IRepository<SubjectVisit> subjectVisitRepository,
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
@ -47,8 +46,7 @@ namespace IRaCIS.Core.Application.Services
IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository,
IRepository<ReadingPeriodPlan> readingPeriodPlanRepository,
IRepository<Subject> subjectRepository,
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
IRepository<SubjectCriteriaEvaluationVisitStudyFilter> subjectCriteriaEvaluationVisitStudyFilterRepository
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository
)
{
@ -66,7 +64,6 @@ namespace IRaCIS.Core.Application.Services
this._readingPeriodPlanRepository = readingPeriodPlanRepository;
_subjectRepository = subjectRepository;
_trialReadingCriterionRepository = trialReadingCriterionRepository;
_subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository;
}
@ -427,7 +424,6 @@ namespace IRaCIS.Core.Application.Services
var isManualGenerate = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == taskInfo.TrialReadingCriterionId && t.IsAutoCreate == false);
var studyList = await _repository.Where<DicomStudy>(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId)
.WhereIf(isManualGenerate,t=>t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t=>t.TrialReadingCriterionId==taskInfo.TrialReadingCriterionId && t.IsConfirmed &&t.IsReading ))
.Select(k => new VisitStudyDTO()
{
InstanceCount = k.InstanceCount,
@ -446,7 +442,6 @@ namespace IRaCIS.Core.Application.Services
List<DicomSeriesDTO> seriesLists = await _repository.Where<DicomSeries>(s => studyIds.Contains(s.StudyId) /*&& s.IsReading*/)
.WhereIf(isManualGenerate==false, t => t.IsReading)
.WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading))
.OrderBy(s => s.SeriesNumber).
ThenBy(s => s.SeriesTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();

View File

@ -1,855 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class DoctorWorkloadService : BaseService, IDoctorWorkloadService
{
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<Workload> _doctorWorkloadRepository;
private readonly IRepository<EnrollReadingCategory> _enrollReadingCategoryRepository;
private readonly IRepository<Attachment> _attachmentRepository;
private readonly IRepository<Payment> _costStatisticsRepository;
private readonly IRepository<TrialRevenuesPrice> _trialRevenuesPriceRepository;
private readonly IRepository<TrialRevenuesPriceVerification> _trialRevenuesPriceVerificationRepository;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
public DoctorWorkloadService(IRepository<Trial> clinicalTrialProjectRepository,
IRepository<Enroll> intoGroupRepository,
IRepository<Doctor> doctorInfoRepository,
IRepository<Workload> doctorWorkloadRepository,
IRepository<EnrollReadingCategory> enrollReadingCategoryRepository,
IRepository<Attachment> attachmentRepository,
IRepository<Payment> costStatisticsRepository,
IRepository<TrialRevenuesPrice> trialRevenuesPriceRepository,
IRepository<TaskAllocationRule> taskAllocationRuleRepository,
IRepository<TrialRevenuesPriceVerification> trialRevenuesPriceVerificationRepository,
IMapper mapper)
{
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_trialRepository = clinicalTrialProjectRepository;
_enrollRepository = intoGroupRepository;
_doctorRepository = doctorInfoRepository;
_doctorWorkloadRepository = doctorWorkloadRepository;
this._enrollReadingCategoryRepository = enrollReadingCategoryRepository;
_attachmentRepository = attachmentRepository;
_costStatisticsRepository = costStatisticsRepository;
_trialRevenuesPriceRepository = trialRevenuesPriceRepository;
_trialRevenuesPriceVerificationRepository = trialRevenuesPriceVerificationRepository;
}
#region 入组工作量统计列表 具体详情 增删改查相关 上传\删除协议
#region 协议废弃
///// <summary>
///// 保存协议- ack Sow [AUTH]
///// </summary>
//[HttpPost("{trialId}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
////[Authorize(Policy = IRaCISPolicy.PM_APM)]
//public async Task<IResponseOutput> UploadReviewerAckSOW(Guid trialId,
// ReviewerAckDTO attachmentViewModel)
//{
// var intoGroupItem = (await _enrollRepository.Where(t => t.TrialId == trialId && t.DoctorId == attachmentViewModel.DoctorId).FirstOrDefaultAsync()).IfNullThrowException();
// if (attachmentViewModel.Id != Guid.Empty)
// {
// await _attachmentRepository.BatchDeleteNoTrackingAsync(t => t.Id == attachmentViewModel.Id);
// }
// var attachment = await _attachmentRepository.InsertFromDTOAsync(attachmentViewModel);
// //intoGroupItem.AttachmentId = attachment.Id;
// await _enrollRepository.UpdatePartialFromQueryAsync(intoGroupItem.Id, u => new Enroll() { AttachmentId = attachment.Id });
// var success = await _enrollRepository.SaveChangesAsync();
// return ResponseOutput.Result(success, attachment.Id.ToString());
//}
///// <summary>
///// 删除协议
///// </summary>
//[HttpDelete, Route("{trialId}/{doctorId}/{attachmentId}")]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
////[Authorize(Policy = IRaCISPolicy.PM_APM)]
//public async Task<IResponseOutput> DeleteReviewerAckSOW(Guid trialId, Guid doctorId, Guid attachmentId)
//{
// var success1 = await _attachmentRepository.BatchDeleteNoTrackingAsync(a => a.Id == attachmentId);
// await _enrollRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.DoctorId == doctorId, u =>
// new Enroll()
// {
// AttachmentId = Guid.Empty
// }, true);
// return ResponseOutput.Ok(success1);
//}
#endregion
/// <summary>
/// 修改项目医生的阅片类型
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SetEnrollReadingCategory(SetEnrollReadingCategoryInDto inDto)
{
var enroll = await _enrollRepository.FirstAsync(t => t.Id == inDto.EnrollId);
if (_repository.Where<VisitTask>(t => t.TrialId == enroll.TrialId && t.DoctorUserId == enroll.DoctorUserId && t.TaskAllocationState == TaskAllocationState.Allocated && t.TrialReadingCriterionId==inDto.TrialReadingCriterionId).Any())
{
var readingCategoryList = await _enrollReadingCategoryRepository.Where(t => t.EnrollId == inDto.EnrollId && t.TrialReadingCriterionId == inDto.TrialReadingCriterionId).Select(t => t.ReadingCategory).ToListAsync();
if (readingCategoryList.Except(inDto.ReadingCategorys).Count() > 0)
{
//---已分配任务,不允许减少阅片类型
return ResponseOutput.NotOk(_localizer["DoctorWorkload_AssignType"]);
}
}
//if (inDto.ReadingCategorys.Count > 0)
//{
// await _enrollReadingCategoryRepository.BatchDeleteNoTrackingAsync(x => x.EnrollId == inDto.EnrollId);
//}
//else
//{
// await _enrollReadingCategoryRepository.DeleteFromQueryAsync(x => x.EnrollId == inDto.EnrollId);
//}
await _enrollReadingCategoryRepository.DeleteFromQueryAsync(x => x.EnrollId == inDto.EnrollId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId);
List<EnrollReadingCategory> enrollReadings = inDto.ReadingCategorys.Select(x => new EnrollReadingCategory()
{
TrialReadingCriterionId= inDto.TrialReadingCriterionId,
EnrollId = inDto.EnrollId,
ReadingCategory = x
}).ToList();
await _enrollReadingCategoryRepository.AddRangeAsync(enrollReadings);
var result = await _enrollReadingCategoryRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 修改项目医生启用禁用状态
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> UpdateTrialReviewerState(SetEnrollEnableCommand inCommand)
{
await _taskAllocationRuleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == inCommand.TrialId && t.EnrollId == inCommand.EnrollId, u => new TaskAllocationRule() { IsEnable = inCommand.IsEnable },true);
return ResponseOutput.Ok();
}
/// <summary>
/// 0代表裁判和Tp 都可以 1、代表Tp 2 代表裁判
/// </summary>
/// <returns></returns>
[HttpPost("{trialId}/{doctorId}/{type}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> UpdateReviewerReadingType(Guid trialId, Guid doctorId, int type)
{
var success2 = await _enrollRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.DoctorId == doctorId, u =>
new Enroll()
{
ReviewerReadingType = type
});
return ResponseOutput.Result(success2);
}
/// <summary>
/// 获取某个项目入组的医生工作量统计列表
/// </summary>
[HttpPost]
public async Task<PageOutput<WorkLoadAndAgreementDTO>> GetTrialEnrollmentWorkloadStats(WorkLoadDoctorQueryDTO doctorSearchModel)
{
//https://blog.csdn.net/sunshineblog/article/details/78636389
var trialId = doctorSearchModel.TrialId;
var doctorIntoGroupQueryable =
from intoGroup in _enrollRepository.Where(x => x.TrialId == trialId && x.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
join allocateRule in _taskAllocationRuleRepository.AsQueryable() on intoGroup.Id equals allocateRule.EnrollId
join doctor in _doctorRepository.AsQueryable() on intoGroup.DoctorId equals doctor.Id
join attachmentItem in _attachmentRepository.AsQueryable() on intoGroup.AttachmentId equals attachmentItem.Id into cc
from attachment in cc.DefaultIfEmpty()
select new WorkLoadAndAgreementDTO()
{
EnrollId = intoGroup.Id,
IsEnable = allocateRule.IsEnable,
TrialReadingCriterionList = intoGroup.Trial.ReadingQuestionCriterionTrialList.Where(t=>t.IsConfirm).Select(t=>new TrialReadingCriterionDto() { TrialReadingCriterionId=t.Id,TrialReadingCriterionName=t.CriterionName,CriterionType=t.CriterionType,IsOncologyReading=t.IsOncologyReading,IsArbitrationReading=t.IsArbitrationReading,IsGlobalReading=t.IsGlobalReading,ReadingInfoSignTime=t.ReadingInfoSignTime,ReadingType=t.ReadingType}).ToList(),
CriterionReadingCategoryList =intoGroup.EnrollReadingCategoryList.Select(t=>new TrialCriterionReadingCategory() { EnrollId=t.EnrollId,ReadingCategory=t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }).ToList(),
CriterionFileList = doctor.CriterionFileList.Where(x => x.IsEnable && (x.TrialId==null ||x.TrialId==trialId)).Select(x => new CriterionFile()
{
CriterionType = x.CriterionType,
DoctorId = x.DoctorId,
FileName = x.FileName,
FilePath = x.FilePath,
FileType = x.FileType,
Remark = x.Remark,
TrialReadingCriterionId=x.TrialReadingCriterionId,
Id = x.Id
}).ToList(),
ReadingTaskStateList = doctor.User.VisitTaskList.Where(x => x.TaskState == TaskState.Effect && x.TrialId == trialId).Select(x => new DoctorUserTask()
{
ReadingTaskState = x.ReadingTaskState,
TrialReadingCriterionId=x.TrialReadingCriterionId,
CriterionType = x.TrialReadingCriterion.CriterionType,
}).ToList(),
DoctorId = doctor.Id,
Code = doctor.ReviewerCode,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
FullName = doctor.FullName,
ChineseName = doctor.ChineseName,
UserName= intoGroup.DoctorUser.UserName,
OutEnrollTime = intoGroup.OutEnrollTime,
EnrollTime = intoGroup.EnrollTime,
AgreementId = intoGroup.AttachmentId,
ReviewerReadingType = intoGroup.ReviewerReadingType,
AgreementPath = attachment.Path,
};
return await doctorIntoGroupQueryable.ToPagedListAsync(doctorSearchModel.PageIndex, doctorSearchModel.PageSize, doctorSearchModel.SortField == "" ? "EnrollTime" : doctorSearchModel.SortField, doctorSearchModel.Asc);
}
/// <summary>
/// 获取入组某个项目的医生的最近几个月的工作量详情(带有填充数据)
/// </summary>
[HttpPost]
public PageOutput<WorkLoadDetailDTO> GetEnrollmentWorkloadStatsDetail(WorkLoadStatsQueryDTO workLoadSearch)
{
#region 条件查询
Expression<Func<Workload, bool>> workloadLambda = x => true;
if (workLoadSearch.TrialId != Guid.Empty && workLoadSearch.TrialId != null)
{
workloadLambda = workloadLambda.And(x => x.TrialId == workLoadSearch.TrialId);
}
if (workLoadSearch.DoctorId != Guid.Empty && workLoadSearch.DoctorId != null)
{
workloadLambda = workloadLambda.And(t => t.DoctorId == workLoadSearch.DoctorId);
}
if (workLoadSearch.SearchBeginDateTime != null)
{
var bDate = workLoadSearch.SearchBeginDateTime;
var beginDate = new DateTime(bDate.Value.Year, bDate.Value.Month, 1);
workloadLambda = workloadLambda.And(t =>
t.WorkTime >= beginDate);
}
if (workLoadSearch.SearchEndDateTime != null)
{
var eDate = workLoadSearch.SearchEndDateTime.Value.AddMonths(1);
DateTime endDate = new DateTime(eDate.Year, eDate.Month, 1);
workloadLambda = workloadLambda.And(t =>
t.WorkTime < endDate);
}
#endregion
IQueryable<WorkLoadDetailDTO>? workLoadQueryable = default;
var tempWorkload = new List<WorkLoadDetailDTO>();
if (workLoadSearch.WorkLoadFromStatus.Contains(1))
{
workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.CRO))
join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new WorkLoadDetailDTO()
{
Id = workLoad.Id,
DoctorId = workLoad.DoctorId,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
YearMonthStr = workLoad.YearMonth,
CreateTime = workLoad.CreateTime,
WorkTime = workLoad.WorkTime,
DataFrom = workLoad.DataFrom,
TrialId = workLoad.TrialId,
Indication = trial.Indication,
Code = trial.TrialCode,
Timepoint = workLoad.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H,
Global = workLoad.Global,
RefresherTraining = workLoad.RefresherTraining,
Adjudication = workLoad.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H,
Training = workLoad.Training,
Downtime = workLoad.Downtime,
IsLock = workLoad.IsLock
};
tempWorkload.AddRange(workLoadQueryable.ToList());
}
if (workLoadSearch.WorkLoadFromStatus.Contains(2))
{
workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm))
join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new WorkLoadDetailDTO()
{
Id = workLoad.Id,
DoctorId = workLoad.DoctorId,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
YearMonthStr = workLoad.YearMonth,
CreateTime = workLoad.CreateTime,
WorkTime = workLoad.WorkTime,
DataFrom = workLoad.DataFrom,
TrialId = workLoad.TrialId,
Indication = trial.Indication,
Code = trial.TrialCode,
Timepoint = workLoad.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H,
Global = workLoad.Global,
RefresherTraining = workLoad.RefresherTraining,
Adjudication = workLoad.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H,
Training = workLoad.Training,
Downtime = workLoad.Downtime,
IsLock = workLoad.IsLock
};
tempWorkload.AddRange(workLoadQueryable.ToList());
}
if (workLoadSearch.WorkLoadFromStatus.Contains(0))
{
workLoadQueryable =
from workLoad in (from workLoadItem in _doctorWorkloadRepository.Where(workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.Doctor))
group workLoadItem by new { workLoadItem.YearMonth, workLoadItem.DoctorId, workLoadItem.TrialId, workLoadItem.IsLock } into g
select new
{
Id = Guid.NewGuid(),
DoctorId = g.Key.DoctorId,
DataFrom = 0,
TrialId = g.Key.TrialId,
IsLock = g.Key.IsLock,
YearMonthStr = g.Key.YearMonth,
Timepoint = g.Sum(workLoad => workLoad.Timepoint),
TimepointIn24H = g.Sum(workLoad => workLoad.TimepointIn24H),
TimepointIn48H = g.Sum(workLoad => workLoad.TimepointIn48H),
Global = g.Sum(workLoad => workLoad.Global),
RefresherTraining = g.Sum(workLoad => workLoad.RefresherTraining),
Adjudication = g.Sum(workLoad => workLoad.Adjudication),
AdjudicationIn24H = g.Sum(workLoad => workLoad.AdjudicationIn24H),
AdjudicationIn48H = g.Sum(workLoad => workLoad.AdjudicationIn48H),
Training = g.Sum(workLoad => workLoad.Training),
Downtime = g.Sum(workLoad => workLoad.Downtime)
})
join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new WorkLoadDetailDTO()
{
Id = workLoad.Id,
DoctorId = workLoad.DoctorId,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
YearMonthStr = workLoad.YearMonthStr,
DataFrom = workLoad.DataFrom,
TrialId = workLoad.TrialId,
Indication = trial.Indication,
Code = trial.TrialCode,
Timepoint = workLoad.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H,
Global = workLoad.Global,
RefresherTraining = workLoad.RefresherTraining,
Adjudication = workLoad.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H,
Training = workLoad.Training,
Downtime = workLoad.Downtime,
IsLock = workLoad.IsLock
};
tempWorkload.AddRange(workLoadQueryable.ToList());
}
//workLoadQueryable = workLoadQueryable.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom);
//取选取月份的数据
var month = (workLoadSearch.SearchEndDateTime?.Year - workLoadSearch.SearchBeginDateTime?.Year) * 12 + (workLoadSearch.SearchEndDateTime?.Month - workLoadSearch.SearchBeginDateTime?.Month) + 1;
var count = (month ?? 1) * workLoadSearch.WorkLoadFromStatus.Count;
//tempWorkload = tempWorkload.Take(count);
tempWorkload.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom).Take(count);
//var workLoadList = workLoadQueryable.ToList();
return BuildFullData(tempWorkload, workLoadSearch);
}
/// <summary>
/// 获取来自Reviewer自己的数据某个月添加的多条
/// </summary>
[HttpPost]
public async Task<List<WorkLoadDetailViewModel>> GetReviewerWorkLoadListDetail(
WorkLoadDetailQueryDTO workLoadSearch)
{
Expression<Func<Workload, bool>> workloadLambda = t => t.DataFrom == (int)WorkLoadFromStatus.Doctor && t.YearMonth == workLoadSearch.YearMonthStr;
if (workLoadSearch.TrialId != Guid.Empty)
{
workloadLambda = workloadLambda.And(x => x.TrialId == workLoadSearch.TrialId);
}
if (workLoadSearch.DoctorId != Guid.Empty)
{
workloadLambda = workloadLambda.And(t => t.DoctorId == workLoadSearch.DoctorId);
}
var workLoadQueryable = from workLoad in _doctorWorkloadRepository.Where(workloadLambda)
join doctor in _doctorRepository.AsQueryable() on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new WorkLoadDetailViewModel()
{
Id = workLoad.Id,
DoctorId = workLoad.DoctorId,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
YearMonthStr = workLoad.YearMonth,
CreateTime = workLoad.CreateTime,
WorkTime = workLoad.WorkTime,
DataFrom = workLoad.DataFrom,
TrialId = workLoad.TrialId,
Indication = trial.Indication,
Code = trial.TrialCode,
Timepoint = workLoad.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H,
Global = workLoad.Global,
Adjudication = workLoad.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H,
RefresherTraining = workLoad.RefresherTraining,
Training = workLoad.Training,
Downtime = workLoad.Downtime,
IsLock = workLoad.IsLock
};
workLoadQueryable = workLoadQueryable.OrderBy("WorkTime");
var workLoadList = await workLoadQueryable.ToListAsync();
workLoadList.ForEach(t => t.RowGuid = Guid.NewGuid());
return workLoadList;
}
/// <summary>
/// 工作量是否存在,用于判断只能添加一条的工作量记录
/// </summary>
/// <summary>
/// 查询某个医生是否在某天有某个项目的工作量数据,处理添加来自医生自己的工作量数据
/// </summary>
[HttpPost]
public async Task<IResponseOutput<ExistWorkloadViewModel>> WorkloadExist(WorkloadExistQueryDTO param)
{
var isExist = false;
var exist = await _doctorWorkloadRepository.FirstOrDefaultAsync(u => u.TrialId == param.TrialId && u.DoctorId == param.DoctorId
&& u.WorkTime == param.WorkDate && u.DataFrom == 0);
if (exist != null)
{
isExist = true;
}
return ResponseOutput.Ok(new ExistWorkloadViewModel
{
IsExist = isExist,
WorkLoad = _mapper.Map<WorkloadDTO>(exist),
});
}
/// <summary>
/// 添加或更新工作量
/// </summary>
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> AddOrUpdateWorkload(WorkloadCommand workLoadAddOrUpdateModel,
Guid userId)
{
var yearMonthStr = workLoadAddOrUpdateModel.WorkTime.ToString("yyyy-MM");
if (workLoadAddOrUpdateModel.Id == Guid.Empty || workLoadAddOrUpdateModel.Id == null)
{
//确定是那个医生 那个项目 那个月份做的
Expression<Func<Workload, bool>> workloadLambda = x => x.DoctorId == workLoadAddOrUpdateModel.DoctorId && x.TrialId == workLoadAddOrUpdateModel.TrialId && x.YearMonth == yearMonthStr;
//只要是来自CRO或者最终确认的 只能有一条
switch (workLoadAddOrUpdateModel.DataFrom)
{
case (int)WorkLoadFromStatus.CRO: //1 来自CRO的
workloadLambda = workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.CRO);
break;
case (int)WorkLoadFromStatus.FinalConfirm: //2 最终确认的
workloadLambda = workloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm);
var isExist = await _costStatisticsRepository.AnyAsync(u => u.YearMonth == yearMonthStr && u.DoctorId == workLoadAddOrUpdateModel.DoctorId);
if (!isExist)
{
await _costStatisticsRepository.AddAsync(new Payment
{
DoctorId = workLoadAddOrUpdateModel.DoctorId,
YearMonth = yearMonthStr,
YearMonthDate = DateTime.Parse(yearMonthStr),
IsLock = false
});
}
//处理 验证项目收入价格是否都填写了
var revenuesPriceExist = await _trialRevenuesPriceRepository.AsQueryable()
.FirstOrDefaultAsync(t => t.TrialId == workLoadAddOrUpdateModel.TrialId);
//没填写收入价格 插入记录 所有的都是false
if (revenuesPriceExist == null)
{
await _trialRevenuesPriceVerificationRepository.AddAsync(new TrialRevenuesPriceVerification()
{
TrialId = workLoadAddOrUpdateModel.TrialId,
ReviewerId = workLoadAddOrUpdateModel.DoctorId,
YearMonth = yearMonthStr,
WorkLoadDate = workLoadAddOrUpdateModel.WorkTime
});
}
else //有价格 校验 看全不全
{
var tpNeedSetPrice = workLoadAddOrUpdateModel.Timepoint > 0 &&
revenuesPriceExist.Timepoint <= 0;
var tp24HNeedSetPrice = workLoadAddOrUpdateModel.TimepointIn24H > 0 &&
revenuesPriceExist.TimepointIn24H <= 0;
var tp48NeedSetPrice = workLoadAddOrUpdateModel.TimepointIn48H > 0 &&
revenuesPriceExist.TimepointIn48H <= 0;
var adNeedSetPrice = workLoadAddOrUpdateModel.Adjudication > 0 &&
revenuesPriceExist.Adjudication <= 0;
var ad24NeedSetPrice = workLoadAddOrUpdateModel.AdjudicationIn24H > 0 &&
revenuesPriceExist.AdjudicationIn24H <= 0;
var ad48NeedSetPrice = workLoadAddOrUpdateModel.AdjudicationIn48H > 0 &&
revenuesPriceExist.AdjudicationIn48H <= 0;
var downtimeNeedSetPrice = workLoadAddOrUpdateModel.Downtime > 0 &&
revenuesPriceExist.Downtime <= 0;
var globalNeedSetPrice = workLoadAddOrUpdateModel.Global > 0 &&
revenuesPriceExist.Global <= 0;
var trainingNeedSetPrice = workLoadAddOrUpdateModel.Training > 0 &&
revenuesPriceExist.Training <= 0;
var refresherTrainingTrainingNeedSetPrice = workLoadAddOrUpdateModel.RefresherTraining > 0 &&
revenuesPriceExist.RefresherTraining <= 0;
var needAdd = tpNeedSetPrice || tp24HNeedSetPrice || tp48NeedSetPrice || adNeedSetPrice || ad24NeedSetPrice ||
ad48NeedSetPrice || downtimeNeedSetPrice || globalNeedSetPrice && trainingNeedSetPrice || refresherTrainingTrainingNeedSetPrice;
//验证不通过 增加
if (needAdd)
{
await _trialRevenuesPriceVerificationRepository.AddAsync(new TrialRevenuesPriceVerification()
{
TrialId = workLoadAddOrUpdateModel.TrialId,
ReviewerId = workLoadAddOrUpdateModel.DoctorId,
YearMonth = yearMonthStr,
WorkLoadDate = workLoadAddOrUpdateModel.WorkTime,
//需要设置价格和 有价格是相反的 数据库此字段存储的时候对应项是否有价格
Timepoint = !tpNeedSetPrice,
TimepointIn24H = !tp24HNeedSetPrice,
TimepointIn48H = !tp48NeedSetPrice,
Adjudication = !adNeedSetPrice,
AdjudicationIn24H = !ad24NeedSetPrice,
AdjudicationIn48H = !ad48NeedSetPrice,
Downtime = !downtimeNeedSetPrice,
Global = !globalNeedSetPrice,
Training = !trainingNeedSetPrice,
RefresherTraining = !refresherTrainingTrainingNeedSetPrice
});
}
}
break;
}
if (workLoadAddOrUpdateModel.DataFrom != (int)WorkLoadFromStatus.Doctor)
{
if (await _doctorWorkloadRepository.AnyAsync(workloadLambda))
{
//---This type of data can only have one
return ResponseOutput.NotOk(_localizer["DoctorWorkload_Unique"]);
}
}
if (workLoadAddOrUpdateModel.DataFrom == (int)WorkLoadFromStatus.Doctor)
{
Expression<Func<Workload, bool>> doctorworkloadLambda = x => x.DoctorId == workLoadAddOrUpdateModel.DoctorId && x.TrialId == workLoadAddOrUpdateModel.TrialId && x.YearMonth == yearMonthStr && workLoadAddOrUpdateModel.WorkTime == x.WorkTime;
doctorworkloadLambda = doctorworkloadLambda.And(t => t.DataFrom == (int)WorkLoadFromStatus.Doctor);
if (await _doctorWorkloadRepository.AnyAsync(doctorworkloadLambda))
{
//---This type of data can only have one
return ResponseOutput.NotOk(_localizer["DoctorWorkload_Unique"]);
}
}
var workLoad = _mapper.Map<Workload>(workLoadAddOrUpdateModel);
workLoad.YearMonth = yearMonthStr;
await _doctorWorkloadRepository.AddAsync(workLoad);
await _enrollRepository.BatchUpdateNoTrackingAsync(
t => t.DoctorId == workLoadAddOrUpdateModel.DoctorId && t.TrialId == workLoadAddOrUpdateModel.TrialId, u => new Enroll()
{
EnrollStatus = EnrollStatus.DoctorReading,
});
var success = await _doctorWorkloadRepository.SaveChangesAsync();
return ResponseOutput.Result(success, workLoad.Id);
}
else
{
//判断是否已经被锁定
var isLocked = await _costStatisticsRepository.AnyAsync(u => u.DoctorId == workLoadAddOrUpdateModel.DoctorId &&
u.YearMonth == yearMonthStr && u.IsLock);
if (isLocked)
{
//---Expenses have been settled and workload cannot be modified.
return ResponseOutput.NotOk(_localizer["DoctorWorkload_FeeSettled"]);
}
var success = await _doctorWorkloadRepository.BatchUpdateNoTrackingAsync(t => t.Id == workLoadAddOrUpdateModel.Id,
u => new Workload()
{
Timepoint = workLoadAddOrUpdateModel.Timepoint,
TimepointIn24H = workLoadAddOrUpdateModel.TimepointIn24H,
TimepointIn48H = workLoadAddOrUpdateModel.TimepointIn48H,
Adjudication = workLoadAddOrUpdateModel.Adjudication,
AdjudicationIn24H = workLoadAddOrUpdateModel.AdjudicationIn24H,
AdjudicationIn48H = workLoadAddOrUpdateModel.AdjudicationIn48H,
RefresherTraining = workLoadAddOrUpdateModel.RefresherTraining,
Downtime = workLoadAddOrUpdateModel.Downtime,
Training = workLoadAddOrUpdateModel.Training,
Global = workLoadAddOrUpdateModel.Global,
WorkTime = workLoadAddOrUpdateModel.WorkTime,
YearMonth = yearMonthStr
});
return ResponseOutput.Result(success);
}
}
/// <summary>
/// 删除工作量
/// </summary>
public async Task<IResponseOutput> DeleteWorkload(Guid workloadId)
{
return ResponseOutput.Result(await _doctorWorkloadRepository.BatchDeleteNoTrackingAsync(t => t.Id == workloadId));
}
/// <summary>
/// 获取工作量详情(用于判断工作量锁定时,调用)
/// </summary>
public async Task<WorkloadDTO> GetWorkloadDetailById(Guid id)
{
var workload = await _doctorWorkloadRepository.FirstOrDefaultAsync(u => u.Id == id);
return _mapper.Map<WorkloadDTO>(workload);
}
#endregion
private PageOutput<WorkLoadDetailDTO> BuildFullData(
List<WorkLoadDetailDTO> workLoadList, WorkLoadStatsQueryDTO workLoadSearch)
{
var doctor = _doctorRepository.Where(t => t.Id == workLoadSearch.DoctorId).ProjectTo<DoctorBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefault().IfNullThrowException();
//查询 1-3月的 共3个月
var month = (workLoadSearch.SearchEndDateTime?.Year - workLoadSearch.SearchBeginDateTime?.Year) * 12 +
(workLoadSearch.SearchEndDateTime?.Month - workLoadSearch.SearchBeginDateTime?.Month) + 1;
var needCount = month * workLoadSearch.WorkLoadFromStatus.Count ?? 1;
if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.FinalConfirm))
{
if (workLoadList.Count != needCount)
{
for (int i = 0; i < month; i++)
{
var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm))
{
workLoadList.Add(new WorkLoadDetailDTO()
{
Id = Guid.Empty,
DataFrom = (int)WorkLoadFromStatus.FinalConfirm,
YearMonthStr = yearMonthStr,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
Code = doctor.ReviewerCode
});
}
}
}
}
if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.CRO))
{
if (workLoadList.Count != needCount)
{
for (int i = 0; i < month; i++)
{
var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
t.DataFrom == (int)WorkLoadFromStatus.CRO))
{
workLoadList.Add(new WorkLoadDetailDTO()
{
Id = Guid.Empty,
DataFrom = (int)WorkLoadFromStatus.CRO,
YearMonthStr = yearMonthStr,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
Code = doctor.ReviewerCode
});
}
}
}
}
if (workLoadSearch.WorkLoadFromStatus.Contains((int)WorkLoadFromStatus.Doctor))
{
if (workLoadList.Count != needCount)
{
for (int i = 0; i < month; i++)
{
var yearMonthStr = workLoadSearch.SearchBeginDateTime?.AddMonths(i).ToString("yyyy-MM");
if (!workLoadList.Any(t => t.YearMonthStr == yearMonthStr &&
t.DataFrom == (int)WorkLoadFromStatus.Doctor))
{
workLoadList.Add(new WorkLoadDetailDTO()
{
Id = Guid.Empty,
DataFrom = (int)WorkLoadFromStatus.Doctor,
YearMonthStr = yearMonthStr,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
Code = doctor.ReviewerCode
});
}
}
}
}
workLoadList = workLoadList.OrderByDescending(t => t.YearMonthStr).ThenBy(t => t.DataFrom)
.ToList();
int tempRowId = 0;
foreach (var workLoad in workLoadList)
{
workLoad.RowGuid = Guid.NewGuid();
workLoad.RowIntId = tempRowId + 1;
tempRowId++;
}
return new PageOutput<WorkLoadDetailDTO>(1, workLoadList.Count,
workLoadList.Count, workLoadList);
}
}
}

View File

@ -1,517 +0,0 @@
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using System.Text.RegularExpressions;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Enroll")]
public class EnrollService : BaseService, IEnrollService
{
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialStatusDetail> _trialDetailRepository;
private readonly IRepository<TrialPaymentPrice> _TrialPaymentPriceRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<EnrollDetail> _enrollDetailRepository;
private readonly IRepository<Workload> _workloadRepository;
private readonly IMailVerificationService _mailVerificationService;
//private readonly IRepository<TrialUser> _trialUserRepository;
public EnrollService(IRepository<Trial> clinicalTrialProjectRepository,
IRepository<TrialStatusDetail> clinicalProjectDetailRepository,
IRepository<Enroll> intoGroupRepository,
IRepository<Doctor> doctorRepository,
IRepository<TrialPaymentPrice> TrialPaymentPriceRepository,
IRepository<EnrollDetail> intoGroupDetailRepository,
IRepository<Workload> workloadRepository,
IMailVerificationService mailVerificationService)
{
_trialRepository = clinicalTrialProjectRepository;
_TrialPaymentPriceRepository = TrialPaymentPriceRepository;
_doctorRepository = doctorRepository;
_trialDetailRepository = clinicalProjectDetailRepository;
_enrollRepository = intoGroupRepository;
_enrollDetailRepository = intoGroupDetailRepository;
_workloadRepository = workloadRepository;
_mailVerificationService = mailVerificationService;
//_trialUserRepository = trialUserRepository;
}
/// <summary>
/// 添加或更新项目医生项目价格
/// </summary>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateEnroll(EnrollCommand addOrUpdateModel)
{
var trialDoctoritem = await _enrollRepository.FirstOrDefaultAsync(u => u.Id == addOrUpdateModel.Id);
if (trialDoctoritem == null)//insert
{
await _enrollRepository.InsertFromDTOAsync(addOrUpdateModel);
}
else//update
{
await _enrollRepository.UpdateFromDTOAsync(addOrUpdateModel);
}
var success = await _enrollRepository.SaveChangesAsync();
return ResponseOutput.Result(success);
}
/// <summary>
/// 获取医生项目列表
/// </summary>
/// <param name="challengeQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<EnrollViewModel>> GetTrialDoctorList(EnrollGetQuery challengeQuery)
{
var costStatisticsQueryable = from enroll in _enrollRepository.Where(t => t.TrialId == challengeQuery.TrialId)
join dociorc in _doctorRepository.Where() on enroll.DoctorId equals dociorc.Id
join price in _TrialPaymentPriceRepository.Where() on enroll.TrialId equals price.TrialId
select new EnrollViewModel()
{
ChineseName = dociorc.ChineseName,
AdjustmentMultiple = enroll.AdjustmentMultiple,
FirstName = dociorc.FirstName,
LastName = dociorc.LastName,
DoctorId = dociorc.Id,
TrialId = challengeQuery.TrialId,
Id = enroll.Id,
Training = enroll.Training,
RefresherTraining = enroll.RefresherTraining,
Timepoint = enroll.Timepoint,
Timepoint48H = enroll.Timepoint48H,
Timepoint24H = enroll.Timepoint24H,
Adjudication = enroll.Adjudication,
Adjudication48H = enroll.Adjudication48H,
Adjudication24H = enroll.Adjudication24H,
Global = enroll.Global,
Code = dociorc.Code,
ReviewerCode = dociorc.ReviewerCode,
Downtime = enroll.Downtime,
};
return await costStatisticsQueryable.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, "ChineseName");
//var query2 = _repository.Where<EnrollViewModel>(x => x.TrialId == challengeQuery.TrialId)
// .WhereIf(challengeQuery.TrialId != null, t => t.TrialId == challengeQuery.TrialId)
// .WhereIf(challengeQuery.DoctorId != null, t => t.DoctorId == challengeQuery.DoctorId)
// .ProjectTo<Enroll>(_mapper.ConfigurationProvider);
//var pageList = await query2.ToListAsync();
// return new PageOutput<EnrollViewModel>(challengeQuery.pageIndex, challengeQuery.pageSize,
//costStatisticsQueryable);
}
#region Reviewer 入组审核流程select-submit-approve-confirm
/// <summary> 为项目筛选医生 提交 【select】 </summary>
/// <param name="trialId">项目Id</param>
/// <param name="doctorIdArray">医生Id数组</param>
/// <returns></returns>
[HttpPost("{trialId:guid}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM_SMM_CMM)]
public async Task<IResponseOutput> SelectReviewers(Guid trialId, Guid[] doctorIdArray)
{
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
if (trial == null) return Null404NotFound(trial);
//_trialRepository.Attach(trial);
//更新项目状态
trial.TrialEnrollStatus = (int)TrialEnrollStatus.HasApplyDownLoadResume;
//_trialRepository.Update(trial);
//添加项目状态变化记录
var trialDetail = new TrialStatusDetail()
{
TrialId = trial.Id,
TrialStatus = (int)TrialEnrollStatus.HasApplyDownLoadResume,
};
await _trialDetailRepository.AddAsync(trialDetail);
// 入组表 入组状态跟踪表
foreach (var doctorId in doctorIdArray)
{
await _enrollRepository.AddAsync(new Enroll()
{
DoctorId = doctorId,
TrialId = trialId,
EnrollStatus = EnrollStatus.HasApplyDownloadResume,
DoctorUserId = _repository.Where<User>(t => t.DoctorId == doctorId).Select(t => t.Id).FirstOrDefault()
}); ;
await _enrollDetailRepository.AddAsync(new EnrollDetail()
{
DoctorId = doctorId,
TrialId = trialId,
EnrollStatus = EnrollStatus.HasApplyDownloadResume,
OptUserType = (int)SystemUserType.AdminUser,
});
}
return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync());
}
/// <summary>
/// 入组流程-向CRO提交医生[Submit]
/// </summary>
[HttpPost("{trialId:guid}/{commitState:int}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM_SMM_CMM)]
public async Task<IResponseOutput> SubmitReviewer(Guid trialId, Guid[] doctorIdArray, int commitState)
{
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
if (trial != null)
{
if (commitState == 1) //确认提交CRO
{
//更新项目状态
trial.TrialEnrollStatus = (int)TrialEnrollStatus.HasCommitCRO;
//添加项目详细记录
var trialDetail = new TrialStatusDetail()
{
TrialId = trial.Id,
TrialStatus = (int)TrialEnrollStatus.HasCommitCRO
};
await _trialDetailRepository.AddAsync(trialDetail);
//更新入组表 跟踪了 所以不用下面的_enrollRepository.Update(intoGroupItem);
var intoGroupList = await _enrollRepository.Where(t => t.TrialId == trialId, true).ToListAsync();
foreach (var intoGroupItem in intoGroupList)
{
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
{
intoGroupItem.EnrollStatus = EnrollStatus.HasCommittedToCRO;
//_enrollRepository.Update(intoGroupItem);
await _enrollDetailRepository.AddAsync(new EnrollDetail()
{
TrialDetailId = trialDetail.Id,
DoctorId = intoGroupItem.DoctorId,
TrialId = trialId,
EnrollStatus = EnrollStatus.HasCommittedToCRO,
OptUserType = (int)SystemUserType.AdminUser, //后台用户
});
}
}
}
else if (commitState == 0)//回退上一步
{
//更新入组表
var intoGroupList = await _enrollRepository.Where(t => t.TrialId == trialId, true).ToListAsync();
foreach (var intoGroupItem in intoGroupList)
{
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
{
intoGroupItem.EnrollStatus = EnrollStatus.HasApplyDownloadResume;
//_enrollRepository.Update(intoGroupItem);
var deleteItem = await _enrollDetailRepository.FirstOrDefaultAsync(t =>
t.TrialId == trialId && t.DoctorId == intoGroupItem.DoctorId &&
t.EnrollStatus == EnrollStatus.HasCommittedToCRO);
await _enrollDetailRepository.DeleteAsync(deleteItem);
}
}
}
return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync());
}
//$"Cannot find trial {trialId}"
return ResponseOutput.NotOk(_localizer["Enroll_NotFound", trialId]);
}
/// <summary>
/// 入组流程-CRO确定医生名单 [ Approve]
/// </summary>
[HttpPost("{trialId:guid}/{auditState:int}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM_SMM_CMM)]
public async Task<IResponseOutput> ApproveReviewer(Guid trialId, Guid[] doctorIdArray, int auditState)
{
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
if (trial == null) return Null404NotFound(trial);
if (auditState == 1) //确认入组
{
//var existItem = _trialRepository.FindSingleOrDefault(u => u.Id == trialId && u.TrialStatus >= (int)TrialEnrollStatus.HasConfirmedDoctorNames);
//if (existItem == null)
//{
// trial.TrialStatus = (int)TrialEnrollStatus.HasConfirmedDoctorNames;
// trial.TrialStatusStr = "Approved";
//}
//_trialRepository.Update(trial);
//更新项目状态
trial.TrialEnrollStatus = (int)TrialEnrollStatus.HasConfirmedDoctorNames;
//添加项目详细记录
var trialDetail = new TrialStatusDetail()
{
TrialId = trialId,
TrialStatus = (int)TrialEnrollStatus.HasConfirmedDoctorNames
};
await _trialDetailRepository.AddAsync(trialDetail);
//更新入组表 跟踪方式不用下面的_enrollRepository.Update(intoGroupItem);
var intoGroupList = _enrollRepository.Where(t => t.TrialId == trialId, true).ToList();
foreach (var intoGroupItem in intoGroupList)
{
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
{
intoGroupItem.EnrollStatus = EnrollStatus.InviteIntoGroup;
//_enrollRepository.Update(intoGroupItem);
await _enrollDetailRepository.AddAsync(new EnrollDetail()
{
DoctorId = intoGroupItem.DoctorId,
TrialId = trialId,
EnrollStatus = EnrollStatus.InviteIntoGroup,
OptUserType = (int)SystemUserType.AdminUser, //后台用户
});
}
}
}
else if (auditState == 0)//回退上一步
{
//更新入组表
var intoGroupList = _enrollRepository.Where(t => t.TrialId == trialId, true).ToList();
foreach (var intoGroupItem in intoGroupList)
{
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
{
intoGroupItem.EnrollStatus = EnrollStatus.HasCommittedToCRO;
//_enrollRepository.Update(intoGroupItem);
var deleteItem = await _enrollDetailRepository.FirstOrDefaultAsync(t =>
t.TrialId == trialId && t.DoctorId == intoGroupItem.DoctorId &&
t.EnrollStatus == EnrollStatus.InviteIntoGroup);
await _enrollDetailRepository.DeleteAsync(deleteItem);
}
}
}
return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync());
}
/// <summary>
/// 入组流程-后台确认医生入组[Confirm]
/// </summary>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM_SMM_CMM)]
[UnitOfWork]
public async Task<IResponseOutput> ConfirmReviewer(ConfirmReviewerCommand confirmReviewerCommand,
[FromServices] IRepository<TrialUser> _trialUserRepository,
[FromServices] IRepository<TaskAllocationRule> _taskAllocationRuleRepository)
{
//var trial = _trialRepository.FirstOrDefault(t => t.Id == trialId);
//var existItem = _trialRepository.FindSingleOrDefault(u => u.Id == trialId && u.TrialStatus >= (int)TrialEnrollStatus.HasConfirmedDoctorNames);
//trial.TrialStatusStr = "Reading";
////trial.TrialStatus = (int)TrialStatus.HasConfirmedDoctorNames;
//_trialRepository.Update(trial);
var trialId = confirmReviewerCommand.TrialId;
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
if (trial == null) return Null404NotFound(trial);
//更新入组表
var intoGroupList = await _enrollRepository.Where(t => t.TrialId == trialId,true).ToListAsync();
//验证邮件
var emaiList = await _doctorRepository.Where(t => intoGroupList.Select(t => t.DoctorId).Contains(t.Id))
.Select(t => new { t.EMail, t.FirstName, t.LastName }).ToListAsync();
var errorList = emaiList.Where(t => !Regex.IsMatch(t.EMail, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"))
.ToList();
if (errorList.Count() > 0)
{
// errorList.Select(c => c.LastName+" / "+c.FirstName)) +"邮箱格式存在问题"
return ResponseOutput.NotOk(string.Join(',', _localizer["Enroll_EmailFormat"], errorList.Select(c => c.LastName + " / " + c.FirstName))) ;
}
if (confirmReviewerCommand.ConfirmState == 1) //确认入组
{
foreach (var intoGroupItem in intoGroupList)
{
if (confirmReviewerCommand.DoctorIdArray.Contains(intoGroupItem.DoctorId))
{
//当邮件发送没有问题的时候,才修改状态 如果有问题,就当前不做处理
try
{
var userId = await _mailVerificationService.DoctorJoinTrialEmail(trialId, intoGroupItem.DoctorId, confirmReviewerCommand.BaseUrl, confirmReviewerCommand.RouteUrl);
if (!await _trialUserRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId, true))
{
await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now });
}
await _enrollRepository.BatchUpdateNoTrackingAsync(t => t.Id == intoGroupItem.Id, u => new Enroll() { DoctorUserId = userId });
if (!await _taskAllocationRuleRepository.AnyAsync(t => t.TrialId == trialId && t.DoctorUserId == userId && t.EnrollId == intoGroupItem.Id, true))
{
await _taskAllocationRuleRepository.AddAsync(new TaskAllocationRule() { TrialId = trialId, DoctorUserId = userId, EnrollId = intoGroupItem.Id });
}
await _enrollDetailRepository.AddAsync(new EnrollDetail()
{
DoctorId = intoGroupItem.DoctorId,
TrialId = trialId,
EnrollStatus = EnrollStatus.ConfirmIntoGroup,
OptUserType = (int)SystemUserType.AdminUser, //后台用户
});
intoGroupItem.EnrollStatus = EnrollStatus.ConfirmIntoGroup;
intoGroupItem.EnrollTime = DateTime.Now;
}
catch (Exception )
{
intoGroupItem.EnrollStatus = EnrollStatus.ConfirmIntoGroupFailed;
}
}
}
}
else if (confirmReviewerCommand.ConfirmState == 0)//回退上一步
{
foreach (var intoGroupItem in intoGroupList)
{
if (confirmReviewerCommand.DoctorIdArray.Contains(intoGroupItem.DoctorId))
{
intoGroupItem.EnrollStatus = EnrollStatus.InviteIntoGroup;
intoGroupItem.EnrollTime = null;
var deleteItem = await _enrollDetailRepository.FirstOrDefaultAsync(t =>
t.TrialId == trialId && t.DoctorId == intoGroupItem.DoctorId &&
t.EnrollStatus == EnrollStatus.ConfirmIntoGroup);
await _enrollDetailRepository.DeleteAsync(deleteItem);
}
}
}
await _enrollRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// optType 0表示入组列表没这条数据了 1表示出组需要填写出组时间 废弃
/// </summary>
/// <param name="trialId"></param>
/// <param name="doctorId"></param>
/// <param name="optType"></param>
/// <param name="outEnrollTime"></param>
/// <returns></returns>
[HttpPost("{trialId:guid}/{doctorId:guid}/{optType:int}")]
[TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]
//[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM)]
[Obsolete]
public async Task<IResponseOutput> EnrollBackOrOut(Guid trialId, Guid doctorId, int optType, DateTime? outEnrollTime)
{
var intoGroupItem = await _enrollRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.DoctorId == doctorId);
if (optType == 0)
{
var sum = _workloadRepository.Where(t =>
t.TrialId == trialId && t.DoctorId == doctorId &&
t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm)
.Sum(u => u.Adjudication + u.AdjudicationIn24H + u.AdjudicationIn48H + u.Timepoint +
u.TimepointIn24H + u.TimepointIn48H + u.RefresherTraining + u.Training + u.Global +
u.Downtime);
if (sum != 0)
{
//---Reviewers with workload cannot go back
return ResponseOutput.NotOk(_localizer["Enroll_CannotRollback"]);
}
intoGroupItem.EnrollStatus = EnrollStatus.InviteIntoGroup;
intoGroupItem.EnrollTime = null;
var deleteItem = await _enrollDetailRepository.FirstOrDefaultAsync(t =>
t.TrialId == trialId && t.DoctorId == intoGroupItem.DoctorId &&
t.EnrollStatus == EnrollStatus.ConfirmIntoGroup);
await _enrollDetailRepository.DeleteAsync(deleteItem);
}
else if (optType == 1)
{
intoGroupItem.OutEnrollTime = outEnrollTime;
}
return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync());
}
#endregion
}
}

View File

@ -1,18 +0,0 @@
using IRaCIS.Application.Contracts;
namespace IRaCIS.Application.Services
{
public interface IDoctorWorkloadService
{
Task<IResponseOutput> AddOrUpdateWorkload(WorkloadCommand workLoadAddOrUpdateModel, Guid userId);
//Task<IResponseOutput> DeleteReviewerAckSOW(Guid trialId, Guid doctorId, Guid attachmentId);
Task<IResponseOutput> DeleteWorkload(Guid workloadId);
PageOutput<WorkLoadDetailDTO> GetEnrollmentWorkloadStatsDetail(WorkLoadStatsQueryDTO workLoadSearch);
Task<List<WorkLoadDetailViewModel>> GetReviewerWorkLoadListDetail(WorkLoadDetailQueryDTO workLoadSearch);
Task<PageOutput<WorkLoadAndAgreementDTO>> GetTrialEnrollmentWorkloadStats(WorkLoadDoctorQueryDTO doctorSearchModel);
Task<WorkloadDTO> GetWorkloadDetailById(Guid id);
Task<IResponseOutput> UpdateReviewerReadingType(Guid trialId, Guid doctorId, int type);
//Task<IResponseOutput> UploadReviewerAckSOW(Guid trialId, ReviewerAckDTO attachmentViewModel);
Task<IResponseOutput<ExistWorkloadViewModel>> WorkloadExist(WorkloadExistQueryDTO param);
}
}

View File

@ -1,15 +0,0 @@
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
namespace IRaCIS.Application.Services
{
public interface IEnrollService
{
Task<IResponseOutput> AddOrUpdateEnroll(EnrollCommand addOrUpdateModel);
Task<IResponseOutput> ApproveReviewer(Guid trialId, Guid[] doctorIdArray, int auditState);
//Task<IResponseOutput> ConfirmReviewer(Guid trialId, Guid[] doctorIdArray, int confirmState);
Task<IResponseOutput> EnrollBackOrOut(Guid trialId, Guid doctorId, int optType, DateTime? outEnrollTime);
Task<PageOutput<EnrollViewModel>> GetTrialDoctorList(EnrollGetQuery challengeQuery);
Task<IResponseOutput> SelectReviewers(Guid trialId, Guid[] doctorIdArray);
Task<IResponseOutput> SubmitReviewer(Guid trialId, Guid[] doctorIdArray, int commitState);
}
}

View File

@ -1,29 +0,0 @@
using System;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Application.Interfaces
{
public interface ITrialEnrollmentService
{
IResponseOutput AddOrUpdateEnroll(EnrollCommand addOrUpdateModel);
Task< PageOutput<EnrollViewModel>> GetTrialDoctorList(EnrollGetQuery challengeQuery);
/// <summary>入组流程-筛选医生 [select]</summary>
IResponseOutput SelectReviewers( Guid trialId, Guid[] doctorIdArray);
/// <summary>入组流程-向CRO提交医生[Submit]</summary>
IResponseOutput SubmitReviewer( Guid trialId, Guid[] doctorIdArray, int commitState);
/// <summary>入组流程-CRO确定医生名单 [ Approve]</summary>
IResponseOutput ApproveReviewer( Guid trialId, Guid[] doctorIdArray, int auditState);
/// <summary>入组流程-向CRO提交医生[Submit]</summary>
IResponseOutput ConfirmReviewer(Guid trialId, Guid[] doctorIdArray, int confirmState);
IResponseOutput EnrollBackOrOut( Guid trialId, Guid doctorId, int optType,DateTime? outEnrollTime);
}
}

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infrastructure.Extention;
namespace IRaCIS.Core.Application.Contracts
{
public interface IWorkloadDistributionService
{
PageOutput<WorkloadTPDTO> GetWorkloadTPList(WorkloadDistributionQueryParam param);
IResponseOutput DistributeTP(WorkloadTPCommand workloadTPCommand);
IResponseOutput UpdateDistributeTP(Guid tpId, Guid ReviewerId, Guid studyId);
PageOutput<WorkloadGlobalDTO> GetWorkloadGlobalList(WorkloadDistributionQueryParam param);
IResponseOutput DistributeGlobal(WorkloadGlobalCommand workloadGlobalCommand);
IResponseOutput UpdateDistributeGlobal(Guid tpId, Guid ReviewerId,Guid subjectId, decimal visitNum);
PageOutput<WorkloadADDTO> GetWorkloadADList(WorkloadDistributionQueryParam param);
IResponseOutput DistributeAD(WorkloadAdCommand workloadTPCommand);
IResponseOutput UpdateDistributeAD(Guid tpId, Guid ReviewerId);
IResponseOutput<List<WorkloadDetailDTO>> GetWorkloadDetail(Guid WorkloadId);
IResponseOutput UpdateGlobalStatus(Guid globalId);
}
}

View File

@ -1,573 +0,0 @@
//using IRaCIS.Application.Contracts;
//using IRaCIS.Core.Application.Contracts;
//using System.Linq.Expressions;
//using IRaCIS.Core.Infrastructure.ExpressionExtend;
//using IRaCIS.Core.Infra.EFCore;
//using IRaCIS.Core.Domain.Models;
//using IRaCIS.Core.Domain.Share;
//using IRaCIS.Core.Infrastructure.Extention;
//using Microsoft.AspNetCore.Mvc;
//namespace IRaCIS.Core.Application.Services
//{
// /// <summary>
// /// TP、Global、AD 工作量分配查看
// /// </summary>
// [ ApiExplorerSettings(GroupName = "Trial")]
//#pragma warning disable
// public class WorkloadDistributionService : BaseService, IWorkloadDistributionService
// {
// private readonly IWorkloadTPRepository _workloadTpRepository;
// private readonly IWorkloadGlobalRepository _workloadGlobalRepository;
// private readonly IWorkloadADRepository _workloadAdRepository;
// private readonly IRepository<SubjectVisit> _subjectVisitRepository;
// private readonly IRepository<DicomStudy> _studyRepository;
// private readonly IRepository<Doctor> _doctorRepository;
// private readonly IRepository<Subject> _subjectRepository;
// private readonly IRepository<Site> _siteRepository;
// private readonly IWorkloadDetailRepository _workloadDetailRepository;
// public WorkloadDistributionService(IWorkloadTPRepository workloadTpRepository,
// IWorkloadGlobalRepository workloadGlobalRepository,
// IWorkloadADRepository workloadAdRepository,
// IRepository<SubjectVisit> subjectVisitRepository, IRepository<DicomStudy> studyRepository,
// IRepository<Doctor> doctorRepository, IRepository<Subject> subjectRepository,
// IRepository<Site> siteRepository,
// IWorkloadDetailRepository workloadDetailRepository,
// IUserInfo userInfo)
// {
// _workloadTpRepository = workloadTpRepository;
// _workloadGlobalRepository = workloadGlobalRepository;
// _workloadAdRepository = workloadAdRepository;
// _subjectVisitRepository = subjectVisitRepository;
// _studyRepository = studyRepository;
// _doctorRepository = doctorRepository;
// _subjectRepository = subjectRepository;
// _siteRepository = siteRepository;
// _workloadDetailRepository = workloadDetailRepository;
// }
// /// <summary>
// /// 批量分配Tp
// /// </summary>
// /// <param name="workloadTPCommand"></param>
// /// <returns></returns>
// [HttpPost]
// public IResponseOutput DistributeTP(WorkloadTPCommand workloadTPCommand)
// {
// //当前采用的是没有提示到具体的TP如有需要在修改下
// var studyIdList = workloadTPCommand.TpList.Select(u => u.StudyId);
// var temp = _workloadTpRepository.Where(u => studyIdList.Contains(u.StudyId) && u.ReviewerId == workloadTPCommand.ReviewerId);
// if (temp.Any() )
// {
// return ResponseOutput.NotOk("The TPs of different Arms of the same subject couldn't be assigned to the same reviewer.");
// }
// var success = false;
// workloadTPCommand.TpList.ForEach(t =>
// {
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = t.Id,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = workloadTPCommand.ReviewerId
// });
// _workloadDetailRepository.SaveChanges();
// success = _workloadTpRepository.Update(u => u.Id == t.Id, k => new WorkloadTP()
// {
// ReviewerId = workloadTPCommand.ReviewerId,
// Status = (int)WorkloadStatus.Distributed
// });
// });
// return ResponseOutput.Result(success);
// }
// /// <summary>
// /// 批量分配AD
// /// </summary>
// /// <param name="workloadTPCommand"></param>
// /// <returns></returns>
// [HttpPost]
// public IResponseOutput DistributeAD(WorkloadAdCommand workloadTPCommand)
// {
// var success = false;
// workloadTPCommand.IdList.ForEach(t =>
// {
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = t,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = workloadTPCommand.ReviewerId
// });
// _workloadDetailRepository.SaveChanges();
// success = _workloadAdRepository.Update(u => u.Id == t, k => new WorkloadAD()
// {
// ReviewerId = workloadTPCommand.ReviewerId,
// Status = (int)WorkloadStatus.Distributed
// });
// });
// return ResponseOutput.Result(success);
// }
// /// <summary>
// /// 批量分配Global
// /// </summary>
// /// <param name="workloadGCommand"></param>
// /// <returns></returns>
// [HttpPost]
// public IResponseOutput DistributeGlobal(WorkloadGlobalCommand workloadGCommand)
// {
// var temp = _workloadGlobalRepository.Where(u => workloadGCommand.GlobalList.Select(s => s.SubjectId).Contains(u.SubjectId)
// && workloadGCommand.GlobalList.Select(s => s.VisitNum).Contains(u.VisitNum) &&
// u.ReviewerId == workloadGCommand.ReviewerId);
// if (temp.Any())
// {
// return ResponseOutput.NotOk("The Globals of different Arms of the same subject couldn't be assigned to the same reviewer.");
// }
// var success = false;
// workloadGCommand.GlobalList.ForEach(t =>
// {
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = t.Id,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = workloadGCommand.ReviewerId
// });
// _workloadDetailRepository.SaveChanges();
// success = _workloadGlobalRepository.Update(u => u.Id == t.Id, k => new WorkloadGlobal()
// {
// ReviewerId = workloadGCommand.ReviewerId,
// Status = (int)WorkloadStatus.Distributed
// });
// });
// return ResponseOutput.Result(success);
// }
// [HttpPost]
// public PageOutput<WorkloadGlobalDTO> GetWorkloadGlobalList(WorkloadDistributionQueryParam param)
// {
// IQueryable<WorkloadGlobalDTO> query = null;
// Expression<Func<WorkloadGlobal, bool>> workloadTPLambda = x => x.TrialId == param.TrialId;
// if (param.SiteId != null)
// {
// workloadTPLambda = workloadTPLambda.And(t => t.SiteId == param.SiteId);
// }
// if (param.Status != null)
// {
// workloadTPLambda = workloadTPLambda.And(t => t.Status == param.Status);
// }
// if (!string.IsNullOrEmpty(param.WorkloadCode))
// {
// var globalCode = param.WorkloadCode.Trim();
// workloadTPLambda = workloadTPLambda.And(t => t.GlobalCode.Contains(globalCode));
// }
// if (param.GroupId != null && param.GroupId > 0)
// {
// var groupCode = "G0" + param.GroupId;
// workloadTPLambda = workloadTPLambda.And(t => t.GlobalCode.Contains(groupCode));
// }
// Expression<Func<Subject, bool>> subjectLambda = x => x.TrialId == param.TrialId;
// if (!string.IsNullOrEmpty(param.SubjectCode))
// {
// var subjectCode = param.SubjectCode.Trim();
// subjectLambda = subjectLambda.And(t => t.Code.Contains(subjectCode));
// }
// Expression<Func<Doctor, bool>> doctorLambda = x => true;
// if (!string.IsNullOrEmpty(param.Reviewer))
// {
// var reviewer = param.Reviewer.Trim();
// doctorLambda = doctorLambda.And(t => t.ChineseName.Contains(reviewer)
// || t.FirstName.Contains(reviewer) || t.LastName.Contains(reviewer));
// query = from workloadG in _workloadGlobalRepository.Where(workloadTPLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadG.SubjectId equals subject.Id
// join site in _siteRepository.AsQueryable() on workloadG.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadG.ReviewerId equals doctor.Id
// select new WorkloadGlobalDTO()
// {
// Id = workloadG.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadG.SiteId,
// SiteName = site.SiteName,
// Status = workloadG.Status,
// GlobalCode = workloadG.GlobalCode,
// SubjectCode = subject.Code,
// VisitId = workloadG.VisitId,
// UpdateTime = workloadG.UpdateTime,
// SubjectId = workloadG.SubjectId,
// VisitNum = workloadG.VisitNum,
// VisitName = workloadG.VisitName
// };
// }
// else
// {
// query = from workloadG in _workloadGlobalRepository.Where(workloadTPLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadG.SubjectId equals subject.Id
// join site in _siteRepository.AsQueryable() on workloadG.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadG.ReviewerId equals doctor.Id into cc
// from doctor in cc.DefaultIfEmpty()
// select new WorkloadGlobalDTO()
// {
// Id = workloadG.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadG.SiteId,
// SiteName = site.SiteName,
// Status = workloadG.Status,
// GlobalCode = workloadG.GlobalCode,
// SubjectCode = subject.Code,
// VisitId = workloadG.VisitId,
// UpdateTime = workloadG.UpdateTime,
// SubjectId = workloadG.SubjectId,
// VisitNum = workloadG.VisitNum,
// VisitName = workloadG.VisitName
// };
// }
// var count = query.Count();
// var propName = param.SortField == string.Empty ? "GlobalCode" : param.SortField;
// query = param.Asc
// ? query.OrderBy(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode)
// : query.OrderByDescending(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode);
// query = query.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize);
// var list = query.ToList();
// return new PageOutput<WorkloadGlobalDTO>(param.PageIndex,
// param.PageSize, count, list);
// }
// [HttpPost]
// public PageOutput<WorkloadADDTO> GetWorkloadADList(WorkloadDistributionQueryParam param)
// {
// IQueryable<WorkloadADDTO> query = null;
// Expression<Func<WorkloadAD, bool>> workloadAdLambda = x => x.TrialId == param.TrialId;
// if (param.SiteId != null)
// {
// workloadAdLambda = workloadAdLambda.And(t => t.SiteId == param.SiteId);
// }
// if (param.Status != null)
// {
// workloadAdLambda = workloadAdLambda.And(t => t.Status == param.Status);
// }
// if (!string.IsNullOrEmpty(param.WorkloadCode))
// {
// var adCode = param.WorkloadCode.Trim();
// workloadAdLambda = workloadAdLambda.And(t => t.ADCode.Contains(adCode));
// }
// Expression<Func<Subject, bool>> subjectLambda = x => x.TrialId == param.TrialId;
// if (!string.IsNullOrEmpty(param.SubjectCode))
// {
// var subjectCode = param.SubjectCode.Trim();
// subjectLambda = subjectLambda.And(t => t.Code.Contains(subjectCode));
// }
// Expression<Func<Doctor, bool>> doctorLambda = x => true;
// if (!string.IsNullOrEmpty(param.Reviewer))
// {
// var reviewer = param.Reviewer.Trim();
// doctorLambda = doctorLambda.And(t => t.ChineseName.Contains(reviewer)
// || t.FirstName.Contains(reviewer) || t.LastName.Contains(reviewer));
// query = from workloadAd in _workloadAdRepository.Where(workloadAdLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadAd.SubjectId equals subject.Id
// join site in _siteRepository.AsQueryable() on workloadAd.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadAd.ReviewerId equals doctor.Id
// select new WorkloadADDTO()
// {
// Id = workloadAd.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadAd.SiteId,
// SiteName = site.SiteName,
// Status = workloadAd.Status,
// ADCode = workloadAd.ADCode,
// SubjectCode = subject.Code,
// SubjectId = workloadAd.SubjectId,
// UpdateTime = workloadAd.UpdateTime
// };
// }
// else
// {
// query = from workloadAd in _workloadAdRepository.Where(workloadAdLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadAd.SubjectId equals subject.Id
// join site in _siteRepository.AsQueryable() on workloadAd.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadAd.ReviewerId equals doctor.Id into cc
// from doctor in cc.DefaultIfEmpty()
// select new WorkloadADDTO()
// {
// Id = workloadAd.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadAd.SiteId,
// SiteName = site.SiteName,
// Status = workloadAd.Status,
// ADCode = workloadAd.ADCode,
// SubjectCode = subject.Code,
// SubjectId = workloadAd.SubjectId,
// UpdateTime = workloadAd.UpdateTime
// };
// }
// var count = query.Count();
// var propName = param.SortField == string.Empty ? "ADCode" : param.SortField;
// query = param.Asc
// ? query.OrderBy(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode)
// : query.OrderByDescending(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode);
// query = query.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize);
// var list = query.ToList();
// return new PageOutput<WorkloadADDTO>(param.PageIndex,
// param.PageSize, count, list);
// }
// [HttpPost]
// public PageOutput<WorkloadTPDTO> GetWorkloadTPList(WorkloadDistributionQueryParam param)
// {
// IQueryable<WorkloadTPDTO> query = null;
// Expression<Func<WorkloadTP, bool>> workloadTPLambda = x => x.TrialId == param.TrialId;
// if (param.SiteId != null)
// {
// workloadTPLambda = workloadTPLambda.And(t => t.SiteId == param.SiteId);
// }
// if (param.Status != null)
// {
// workloadTPLambda = workloadTPLambda.And(t => t.Status == param.Status);
// }
// if (!string.IsNullOrEmpty(param.WorkloadCode))
// {
// var timepoint = param.WorkloadCode.Trim();
// workloadTPLambda = workloadTPLambda.And(t => t.TimepointCode.Contains(timepoint));
// }
// if (param.GroupId != null && param.GroupId > 0)
// {
// var groupCode = "T0" + param.GroupId;
// workloadTPLambda = workloadTPLambda.And(t => t.TimepointCode.Contains(groupCode));
// }
// Expression<Func<Subject, bool>> subjectLambda = x => x.TrialId == param.TrialId;
// if (!string.IsNullOrEmpty(param.SubjectCode))
// {
// var subjectCode = param.SubjectCode.Trim();
// subjectLambda = subjectLambda.And(t => t.Code.Contains(subjectCode));
// }
// Expression<Func<Doctor, bool>> doctorLambda = x => true;
// if (!string.IsNullOrEmpty(param.Reviewer))
// {
// var reviewer = param.Reviewer.Trim();
// doctorLambda = doctorLambda.And(t => t.ChineseName.Contains(reviewer)
// || t.FirstName.Contains(reviewer) || t.LastName.Contains(reviewer));
// query = from workloadTp in _workloadTpRepository.Where(workloadTPLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadTp.SubjectId equals subject.Id
// join subjectVisit in _subjectVisitRepository.AsQueryable() on workloadTp.SubjectVisitId equals subjectVisit.Id
// join study in _studyRepository.AsQueryable() on workloadTp.StudyId equals study.Id
// join site in _siteRepository.AsQueryable() on workloadTp.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadTp.ReviewerId equals doctor.Id
// select new WorkloadTPDTO()
// {
// Id = workloadTp.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadTp.SiteId,
// SiteName = site.SiteName,
// Status = workloadTp.Status,
// StudyCode = study.StudyCode,
// StudyId = workloadTp.StudyId,
// TimepointCode = workloadTp.TimepointCode,
// SubjectCode = subject.Code,
// SubjectVisitId = workloadTp.SubjectVisitId,
// SubjectId = workloadTp.SubjectId,
// VisitNum = subjectVisit.VisitNum,
// VisitName = subjectVisit.VisitName,
// UpdateTime = workloadTp.UpdateTime
// };
// }
// else
// {
// query = from workloadTp in _workloadTpRepository.Where(workloadTPLambda)
// join subject in _subjectRepository.Where(subjectLambda) on workloadTp.SubjectId equals subject.Id
// join subjectVisit in _subjectVisitRepository.AsQueryable() on workloadTp.SubjectVisitId equals subjectVisit.Id
// join study in _studyRepository.AsQueryable() on workloadTp.StudyId equals study.Id
// join site in _siteRepository.AsQueryable() on workloadTp.SiteId equals site.Id
// join doctor in _doctorRepository.Where(doctorLambda) on workloadTp.ReviewerId equals doctor.Id into cc
// from doctor in cc.DefaultIfEmpty()
// select new WorkloadTPDTO()
// {
// Id = workloadTp.Id,
// ReviewerCode = doctor.ReviewerCode,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerId = doctor.Id,
// ReviewerLastName = doctor.LastName,
// SiteId = workloadTp.SiteId,
// SiteName = site.SiteName,
// Status = workloadTp.Status,
// StudyCode = study.StudyCode,
// StudyId = workloadTp.StudyId,
// TimepointCode = workloadTp.TimepointCode,
// SubjectCode = subject.Code,
// SubjectVisitId = workloadTp.SubjectVisitId,
// SubjectId = workloadTp.SubjectId,
// VisitNum = subjectVisit.VisitNum,
// VisitName = subjectVisit.VisitName,
// UpdateTime = workloadTp.UpdateTime
// };
// }
// var count = query.Count();
// var propName = param.SortField == string.Empty ? "TimepointCode" : param.SortField;
// query = param.Asc
// ? query.OrderBy(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode)
// : query.OrderByDescending(propName).ThenBy(t => t.SiteName).ThenBy(t => t.SubjectCode);
// query = query.Skip((param.PageIndex - 1) * param.PageSize).Take(param.PageSize);
// var list = query.ToList();
// return new PageOutput<WorkloadTPDTO>(param.PageIndex,
// param.PageSize, count, list);
// }
// //修改单个TP
// [HttpPost("{tpId:guid}/{reviewerId:guid}")]
// public IResponseOutput UpdateDistributeAD(Guid tpId, Guid reviewerId)
// {
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = tpId,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = reviewerId
// });
// _workloadDetailRepository.SaveChanges();
// var success= _workloadAdRepository.Update(t => t.Id == tpId, u => new WorkloadAD()
// {
// ReviewerId = reviewerId,
// Status = (int)WorkloadStatus.Distributed
// });
// return ResponseOutput.Result(success);
// }
// //修改单个Global
// [HttpPost("{tpId:guid}/{reviewerId:guid}/{subjectId:guid}/{visitNum}")]
// public IResponseOutput UpdateDistributeGlobal(Guid tpId, Guid reviewerId, Guid subjectId, decimal visitNum)
// {
// var temp = _workloadGlobalRepository.Where(u => u.SubjectId == subjectId &&
// u.VisitNum == visitNum &&
// u.ReviewerId == reviewerId && u.Id != tpId);
// if (temp.Any())
// {
// return ResponseOutput.NotOk("The Global of the other arm of this subject has already been assigned to this reviewer, and the assignment couldn't be performed.");
// }
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = tpId,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = reviewerId
// });
// _workloadDetailRepository.SaveChanges();
// return ResponseOutput.Result(_workloadGlobalRepository.Update(t => t.Id == tpId, u => new WorkloadGlobal()
// {
// ReviewerId = reviewerId,
// Status = (int)WorkloadStatus.Distributed
// }));
// }
// //修改单个TP
// [HttpPost("{tpId:guid}/{reviewerId:guid}/{studyId:guid}")]
// public IResponseOutput UpdateDistributeTP(Guid tpId, Guid reviewerId, Guid studyId)
// {
// var temp = _workloadTpRepository.Where(u => u.StudyId == studyId && u.ReviewerId == reviewerId && u.Id != tpId);
// if (temp.Any())
// {
// return ResponseOutput.NotOk("The TP of the other arm of this subject has already been assigned to this reviewer, and the assignment couldn't be performed.");
// }
// _workloadDetailRepository.Add(new WorkloadDetail
// {
// WorkloadId = tpId,
// OptUserName = _userInfo.RealName,
// OptTime = DateTime.Now,
// Status = (int)WorkloadStatus.Distributed,
// ReviewerId = reviewerId
// });
// _workloadDetailRepository.SaveChanges();
// return ResponseOutput.Result(_workloadTpRepository.Update(t => t.Id == tpId, u => new WorkloadTP()
// {
// ReviewerId = reviewerId,
// Status = (int)WorkloadStatus.Distributed
// }));
// }
// [HttpGet("{workloadId:guid}")]
// public IResponseOutput<List<WorkloadDetailDTO>> GetWorkloadDetail(Guid workloadId)
// {
// IQueryable<WorkloadDetailDTO> query = null;
// query = from detail in _workloadDetailRepository.Where(u => u.WorkloadId == workloadId)
// join doctor in _doctorRepository.AsQueryable() on detail.ReviewerId equals doctor.Id into cc
// from doctor in cc.DefaultIfEmpty()
// select new WorkloadDetailDTO()
// {
// OptTime = detail.OptTime,
// OptUserName = detail.OptUserName,
// ReviewerChineseName = doctor.ChineseName,
// ReviewerFirstName = doctor.FirstName,
// ReviewerLastName = doctor.LastName,
// Status = detail.Status
// };
// var list = query.OrderByDescending(u => u.OptTime).ToList();
// return ResponseOutput.Ok(list);
// }
// [HttpPost("UpdateGlobalStatus/{globalId:guid}")]
// public IResponseOutput UpdateGlobalStatus(Guid globalId)
// {
// return ResponseOutput.Result(_workloadGlobalRepository.Update(u => u.Id == globalId, t => new WorkloadGlobal()
// {
// Status = 0
// }));
// }
// }
//}

View File

@ -1,21 +0,0 @@
using AutoMapper;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Core.Application.Service
{
public class WorkLoadConfig : Profile
{
public WorkLoadConfig()
{
CreateMap<WorkloadCommand, Workload>();
CreateMap<Workload, WorkloadDTO>();
CreateMap<EnrollCommand, Enroll>();
}
}
}

View File

@ -23,30 +23,28 @@ namespace IRaCIS.Core.Application.Triggers
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
private readonly IRepository<SubjectCriteriaEvaluationVisitFilter> _SubjectCriteriaEvaluationVisitFilterRepository;
private readonly ISubjectCriteriaEvaluationService _subjectCriteriaEvaluationService;
private readonly IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository;
public SubjectVisitCheckPassedTrigger(IRepository<Subject> subjectRepository,
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
IRepository<ReadingClinicalData> readingClinicalDataRepository,
IVisitTaskHelpeService visitTaskHelpeService, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
IRepository<SubjectCriteriaEvaluationVisitFilter> subjectCriteriaEvaluationVisitFilterRepository, ISubjectCriteriaEvaluationService subjectCriteriaEvaluationService
, IRepository<SubjectCriteriaEvaluation> subjectCriteriaEvaluationRepository)
IVisitTaskHelpeService visitTaskHelpeService, IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository
)
{
_subjectCriteriaEvaluationRepository= subjectCriteriaEvaluationRepository;
_subjectRepository = subjectRepository;
_clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
_readingClinicalDataRepository = readingClinicalDataRepository;
this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
_visitTaskHelpeService = visitTaskHelpeService;
_trialReadingCriterionRepository = trialReadingCriterionRepository;
_SubjectCriteriaEvaluationVisitFilterRepository = subjectCriteriaEvaluationVisitFilterRepository;
_subjectCriteriaEvaluationService = subjectCriteriaEvaluationService;
}
@ -80,12 +78,7 @@ namespace IRaCIS.Core.Application.Triggers
// await _SubjectCriteriaEvaluationVisitFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitFilter() { SubjectId = subjectVisit.SubjectId, SubjectVisitId = subjectVisit.Id, TrialReadingCriterionId = criterion.Id });
//}
//如果参与评估,那么久对当前访视进行自动筛选
if( await _subjectCriteriaEvaluationRepository.AnyAsync(t=>t.SubjectId==subjectVisit.SubjectId && t.TrialReadingCriterionId==criterion.Id && t.IsJoinEvaluation))
{
await _subjectCriteriaEvaluationService.AutoSubjectCriteriaEvaluationVisitFilter(subjectVisit.SubjectId, subjectVisit.Id, criterion.Id);
}

View File

@ -1,15 +0,0 @@
namespace IRaCIS.Core.Domain.Share
{
public enum WorkloadStatus
{
ToBeAllocated=0,//待分配
Distributed = 30,//已分配
Reading = 40,//都片中,未提交读片报告之前
ReviewFinish = 80,//读片完成
//Archived=100,//流程结束,归档锁库
}
}

View File

@ -58,10 +58,6 @@ namespace IRaCIS.Core.Domain.Models
[Table("WorkloadDetail")]
public class WorkloadDetail : Entity
{
[JsonIgnore]
public Workload Workload { get; set; }
public Guid WorkloadId { get; set; }
public string OptUserName { get; set; }
public DateTime OptTime { get; set; } = DateTime.Now;

View File

@ -1,90 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-10 11:59:27
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace IRaCIS.Core.Domain.Models
{
///<summary>
///SubjectUser
///</summary>
[Table("SubjectUser")]
public class SubjectUser : Entity, IAuditUpdate, IAuditAdd
{
[JsonIgnore]
public Trial Trial { get; set; }
public Guid TrialId { get; set; }
public Guid TrialReadingCriterionId { get; set; }
/// <summary>
/// CreateUserId
/// </summary>
[Required]
public Guid CreateUserId { get; set; }
/// <summary>
/// CreateTime
/// </summary>
[Required]
public DateTime CreateTime { get; set; }
/// <summary>
/// UpdateTime
/// </summary>
[Required]
public DateTime UpdateTime { get; set; }
/// <summary>
/// UpdateUserId
/// </summary>
[Required]
public Guid UpdateUserId { get; set; }
public DateTime? AssignTime { get; set; }
/// <summary>
/// SubjectId
/// </summary>
[Required]
public Guid SubjectId { get; set; }
public Subject Subject { get; set; }
public Guid DoctorUserId { get; set; }
[JsonIgnore]
public User DoctorUser { get; set; }
public Arm ArmEnum { get; set; }
public bool IsConfirmed { get; set; } = true;
//该属性有值 说明该医生被替换了 分配的时候 要过滤掉
public Guid? OrignalSubjectUserId { get; set; }
[JsonIgnore]
//Parent
[ForeignKey("OrignalSubjectUserId")]
public SubjectUser OrignalSubjectUser { get; set; }
//ChildList
[JsonIgnore]
public List<SubjectUser> EarlierSubjectUserList { get; set; }
//public List<VisitTask> SubjectArmVisitTaskList { get; set; }
}
}

View File

@ -1,62 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-07 13:13:13
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
using System;
using IRaCIS.Core.Domain.Share;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace IRaCIS.Core.Domain.Models
{
///<summary>
///TaskAllocationRule
///</summary>
[Table("TaskAllocationRule")]
public class TaskAllocationRule : Entity, IAuditUpdate, IAuditAdd
{
[JsonIgnore]
public Trial Trial { get; set; }
public Guid TrialId { get; set; }
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
public Guid UpdateUserId { get; set; }
public int PlanSubjectCount { get; set; }
public bool IsEnable { get; set; }
public string Note { get; set; } = string.Empty;
public Guid DoctorUserId { get; set; }
[ForeignKey("DoctorUserId")]
[JsonIgnore]
public User DoctorUser { get; set; }
public Guid EnrollId { get; set; }
[JsonIgnore]
public Enroll Enroll { get; set; }
//是否是裁判医生 裁判医生单独加入
public bool IsJudgeDoctor { get; set; }
public int PlanReadingRatio { get; set; }
}
}

View File

@ -1,76 +0,0 @@
//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-07-01 15:32:56
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
using EntityFrameworkCore.Projectables;
using System.Linq;
namespace IRaCIS.Core.Domain.Models
{
///<summary>
///TaskConsistentRule
///</summary>
[Table("TaskConsistentRule")]
public class TaskConsistentRule : Entity, IAuditUpdate, IAuditAdd
{
public Trial Trial { get; set; }
public Guid CreateUserId { get; set; }
public DateTime CreateTime { get; set; }
public DateTime UpdateTime { get; set; }
public Guid UpdateUserId { get; set; }
public Guid TrialId { get; set; }
public int PlanSubjectCount { get; set; }
public int PlanVisitCount { get; set; }
public int IntervalWeeks { get; set; }
public bool IsHaveReadingPeriod { get; set; }
public bool IsGenerateGlobalTask { get; set; }
public int BlindSubjectNumberOfPlaces { get; set; }
public string BlindTrialSiteCode { get; set; } = string.Empty;
public bool IsSelfAnalysis { get; set; }
//public Guid? CompareDoctorUserId { get; set; }
//public User AnalysisDoctorUser { get; set; }
//public Guid AnalysisDoctorUserId { get; set; }
//public List<VisitTask> DoctorVisitTaskList { get; set; }
public bool IsEnable { get; set; }
public string Note { get; set; }
public Guid TrialReadingCriterionId { get; set; }
[JsonIgnore]
[ForeignKey("TrialReadingCriterionId")]
public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; }
//[Projectable]
//public List<VisitTask> DoctorConsistentTaskList => DoctorVisitTaskList.Where(t => t.IsAnalysisCreate && t.TaskConsistentRuleId == Id).ToList();
}
}

View File

@ -10,9 +10,6 @@ namespace IRaCIS.Core.Domain.Models
[Table("Dictionary")]
public partial class Dictionary : Entity, IAuditUpdate, IAuditAdd
{
[JsonIgnore]
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
public string ChildGroup { get; set; }
public int ChildCodeEnum { get; set; }

Some files were not shown because too many files have changed in this diff Show More