You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
7.3 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Fee.Interface;
using DS.WMS.Core.Sys.Entity;
using Mapster;
namespace DS.WMS.Core.Fee.Method
{
/// <summary>
/// 汇率服务
/// </summary>
public class FeeCurrencyExchangeService : FeeServiceBase, IFeeCurrencyExchangeService
{
/// <summary>
///
/// </summary>
/// <param name="serviceProvider"></param>
public FeeCurrencyExchangeService(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public DataResult<List<FeeCurrencyExchangeRes>> GetListByPage(PageRequest request)
{
//序列化查询条件
var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
var data = TenantDb.Queryable<FeeCurrencyExchange>()
.Where(whereList)
.Select<FeeCurrencyExchangeRes>().ToQueryPage(request.PageCondition);
return data;
}
/// <summary>
/// 编辑
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public DataResult EditFeeCurrencyExchange(FeeCurrencyExchangeReq req)
{
if (req.Id == 0)
{
if (TenantDb.Queryable<FeeCurrencyExchange>()
.Where(x => x.CurrencyCode == req.CurrencyCode && x.LocalCurrency == req.LocalCurrency && x.StartDate == req.StartDate && x.EndDate == req.EndDate).Any())
{
return DataResult.Failed("汇率设置已存在!", MultiLanguageConst.FeeCurrencyExchangeExist);
}
//判断汇率设置日期是否交叉
if (TenantDb.Queryable<FeeCurrencyExchange>()
.Where(x => x.CurrencyCode == req.CurrencyCode && x.LocalCurrency == req.LocalCurrency &&
((x.StartDate >= req.StartDate && x.StartDate <= req.EndDate) || (x.EndDate >= req.StartDate && x.EndDate <= req.EndDate) || (x.StartDate >= req.StartDate && x.EndDate <= req.EndDate))).Any())
{
return DataResult.Failed("汇率设置存在重叠!", MultiLanguageConst.FeeCurrencyExchangeExist);
}
var data = req.Adapt<FeeCurrencyExchange>();
var entity = TenantDb.Insertable(data).ExecuteReturnEntity();
return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess);
}
else
{
var info = TenantDb.Queryable<FeeCurrencyExchange>().Where(x => x.Id == req.Id).First();
info = req.Adapt(info);
TenantDb.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
}
}
/// <summary>
/// 详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public DataResult<FeeCurrencyExchangeRes> GetFeeCurrencyExchangeInfo(string id)
{
var data = TenantDb.Queryable<FeeCurrencyExchange>()
.Where(x => x.Id == long.Parse(id))
.Select<FeeCurrencyExchangeRes>()
.First();
return DataResult<FeeCurrencyExchangeRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
}
/// <summary>
/// 获取两种币别之间的汇率
/// </summary>
/// <param name="exchange">币别信息</param>
/// <returns></returns>
public async Task<DataResult<ExchangeRate>> GetExchangeRateAsync(ExchangeRate exchange)
{
if (exchange.CurrencyFrom == exchange.CurrencyTo)
{
exchange.ReverseRate = exchange.Rate = 1m;
return DataResult<ExchangeRate>.Success(exchange);
}
long id = User.OrgId;
//获取本位币,默认=人民币
string localCurrency = await Db.Queryable<SysOrg>().Where(x => x.Id == id).Select(x => x.LocalCurrency).FirstAsync() ?? FeeCurrency.RMB_CODE;
if (string.IsNullOrWhiteSpace(exchange.CurrencyTo))
{
exchange.CurrencyTo = localCurrency;
}
//需要做二次转换
if (exchange.CurrencyFrom != localCurrency && exchange.CurrencyTo != localCurrency)
{
//获取中间汇率
var middleRate = await GetLocalRateAsync(exchange.CurrencyFrom, localCurrency, exchange.FeeType);
if (middleRate == null)
return DataResult<ExchangeRate>.FailedData(exchange, message: $"{MultiLanguageConst.FeeCurrencyNotFound}{exchange.CurrencyFrom}");
var rate = await GetLocalRateAsync(exchange.CurrencyTo, localCurrency, exchange.FeeType);
exchange.Rate = Math.Round(1 / (rate ?? 1m) * middleRate.GetValueOrDefault(), 4, MidpointRounding.AwayFromZero);
exchange.ReverseRate = Math.Round(1 / exchange.Rate, 4, MidpointRounding.AwayFromZero);
}
else
{
string currency = exchange.CurrencyFrom == FeeCurrency.RMB_CODE ? exchange.CurrencyTo : exchange.CurrencyFrom;
var rate = await GetLocalRateAsync(currency, localCurrency, exchange.FeeType);
if (currency == exchange.CurrencyFrom)
{
exchange.Rate = rate ?? 1m;
exchange.ReverseRate = Math.Round(1 / exchange.Rate, 4, MidpointRounding.AwayFromZero);
}
else
{
exchange.ReverseRate = rate ?? 1m;
exchange.Rate = Math.Round(1 / exchange.ReverseRate, 4, MidpointRounding.AwayFromZero);
}
}
return DataResult<ExchangeRate>.Success(exchange);
}
internal async Task<decimal?> GetLocalRateAsync(string currency, string localCurrency, FeeType? type)
{
var entity = await TenantDb.Queryable<FeeCurrency>().Where(x => x.CodeName == currency).Includes(x => x.Exchanges).FirstAsync();
if (entity == null)
return null;
var rate = entity.DefaultRate;
DateTime dtNow = DateTime.Now;
if (type.HasValue && entity.Exchanges?.Count > 0)
{
//取当前时间范围内的最新一条,优先获取本位币
var item = entity.Exchanges.Where(x => x.Status == StatusEnum.Enable && x.LocalCurrency == localCurrency &&
dtNow >= x.StartDate && dtNow <= x.EndDate).OrderByDescending(x => x.CreateTime).FirstOrDefault();
item ??= entity.Exchanges.Where(x => x.Status == StatusEnum.Enable &&
dtNow >= x.StartDate && dtNow <= x.EndDate).OrderByDescending(x => x.CreateTime).FirstOrDefault();
if (item != null)
rate = type.Value == FeeType.Receivable ? item.DRValue : item.CRValue;
}
return rate;
}
}
}