using AutoMapper; using AutoMapper.QueryableExtensions; using IRaCIS.Application.ExpressionExtend; using IRaCIS.Application.Interfaces; using IRaCIS.Application.ViewModels; using IRaCIS.Application.ViewModels.Pay; using IRaCIS.Core.Application.Contracts.RequestAndResponse; using IRaCIS.Core.Domain.Share; using IRaCIS.Infra.Data.ExpressionExtend; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using IRaCIS.Core.Domain.Interfaces; using IRaCIS.Core.Domain.Models; using System.IO; using MiniExcelLibs; using Microsoft.AspNetCore.Http; using System.IO.Compression; namespace IRaCIS.Application.Services { public class FinancialService : IPaymentService { private readonly IPaymentRepository _paymentRepository; private readonly IReviewerPayInfoRepository _doctorPayInfoRepository; private readonly ITrialRepository _trialRepository; private readonly IDoctorRepository _doctorRepository; private readonly IExchangeRateService _exchangeRateService; private readonly IRankPriceRepository _rankPriceRepository; private readonly IPaymentDetailRepository _paymentDetailRepository; private readonly ICRORepository _croRepository; private readonly IWorkloadRepository _workloadRepository; private readonly ITrialRevenuesPriceRepository _trialRevenuePriceRepository; private readonly IPaymentAdjustmentRepository _payAdjustmentRepository; private readonly IEnrollRepository _enrollRepository; private readonly ITrialPaymentPriceRepository _TrialPaymentPriceRepository; private readonly IMapper _mapper; public FinancialService(IPaymentRepository costStatisticsRepository, IReviewerPayInfoRepository doctorPayInfoRepository, ITrialRepository trialRepository, IDoctorRepository doctorRepository, IExchangeRateService exchangeRateService, IRankPriceRepository rankPriceRepository, IPaymentDetailRepository costStatisticsDetailRepository, ICRORepository croCompanyRepository, IWorkloadRepository workloadRepository, ITrialRevenuesPriceRepository trialCostRepository, IEnrollRepository enrollRepository, ITrialPaymentPriceRepository trialPaymentPriceRepository, IPaymentAdjustmentRepository costAdjustmentRepository, IMapper mapper ) { _TrialPaymentPriceRepository = trialPaymentPriceRepository; _enrollRepository = enrollRepository; _paymentRepository = costStatisticsRepository; _doctorPayInfoRepository = doctorPayInfoRepository; _trialRepository = trialRepository; _doctorRepository = doctorRepository; this._exchangeRateService = exchangeRateService; _rankPriceRepository = rankPriceRepository; _paymentDetailRepository = costStatisticsDetailRepository; _croRepository = croCompanyRepository; _workloadRepository = workloadRepository; _trialRevenuePriceRepository = trialCostRepository; _payAdjustmentRepository = costAdjustmentRepository; _mapper = mapper; } /// /// Financials /MonthlyPayment 列表查询接口 /// public PageOutput GetMonthlyPaymentList(MonthlyPaymentQueryDTO queryParam) { //var year = queryParam.StatisticsDate.Year; //var month = queryParam.StatisticsDate.Month; //var searchBeginDateTime = queryParam.StatisticsDate; //Expression> 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> 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.Code.Contains(reviewer)); } if (queryParam.Nation != null) { doctorLambda = doctorLambda.And(u => u.Nation == queryParam.Nation); } var costStatisticsQueryable = from monthlyPayment in _paymentRepository.GetAll().Where(t => t.YearMonth == yearMonth) join payInfo in _doctorPayInfoRepository.GetAll() on monthlyPayment.DoctorId equals payInfo.DoctorId into cc from payInfo in cc.DefaultIfEmpty() join doctor in _doctorRepository.GetAll().Where(doctorLambda) on monthlyPayment.DoctorId equals doctor.Id join rankPrice in _rankPriceRepository.GetAll() on payInfo.RankId equals rankPrice.Id into dd from rankPriceItem in dd.DefaultIfEmpty() select new PaymentViewModel() { 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, PaymentMethod= monthlyPayment.PaymentMethod, Code = doctor.Code, 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 = costStatisticsQueryable.ToList(); #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(queryParam.PageIndex, queryParam.PageSize, count, costStatisticsList); } /// /// Financials / MonthlyPaymentDetail 详情查询接口 /// public PayDetailDTO GetMonthlyPaymentDetailList(Guid paymentId, Guid reviewerId, DateTime yearMonth) { var returnModel = new PayDetailDTO(); var yearMonthStr = yearMonth.ToString("yyyy-MM"); List detailList = new List(); //有详细表的数据 先查出来 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.GetAll() .Where(t => t.PaymentId == paymentId) .OrderBy(t => t.ShowCodeOrder).ThenBy(t => t.ShowTypeOrder).ProjectTo(_mapper.ConfigurationProvider).ToList(); //detailList =(from pay in _paymentDetailRepository.GetAll().Where(t => t.PaymentId == paymentId) // //join enroll in _enrollRepository.GetAll() on new { pay.DoctorId, pay.TrialId } equals new { enroll.DoctorId, enroll.TrialId } // //join price in _TrialPaymentPriceRepository.GetAll() 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, // PaymentType=pay.PaymentType, // PersonalAdditional = pay.PersonalAdditional, // TrialAdditional = pay.TrialAdditional, // TrialCode = pay.TrialCode, // PaymentCNY = pay.PaymentCNY, // DoctorId = pay.DoctorId, // ExchangeRate = pay.ExchangeRate, // //IsNewTrial = price.IsNewTrial, // // NewPersonalAdditional = enroll.AdjustmentMultiple, // Count=pay.Count, // }).ToList(); } //费用调整 //_payAdjustmentRepository.Where(t => t.YearMonth == yearMonthStr && t.ReviewerId == reviewerId) var adjList = (from costAdjustment in _payAdjustmentRepository.GetAll().Where(t => t.YearMonth == yearMonthStr && t.ReviewerId == reviewerId) //join enroll in _enrollRepository.GetAll()on new { costAdjustment.ReviewerId, costAdjustment.TrialId } equals new { ReviewerId = enroll.DoctorId, enroll.TrialId } //join price in _TrialPaymentPriceRepository.GetAll() 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, }).ToList(); 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.OrderBy(x=>x.ShowCodeOrder).ThenBy(x=>x.ShowTypeOrder).ToList(); var doctorId = returnModel.DetailList.FirstOrDefault()?.DoctorId; var query = from doctor in _doctorRepository.GetAll() .Where(t => t.Id == doctorId) join payInfo in _doctorPayInfoRepository.GetAll() on doctor.Id equals payInfo.DoctorId join rank in _rankPriceRepository.GetAll() on payInfo.RankId equals rank.Id select new DoctorPayInfo() { Code = doctor.Code, ChineseName = doctor.ChineseName, FirstName = doctor.FirstName, LastName = doctor.LastName, Phone = doctor.Phone, DoctorId = doctor.Id, PayTitle = rank.RankName, YearMonth = yearMonthStr }; returnModel.DoctorInfo = query.FirstOrDefault(); return returnModel; } public List GetReviewersMonthlyPaymentDetail(List manyReviewers) { List result = new List(); manyReviewers.ForEach(t => result.Add(GetMonthlyPaymentDetailList(t.PaymentId, t.ReviewerId, t.YearMonth))); return result; } /// /// Financials / Payment History 列表查询接口 /// public PageOutput GetPaymentHistoryList(PaymentQueryDTO queryParam) { Expression> 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.Code.Contains(reviewer)); } if (queryParam.Nation != null) { doctorLambda = doctorLambda.And(u => u.Nation == queryParam.Nation); } Expression> paymentLambda = x => x.IsLock && x.YearMonthDate >= queryParam.BeginMonth && x.YearMonthDate <= queryParam.EndMonth; #region 在 payment表加 调整总计前 //var paymentQueryable = _paymentRepository.GetAll().Where(paymentLambda) // .Select( // t => new // { // ReviewerId = t.DoctorId, // t.YearMonth, // t.PaymentUSD, // t.PaymentCNY, // t.AdjustPaymentCNY, // t.AdjustPaymentUSD // }); //Expression> 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.GetAll().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.Find(doctorLambda) on monthlyPay.ReviewerId equals doctor.Id select new MonthlyPaymentDTO { ReviewerId = doctor.Id, ChineseName = doctor.ChineseName, FirstName = doctor.FirstName, LastName = doctor.LastName, ReviewerCode = doctor.Code, 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 = query.Count(); query = query.Skip((queryParam.PageIndex - 1) * queryParam.PageSize).Take(queryParam.PageSize); var list = query.ToList(); return new PageOutput(queryParam.PageIndex, queryParam.PageSize, count, list); } /// /// Financials / Payment History 详情接口 /// public List 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> monthlyPayLambda = x => x.IsLock && x.DoctorId == param.ReviewerId && x.YearMonthDate >= beginDate && x.YearMonthDate <= endDate; var query = from monthlyPayment in _paymentRepository.Find(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 = query.OrderBy(t => t.Month).ToList(); List statisticsIdList = payDetailList.Select(t => t.StatisticsId).ToList(); var monthlyPayDetailList = _paymentDetailRepository.Find(u => statisticsIdList.Contains(u.PaymentId)).Select(t => new { PaymentId = t.PaymentId, t.PaymentUSD, t.TrialCode, t.PaymentCNY, t.YearMonth }).ToList(); 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; } /// /// Financials / Revenues 列表查询接口 /// public PageOutput GetRevenuesList(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> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm; workloadLambda = workloadLambda.And(x => x.WorkTime >= bDate && x.WorkTime <= eDate); Expression> 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.Code.Contains(trialCode)); } if (queryParam.AttendedReviewerType != null) { trialLambda = trialLambda.And(u => u.AttendedReviewerType == queryParam.AttendedReviewerType); } Expression> 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.Code.Contains(reviewer)); } if (queryParam.Nation != null) { doctorLambda = doctorLambda.And(u => u.Nation == queryParam.Nation); } List incomeList = new List(); IQueryable query = default; var propName = string.Empty; var count = 0; #region 按照详细维度 ReviewId TrialId if (queryParam.StatType == 0) { query = from workLoad in _workloadRepository.GetAll().Where(workloadLambda) join doctor in _doctorRepository.Find(doctorLambda) on workLoad.DoctorId equals doctor.Id join trial in _trialRepository.Find(trialLambda) on workLoad.TrialId equals trial.Id join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into ttt from croItem in ttt.DefaultIfEmpty() join trialCost in _trialRevenuePriceRepository.GetAll() on workLoad.TrialId equals trialCost.TrialId into c from trialCost in c.DefaultIfEmpty() select new RevenuesDTO { TrialId = workLoad.TrialId, Cro = croItem.CROName, ReviewerCode = doctor.Code, ChineseName = doctor.ChineseName, FirstName = doctor.FirstName, LastName = doctor.LastName, Indication = trial.Indication, TrialCode = trial.Code, 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.GetAll().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.GetAll() on workLoad.TrialId equals trialCost.TrialId into c from trialCost in c.DefaultIfEmpty() join trial in _trialRepository.Find(trialLambda) on workLoad.TrialId equals trial.Id join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into ttt from croItem in ttt.DefaultIfEmpty() select new RevenuesDTO { TrialId = trial.Id, Indication = trial.Indication, TrialCode = trial.Code, 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.GetAll().Where(workloadLambda) join doctor in _doctorRepository.Find(doctorLambda) on workLoad.DoctorId equals doctor.Id join trial in _trialRepository.Find(trialLambda) on workLoad.TrialId equals trial.Id join trialCost in _trialRevenuePriceRepository.GetAll() 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.Code, 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.GetAll().Where(workloadLambda) join trial in _trialRepository.Find(trialLambda) on workLoad.TrialId equals trial.Id join doctor in _doctorRepository.Find(doctorLambda) on workLoad.DoctorId equals doctor.Id join trialCost in _trialRevenuePriceRepository.GetAll() 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 = query.ToList(); #region 处理缺失项目价格 按照医生 或者月份维度 if (queryParam.StatType == 2 || queryParam.StatType == 3) { var hasIncomePriceTrialIds = _trialRevenuePriceRepository.GetAll().Select(t => t.TrialId).ToList(); workloadLambda = workloadLambda.And(t => !hasIncomePriceTrialIds.Contains(t.TrialId)); var doctorMissingTrialCodesQuery = (from workLoad in _workloadRepository.GetAll().Where(workloadLambda) join trial in _trialRepository.GetAll() on workLoad.TrialId equals trial.Id select new { DoctorId = workLoad.DoctorId, Month = workLoad.YearMonth, TrialCode = trial.Code }).Distinct(); var doctorMissingTrialCodes = (doctorMissingTrialCodesQuery.ToList().GroupBy(t => t.DoctorId).Select(g => new { DoctorId = g.Key, TrialCodes = g.Select(u => u.TrialCode).Distinct().ToList() })).ToList(); var monthMissingTrialCode = (doctorMissingTrialCodesQuery.ToList().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() : doctor.TrialCodes; } else { income.MissingTrialCodes = month == null ? new List() : month.TrialCodes; } }); } if (queryParam.StatType == 0 || queryParam.StatType == 1) { incomeList.ForEach(income => { List temp = new List(); if (Math.Abs(income.Total) < 0.001m) { temp.Add(income.TrialCode); income.MissingTrialCodes = temp; } }); } #endregion return new PageOutput(queryParam.PageIndex, queryParam.PageSize, count, incomeList); } /// /// Financials / Analysis 项目维度分析接口 /// public List 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> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm; Expression> 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.Code.Contains(trialCode)); } if (param.AttendedReviewerType != null) { trialLambda = trialLambda.And(u => u.AttendedReviewerType == param.AttendedReviewerType); } var lockedPaymentIdAndYearMonth = _paymentRepository.GetAll().Where(t => t.IsLock && t.YearMonthDate >= bDate && t.YearMonthDate <= eDate).Select(t => new { PaymentId = t.Id, t.YearMonth, t.DoctorId }); var costStatisticsIds = lockedPaymentIdAndYearMonth.Select(t => t.PaymentId).ToList(); var lockedDoctorIdAndYearMonthQueryable = lockedPaymentIdAndYearMonth.Select(t => new { t.YearMonth, t.DoctorId }); ////工作量过滤查询 锁定得月份 //workloadLambda = workloadLambda.And(x => lockedDoctorIdAndYearMonthQueryable.Contains()); var trialPayQuery = from costStatisticsDetail in _paymentDetailRepository.GetAll() .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.GetAll().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.GetAll() on workLoad.TrialId equals trialCost.TrialId into c from trialCost in c.DefaultIfEmpty() join trial in _trialRepository.Find(trialLambda) on workLoad.TrialId equals trial.Id into t from trial in t.DefaultIfEmpty() join cro in _croRepository.GetAll() on trial.CROId equals cro.Id into ttt from croItem in ttt.DefaultIfEmpty() select new TrialAnalysisDTO { TrialId = trial.Id, Indication = trial.Indication, TrialCode = trial.Code, 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 = trialPayQuery.OrderBy(t => t.PaymentUSD).ToList(); var workloadIncomeList = workloadIncomeQuery.ToList(); 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.GetAll() .Where(t => costStatisticsIds.Contains(t.PaymentId) && t.TrialCode == "Volume Reward") .Sum(t => (decimal?)t.PaymentUSD) ?? 0; var adjustment = _payAdjustmentRepository.GetAll() .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; } /// /// Financials / Analysis 医生维度分析接口 /// public List 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> workloadLambda = x => x.DataFrom == (int)WorkLoadFromStatus.FinalConfirm; Expression> 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.Code.Contains(reviewer)); } if (param.Nation != null) { doctorLambda = doctorLambda.And(u => u.Nation == param.Nation); } var lockedPaymentIdAndYearMonth = _paymentRepository.GetAll().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> monthlyPayLambda = x => x.IsLock && x.YearMonthDate >= beginDate && x.YearMonthDate <= endDate; var payQuery = from monthlyPayment in _paymentRepository.Find(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.Find(doctorLambda) on monthlyPayment.ReviewerId equals doctor.Id select new MonthlyPaymentDTO { ReviewerId = doctor.Id, ChineseName = doctor.ChineseName, FirstName = doctor.FirstName, LastName = doctor.LastName, ReviewerCode = doctor.Code, 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.GetAll().Where(workloadLambda) join doctor in _doctorRepository.Find(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.GetAll() 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 = 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), }).ToList(); var workloadPayList = payQuery.ToList(); //var workloadIncomeList = workloadIncomeQuery.ToList(); var returnList = new List(); #region 处理找到缺失的项目 //有项目价格的trial Id 集合 var hasIncomePriceTrialIds = _trialRevenuePriceRepository.GetAll().Select(t => t.TrialId).ToList(); workloadLambda = workloadLambda.And(t => !hasIncomePriceTrialIds.Contains(t.TrialId)); var doctorMissingTrialCodesQuery = (from workLoad in _workloadRepository.GetAll().Where(workloadLambda) join trial in _trialRepository.GetAll() on workLoad.TrialId equals trial.Id select new { DoctorId = workLoad.DoctorId, TrialCode = trial.Code }).Distinct(); var doctorMissingTrialCodes = (doctorMissingTrialCodesQuery.ToList().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() }); }); return returnList.OrderBy(t => t.ReviewerCode).ToList(); } public void ChangePaymentMethod(ChangePaymentMethodInDto inDto) { var payment = _paymentRepository.FindSingleOrDefault(t => t.Id == inDto.Id); payment.PaymentMethod = inDto.PaymentMethod; _paymentRepository.Update(payment); _paymentRepository.SaveChanges(); } public Stream ExportLaborPayment(ExportLaborPaymentInDto inDto) { #region 创建文件夹 if (!System.IO.Directory.Exists("./file")) { System.IO.Directory.CreateDirectory("./file"); } if (!System.IO.Directory.Exists("./file/云账户")) { System.IO.Directory.CreateDirectory("./file/云账户"); } if (!System.IO.Directory.Exists("./file/Direct")) { System.IO.Directory.CreateDirectory("./file/Direct"); } if (!System.IO.Directory.Exists("./Zip")) { System.IO.Directory.CreateDirectory("./Zip"); } #endregion List laborPaymentList = GetLaborPaymentList(inDto.PaymentIds); //报酬 var remunerationList = laborPaymentList.Where(x => x.PaymentMethod == PaymentMethod.Remuneration).ToList(); // var cloudPaymentList = laborPaymentList.Where(x => x.PaymentMethod == PaymentMethod.CloudPayment).ToList(); var deletepaths =new List(){ "./file/Direct","./file/云账户" ,"./file" }; foreach (var item in deletepaths) { DirectoryInfo folder = new DirectoryInfo(item); foreach (FileInfo file in folder.GetFiles()) { file.Delete(); } } FileInfo fi2 = new FileInfo("./Zip/Payroll.zip"); fi2.Delete(); RemunerationInfo remunerationInfo = new RemunerationInfo() { YearMonth = remunerationList.Select(x => x.YearMonth).FirstOrDefault(), Rows = new List(), }; CloudPaymentInfo cloudPaymentInfo = new CloudPaymentInfo() { YearMonth = remunerationList.Select(x => x.YearMonth).FirstOrDefault(), Rows = new List(), }; foreach (var item in remunerationList) { var remunerationSingle = new Remuneration() { ChineseName = item.ChineseName, ResidentId = item.ResidentId, YearMonth = item.YearMonth, NextYearMonth = DateTime.Parse(item.YearMonth + "-01").AddMonths(1).ToString("yyyy-MM"), PaymentCNY = item.PaymentCNY, TaxCNY = item.TaxCNY, ActuallyPaidCNY = item.ActuallyPaidCNY, BankTransferCNY = item.BankTransferCNY, Bank=item.Bank, AccountNumber=item.AccountNumber, Phone=item.Phone, }; remunerationInfo.Rows.Add(remunerationSingle); var path = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\paystub(Direct).xlsx"); // 导入excel MiniExcel.SaveAsByTemplate($"./file/Direct/{item.ChineseName}_paystub_{inDto.YearMonth}(Direct).xlsx", path, remunerationSingle); } foreach (var item in cloudPaymentList) { var cloudPaymentSingle = new CloudPayment() { ChineseName= item.ChineseName, ResidentId = item.ResidentId, YearMonth = item.YearMonth, NextYearMonth = DateTime.Parse(item.YearMonth + "-01").AddMonths(1).ToString("yyyy-MM"), PaymentCNY = item.PaymentCNY, TaxCNY = decimal.Round(item.PaymentCNY*(decimal)0.1,2), ActuallyPaidCNY = item.PaymentCNY - decimal.Round((item.PaymentCNY * (decimal)0.1),2) , BankTransferCNY = item.PaymentCNY - decimal.Round((item.PaymentCNY * (decimal)0.1),2), PlatformFee= (item.PaymentCNY - decimal.Round(item.PaymentCNY * (decimal)0.1,2)) *(decimal)0.065, Bank = item.Bank, AccountNumber = item.AccountNumber, Phone = item.Phone, }; cloudPaymentInfo.Rows.Add(cloudPaymentSingle); var path = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\paystub(云账户).xlsx"); MiniExcel.SaveAsByTemplate($"./file/云账户/{item.ChineseName}_paystub_{inDto.YearMonth}(云账户).xlsx", path, cloudPaymentSingle); } remunerationInfo.YearMonth = inDto.YearMonth; cloudPaymentInfo.YearMonth = inDto.YearMonth; var remunerationPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\Payroll Summary_(Direct).xlsx"); MiniExcel.SaveAsByTemplate($"./file/Direct/Payroll Summary_{inDto.YearMonth}(Direct).xlsx", remunerationPath, remunerationInfo); var cloudPaymentPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\Payroll Summary_(云账户).xlsx"); MiniExcel.SaveAsByTemplate($"./file/云账户/Payroll Summary_{inDto.YearMonth}(云账户).xlsx", cloudPaymentPath, cloudPaymentInfo); // 生成summary var summaryPaymentPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\Payment Summary.xlsx"); var sumData = GetMonthlyPaymentList(new MonthlyPaymentQueryDTO() { PageIndex = 1, PageSize = 99999, Asc = true, StatisticsDate = DateTime.Parse(inDto.YearMonth), }).CurrentPageData.ToList(); SummaryPaymentData summaryPaymentData = new SummaryPaymentData() { YearMonth=inDto.YearMonth, Row= sumData, ExchangeRate = _exchangeRateService.GetExchangeRateByMonth(inDto.YearMonth) }; MiniExcel.SaveAsByTemplate($"./file/Payroll Summary_{inDto.YearMonth}.xlsx", summaryPaymentPath, summaryPaymentData); ZipFile.CreateFromDirectory("./file", "Zip/Payroll.zip"); Stream stream = new System.IO.FileStream("./Zip/Payroll.zip", FileMode.Open, FileAccess.Read); foreach (var item in deletepaths) { DirectoryInfo folder = new DirectoryInfo(item); foreach (FileInfo file in folder.GetFiles()) { file.Delete(); } } return stream; } public List GetLaborPaymentList(List paymentIds) { var query = from payment in _paymentRepository.GetAll().Where(t => paymentIds.Contains(t.Id)) join reviewer in _doctorRepository.GetAll() on payment.DoctorId equals reviewer.Id join payInfo in _doctorPayInfoRepository.GetAll() 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, PaymentMethod=payment.PaymentMethod //TaxCNY = payment.TaxCNY, //ActuallyPaidCNY = payment.ActuallyPaidCNY, //BankTransferCNY = payment.BankTransferCNY, }; var result = query.ToList(); result.ForEach(t => { t.TaxCNY =GetTax2(t.PaymentCNY); t.ActuallyPaidCNY = t.PaymentCNY - t.TaxCNY; t.BankTransferCNY = t.PaymentCNY - t.TaxCNY; }); return result; } //会计报税方式和计算方式不同 导致 超过2w的人 扣钱多了 private decimal GetTax(decimal paymentCNY) { if (paymentCNY >= 0 && paymentCNY <= 800) { return 0; } else if (paymentCNY >= 800 && paymentCNY <= 4000) { return (paymentCNY - 800) * 0.2m; } else if (paymentCNY > 4000 && paymentCNY <= 20000) { return paymentCNY * 0.8m * 0.2m; } else if (paymentCNY > 20000 && paymentCNY <= 50000) { return (paymentCNY * 0.3m) - 2000; } else { return paymentCNY * 0.4m - 7000; } } private 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; } } } }