CostCalculationItem/IRaCIS.Core.Application/Financial/FinancialService.cs

1410 lines
71 KiB
C#

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 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,
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;
_rankPriceRepository = rankPriceRepository;
_paymentDetailRepository = costStatisticsDetailRepository;
_croRepository = croCompanyRepository;
_workloadRepository = workloadRepository;
_trialRevenuePriceRepository = trialCostRepository;
_payAdjustmentRepository = costAdjustmentRepository;
_mapper = mapper;
}
/// <summary>
/// Financials /MonthlyPayment 列表查询接口
/// </summary>
public PageOutput<PaymentViewModel> 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.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,
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<PaymentViewModel>(queryParam.PageIndex, queryParam.PageSize, count, costStatisticsList);
}
/// <summary>
/// Financials / MonthlyPaymentDetail 详情查询接口
/// </summary>
public 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 =(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,
PersonalAdditional = pay.PersonalAdditional,
TrialAdditional = pay.TrialAdditional,
TrialCode = pay.TrialCode,
PaymentCNY = pay.PaymentCNY,
DoctorId = pay.DoctorId,
ExchangeRate = pay.ExchangeRate,
IsNewTrial = price.IsNewTrial,
NewPersonalAdditional = enroll.AdjustmentMultiple,
}).ToList();
}
//费用调整
//_payAdjustmentRepository.Where(t => t.YearMonth == yearMonthStr && t.ReviewerId == reviewerId)
var adjList =
(from costAdjustment in _payAdjustmentRepository.GetAll().Where(t => t.YearMonth == yearMonthStr && t.ReviewerId == paymentId)
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;
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.ReviewerCode,
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<PayDetailDTO> GetReviewersMonthlyPaymentDetail(List<MonthlyPaymentDetailQuery> manyReviewers)
{
List<PayDetailDTO> result = new List<PayDetailDTO>();
manyReviewers.ForEach(t => result.Add(GetMonthlyPaymentDetailList(t.PaymentId, t.ReviewerId, t.YearMonth)));
return result;
}
/// <summary>
/// Financials / Payment History 列表查询接口
/// </summary>
public 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.Code.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.GetAll().Where(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.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<MonthlyPaymentDTO>(queryParam.PageIndex, queryParam.PageSize, count, list);
}
/// <summary>
/// Financials / Payment History 详情接口
/// </summary>
public 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.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<Guid> 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;
}
/// <summary>
/// Financials / Revenues 列表查询接口
/// </summary>
public PageOutput<RevenuesDTO> 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<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.Code.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.Code.Contains(reviewer));
}
if (queryParam.Nation != null)
{
doctorLambda = doctorLambda.And(u => u.Nation == queryParam.Nation);
}
List<RevenuesDTO> incomeList = new List<RevenuesDTO>();
IQueryable<RevenuesDTO> 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<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>
/// Financials / Analysis 项目维度分析接口
/// </summary>
public 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.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;
}
/// <summary>
/// Financials / Analysis 医生维度分析接口
/// </summary>
public 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.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<Func<Payment, bool>> 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<ReviewerAnalysisDTO>();
#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<string>()
});
});
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(List<Guid> paymentIds)
{
List<LaborPayment> laborPaymentList = GetLaborPaymentList(paymentIds);
//报酬
var remunerationList = laborPaymentList.Where(x => x.PaymentMethod == PaymentMethod.Remuneration).ToList();
//
var cloudPaymentList = laborPaymentList.Where(x => x.PaymentMethod == PaymentMethod.CloudPayment).ToList();
DirectoryInfo folder = new DirectoryInfo("./file");
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<Remuneration>(),
};
CloudPaymentInfo cloudPaymentInfo = new CloudPaymentInfo()
{
YearMonth = remunerationList.Select(x => x.YearMonth).FirstOrDefault(),
Rows = new List<CloudPayment>(),
};
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(报酬).xlsx");
// 导入excel
MiniExcel.SaveAsByTemplate($"./file/{item.ChineseName}_paystub_{item.YearMonth}(报酬).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 = item.PaymentCNY*(decimal)0.1,
ActuallyPaidCNY = item.ActuallyPaidCNY* (decimal)0.9,
BankTransferCNY = item.BankTransferCNY * (decimal)0.9,
PlatformFee= item.ActuallyPaidCNY * (decimal)0.9*(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_{item.YearMonth}(云支付).xlsx", path, cloudPaymentSingle);
}
var remunerationPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\Payroll Summary_(报酬).xlsx");
MiniExcel.SaveAsByTemplate($"./file/Payroll Summary_{remunerationInfo.YearMonth}(报酬).xlsx", remunerationPath, remunerationInfo);
var cloudPaymentPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Template\Payroll Summary_(云支付).xlsx");
MiniExcel.SaveAsByTemplate($"./file/Payroll Summary_{cloudPaymentInfo.YearMonth}(云支付).xlsx", cloudPaymentPath, cloudPaymentInfo);
ZipFile.CreateFromDirectory("./file", "Zip/Payroll.zip");
Stream stream = new System.IO.FileStream("./Zip/Payroll.zip", FileMode.Open, FileAccess.Read);
foreach (FileInfo file in folder.GetFiles())
{
file.Delete();
}
return stream;
}
public List<LaborPayment> GetLaborPaymentList(List<Guid> paymentIds)
{
var query =
//from payment in _paymentRepository.GetAll().Where(t => paymentIds.Contains(t.Id))
from payment in _paymentRepository.GetAll()
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;
}
}
}
}