using AutoMapper; using IRaCIS.Application.Interfaces; using IRaCIS.Application.Contracts.Pay; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.AspNetCore.Mvc; using Panda.DynamicWebApi.Attributes; namespace IRaCIS.Application.Services { [ApiExplorerSettings(GroupName = "Financial")] public class PaymentAdjustmentService : BaseService, IPaymentAdjustmentService { private readonly IRepository _payAdjustmentRepository; private readonly IRepository _doctorRepository; private readonly IRepository _exchangeRateRepository; private readonly IRepository _paymentRepository; public PaymentAdjustmentService(IRepository costAdjustmentRepository, IRepository doctorRepository, IRepository exchangeRateRepository, IRepository paymentRepository, IMapper mapper) { _payAdjustmentRepository = costAdjustmentRepository; _doctorRepository = doctorRepository; _exchangeRateRepository = exchangeRateRepository; _paymentRepository = paymentRepository; } /// /// 添加或更新费用调整[AUTH] /// [HttpPost] public async Task AddOrUpdatePaymentAdjustment(PaymentAdjustmentCommand addOrUpdateModel) { var yearMonthDate = new DateTime(addOrUpdateModel.YearMonth.Year, addOrUpdateModel.YearMonth.Month, 1); var yearMonth = addOrUpdateModel.YearMonth.ToString("yyyy-MM"); var payment = await _paymentRepository.FirstOrDefaultAsync(u => u.DoctorId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth); //判断付费表中是否有记录 if (payment == null) { //没有 添加仅有的调整费用记录 payment = new Payment { DoctorId = addOrUpdateModel.ReviewerId, YearMonth = yearMonth, YearMonthDate = yearMonthDate, PaymentCNY = 0, PaymentUSD = 0, AdjustmentCNY = 0, AdjustmentUSD = 0 }; await _paymentRepository.AddAsync(payment); await _paymentRepository.SaveChangesAsync(); } else { if (payment.IsLock) { return ResponseOutput.NotOk("Doctor payment has confirmed lock"); } } var exchangeRate = await _exchangeRateRepository.FirstOrDefaultAsync(t => t.YearMonth == yearMonth); if (addOrUpdateModel.Id == Guid.Empty || addOrUpdateModel.Id == null) { var costAdjustment = _mapper.Map(addOrUpdateModel); //视图模型和领域模型没对应 重新赋值 costAdjustment.ExchangeRate = exchangeRate?.Rate ?? 0; costAdjustment.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0); costAdjustment.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD; await _payAdjustmentRepository.AddAsync(costAdjustment); //添加的时候,每个月调整汇总费用 需要加上本次调整的费用 payment.AdjustmentCNY += costAdjustment.AdjustmentCNY; payment.AdjustmentUSD += costAdjustment.AdjustmentUSD; await _paymentRepository.UpdateAsync(payment); await _payAdjustmentRepository.SaveChangesAsync(); return ResponseOutput.Ok(costAdjustment.Id.ToString()); } else { // 更新的时候,先查出来,更新前的调整费用数据 var paymentAdjust = await _payAdjustmentRepository.FirstOrDefaultAsync(t => t.Id == addOrUpdateModel.Id); _mapper.Map(addOrUpdateModel, paymentAdjust); paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0; paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD; paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0); await _payAdjustmentRepository.UpdateAsync(paymentAdjust); var success = await _payAdjustmentRepository.SaveChangesAsync(); if (success) { var adjustmentList = await _payAdjustmentRepository.Where(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth).ToListAsync(); payment.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY); payment.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD); await _paymentRepository.UpdateAsync(payment); await _paymentRepository.SaveChangesAsync(); } //查询得到历史汇总 return ResponseOutput.Ok(success); #region 逻辑存在错误 问题待查 //// 更新的时候,先查出来,更新前的调整费用数据 //var paymentAdjust = _payAdjustmentRepository.FindSingleOrDefault(t => t.Id == addOrUpdateModel.Id); ////减去数据库本条记录的值 //payment.AdjustmentCNY = -paymentAdjust.AdjustmentCNY; //payment.AdjustmentUSD = -paymentAdjust.AdjustmentUSD; //_mapper.Map(addOrUpdateModel, paymentAdjust); //paymentAdjust.ExchangeRate = exchangeRate?.Rate ?? 0; //paymentAdjust.AdjustmentUSD = addOrUpdateModel.AdjustPaymentUSD; //paymentAdjust.AdjustmentCNY = addOrUpdateModel.AdjustPaymentUSD * (exchangeRate?.Rate ?? 0); //_payAdjustmentRepository.Update(paymentAdjust); ////查询得到历史汇总 //var adjustment = _payAdjustmentRepository.Find(u => u.ReviewerId == addOrUpdateModel.ReviewerId && u.YearMonth == yearMonth) // .GroupBy(u => new { u.ReviewerId, u.YearMonth }).Select(g => new // { // AdjustCNY = g.Sum(t => t.AdjustmentCNY), // AdjustUSD = g.Sum(t => t.AdjustmentUSD) // }).FirstOrDefault(); ////最终的值 等于历史汇总 减去更新前的加上当前更新的值 //payment.AdjustmentCNY += (adjustment.AdjustCNY + paymentAdjust.AdjustmentCNY); //payment.AdjustmentUSD += (adjustment.AdjustUSD + paymentAdjust.AdjustmentUSD); //_paymentRepository.Update(payment); //var success = _payAdjustmentRepository.SaveChanges(); //return ResponseOutput.Result(success, success ? string.Empty : StaticData.UpdateFailed); #endregion } } /// /// 删除费用调整记录 /// [HttpDelete("{id:guid}")] public async Task DeletePaymentAdjustment(Guid id) { var adjustPayment = await _payAdjustmentRepository.FirstOrDefaultAsync(u => u.Id == id); var monthPay = await _paymentRepository.FirstOrDefaultAsync(t => t.DoctorId == adjustPayment.ReviewerId && t.YearMonth == adjustPayment.YearMonth); await _payAdjustmentRepository.DeleteAsync(new PaymentAdjustment() { Id = id }); var success = await _payAdjustmentRepository.SaveChangesAsync(); if (success) { var adjustmentList = await _payAdjustmentRepository.Where(u => u.ReviewerId == adjustPayment.ReviewerId && u.YearMonth == adjustPayment.YearMonth).ToListAsync(); monthPay.AdjustmentCNY = adjustmentList.Sum(t => t.AdjustmentCNY); monthPay.AdjustmentUSD = adjustmentList.Sum(t => t.AdjustmentUSD); await _paymentRepository.UpdateAsync(monthPay); await _paymentRepository.SaveChangesAsync(); } return ResponseOutput.Result(success); } /// /// 获取费用调整列表 /// [HttpPost] public async Task> GetPaymentAdjustmentList(PaymentAdjustmentQueryDTO queryParam) { var beginYearMonth = queryParam.BeginMonth.AddDays(1 - queryParam.BeginMonth.Day); var endYearMonth = queryParam.EndMonth.AddDays(1 - queryParam.EndMonth.Day).AddMonths(1).AddDays(-1); var costAdjustmentQueryable = from costAdjustment in _payAdjustmentRepository .Where(t => t.YearMonthDate >= beginYearMonth && t.YearMonthDate <= endYearMonth) join doctor in _doctorRepository.AsQueryable(). WhereIf(!string.IsNullOrWhiteSpace(queryParam.Reviewer), u => u.ChineseName.Contains(queryParam.Reviewer) || (u.LastName + u.FirstName).Contains(queryParam.Reviewer) || u.ReviewerCode.Contains(queryParam.Reviewer)) on costAdjustment.ReviewerId equals doctor.Id select new PaymentAdjustmentDetailDTO() { AdjustPaymentCNY = costAdjustment.AdjustmentCNY, AdjustPaymentUSD = costAdjustment.AdjustmentUSD, IsLock = costAdjustment.IsLock, Id = costAdjustment.Id, YearMonth = costAdjustment.YearMonth, YearMonthDate = costAdjustment.YearMonthDate, Note = costAdjustment.Note, ReviewerId = costAdjustment.ReviewerId, ReviewerCode = doctor.ReviewerCode, FirstName = doctor.FirstName, LastName = doctor.LastName, ChineseName = doctor.ChineseName }; return await costAdjustmentQueryable.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, string.IsNullOrWhiteSpace(queryParam.SortField) ? "YearMonthDate" : queryParam.SortField, queryParam.Asc); } public async Task> GetReviewerSelectList() { return await _doctorRepository.Where(t => t.CooperateStatus == ContractorStatusEnum.Cooperation && t.ResumeStatus == ResumeStatusEnum.Pass).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } [NonDynamicMethod] public async Task CalculateCNY(string yearMonth, decimal rate) { //如果是double 不会保留两位小数 await _payAdjustmentRepository.BatchUpdateAsync(u => u.YearMonth == yearMonth && !u.IsLock, t => new PaymentAdjustment { AdjustmentCNY = t.AdjustmentUSD * rate, ExchangeRate = rate, UpdateTime = DateTime.Now }); var adjustList = await _payAdjustmentRepository.Where(u => u.YearMonth == yearMonth && !u.IsLock).ToListAsync(); var needUpdatePayment = adjustList.GroupBy(t => t.ReviewerId).Select(g => new { ReviewerId = g.Key, AdjustCNY = g.Sum(t => t.AdjustmentCNY), AdjustUSD = g.Sum(t => t.AdjustmentUSD) }); foreach (var reviewer in needUpdatePayment) { await _paymentRepository.BatchUpdateAsync(u => u.YearMonth == yearMonth && !u.IsLock && u.DoctorId == reviewer.ReviewerId, t => new Payment() { AdjustmentUSD = reviewer.AdjustUSD, AdjustmentCNY = reviewer.AdjustCNY }); } } } }