1305 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			1305 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			C#
		
	
	
| using IRaCIS.Core.Infrastructure.ExpressionExtend;
 | ||
| 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 Microsoft.AspNetCore.Mvc;
 | ||
| using Panda.DynamicWebApi.Attributes;
 | ||
| 
 | ||
| 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 queryParam)
 | ||
|         {
 | ||
|             //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 = queryParam.StatisticsDate.ToString("yyyy-MM");
 | ||
| 
 | ||
|             Expression<Func<Doctor, bool>> doctorLambda = x => true;
 | ||
|             if (!string.IsNullOrWhiteSpace(queryParam.KeyWord))
 | ||
|             {
 | ||
|                 var reviewer = queryParam.KeyWord.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);
 | ||
|             }
 | ||
| 
 | ||
|             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
 | ||
|                                            };
 | ||
| 
 | ||
|             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();
 | ||
| 
 | ||
| 
 | ||
|             #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
 | ||
| 
 | ||
|             return new PageOutput<PaymentModel>(queryParam.PageIndex, queryParam.PageSize, count, costStatisticsList);
 | ||
|         }
 | ||
| 
 | ||
|         /// <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 queryParam)
 | ||
|         {
 | ||
|             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);
 | ||
|             }
 | ||
| 
 | ||
|             Expression<Func<Payment, bool>> paymentLambda = x => x.IsLock && x.YearMonthDate >= queryParam.BeginMonth && x.YearMonthDate <= queryParam.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,
 | ||
|                             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
 | ||
|                         };
 | ||
|             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.OrderByDescending(propName);
 | ||
|             }
 | ||
|             //详情  多字段排序
 | ||
|             if (queryParam.StatType == 0)
 | ||
|             {
 | ||
|                 query = queryParam.Asc ? query.OrderBy(propName).ThenBy(t => t.TrialId).ThenBy(t => t.YearMonth).ThenBy(t => t.ReviewerCode) :
 | ||
|                         query.OrderByDescending(propName).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.UpdateFromQueryAsync(u => reviewerIds.Contains(u.DoctorId) && u.YearMonth == yearMonth, t => new Payment
 | ||
|             {
 | ||
|                 IsLock = isLock
 | ||
|             });
 | ||
| 
 | ||
|             var adjustmentLockSuccess = await _payAdjustmentRepository.UpdateFromQueryAsync(
 | ||
|                 t => t.YearMonth == yearMonth && reviewerIds.Contains(t.ReviewerId), u =>
 | ||
|                     new PaymentAdjustment()
 | ||
|                     {
 | ||
|                         IsLock = true
 | ||
|                     });
 | ||
|            await  _doctorWorkloadRepository.UpdateFromQueryAsync(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;
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
|     }
 | ||
| } |