删除不要的功能
parent
f0cde942fb
commit
53251e53a0
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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"))
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>()
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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>();
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);//新增也不需要返回Id,TrialId 也是唯一
|
||||
Task<PageOutput<TrialPaymentPriceDTO>> GetTrialPaymentPriceList(TrialPaymentPriceQueryDTO queryParam);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传入组后的Ack-SOW
|
||||
/// </summary>
|
||||
Task<IResponseOutput> UploadTrialSOW( TrialSOWPathDTO trialSowPath);
|
||||
|
||||
|
||||
|
||||
Task<IResponseOutput> DeleteTrialSOW( DeleteSowPathDTO trialSowPath);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))))
|
||||
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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("该医院下存在用户,暂时无法删除。");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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 });
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
|
||||
|
||||
CreateMap<Enroll, ReviewerSelectToBeDoneDto>();
|
||||
|
||||
|
||||
CreateMap<VisitTask, ReReadingApprovalToBeDoneDto>();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
// }));
|
||||
// }
|
||||
|
||||
// }
|
||||
//}
|
|
@ -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>();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
namespace IRaCIS.Core.Domain.Share
|
||||
{
|
||||
public enum WorkloadStatus
|
||||
{
|
||||
ToBeAllocated=0,//待分配
|
||||
|
||||
Distributed = 30,//已分配
|
||||
|
||||
Reading = 40,//都片中,未提交读片报告之前
|
||||
|
||||
ReviewFinish = 80,//读片完成
|
||||
|
||||
//Archived=100,//流程结束,归档锁库
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue