irc-netcore-api/IRaCIS.Core.Application/Service/Financial/FinancialService.cs

1314 lines
68 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts.Pay;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Application.Services
{
[ ApiExplorerSettings(GroupName = "Financial")]
public class FinancialService : BaseService, IPaymentService
{
private readonly IRepository<Payment> _paymentRepository;
private readonly IRepository<ReviewerPayInformation> _doctorPayInfoRepository;
private readonly IRepository<TrialPaymentPrice> _TrialPaymentPriceRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<Doctor> _doctorRepository;
private readonly IRepository<RankPrice> _rankPriceRepository;
private readonly IRepository<PaymentDetail> _paymentDetailRepository;
private readonly IRepository<CRO> _croRepository;
private readonly IRepository<Workload> _workloadRepository;
private readonly IRepository<TrialRevenuesPrice> _trialRevenuePriceRepository;
private readonly IRepository<PaymentAdjustment> _payAdjustmentRepository;
private readonly IRepository<Enroll> _enrollRepository;
private readonly IRepository<Workload> _doctorWorkloadRepository;
public FinancialService(IRepository<Payment> costStatisticsRepository,
IRepository<ReviewerPayInformation> doctorPayInfoRepository,
IRepository<Trial> trialRepository,
IRepository<Doctor> doctorRepository,
IRepository<RankPrice> rankPriceRepository,
IRepository<PaymentDetail> costStatisticsDetailRepository,
IRepository<CRO> croCompanyRepository,
IRepository<Workload> workloadRepository,
IRepository<Enroll> intoGroupRepository,
IRepository<TrialPaymentPrice> trialPaymentPriceRepository,
IRepository<TrialRevenuesPrice> trialCostRepository,
IRepository<PaymentAdjustment> costAdjustmentRepository,
IRepository<Workload> doctoWorkloadRepository
)
{
_TrialPaymentPriceRepository = trialPaymentPriceRepository;
_paymentRepository = costStatisticsRepository;
_doctorPayInfoRepository = doctorPayInfoRepository;
_trialRepository = trialRepository;
_doctorRepository = doctorRepository;
_rankPriceRepository = rankPriceRepository;
_paymentDetailRepository = costStatisticsDetailRepository;
_croRepository = croCompanyRepository;
_enrollRepository = intoGroupRepository;
_workloadRepository = workloadRepository;
_trialRevenuePriceRepository = trialCostRepository;
_payAdjustmentRepository = costAdjustmentRepository;
_doctorWorkloadRepository = doctoWorkloadRepository;
}
/// <summary>
/// Financials /MonthlyPayment 列表查询接口
/// </summary>
[NonDynamicMethod]
public async Task<PageOutput<PaymentModel>> GetMonthlyPaymentList(MonthlyPaymentQueryDTO inQuery)
{
//var year = queryParam.StatisticsDate.Year;
//var month = queryParam.StatisticsDate.Month;
//var searchBeginDateTime = queryParam.StatisticsDate;
//Expression<Func<Workload, bool>> workloadLambda = t => t.DataFrom == (int)WorkLoadFromStatus.FinalConfirm;
//workloadLambda = workloadLambda.And(t =>
// t.WorkTime >= queryParam.StatisticsDate && t.WorkTime <= queryParam.StatisticsDate);
//var rate = _exchangeRateRepository.FindSingleOrDefault(u => u.YearMonth == yearMonth);
//var exchangeRate = rate == null ? 0 : rate.Rate;
var yearMonth = inQuery.StatisticsDate.ToString("yyyy-MM");
Expression<Func<Doctor, bool>> doctorLambda = x => true;
if (!string.IsNullOrWhiteSpace(inQuery.KeyWord))
{
var reviewer = inQuery.KeyWord.Trim();
doctorLambda = doctorLambda.And(u => u.ChineseName.Contains(reviewer)
|| u.FirstName.Contains(reviewer)
|| u.LastName.Contains(reviewer)
|| u.ReviewerCode.Contains(reviewer));
}
if (inQuery.Nation != null)
{
doctorLambda = doctorLambda.And(u => u.Nation == inQuery.Nation);
}
var costStatisticsQueryable =
from monthlyPayment in _paymentRepository.Where(t => t.YearMonth == yearMonth)
join payInfo in _doctorPayInfoRepository.AsQueryable() on monthlyPayment.DoctorId equals payInfo.DoctorId
into cc
from payInfo in cc.DefaultIfEmpty()
join doctor in _doctorRepository.Where(doctorLambda) on monthlyPayment.DoctorId equals doctor.Id
join rankPrice in _rankPriceRepository.AsQueryable() on payInfo.RankId equals rankPrice.Id into dd
from rankPriceItem in dd.DefaultIfEmpty()
select new PaymentModel()
{
Id = monthlyPayment.Id,
DoctorId = monthlyPayment.DoctorId,
YearMonth = monthlyPayment.YearMonth,
PaymentUSD = monthlyPayment.PaymentUSD,
CalculateTime = monthlyPayment.CalculateTime,
CalculateUser = monthlyPayment.CalculateUser,
IsLock = monthlyPayment.IsLock,
ExchangeRate = monthlyPayment.ExchangeRate,
PaymentCNY = monthlyPayment.PaymentCNY,
AdjustPaymentCNY = monthlyPayment.AdjustmentCNY,
AdjustPaymentUSD = monthlyPayment.AdjustmentUSD,
TotalPaymentCNY = monthlyPayment.AdjustmentCNY + monthlyPayment.PaymentCNY,
TotalPaymentUSD = monthlyPayment.AdjustmentUSD + monthlyPayment.PaymentUSD,
Code = doctor.ReviewerCode,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
ChineseName = doctor.ChineseName,
Phone = doctor.Phone,
DoctorNameInBank = payInfo.DoctorNameInBank,
RankName = rankPriceItem.RankName,
IDCard = payInfo.IDCard,
BankCardNumber = payInfo.BankCardNumber,
BankName = payInfo.BankName
};
return await costStatisticsQueryable.ToPagedListAsync(inQuery);
//var propName = string.IsNullOrWhiteSpace(queryParam.SortField) ? "Code" : queryParam.SortField;
//costStatisticsQueryable = queryParam.Asc ? costStatisticsQueryable.OrderBy(propName).ThenBy(u => u.Code)
// : costStatisticsQueryable.OrderByDescending(propName).ThenBy(u => u.Code);
//var count = costStatisticsQueryable.Count();
//costStatisticsQueryable = costStatisticsQueryable.Skip((queryParam.PageIndex - 1) * queryParam.PageSize).Take(queryParam.PageSize);
//var costStatisticsList = await costStatisticsQueryable.ToListAsync();
//return new PageOutput<PaymentModel>(queryParam.PageIndex, queryParam.PageSize, count, costStatisticsList);
#region 增加调整费用总计字段之前
//var doctorIds = costStatisticsList.Select(t => t.DoctorId).ToList();
//var adjList = _payAdjustmentRepository.GetAll()
// .Where(t => t.YearMonth == yearMonth && doctorIds.Contains(t.ReviewerId))
// .GroupBy(t => t.ReviewerId).Select(g => new
// {
// ReviewerId = g.Key,
// AdjustPaymentCNY = g.Sum(t => t.AdjustPaymentCNY),
// AdjustPaymentUSD = g.Sum(t => t.AdjustPaymentUSD)
// }).ToList();
//costStatisticsList.ForEach(t =>
//{
// var tempAdj = adjList.FirstOrDefault(u => u.ReviewerId == t.DoctorId);
// if (tempAdj != null)
// {
// t.AdjustPaymentUSD = tempAdj.AdjustPaymentUSD;
// t.AdjustPaymentCNY = tempAdj.AdjustPaymentCNY;
// }
//});
#endregion
}
/// <summary>
/// Financials /MonthlyPaymentDetail 详情查询接口
/// </summary>
[HttpPost("{paymentId:guid}/{doctorId:guid}/{yearMonth:datetime}")]
public async Task<PayDetailDTO> GetMonthlyPaymentDetailList(Guid paymentId, Guid reviewerId, DateTime yearMonth)
{
var returnModel = new PayDetailDTO();
var yearMonthStr = yearMonth.ToString("yyyy-MM");
List<PaymentDetailDTO> detailList = new List<PaymentDetailDTO>();
//有详细表的数据 先查出来
if (paymentId != Guid.Empty)
{
//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
//};
//detailList = _paymentDetailRepository.AsQueryable()
// .Where(t => t.PaymentId == paymentId)
// .OrderBy(t => t.ShowCodeOrder).ThenBy(t => t.ShowTypeOrder).ProjectTo<PaymentDetailDTO>(_mapper.ConfigurationProvider).ToList();
detailList = await (from pay in _paymentDetailRepository.Where(t => t.PaymentId == paymentId)
join enroll in _enrollRepository.Where() on new { pay.DoctorId, pay.TrialId } equals new { enroll.DoctorId, enroll.TrialId }
join price in _TrialPaymentPriceRepository.Where() on pay.TrialId equals price.TrialId
orderby pay.ShowCodeOrder
orderby pay.ShowTypeOrder
select new PaymentDetailDTO()
{
Id=pay.Id,
ShowCodeOrder = pay.ShowCodeOrder,
ShowTypeOrder = pay.ShowTypeOrder,
PaymentUSD = pay.PaymentUSD,
BasePrice = pay.BasePrice,
PersonalAdditional = pay.PersonalAdditional,
TrialAdditional = pay.TrialAdditional,
TrialCode = pay.TrialCode,
PaymentCNY = pay.PaymentCNY,
DoctorId = pay.DoctorId,
ExchangeRate = pay.ExchangeRate,
IsNewTrial = price.IsNewTrial,
NewPersonalAdditional= enroll.AdjustmentMultiple,
}).ToListAsync();
}
//费用调整
//_payAdjustmentRepository.Where(t => t.YearMonth == yearMonthStr && t.ReviewerId == reviewerId)
var adjList =
await (from costAdjustment in _payAdjustmentRepository.Where(t => t.YearMonth == yearMonthStr&& t.ReviewerId == paymentId)
join enroll in _enrollRepository.Where() on new { costAdjustment.ReviewerId, costAdjustment.TrialId } equals new { ReviewerId= enroll.DoctorId, enroll.TrialId }
join price in _TrialPaymentPriceRepository.Where() on costAdjustment.TrialId equals price.TrialId
select new PaymentDetailDTO()
{
Id=costAdjustment.Id,
TrialCode = "Adjustment",
PaymentCNY = costAdjustment.AdjustmentCNY,
PaymentUSD = costAdjustment.AdjustmentUSD,
DoctorId = costAdjustment.ReviewerId,
ExchangeRate = costAdjustment.ExchangeRate,
AdjustmentView = new AdjustmentDTO()
{
AdjustPaymentUSD = costAdjustment.AdjustmentUSD,
AdjustPaymentCNY = costAdjustment.AdjustmentCNY,
Note = costAdjustment.Note
},
IsNewTrial = price.IsNewTrial,
NewPersonalAdditional = enroll.AdjustmentMultiple,
}).ToListAsync();
detailList.AddRange(adjList);
detailList.ForEach(x =>
{
x.PersonalAdditional = x.IsNewTrial == true && x.NewPersonalAdditional != null ? 0 : x.PersonalAdditional;
x.TrialAdditional = x.IsNewTrial == true && x.NewPersonalAdditional != null ? 0 : x.TrialAdditional;
x.BasePrice = x.IsNewTrial == true && x.NewPersonalAdditional != null ? x.NewPersonalAdditional.Value : x.BasePrice;
});
returnModel.DetailList = detailList;
var doctorId = returnModel.DetailList.FirstOrDefault()?.DoctorId;
var query = from doctor in _doctorRepository.AsQueryable()
.Where(t => t.Id == doctorId)
join payInfo in _doctorPayInfoRepository.AsQueryable() on doctor.Id equals payInfo.DoctorId
join rank in _rankPriceRepository.AsQueryable() on payInfo.RankId equals rank.Id
select new DoctorPayInfo()
{
Code = doctor.ReviewerCode,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
Phone = doctor.Phone,
DoctorId = doctor.Id,
PayTitle = rank.RankName,
YearMonth = yearMonthStr
};
returnModel.DoctorInfo =(await query.FirstOrDefaultAsync()).IfNullThrowException();
return returnModel;
}
/// <summary>
/// NEW 导出Excel压缩包 数据获取
/// </summary>
[HttpPost]
public async Task<List<PayDetailDTO>> GetReviewersMonthlyPaymentDetail(List<MonthlyPaymentDetailQuery> manyReviewers)
{
List<PayDetailDTO> result = new List<PayDetailDTO>();
foreach (var t in manyReviewers)
{
result.Add(await GetMonthlyPaymentDetailList(t.PaymentId, t.ReviewerId, t.YearMonth));
}
return result;
}
/// <summary>
/// Financials / Payment History 列表查询接口(已经支付锁定的数据,包含调整的)[New]
/// </summary>
[HttpPost]
public async Task<PageOutput<MonthlyPaymentDTO>> GetPaymentHistoryList(PaymentQueryDTO inQuery)
{
Expression<Func<Doctor, bool>> doctorLambda = x => true;
if (!string.IsNullOrWhiteSpace(inQuery.Reviewer))
{
var reviewer = inQuery.Reviewer.Trim();
doctorLambda = doctorLambda.And(u => u.ChineseName.Contains(reviewer)
|| u.FirstName.Contains(reviewer)
|| u.LastName.Contains(reviewer)
|| u.ReviewerCode.Contains(reviewer));
}
if (inQuery.Nation != null)
{
doctorLambda = doctorLambda.And(u => u.Nation == inQuery.Nation);
}
Expression<Func<Payment, bool>> paymentLambda = x => x.IsLock && x.YearMonthDate >= inQuery.BeginMonth && x.YearMonthDate <= inQuery.EndMonth;
#region 在 payment表加 调整总计前
//var paymentQueryable = _paymentRepository.Find(paymentLambda)
// .Select(
// t => new
// {
// ReviewerId = t.DoctorId,
// t.YearMonth,
// t.PaymentUSD,
// t.PaymentCNY,
// t.AdjustPaymentCNY,
// t.AdjustPaymentUSD
// });
//Expression<Func<PaymentAdjustment, bool>> payAdjustmentLambda = x => x.IsLock && x.AdjustedYearMonth >= param.BeginMonth && x.AdjustedYearMonth <= param.EndMonth;
//var adjQueryable = _payAdjustmentRepository.GetAll()
// .Where(payAdjustmentLambda)
// .GroupBy(t => new { t.ReviewerId, t.YearMonth }).Select(g => new
// {
// g.Key.ReviewerId,
// g.Key.YearMonth,
// PaymentUSD = 0,
// PaymentCNY = 0,
// AdjustPaymentCNY = g.Sum(t => t.AdjustPaymentCNY),
// AdjustPaymentUSD = g.Sum(t => t.AdjustPaymentUSD)
// });
//var query = from pay in (from paymentCost in paymentQueryable
// join adjCost in adjQueryable on new { paymentCost.YearMonth, paymentCost.ReviewerId } equals new { adjCost.YearMonth, adjCost.ReviewerId } into a
// from adjCost in a.DefaultIfEmpty()
// select new
// {
// paymentCost.ReviewerId,
// paymentCost.PaymentUSD,
// paymentCost.PaymentCNY,
// AdjustmentCNY = adjCost == null ? 0 : adjCost.AdjustPaymentCNY,
// AdjustmentUSD = adjCost == null ? 0 : adjCost.AdjustPaymentUSD
// }
// ).Union(
// from adjCost in adjQueryable
// join paymentCost in paymentQueryable on new { adjCost.YearMonth, adjCost.ReviewerId } equals new { paymentCost.YearMonth, paymentCost.ReviewerId } into a
// from paymentCost in a.DefaultIfEmpty()
// select new
// {
// ReviewerId = adjCost.ReviewerId,
// PaymentUSD = paymentCost == null ? 0 : paymentCost.PaymentUSD,
// PaymentCNY = paymentCost == null ? 0 : paymentCost.PaymentCNY,
// AdjustmentCNY = adjCost.AdjustPaymentCNY,
// AdjustmentUSD = adjCost.AdjustPaymentUSD
// }
// )
#endregion
var query = from monthlyPay in _paymentRepository.Where(paymentLambda)
.GroupBy(t => t.DoctorId).Select(g => new
{
ReviewerId = g.Key,
PaymentUSD = g.Sum(u => u.PaymentUSD),
PaymentCNY = g.Sum(u => u.PaymentCNY),
AdjustmentCNY = g.Sum(u => u.AdjustmentCNY),
AdjustmentUSD = g.Sum(u => u.AdjustmentCNY)
})
join doctor in _doctorRepository.Where(doctorLambda) on monthlyPay.ReviewerId equals doctor.Id
select new MonthlyPaymentDTO
{
ReviewerId = doctor.Id,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
FullName= doctor.FullName,
ReviewerCode = doctor.ReviewerCode,
PaymentUSD = monthlyPay.PaymentUSD,
PaymentCNY = monthlyPay.PaymentCNY,
AdjustmentCNY = monthlyPay.AdjustmentCNY,
AdjustmentUSD = monthlyPay.AdjustmentUSD,
TotalCNY = monthlyPay.AdjustmentCNY + monthlyPay.PaymentCNY,
TotalUSD = monthlyPay.AdjustmentUSD + monthlyPay.PaymentUSD
};
return await query.ToPagedListAsync(inQuery);
//var propName = queryParam.SortField == string.Empty ? "ReviewerCode" : queryParam.SortField;
//query = queryParam.Asc ? query.OrderBy(propName).ThenBy(u => u.ReviewerCode) : query.OrderByDescending(propName).ThenBy(u => u.ReviewerCode);
//if (propName == "FirstName" || propName == "LastName")
//{
// query = queryParam.Asc ? query.OrderBy(t => t.LastName).ThenBy(t => t.FirstName)
// : query.OrderByDescending(t => t.LastName).ThenBy(t => t.FirstName);
//}
//var count = await query.CountAsync();
//query = query.Skip((queryParam.PageIndex - 1) * queryParam.PageSize).Take(queryParam.PageSize);
//var list = await query.ToListAsync();
//return new PageOutput<MonthlyPaymentDTO>(queryParam.PageIndex, queryParam.PageSize, count, list);
}
/// <summary>
/// Financials / Payment History 详情接口[New]
/// </summary>
[HttpPost]
public async Task<List<VolumeStatisticsDTO>> GetPaymentHistoryDetailList(VolumeQueryDTO param)
{
var beginDate = new DateTime(param.BeginMonth.Year, param.BeginMonth.Month, 1);
var endDate = new DateTime(param.EndMonth.Year, param.EndMonth.Month, 1);
Expression<Func<Payment, bool>> monthlyPayLambda = x => x.IsLock && x.DoctorId == param.ReviewerId && x.YearMonthDate >= beginDate && x.YearMonthDate <= endDate;
var query =
from monthlyPayment in _paymentRepository.Where(monthlyPayLambda)
select new VolumeStatisticsDTO
{
StatisticsId = monthlyPayment.Id,
Month = monthlyPayment.YearMonth,
ExchangeRate = monthlyPayment.ExchangeRate,
PaymentUSD = monthlyPayment.PaymentUSD,
PaymentCNY = monthlyPayment.PaymentCNY,
AdjustmentCNY = monthlyPayment.AdjustmentCNY,
AdjustmentUSD = monthlyPayment.AdjustmentUSD,
VolumeReward = 0
};
var payDetailList = await query.OrderBy(t => t.Month).ToListAsync();
List<Guid> statisticsIdList = payDetailList.Select(t => t.StatisticsId).ToList();
var monthlyPayDetailList = await _paymentDetailRepository.Where(u =>
statisticsIdList.Contains(u.PaymentId)).Select(t => new
{
PaymentId = t.PaymentId,
t.PaymentUSD,
t.TrialCode,
t.PaymentCNY,
t.YearMonth
}).ToListAsync();
payDetailList.ForEach(t =>
{
t.VolumeReward = monthlyPayDetailList
.Where(u => u.PaymentId == t.StatisticsId && u.TrialCode == "Volume Reward")
.Sum(k => k.PaymentUSD);
t.TrialPaymentList = monthlyPayDetailList
.Where(u => u.PaymentId == t.StatisticsId && u.TrialCode != "Volume Reward" && u.YearMonth == t.Month)
.GroupBy(u => u.TrialCode).Select(g => new TrialPaymentDTO
{
TrialPayment = g.Sum(k => k.PaymentUSD),
TrialCode = g.Key
}).ToList();
});
#region 改表之前
//var tempVolume = _costStatisticsDetailRepository.Find(u =>
// statisticsIdList.Contains(u.PaymentId)).ToList();
//foreach (var item in payDetailList)
//{
// var temp = tempVolume.Where(u => u.PaymentId == item.StatisticsId && u.TrialCode == "Volume Reward");
// var Volume = 0.0;
// foreach (var t in temp)
// {
// Volume += (t.BasePrice * t.Count);
// }
// item.VolumeReward = Volume;
// var trialCodes = tempVolume.Where(u => u.PaymentId == item.StatisticsId
// && u.TrialCode != "Volume Reward").GroupBy(u => u.TrialCode).Select(u => u.Key).Distinct();
// foreach (var trial in trialCodes)
// {
// var trialFee = 0.0;
// var aa = tempVolume.Where(u => u.PaymentId == item.StatisticsId && u.TrialCode == trial
// ).ToList();
// foreach (var a in aa)
// {
// trialFee += (a.Count * (a.BasePrice + a.PersonalAdditional + a.TrialAdditional));
// }
// item.TrialFeeList.Add(new TrialFeeViewModel
// {
// TrialCode = trial,
// TrialFee = trialFee
// });
// }
//}
#endregion
return payDetailList;
}
/// <summary>
/// Revenues列表接口收入统计[New] 0是Detail 1是按照项目 2是按照人 3按照月份
/// </summary>
[HttpPost]
public async Task<PageOutput<RevenuesDTO>> GetRevenuesStatistics(StatisticsQueryDTO queryParam)
{
var bDate = new DateTime(queryParam.BeginDate.Year, queryParam.BeginDate.Month, 1);
var eDate = new DateTime(queryParam.EndDate.Year, queryParam.EndDate.Month, 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 (Guid.Empty != queryParam.CroId && queryParam.CroId != null)
{
trialLambda = trialLambda.And(u => u.CROId == queryParam.CroId);
}
if (!string.IsNullOrWhiteSpace(queryParam.TrialCode))
{
var trialCode = queryParam.TrialCode.Trim();
trialLambda = trialLambda.And(u => u.TrialCode.Contains(trialCode));
}
//if (queryParam.AttendedReviewerType != null)
//{
// trialLambda = trialLambda.And(u => u.AttendedReviewerType == queryParam.AttendedReviewerType);
//}
Expression<Func<Doctor, bool>> doctorLambda = x => true;
if (!string.IsNullOrWhiteSpace(queryParam.Reviewer))
{
var reviewer = queryParam.Reviewer.Trim();
doctorLambda = doctorLambda.And(u => u.ChineseName.Contains(reviewer)
|| u.FirstName.Contains(reviewer)
|| u.LastName.Contains(reviewer)
|| u.ReviewerCode.Contains(reviewer));
}
if (queryParam.Nation != null)
{
doctorLambda = doctorLambda.And(u => u.Nation == queryParam.Nation);
}
List<RevenuesDTO> incomeList = new List<RevenuesDTO>();
IQueryable<RevenuesDTO>? query=null ;
var propName = string.Empty;
var count = 0;
#region 按照详细维度 ReviewId TrialId
if (queryParam.StatType == 0)
{
query = from workLoad in _workloadRepository.Where(workloadLambda)
join doctor in _doctorRepository.Where(doctorLambda)
on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.Where(trialLambda)
on workLoad.TrialId equals trial.Id
join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into ttt
from croItem in ttt.DefaultIfEmpty()
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId into c
from trialCost in c.DefaultIfEmpty()
select new RevenuesDTO
{
TrialId = workLoad.TrialId,
Cro = croItem.CROName,
ReviewerCode = doctor.ReviewerCode,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
Indication = trial.Indication,
TrialCode = trial.TrialCode,
Expedited = trial.Expedited,
CroId = trial.CROId,
Downtime = workLoad.Downtime * trialCost.Downtime,
Training = workLoad.Training * trialCost.Training,
Timepoint = workLoad.Timepoint * trialCost.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H * trialCost.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H * trialCost.TimepointIn48H,
Global = workLoad.Global * trialCost.Global,
Adjudication = workLoad.Adjudication * trialCost.Adjudication,
AdjudicationIn24H =
workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H,
YearMonth = workLoad.YearMonth,
Total = (workLoad.Downtime * trialCost.Downtime +
workLoad.Training * trialCost.Training +
workLoad.Timepoint * trialCost.Timepoint +
workLoad.TimepointIn24H * trialCost.TimepointIn24H +
workLoad.TimepointIn48H * trialCost.TimepointIn48H +
workLoad.Global * trialCost.Global +
workLoad.Adjudication * trialCost.Adjudication +
workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H +
workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H +
workLoad.RefresherTraining * trialCost.RefresherTraining
)
};
//处理排序字段
propName = queryParam.SortField == "" ? "ReviewerCode" : queryParam.SortField;
}
//按照项目维度
if (queryParam.StatType == 1)
{
var workloadQuery = from workLoad in _workloadRepository.Where(workloadLambda)
group workLoad by workLoad.TrialId
into gWorkLoad
select new
{
TrialId = gWorkLoad.Key,
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),
};
query = from workLoad in workloadQuery
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId
into c
from trialCost in c.DefaultIfEmpty()
join trial in _trialRepository.Where(trialLambda) on workLoad.TrialId equals trial.Id
join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into ttt
from croItem in ttt.DefaultIfEmpty()
select new RevenuesDTO
{
TrialId = trial.Id,
Indication = trial.Indication,
TrialCode = trial.TrialCode,
Expedited = trial.Expedited,
CroId = trial.CROId,
Cro = croItem.CROName,
Training = workLoad.Training * trialCost.Training,
Timepoint = workLoad.Timepoint * trialCost.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H * trialCost.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H * trialCost.TimepointIn48H,
Adjudication = workLoad.Adjudication * trialCost.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H,
Global = workLoad.Global * trialCost.Global,
Downtime = workLoad.Downtime * trialCost.Downtime,
Total = (workLoad.Downtime * trialCost.Downtime +
workLoad.Training * trialCost.Training +
workLoad.Timepoint * trialCost.Timepoint +
workLoad.TimepointIn24H * trialCost.TimepointIn24H +
workLoad.TimepointIn48H * trialCost.TimepointIn48H +
workLoad.Global * trialCost.Global +
workLoad.Adjudication * trialCost.Adjudication +
workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H +
workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H +
workLoad.RefresherTraining * trialCost.RefresherTraining
)
};
//处理排序字段
propName = queryParam.SortField == "" ? "TrialCode" : queryParam.SortField;
}
//按照人的维度
if (queryParam.StatType == 2)
{
var workloadQuery = from workLoad in _workloadRepository.Where(workloadLambda)
join doctor in _doctorRepository.Where(doctorLambda)
on workLoad.DoctorId equals doctor.Id
join trial in _trialRepository.Where(trialLambda) on workLoad.TrialId equals trial.Id
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId into c
from trialCost in c.DefaultIfEmpty()
select new
{
DoctorId = workLoad.DoctorId,
Downtime = workLoad.Downtime * trialCost.Downtime,
Training = workLoad.Training * trialCost.Training,
Timepoint = workLoad.Timepoint * trialCost.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H * trialCost.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H * trialCost.TimepointIn48H,
Global = workLoad.Global * trialCost.Global,
Adjudication = workLoad.Adjudication * trialCost.Adjudication,
AdjudicationIn24H =
workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H,
RefresherTraining = workLoad.RefresherTraining * trialCost.RefresherTraining,
ReviewerCode = doctor.ReviewerCode,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
};
query = workloadQuery.GroupBy(t => new { t.DoctorId, t.ReviewerCode, t.ChineseName, t.FirstName, t.LastName }).Select(gWorkLoad => new RevenuesDTO
{
ReviewerCode = gWorkLoad.Key.ReviewerCode,
ChineseName = gWorkLoad.Key.ChineseName,
FirstName = gWorkLoad.Key.FirstName,
LastName = gWorkLoad.Key.LastName,
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),
Total = gWorkLoad.Sum(t => t.Downtime) +
gWorkLoad.Sum(t => t.Training) +
gWorkLoad.Sum(t => t.Timepoint) +
gWorkLoad.Sum(t => t.TimepointIn24H) +
gWorkLoad.Sum(t => t.TimepointIn48H) +
gWorkLoad.Sum(t => t.Global) +
gWorkLoad.Sum(t => t.Adjudication) +
gWorkLoad.Sum(t => t.AdjudicationIn24H) +
gWorkLoad.Sum(t => t.AdjudicationIn48H) +
gWorkLoad.Sum(t => t.RefresherTraining)
});
propName = queryParam.SortField == string.Empty ? "ReviewerCode" : queryParam.SortField;
}
//按照月份维度
if (queryParam.StatType == 3)
{
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
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId into c
from trialCost in c.DefaultIfEmpty()
select new
{
workLoad.YearMonth,
Downtime = workLoad.Downtime * trialCost.Downtime,
Training = workLoad.Training * trialCost.Training,
Timepoint = workLoad.Timepoint * trialCost.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H * trialCost.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H * trialCost.TimepointIn48H,
Global = workLoad.Global * trialCost.Global,
Adjudication = workLoad.Adjudication * trialCost.Adjudication,
AdjudicationIn24H =
workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H,
RefresherTraining = workLoad.RefresherTraining * trialCost.RefresherTraining,
};
query = workloadQuery.GroupBy(t => t.YearMonth).Select(gWorkLoad => new RevenuesDTO
{
YearMonth = gWorkLoad.Key,
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),
Total = gWorkLoad.Sum(t => t.Downtime) +
gWorkLoad.Sum(t => t.Training) +
gWorkLoad.Sum(t => t.Timepoint) +
gWorkLoad.Sum(t => t.TimepointIn24H) +
gWorkLoad.Sum(t => t.TimepointIn48H) +
gWorkLoad.Sum(t => t.Global) +
gWorkLoad.Sum(t => t.Adjudication) +
gWorkLoad.Sum(t => t.AdjudicationIn24H) +
gWorkLoad.Sum(t => t.AdjudicationIn48H) +
gWorkLoad.Sum(t => t.RefresherTraining)
});
propName = queryParam.SortField == string.Empty ? "YearMonth" : queryParam.SortField;
}
#endregion
//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);
//}
//非详细 只用单字段排序
if (queryParam.StatType != 0)
{
query = queryParam.Asc ? query.OrderBy(propName) : query.OrderBy(propName + " desc");
}
//详情 多字段排序
if (queryParam.StatType == 0)
{
query = queryParam.Asc ? query.OrderBy(propName).ThenBy(t => t.TrialId).ThenBy(t => t.YearMonth).ThenBy(t => t.ReviewerCode) :
query.OrderBy(propName + " desc").ThenBy(t => t.TrialId).ThenBy(t => t.YearMonth).ThenBy(t => t.ReviewerCode)
;
}
count = query!.Count();
query = query!.Skip((queryParam.PageIndex - 1) * queryParam.PageSize).Take(queryParam.PageSize);
incomeList = await query.ToListAsync();
#region 处理缺失项目价格 按照医生 或者月份维度
if (queryParam.StatType == 2 || queryParam.StatType == 3)
{
var hasIncomePriceTrialIds = await _trialRevenuePriceRepository.Select(t => t.TrialId).ToListAsync();
workloadLambda = workloadLambda.And(t => !hasIncomePriceTrialIds.Contains(t.TrialId));
var doctorMissingTrialCodesQuery = (from workLoad in _workloadRepository.Where(workloadLambda)
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new
{
DoctorId = workLoad.DoctorId,
Month = workLoad.YearMonth,
TrialCode = trial.TrialCode
}).Distinct();
var doctorMissingTrialCodes = ((await doctorMissingTrialCodesQuery.ToListAsync()).GroupBy(t => t.DoctorId).Select(g => new
{
DoctorId = g.Key,
TrialCodes = g.Select(u => u.TrialCode).Distinct().ToList()
})).ToList();
var monthMissingTrialCode = ((await doctorMissingTrialCodesQuery.ToListAsync()).GroupBy(t => t.Month).Select(g => new
{
Month = g.Key,
TrialCodes = g.Select(u => u.TrialCode).Distinct().ToList()
})).ToList();
incomeList.ForEach(income =>
{
var doctor = doctorMissingTrialCodes.FirstOrDefault(t => t.DoctorId == income.Id);
var month = monthMissingTrialCode.FirstOrDefault(t => t.Month == income.YearMonth);
if (queryParam.StatType == 2)
{
income.MissingTrialCodes = doctor == null ? new List<string>() : doctor.TrialCodes;
}
else
{
income.MissingTrialCodes = month == null ? new List<string>() : month.TrialCodes;
}
});
}
if (queryParam.StatType == 0 || queryParam.StatType == 1)
{
incomeList.ForEach(income =>
{
List<string> temp = new List<string>();
if (Math.Abs(income.Total) < 0.001m)
{
temp.Add(income.TrialCode);
income.MissingTrialCodes = temp;
}
});
}
#endregion
return new PageOutput<RevenuesDTO>(queryParam.PageIndex, queryParam.PageSize, count, incomeList);
}
/// <summary>
/// 收入支出分析接口,按照项目维度分析统计
/// </summary>
[HttpPost]
public async Task<List<TrialAnalysisDTO>> GetTrialAnalysisList(TrialAnalysisQueryDTO 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<Workload, bool>> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm;
Expression<Func<Trial, bool>> trialLambda = x => true;
if (Guid.Empty != param.CroId && param.CroId != null)
{
trialLambda = trialLambda.And(u => u.CROId == param.CroId);
}
if (!string.IsNullOrWhiteSpace(param.TrialCode))
{
var trialCode = param.TrialCode.Trim();
trialLambda = trialLambda.And(u => u.TrialCode.Contains(trialCode));
}
//if (param.AttendedReviewerType != null)
//{
// trialLambda = trialLambda.And(u => u.AttendedReviewerType == param.AttendedReviewerType);
//}
var lockedPaymentIdAndYearMonth = _paymentRepository.Where(t => t.IsLock && t.YearMonthDate >= bDate && t.YearMonthDate <= eDate).Select(t => new { PaymentId = t.Id, t.YearMonth, t.DoctorId });
var costStatisticsIds = await lockedPaymentIdAndYearMonth.Select(t => t.PaymentId).ToListAsync();
var lockedDoctorIdAndYearMonthQueryable = lockedPaymentIdAndYearMonth.Select(t => new { t.YearMonth, t.DoctorId });
////工作量过滤查询 锁定得月份
//workloadLambda = workloadLambda.And(x => lockedDoctorIdAndYearMonthQueryable.Contains());
var trialPayQuery = from costStatisticsDetail in _paymentDetailRepository.AsQueryable()
.Where(t => costStatisticsIds.Contains(t.PaymentId) && t.TrialCode != "Volume Reward")
group costStatisticsDetail by costStatisticsDetail.TrialId
into g
select new
{
TrialId = g.Key,
PaymentUSD = g.Sum(t => t.PaymentUSD)
};
var workloadQuery = from workLoad in _workloadRepository.Where(workloadLambda)
join lockedDoctorAndMonth in lockedDoctorIdAndYearMonthQueryable on new { workLoad.DoctorId, YearMonth = workLoad.YearMonth } equals new { lockedDoctorAndMonth.DoctorId, lockedDoctorAndMonth.YearMonth }
group workLoad by workLoad.TrialId
into gWorkLoad
select new
{
TrialId = gWorkLoad.Key,
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)
};
var workloadIncomeQuery = from workLoad in workloadQuery
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId
into c
from trialCost in c.DefaultIfEmpty()
join trial in _trialRepository.Where(trialLambda) on workLoad.TrialId equals trial.Id into t
from trial in t.DefaultIfEmpty()
join cro in _croRepository.AsQueryable() on trial.CROId equals cro.Id into ttt
from croItem in ttt.DefaultIfEmpty()
select new TrialAnalysisDTO
{
TrialId = trial.Id,
Indication = trial.Indication,
TrialCode = trial.TrialCode,
Expedited = trial.Expedited,
Cro = croItem == null ? "" : croItem.CROName,
Type = "Trial",
RevenusUSD = (workLoad.Downtime * trialCost.Downtime) +
(workLoad.Training * trialCost.Training) +
(workLoad.Timepoint * trialCost.Timepoint)
+ (workLoad.TimepointIn24H * trialCost.TimepointIn24H)
+ (workLoad.TimepointIn48H * trialCost.TimepointIn48H)
+ (workLoad.Adjudication * trialCost.Adjudication)
+ (workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H)
+ (workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H)
+ (workLoad.Global * trialCost.Global),
};
var trialPayList = await trialPayQuery.OrderBy(t => t.PaymentUSD).ToListAsync();
var workloadIncomeList = await workloadIncomeQuery.ToListAsync();
var returnList = workloadIncomeList;
returnList.ForEach(t =>
{
var pay = trialPayList.FirstOrDefault(u => u.TrialId == t.TrialId);
t.PaymentUSD = pay == null ? 0 : pay.PaymentUSD;
});
if ((Guid.Empty == param.CroId || null == param.CroId) && string.IsNullOrWhiteSpace(param.TrialCode))
{
var volumeReward = _paymentDetailRepository.AsQueryable()
.Where(t => costStatisticsIds.Contains(t.PaymentId) && t.TrialCode == "Volume Reward")
.Sum(t => (decimal?)t.PaymentUSD) ?? 0;
var adjustment = _payAdjustmentRepository.AsQueryable()
.Where(t => t.YearMonthDate >= param.BeginDate
&& t.YearMonthDate <= param.EndDate && t.IsLock)
.Sum(u => (decimal?)u.AdjustmentUSD) ?? 0;
returnList.Add(new TrialAnalysisDTO()
{
Type = "Volume Reward",
RevenusUSD = 0,
PaymentUSD = volumeReward
});
returnList.Add(new TrialAnalysisDTO()
{
Type = "Adjustment",
RevenusUSD = 0,
PaymentUSD = adjustment
});
}
return returnList;
}
/// <summary>
/// 收入支出分析接口,按照医生维度分析统计
/// </summary>
[HttpPost]
public async Task<List<ReviewerAnalysisDTO>> GetReviewerAnalysisList(AnalysisQueryDTO param)
{
var beginDate = new DateTime(param.BeginDate.Year, param.BeginDate.Month, 1);
var endDate = new DateTime(param.EndDate.Year, param.EndDate.Month, 1);
Expression<Func<Workload, bool>> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm;
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 (param.Nation != null)
{
doctorLambda = doctorLambda.And(u => u.Nation == param.Nation);
}
var lockedPaymentIdAndYearMonth = _paymentRepository.Where(t => t.IsLock && t.YearMonthDate >= param.BeginDate && t.YearMonthDate <= param.EndDate).Select(t => new { PaymentId = t.Id, t.YearMonth, t.DoctorId });
var lockedDoctorIdAndYearMonthQueryable = lockedPaymentIdAndYearMonth.Select(t => new { t.YearMonth, t.DoctorId });
Expression<Func<Payment, bool>> monthlyPayLambda = x => x.IsLock && x.YearMonthDate >= beginDate && x.YearMonthDate <= endDate;
var payQuery =
from monthlyPayment in _paymentRepository.Where(monthlyPayLambda)
.GroupBy(t => t.DoctorId).Select(g => new
{
ReviewerId = g.Key,
PaymentUSD = g.Sum(u => u.PaymentUSD),
PaymentCNY = g.Sum(u => u.PaymentCNY),
AdjustmentCNY = g.Sum(u => u.AdjustmentCNY),
AdjustmentUSD = g.Sum(u => u.AdjustmentUSD)
})
join doctor in _doctorRepository.Where(doctorLambda) on monthlyPayment.ReviewerId equals doctor.Id
select new MonthlyPaymentDTO
{
ReviewerId = doctor.Id,
ChineseName = doctor.ChineseName,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
ReviewerCode = doctor.ReviewerCode,
PaymentUSD = monthlyPayment.PaymentUSD,
PaymentCNY = monthlyPayment.PaymentCNY,
AdjustmentCNY = monthlyPayment.AdjustmentCNY,
AdjustmentUSD = monthlyPayment.AdjustmentUSD,
TotalUSD = monthlyPayment.AdjustmentUSD + monthlyPayment.PaymentUSD,
TotalCNY = monthlyPayment.AdjustmentCNY + monthlyPayment.PaymentCNY,
};
//获取工作量收入 workloadLambda 已经加入过滤 payment锁定月份
////工作量过滤查询 锁定得月份
var workloadIncomeQuery = from workLoad in _workloadRepository.Where(workloadLambda)
join doctor in _doctorRepository.Where(doctorLambda)
on workLoad.DoctorId equals doctor.Id
join lockedDoctorAndMonth in lockedDoctorIdAndYearMonthQueryable on new { workLoad.DoctorId, workLoad.YearMonth } equals new { lockedDoctorAndMonth.DoctorId, lockedDoctorAndMonth.YearMonth }
join trialCost in _trialRevenuePriceRepository.AsQueryable() on workLoad.TrialId equals trialCost.TrialId into c
from trialCost in c.DefaultIfEmpty()
select new
{
DoctorId = workLoad.DoctorId,
Downtime = workLoad.Downtime * trialCost.Downtime,
Training = workLoad.Training * trialCost.Training,
Timepoint = workLoad.Timepoint * trialCost.Timepoint,
TimepointIn24H = workLoad.TimepointIn24H * trialCost.TimepointIn24H,
TimepointIn48H = workLoad.TimepointIn48H * trialCost.TimepointIn48H,
Global = workLoad.Global * trialCost.Global,
Adjudication = workLoad.Adjudication * trialCost.Adjudication,
AdjudicationIn24H = workLoad.AdjudicationIn24H * trialCost.AdjudicationIn24H,
AdjudicationIn48H = workLoad.AdjudicationIn48H * trialCost.AdjudicationIn48H
};
//工作量收入按照人分组统计
var workloadIncomeList = await workloadIncomeQuery.GroupBy(t => t.DoctorId).Select(gWorkLoad => new
{
DoctorId = gWorkLoad.Key,
//TrialId = Guid.Empty,
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),
}).ToListAsync();
var workloadPayList = payQuery.ToList();
//var workloadIncomeList = workloadIncomeQuery.ToList();
var returnList = new List<ReviewerAnalysisDTO>();
#region 处理找到缺失的项目
//有项目价格的trial Id 集合
var hasIncomePriceTrialIds = await _trialRevenuePriceRepository.Select(t => t.TrialId).ToListAsync();
workloadLambda = workloadLambda.And(t => !hasIncomePriceTrialIds.Contains(t.TrialId));
var doctorMissingTrialCodesQuery = (from workLoad in _workloadRepository.Where(workloadLambda)
join trial in _trialRepository.AsQueryable() on workLoad.TrialId equals trial.Id
select new
{
DoctorId = workLoad.DoctorId,
TrialCode = trial.TrialCode
}).Distinct();
var doctorMissingTrialCodes = ((await doctorMissingTrialCodesQuery.ToListAsync()).GroupBy(t => t.DoctorId).Select(g => new
{
DoctorId = g.Key,
TrialCodes = g.Select(u => u.TrialCode).ToList()
})).ToList();
#endregion
workloadPayList.ForEach(pay =>
{
var doctor = workloadIncomeList.FirstOrDefault(t => t.DoctorId == pay.ReviewerId);
var doctorMissingCode = doctorMissingTrialCodes.FirstOrDefault(t => t.DoctorId == pay.ReviewerId);
returnList.Add(new ReviewerAnalysisDTO()
{
ReviewerId = pay.ReviewerId,
ChineseName = pay.ChineseName,
FirstName = pay.FirstName,
LastName = pay.LastName,
ReviewerCode = pay.ReviewerCode,
PaymentUSD = pay.PaymentUSD + pay.AdjustmentUSD,
//付费表的医生数量肯定事全的 工作量的不一定全 (只有调整)
RevenusUSD = doctor != null
? doctor.Adjudication + doctor.AdjudicationIn24H + doctor.AdjudicationIn48H + doctor.Global +
doctor.Downtime + doctor.Training +
doctor.Timepoint + doctor.TimepointIn24H + doctor.TimepointIn48H
: 0,
MissingTrialCodes = doctorMissingCode != null ? doctorMissingCode.TrialCodes : new List<string>()
});
});
return returnList.OrderBy(t => t.ReviewerCode).ToList();
}
/// <summary>
/// 获取劳务费用列表
/// </summary>
[HttpPost]
public async Task<List<LaborPayment>> GetLaborPaymentList(List<Guid> paymentIds)
{
var query = from payment in _paymentRepository.Where(t => paymentIds.Contains(t.Id))
join reviewer in _doctorRepository.AsQueryable() on payment.DoctorId equals reviewer.Id
join payInfo in _doctorPayInfoRepository.AsQueryable() on payment.DoctorId equals payInfo.DoctorId
select new LaborPayment()
{
ChineseName = reviewer.ChineseName,
FirstName = reviewer.FirstName,
LastName = reviewer.LastName,
ResidentId = payInfo.IDCard,
PaymentCNY = payment.PaymentCNY + payment.AdjustmentCNY,
YearMonth = payment.YearMonth,
Phone = reviewer.Phone,
AccountNumber = payInfo.BankCardNumber,
Bank = payInfo.BankName
//TaxCNY = payment.TaxCNY,
//ActuallyPaidCNY = payment.ActuallyPaidCNY,
//BankTransferCNY = payment.BankTransferCNY,
};
var result = await query.ToListAsync();
result.ForEach(t =>
{
t.TaxCNY =GetTax2(t.PaymentCNY);
t.ActuallyPaidCNY = t.PaymentCNY - t.TaxCNY;
t.BankTransferCNY = t.PaymentCNY - t.TaxCNY;
});
return result;
}
/// <summary>
/// 锁定医生费用,锁定后,无法变更该医生对应月份的费用和工作量[New]
/// </summary>
[HttpPost]
public async Task<IResponseOutput> LockMonthlyPayment(LockPaymentDTO param)
{
var reviewerIds = param.ReviewerIdList;
var yearMonth = param.Month.ToString("yyyy-MM");
var isLock = param.IsLock;
var paymentLockSuccess = await _paymentRepository.BatchUpdateNoTrackingAsync(u => reviewerIds.Contains(u.DoctorId) && u.YearMonth == yearMonth, t => new Payment
{
IsLock = isLock
});
var adjustmentLockSuccess = await _payAdjustmentRepository.BatchUpdateNoTrackingAsync(
t => t.YearMonth == yearMonth && reviewerIds.Contains(t.ReviewerId), u =>
new PaymentAdjustment()
{
IsLock = true
});
await _doctorWorkloadRepository.BatchUpdateNoTrackingAsync(u => reviewerIds.Contains(u.DoctorId) && u.YearMonth == yearMonth,
t => new Workload { IsLock = true });
return ResponseOutput.Result(paymentLockSuccess || adjustmentLockSuccess);
}
[NonDynamicMethod]
private static decimal GetTax2(decimal paymentCNY)
{
if (paymentCNY >= 0 && paymentCNY <= 800)
{
return 0;
}
var calculateTaxPart = paymentCNY <= 4000 ? paymentCNY - 800 : paymentCNY * (1 - 0.2m);
if (calculateTaxPart <= 20000)
{
return calculateTaxPart * 0.2m;
}
else if (calculateTaxPart > 20000 && calculateTaxPart <= 50000)
{
return calculateTaxPart * 0.3m - 2000;
}
else
{
return calculateTaxPart * 0.4m - 7000;
}
}
}
}