Browse Source

体检退款

master
wxd 11 months ago
parent
commit
5d77e5475c
  1. 15
      Shentun.WebPeis.Plugins/AppQueueRegisterPlugIns.cs
  2. 14
      src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/AppointPatientRegisterIdsInputDto.cs
  3. 72
      src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/GerAppointPatientRegisterWithAsbitemListDto.cs
  4. 27
      src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/UpdateAppointPatientAsbitemStatusInputDto.cs
  5. 156
      src/Shentun.WebPeis.Application/AppointPatientRegisters/AppointPatientRegisterAppService.cs
  6. 29
      src/Shentun.WebPeis.Application/Charges/ChargeAppService.cs
  7. 5
      src/Shentun.WebPeis.Domain/Charges/ChargeManager.cs

15
Shentun.WebPeis.Plugins/AppQueueRegisterPlugIns.cs

@ -28,6 +28,7 @@ namespace Shentun.WebPeis.Plugins
private string? _appPassword;
private string? _appQueueRegisterUrl;
private string? _appIsPeisRegisterUrl;
private string? _appUpdateAppointPatientAsbitemStatusUrl;
public AppQueueRegisterPlugIns()
{
Init();
@ -49,6 +50,8 @@ namespace Shentun.WebPeis.Plugins
.GetSection("AppQueueRegisterUrl").Value;
_appIsPeisRegisterUrl = AppConfig.GetSection("Peis")
.GetSection("AppIsPeisRegisterUrl").Value;
_appUpdateAppointPatientAsbitemStatusUrl= AppConfig.GetSection("Peis")
.GetSection("AppUpdateAppointPatientAsbitemStatusUrl").Value;
}
@ -81,6 +84,18 @@ namespace Shentun.WebPeis.Plugins
}
/// <summary>
/// 小程序退款成功后,更新体检系统项目收费状态
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task UpdateAppointPatientAsbitemStatusAsync(UpdateAppointPatientAsbitemStatusInputDto input)
{
await CallAppServiceAsync<UpdateAppointPatientAsbitemStatusInputDto, Task>(_appUpdateAppointPatientAsbitemStatusUrl,
input);
}
public async Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post")
{
string baseAddress = _appBaseAddress;

14
src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/AppointPatientRegisterIdsInputDto.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Shentun.WebPeis.AppointPatientRegisters
{
public class AppointPatientRegisterIdsInputDto
{
/// <summary>
/// 预约id集合
/// </summary>
public List<Guid> AppointPatientRegisterIds { get; set; } = new List<Guid>();
}
}

72
src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/GerAppointPatientRegisterWithAsbitemListDto.cs

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Shentun.WebPeis.AppointPatientRegisters
{
public class GerAppointPatientRegisterWithAsbitemListDto
{
/// <summary>
/// 预约id
/// </summary>
public Guid AppointPatientRegisterId { get; set; }
/// <summary>
/// 收费状态 0-未收费 1-已收费 2-已退费
/// </summary>
public char ChargeFlag { get; set; }
/// <summary>
/// 预约日期
/// </summary>
public string AppointDate { get; set; }
/// <summary>
/// 预约项目
/// </summary>
public List<GerAppointPatientRegisterWithAsbitemListChargeAsbitemDto> AppointRegisterAsbitemDetail { get; set; } = new List<GerAppointPatientRegisterWithAsbitemListChargeAsbitemDto>();
}
public class GerAppointPatientRegisterWithAsbitemListChargeAsbitemDto
{
/// <summary>
/// 主键
/// </summary>
public Guid AppointRegisterAsbitemId { get; set; }
/// <summary>
/// 组合项目ID
/// </summary>
public Guid AsbitemId { get; set; }
/// <summary>
/// 组合项目名称
/// </summary>
public string AsbitemName { get; set; }
/// <summary>
/// 标准价格
/// </summary>
public decimal StandardPrice { get; set; }
/// <summary>
/// 收费价格
/// </summary>
public decimal ChargePrice { get; set; }
/// <summary>
/// 支付类别标准
/// </summary>
public char PayTypeFlag { get; set; }
/// <summary>
/// 是否收费
/// </summary>
public char IsCharge { get; set; }
/// <summary>
/// 数量
/// </summary>
public short Amount { get; set; }
}
}

27
src/Shentun.WebPeis.Application.Contracts/AppointPatientRegisters/UpdateAppointPatientAsbitemStatusInputDto.cs

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Shentun.WebPeis.AppointPatientRegisters
{
public class UpdateAppointPatientAsbitemStatusInputDto
{
/// <summary>
/// 预约id
/// </summary>
public Guid AppointPatientRegisterId { get; set; }
/// <summary>
/// 收费项目状态
/// </summary>
public List<UpdateAppointPatientAsbitemStatusInputDetailDto> ChargeAsbitemDetail { get; set; } = new List<UpdateAppointPatientAsbitemStatusInputDetailDto>();
}
public class UpdateAppointPatientAsbitemStatusInputDetailDto
{
public Guid AsbitemId { get; set; }
public char IsCharge { get; set; }
}
}

156
src/Shentun.WebPeis.Application/AppointPatientRegisters/AppointPatientRegisterAppService.cs

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Configuration;
using Shentun.WebPeis.AppointRegisterAsbitems;
using Shentun.WebPeis.AppointScheduleTimes;
using Shentun.WebPeis.CustomerOrgs;
@ -10,9 +11,12 @@ using Shentun.WebPeis.Models;
using Shentun.WebPeis.OrganizationUnits;
using Shentun.WebPeis.PatientRegisters;
using Shentun.WebPeis.Persons;
using Shentun.WebPeis.Plugins;
using Shentun.WebPeis.QuestionRegisters;
using Shentun.WebPeis.SysParmValues;
using Shentun.WebPeis.Wechats;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using System;
using System.Collections;
using System.Collections.Generic;
@ -76,6 +80,10 @@ namespace Shentun.WebPeis.AppointPatientRegisters
private readonly IRepository<Charge> _chargeRepository;
private readonly IRepository<ChargePay> _chargePayRepository;
private readonly IRepository<ChargeAsbitem> _chargeAsbitemRepository;
private readonly IRepository<WeChatOrder> _weChatOrderRepository;
private readonly IRepository<WeChatOrderRefund> _weChatOrderRefundRepository;
private readonly IConfiguration _configuration;
private readonly IWechatTenpayClientFactory _wechatTenpayClientFactory;
public AppointPatientRegisterAppService(IRepository<AppointPatientRegister> repository,
CacheService cacheService,
IRepository<ItemType> itemTypeRepository,
@ -113,7 +121,11 @@ namespace Shentun.WebPeis.AppointPatientRegisters
WeChatOrderAppService weChatOrderAppService,
IRepository<Charge> chargeRepository,
IRepository<ChargePay> chargePayRepository,
IRepository<ChargeAsbitem> chargeAsbitemRepository)
IRepository<ChargeAsbitem> chargeAsbitemRepository,
IRepository<WeChatOrder> weChatOrderRepository,
IRepository<WeChatOrderRefund> weChatOrderRefundRepository,
IConfiguration configuration,
IWechatTenpayClientFactory wechatTenpayClientFactory)
{
_repository = repository;
_cacheService = cacheService;
@ -154,6 +166,10 @@ namespace Shentun.WebPeis.AppointPatientRegisters
_chargeRepository = chargeRepository;
_chargePayRepository = chargePayRepository;
_chargeAsbitemRepository = chargeAsbitemRepository;
_weChatOrderRepository = weChatOrderRepository;
_weChatOrderRefundRepository = weChatOrderRefundRepository;
_configuration = configuration;
_wechatTenpayClientFactory = wechatTenpayClientFactory;
}
/// <summary>
/// 创建预约,小程序使用 部分单位跟个人
@ -1131,6 +1147,7 @@ namespace Shentun.WebPeis.AppointPatientRegisters
}
}
#region 提供给体检系统调用
@ -1394,6 +1411,143 @@ namespace Shentun.WebPeis.AppointPatientRegisters
}
/// <summary>
/// 获取预约记录,包含收费项目 体检退费时用
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("api/app/AppointPatientRegister/GerAppointPatientRegisterWithAsbitemList")]
public async Task<List<GerAppointPatientRegisterWithAsbitemListDto>> GerAppointPatientRegisterWithAsbitemListAsync(AppointPatientRegisterIdsInputDto input)
{
if (!input.AppointPatientRegisterIds.Any())
{
throw new UserFriendlyException("无预约数据");
}
var query = (from appointPatientRegister in await _repository.GetQueryableAsync()
join appointRegisterAsbitem in await _appointRegisterAsbitemRepository.GetQueryableAsync()
on appointPatientRegister.AppointPatientRegisterId equals appointRegisterAsbitem.AppointPatientRegisterId
join asbitem in await _asbitemRepository.GetQueryableAsync() on appointRegisterAsbitem.AsbitemId equals asbitem.AsbitemId
where appointPatientRegister.ChargeFlag == ChargeFlag.Charge
&& input.AppointPatientRegisterIds.Contains(appointPatientRegister.AppointPatientRegisterId)
select new
{
appointPatientRegister,
appointRegisterAsbitem,
asbitem
}).ToList();
var appointPatientRegisterGroup = query.GroupBy(g => g.appointPatientRegister);
var entListDto = appointPatientRegisterGroup.Select(s => new GerAppointPatientRegisterWithAsbitemListDto
{
AppointPatientRegisterId = s.Key.AppointPatientRegisterId,
ChargeFlag = s.Key.ChargeFlag,
AppointDate = DataHelper.ConversionDateShortToString(s.Key.AppointDate),
AppointRegisterAsbitemDetail = s.Select(ss => new GerAppointPatientRegisterWithAsbitemListChargeAsbitemDto
{
Amount = ss.appointRegisterAsbitem.Amount,
AppointRegisterAsbitemId = ss.appointRegisterAsbitem.AppointRegisterAsbitemId,
AsbitemId = ss.appointRegisterAsbitem.AsbitemId,
AsbitemName = ss.asbitem.AsbitemName,
ChargePrice = ss.appointRegisterAsbitem.ChargePrice,
StandardPrice = ss.appointRegisterAsbitem.StandardPrice,
IsCharge = ss.appointRegisterAsbitem.IsCharge,
PayTypeFlag = ss.appointRegisterAsbitem.PayTypeFlag
}).ToList()
}).ToList();
return entListDto;
}
/// <summary>
/// 体检系统申请退款
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("api/app/AppointPatientRegister/CreateWeChatOrderRefund")]
public async Task CreateWeChatOrderRefundAsync(CreateWeChatOrderRefundInputDto input)
{
var weChatOrderEnt = await _weChatOrderRepository.FirstOrDefaultAsync(f => f.AppointPatientRegisterId == input.AppointPatientRegisterId
&& f.Status == "SUCCESS");
if (weChatOrderEnt != null)
{
if (input.RefundMoney * 100 > weChatOrderEnt.OrderMoney)
{
throw new UserFriendlyException($"退款金额不能大于支付金额");
}
var weChatOrderRefundEnt = await _weChatOrderRefundRepository.FirstOrDefaultAsync(f => f.WeChatOrderId == weChatOrderEnt.WeChatOrderId);
if (weChatOrderRefundEnt == null)
{
string appid = _configuration.GetSection("WeChat:Appid").Value;
string mchid = _configuration.GetSection("Merchant:MchId").Value;
string notifyUrl = _configuration.GetSection("Merchant:NotifyUrl").Value;
string outRefundNo = $"T{DateTime.Now.ToString("yyyyMMddHHmmss")}{new Random().Next(100000, 999999)}";
var _wechatTenpayClient = await _wechatTenpayClientFactory.Create(false);
var request = new CreateRefundDomesticRefundRequest()
{
TransactionId = weChatOrderEnt.TransactionId,
OutRefundNumber = outRefundNo,
Amount = new CreateRefundDomesticRefundRequest.Types.Amount()
{
Total = weChatOrderEnt.OrderMoney,
Refund = Convert.ToInt32(Math.Round(input.RefundMoney * 100))
},
Reason = "体检系统申请退款",
NotifyUrl = notifyUrl
};
var response = await _wechatTenpayClient.ExecuteCreateRefundDomesticRefundAsync(request);
if (response.IsSuccessful())
{
#region 生成订单
weChatOrderRefundEnt = new WeChatOrderRefund
{
RefundMoney = request.Amount.Refund,
Status = "PROCESSING",
OutRefundNo = outRefundNo,
Channel = response.Channel,
RefundId = response.RefundId,
UserReceivedAccount = response.UserReceivedAccount,
WeChatOrderId = weChatOrderEnt.WeChatOrderId,
WeChatOrderRefundId = GuidGenerator.Create()
};
var isAdd = await _weChatOrderRefundRepository.InsertAsync(weChatOrderRefundEnt);
#endregion
}
else
{
throw new UserFriendlyException($"发起退款失败:{response.ErrorCode},{response.ErrorMessage}");
}
}
else
{
throw new UserFriendlyException($"已申请过退款,不要重复退款");
}
}
else
{
throw new UserFriendlyException("预约Id不正确");
}
}
#endregion
}
}

29
src/Shentun.WebPeis.Application/Charges/ChargeAppService.cs

@ -2,6 +2,7 @@
using Microsoft.Extensions.Logging;
using Shentun.WebPeis.AppointPatientRegisters;
using Shentun.WebPeis.Models;
using Shentun.WebPeis.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
@ -72,7 +73,33 @@ namespace Shentun.WebPeis.Charges
var appointPatientRegisterEnt = await _appointPatientRegisterRepository.FirstOrDefaultAsync(f => f.AppointPatientRegisterId == input.AppointPatientRegisterId);
if (appointPatientRegisterEnt != null)
{
await _chargeManager.CreateChargeBackAsync(appointPatientRegisterEnt, input.ChargeBackMoney);
var chargeAsbitems = await _chargeManager.CreateChargeBackAsync(appointPatientRegisterEnt, input.ChargeBackMoney);
//处理完退费,同步数据到体检系统
#region 调用体检服务,更新登记的项目状态
try
{
var appQueueRegisterPlugIns = new AppQueueRegisterPlugIns();
await appQueueRegisterPlugIns.UpdateAppointPatientAsbitemStatusAsync(
new UpdateAppointPatientAsbitemStatusInputDto
{
AppointPatientRegisterId = input.AppointPatientRegisterId,
ChargeAsbitemDetail = chargeAsbitems.Select(s => new UpdateAppointPatientAsbitemStatusInputDetailDto
{
AsbitemId = s.AsbitemId,
IsCharge = 'N'
}).ToList()
});
}
catch (Exception ex)
{
_logger.LogInformation($"同步数据到体检系统异常,{ex.Message}");
}
#endregion
}
else
{

5
src/Shentun.WebPeis.Domain/Charges/ChargeManager.cs

@ -128,7 +128,7 @@ namespace Shentun.WebPeis.Charges
/// <param name="appointPatientRegister"></param>
/// <param name="chargeMoney"></param>
/// <returns></returns>
public async Task CreateChargeBackAsync(
public async Task<List<ChargeAsbitem>> CreateChargeBackAsync(
AppointPatientRegister appointPatientRegister,
decimal chargeMoney
)
@ -180,10 +180,13 @@ namespace Shentun.WebPeis.Charges
appointPatientRegister.CompleteFlag = AppointPatientRegisterCompleteFlag.CancelAppoint;
await _appointPatientRegisterRepository.UpdateAsync(appointPatientRegister);
return chargeAsbitems;
}
else
{
_logger.LogInformation($"退费时,{appointPatientRegister.AppointPatientRegisterId}Id未找到收费记录");
return new List<ChargeAsbitem>();
}
}

Loading…
Cancel
Save