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 { /// /// 汇率服务 /// public class FeeCurrencyExchangeService : FeeServiceBase, IFeeCurrencyExchangeService { /// /// /// /// public FeeCurrencyExchangeService(IServiceProvider serviceProvider) : base(serviceProvider) { } /// /// 列表 /// /// /// public DataResult> GetListByPage(PageRequest request) { //序列化查询条件 var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); var data = TenantDb.Queryable() .Where(whereList) .Select().ToQueryPage(request.PageCondition); return data; } /// /// 编辑 /// /// /// public DataResult EditFeeCurrencyExchange(FeeCurrencyExchangeReq req) { if (req.Id == 0) { if (TenantDb.Queryable() .Where(x => x.CurrencyCode == req.CurrencyCode && x.LocalCurrency == req.LocalCurrency).Any()) { return DataResult.Failed("汇率设置已存在!", MultiLanguageConst.FeeCurrencyExchangeExist); } var data = req.Adapt(); var entity = TenantDb.Insertable(data).ExecuteReturnEntity(); return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess); } else { var info = TenantDb.Queryable().Where(x => x.Id == req.Id).First(); info = req.Adapt(info); TenantDb.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand(); return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess); } } /// /// 详情 /// /// /// public DataResult GetFeeCurrencyExchangeInfo(string id) { var data = TenantDb.Queryable() .Where(x => x.Id == long.Parse(id)) .Select() .First(); return DataResult.Success(data, MultiLanguageConst.DataQuerySuccess); } /// /// 获取两种币别之间的汇率 /// /// 币别信息 /// public DataResult GetExchangeRate(ExchangeRate exchange) { if (exchange.CurrencyFrom == exchange.CurrencyTo) { exchange.ReverseRate = exchange.Rate = 1m; return DataResult.Success(exchange); } long id = long.Parse(User.OrgId); //获取本位币,默认=人民币 string localCurrency = Db.Queryable().Where(x => x.Id == id).Select(x => x.LocalCurrency).First() ?? RMB_CODE; //需要做二次转换 if (exchange.CurrencyFrom != localCurrency && exchange.CurrencyTo != localCurrency) { //获取中间汇率 var middleRate = GetLocalRate(exchange.CurrencyFrom, localCurrency, exchange.FeeType); if (middleRate == null) return DataResult.FailedData(exchange, message: $"{MultiLanguageConst.FeeCurrencyNotFound}:{exchange.CurrencyFrom}"); var rate = GetLocalRate(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 == RMB_CODE ? exchange.CurrencyTo : exchange.CurrencyFrom; var rate = GetLocalRate(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.Success(exchange); } internal decimal? GetLocalRate(string currency, string localCurrency, FeeType? type) { var entity = TenantDb.Queryable().Where(x => x.CodeName == currency).Includes(x => x.Exchanges).First(); if (entity == null) return null; var rate = entity.DefaultRate; DateTime dtNow = DateTime.Now; if (type.HasValue && entity.Exchanges != null && entity.Exchanges.Count > 0) { //取当前时间范围内的最新一条,优先获取本位币 var item = entity.Exchanges.FindAll(x => x.Status == StatusEnum.Enable && x.LocalCurrency == localCurrency && x.StartDate >= dtNow && x.EndDate <= dtNow).OrderByDescending(x => x.CreateTime).FirstOrDefault(); item ??= entity.Exchanges.FindAll(x => x.Status == StatusEnum.Enable && x.StartDate >= dtNow && x.EndDate <= dtNow).OrderByDescending(x => x.CreateTime).FirstOrDefault(); if (item != null) rate = type.Value == FeeType.Receivable ? item.DRValue : item.CRValue; } return rate; } } }