Files
zszq-trs/YLErpDAL/Modules/SwapModule/SwapFloatRateService.cs
T

400 lines
18 KiB
C#

using BaseOUDAL;
using Org.BouncyCastle.Ocsp;
using Qdp.Pricing.Library.Base.Utilities;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using YLErp.DBModels;
using YLErp.Helpers;
using YLErp.Model;
using static YLErp.Commons.ExcelHelper;
using YLErp.Modules.SystemModule;
using System.Drawing;
using YLErp.Commons;
using YLErp.Office.ExcelModule;
using YLErp.Office;
using YLErp.DBModels.Consts;
using YLErp.BLL.Calculation;
using OfficeOpenXml;
namespace YLErp.Modules.SwapModule
{
public class SwapFloatRateService : YLBaseService
{
public SwapFloatRateService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 查询浮动利率
/// </summary>
public SearchListResult<SwapFloatRate> SearchList(SwapFloatRateSearchRequest req)
{
var predicate = PredicateBuilder.Create<SwapFloatRate>(n => n.RateMode==req.RateMode);
if (req.StartDate.HasValue)
{
predicate = predicate.And(n => n.StartDate >= req.StartDate.Value);
}
if (req.EndDate.HasValue)
{
predicate = predicate.And(n => n.EndDate <= req.EndDate.Value);
}
if (req.ClientIds!=null&&req.ClientIds.Count > 0)
{
predicate = predicate.And(n => req.ClientIds.Contains(n.ClientId??0));
}
if (!string.IsNullOrEmpty(req.ClientNumber))
{
predicate = predicate.And(x => x.ClientNumber.Contains(req.ClientNumber.Trim()));
}
if (!string.IsNullOrEmpty(req.UnderlyingCodes))
{
var underlyings = req.UnderlyingCodes.Split(",");
predicate = predicate.And(x => underlyings.Contains(x.UnderlyingCode));
}
var rateQuery = DbContext.swap_float_rate.Where(predicate);
var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable();
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "create_time";
req.sord = "desc";
}
var retListResult = rateQuery.ToSearchList(req);
foreach (var item in retListResult.rows)
{
var client = clientQuery.FirstOrDefault(x => x.id == item.ClientId);
item.ClientName = client?.Name;
}
return retListResult;
}
/// <summary>
/// 保存互换浮动利率
/// </summary>
/// <param name="req"></param>
/// <exception cref="Exception"></exception>
public void SaveSwapFloatRate(SwapFloatRate req)
{
ValidateSwapFloatRate(req);
string changeStr = string.Empty;
string changeTitle = "新增";
if (req.id > 0)
{
var swapFloatRate = DbContext.swap_float_rate.Find(req.id);
if (swapFloatRate == null)
{
throw new ServiceException("未找到该浮动利率");
}
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFloatRate.UnderlyingCode);
swapFloatRate.UnderlyingName = underlying?.UnderlyingName;
if (swapFloatRate.ClientId>0)
{
var client = DataCacheProvider.GetClientDataSource().GetData(swapFloatRate.ClientId.Value);
swapFloatRate.ClientName=client?.Name;
swapFloatRate.ClientNumber=client?.Number;
}
var changeList = DataChangeHelper.GetDataChanges(swapFloatRate, req);
changeStr = changeList.ToJson();
changeTitle = "编辑";
swapFloatRate.UnderlyingCode= req.UnderlyingCode;
swapFloatRate.StartDate = req.StartDate;
swapFloatRate.EndDate = req.EndDate;
swapFloatRate.LongPricePoint = req.LongPricePoint;
swapFloatRate.ShortPricePoint = req.ShortPricePoint;
swapFloatRate.BaseUnderlyingCode = req.BaseUnderlyingCode;
swapFloatRate.ClientId = req.ClientId;
swapFloatRate.ClientNumber = req.ClientNumber;
swapFloatRate.ClientName = req.ClientName;
swapFloatRate.interest_type = req.interest_type;
swapFloatRate.interest_rest_days = req.interest_rest_days;
swapFloatRate.interest_rule = req.interest_rule;
swapFloatRate.is_annualized = req.is_annualized;
swapFloatRate.SetOpt(UserId, UserName);
}
else
{
req.SetCreator(UserId, UserName);
req.SetOpt(UserId, UserName);
DbContext.swap_float_rate.Add(req);
}
DbContext.SaveChanges();
new SwapRateLogService(UserInfo).AddSwapRateLog(1, req.id, changeTitle, changeStr, null);
}
/// <summary>
/// 校验数据
/// </summary>
/// <param name="req"></param>
/// <exception cref="ServiceException"></exception>
private void ValidateSwapFloatRate(SwapFloatRate req)
{
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"债券代码{req.UnderlyingCode}不存在");
}
req.UnderlyingName = underlying.UnderlyingName;
}
if (!string.IsNullOrEmpty(req.BaseUnderlyingCode))
{
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.BaseUnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"基准利率代码{req.BaseUnderlyingCode}不存在");
}
req.UnderlyingName = underlying.UnderlyingName;
}
if (req.RateMode== (int)ConstSwapFloatRateEnum.Special)
{
if (!req.ClientId.HasValue)
{
throw new ServiceException("客户名称不能为空");
}
var client = DataCacheProvider.GetClientDataSource().GetData(req.ClientId.Value);
if (client==null)
{
throw new ServiceException("客户名称不存在");
}
req.ClientName = client?.Name;
req.ClientNumber = client?.Number;
}
if (req.StartDate==null)
{
throw new ServiceException("生效起始日不能为空");
}
if (req.EndDate == null)
{
throw new ServiceException("生效终止日不能为空");
}
if (req.StartDate> req.EndDate)
{
throw new ServiceException("生效终止日不能早于生效起始日");
}
if (req.LongPricePoint==null&&req.ShortPricePoint==null)
{
throw new ServiceException("多头价格加点或空头价格减点不能为空");
}
var predicate = PredicateBuilder.Create<SwapFloatRate>(x => x.id != req.id && x.UnderlyingCode == req.UnderlyingCode && x.StartDate <= req.EndDate && x.EndDate >= req.StartDate&&x.RateMode==req.RateMode);
if (req.ClientId>0)
{
predicate = predicate.And(x=>x.ClientId==req.ClientId);
}
if (DbContext.swap_float_rate.Any(predicate))
{
throw new ServiceException($"该生效区间内已经存在浮动利率");
}
}
/// <summary>
/// 删除阶梯费率
/// </summary>
/// <param name="id"></param>
/// <exception cref="Exception"></exception>
public void DeleteSwapFloatRate(int id)
{
var clientRate = DbContext.swap_float_rate.Find(id);
if (clientRate == null)
{
throw new ServiceException("未找到该浮动利率");
}
DbContext.swap_float_rate.Remove(clientRate);
DbContext.SaveChanges();
}
/// <summary>
/// 获取详细
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
public SwapFloatRate GetSwapFloatRate(int id)
{
var swapFloatRate = DbContext.swap_float_rate.Find(id);
if (swapFloatRate == null)
{
throw new ServiceException("未找到该浮动利率");
}
if (swapFloatRate.ClientId>0)
{
var client = DataCacheProvider.GetClientDataSource().GetData(swapFloatRate.ClientId.Value);
swapFloatRate.ClientName = client?.Name;
}
return swapFloatRate;
}
/// <summary>
/// 阶梯费率导入 excel
/// </summary>
/// <param name="streamIn">上传的文件</param>
/// <param name="totalNum">总条数</param>
/// <param name="successNum">成功条数</param>
public void ImportSwapFloatRateFromExcel(Stream streamIn, out int totalNum, out int successNum)
{
totalNum = 0;
successNum = 0;
var rowIndex = 0;
var trans = DbContext.Database.BeginTransaction();
try
{
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
var reader = new DataRowReaderHelper(table);
rowIndex = 1;
totalNum = table.Rows.Count - rowIndex;
var clientList = DataCacheProvider.GetClientDataSource().AsQueryable().ToList();
foreach (var row in table.Rows.Cast<DataRow>().Skip(rowIndex))
{
rowIndex++;
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
totalNum--;
continue;
}
reader.SetDataRow(row, rowIndex);
var swapFloatRate = new SwapFloatRate();
swapFloatRate.UnderlyingCode = reader.GetString("债券代码");
swapFloatRate.BaseUnderlyingCode = reader.GetString("基准利率");
swapFloatRate.StartDate = reader.GetDate("生效起始日",true).Value;
swapFloatRate.EndDate = reader.GetDate("生效终止日", true).Value;
swapFloatRate.interest_rest_days = reader.GetInt32("重置频率", true);
var interestType = reader.GetString("计息方式", true);
if (Enum.TryParse<InterestTypeEnum>(interestType, out InterestTypeEnum parsedInterestType))
{
swapFloatRate.interest_type = (int)parsedInterestType;
}
else
{
// 如果转换失败,可以根据需要处理错误
throw new Exception($"无法将计息方式 '{interestType}' 转换为有效的枚举值");
}
var rule = reader.GetString("利率准则", true);
if (Enum.TryParse<SwapInterestRule>(rule, out SwapInterestRule parsedRule))
{
swapFloatRate.interest_rule = (int)parsedRule;
}
else
{
// 如果转换失败,可以根据需要处理错误
throw new Exception($"无法将利率准则 '{rule}' 转换为有效的枚举值");
}
var is_annualized = reader.GetString("是否年化", true);
swapFloatRate.is_annualized = is_annualized == "是";
swapFloatRate.LongPricePoint = reader.GetDecimal("利差(多头加点)");
swapFloatRate.ShortPricePoint = reader.GetDecimal("利差(空头减点)");
swapFloatRate.ClientName = reader.GetString("客户名称");
if (!string.IsNullOrEmpty(swapFloatRate.ClientName))
{
var client = clientList.FirstOrDefault(x => x.Name == swapFloatRate.ClientName);
if (client == null)
{
throw new ServiceException($"找不到客户名称为{swapFloatRate.ClientName}的客户");
}
swapFloatRate.ClientId = client.id;
swapFloatRate.ClientNumber = client.Number;
}
if (reader.ExistFieldName("客户名称"))
{
swapFloatRate.RateMode = 1;
}
ValidateSwapFloatRate(swapFloatRate);
swapFloatRate.SetCreator(UserId,UserName);
swapFloatRate.SetOpt(UserId, UserName);
DbContext.swap_float_rate.Add(swapFloatRate);
DbContext.SaveChanges();
new SwapRateLogService(UserInfo).AddSwapRateLog(1, swapFloatRate.id, "新增", null, "导入");
successNum++;
}
trans.Commit();
trans.Dispose();
}
catch (Exception ex)
{
trans.Rollback();
trans.Dispose();
LogFactory.GetLogger("导入浮动利率").Error(ex);
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}");
}
}
/// <summary>
/// 浮动利率导出
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
public byte[] exprotSwapFloatRateExcel(SwapFloatRateSearchRequest req)
{
//获取数据
var ret = SearchList(req);
var tplFilePath = OtcAppContext.MapPath("/App_Docs");
var tplName = "浮动利率默认设置导出模板.xlsx";
if (req.RateMode==(int)ConstSwapFloatRateEnum.Special)
{
tplName = "浮动利率特殊设置导出模板.xlsx";
}
var sourceFileName = Path.Combine(tplFilePath, "导出模板", tplName);
var modelDict = new Dictionary<string, object>();
var model = new { list = ret.rows.ToList() };
modelDict.Add("Sheet1", model);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
return new ExcelTemplateGenerator().SetTemplateFile(sourceFileName).SetTemplateData(modelDict).Output();
}
/// <summary>
/// 匹配最适用的浮动利率
/// </summary>
/// <param name="clientId"></param>
/// <param name="underlyingCode"></param>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public SwapFloatRate MatchRate(int clientId,string underlyingCode,DateTime startDate,DateTime? endDate)
{
var predicate = PredicateBuilder.Create<SwapFloatRate>(x => x.StartDate <= startDate);
if (endDate.HasValue)
{
predicate = predicate.And(x=>x.EndDate>=endDate);
}
var query=DbContext.swap_float_rate.Where(predicate);
SwapFloatRate swapFloatRate = GetSwapFloatRate(query,clientId, underlyingCode);
return swapFloatRate;
}
public SwapFloatRate GetSwapFloatRate(IQueryable<SwapFloatRate> query, int clientId, string underlyingCode)
{
SwapFloatRate swapFloatRate = null;
if (!string.IsNullOrEmpty(underlyingCode))
{
swapFloatRate = query.Where(x => x.UnderlyingCode == underlyingCode && x.ClientId == clientId).OrderByDescending(o => o.StartDate).FirstOrDefault();//取特殊逻辑 客户+标的
if (swapFloatRate != null)
{
return swapFloatRate;
}
}
swapFloatRate = query.Where(x => x.ClientId == clientId&&string.IsNullOrEmpty(x.UnderlyingCode)).OrderByDescending(o => o.StartDate).FirstOrDefault();//取特殊逻辑 客户+空标的
if (swapFloatRate != null)
{
return swapFloatRate;
}
if (!string.IsNullOrEmpty(underlyingCode))
{
swapFloatRate = query.Where(x => x.UnderlyingCode == underlyingCode&& x.RateMode == 0).OrderByDescending(o => o.StartDate).FirstOrDefault();//取默认逻辑 标的
if (swapFloatRate != null)
{
return swapFloatRate;
}
}
swapFloatRate = query.Where(x=>x.RateMode==0&&string.IsNullOrEmpty(x.UnderlyingCode)).OrderByDescending(o => o.StartDate).FirstOrDefault();//取默认逻辑 空标的
return swapFloatRate;
}
}
}