using YLErp.BLL; namespace YLErp.Modules.ClientModule { /// /// /// public class ClientSpanService : YLBaseService { public ClientSpanService(OptUserInfo userInfo) : base(userInfo) { } private void CheckModel(ClientMarginModifyRequestModel reqModel, out Client client) { client = null; if (reqModel == null) { throw new ServiceException("实体不能为空"); } if (reqModel.ClientId < 1) { throw new ServiceException("客户不能为空"); } if (reqModel.ValueDate == null) { throw new ServiceException("日期不能为空"); } client = DataCacheProvider.GetClientDataSource().GetData(reqModel.ClientId); if (reqModel.HoldingDeposit > 0 && (client != null && client.MarginOptionType != 1 || client == null)) { throw new ServiceException("预付金占用值不能大于0"); } if (client == null) { throw new ServiceException("系统中没有此客户"); } } public bool UpdateWorstCastClientPayable(ClientMarginModifyRequestModel reqModel) { CheckModel(reqModel, out var client); var worstCastClientPayable = 0.0; var clientSpan = DbContext.client_span.FirstOrDefault(c => c.ClientId == reqModel.ClientId && c.ValueDate == reqModel.ValueDate && c.SpanType == ClientSpan.SpanType_Eod); if (clientSpan == null) { clientSpan = new ClientSpan { ClientId = reqModel.ClientId, ValueDate = reqModel.ValueDate, Spv1 = reqModel.HoldingDeposit, Spv2 = reqModel.HoldingDeposit, Spv3 = reqModel.HoldingDeposit, Spv4 = reqModel.HoldingDeposit, SpanType = ClientSpan.SpanType_Eod }; DbContext.client_span.Add(clientSpan); } worstCastClientPayable = clientSpan.WorstCastClientPayable ?? 0; clientSpan.SetOpt(UserInfo); clientSpan.WorstCastClientPayable = reqModel.HoldingDeposit; clientSpan.ModifiedFlag = true; DbContext.SystemLogs.Add(new SystemLog { EventCategory = "结算报告", EventName = "客户预付金占用", EventData = JsonHelper.Serialize(new { clientSpan.ClientId, ClientNumber = client?.Number, ValueDate = clientSpan.ValueDate.OtcFormatDate(), clientSpan.WorstCastClientPayable }), Remark = $"客户:{client?.Name},日期:{clientSpan.ValueDate.OtcFormatDate()},预付金占用更新为:{clientSpan.WorstCastClientPayable.OtcFormatFlex(2)}" }).Entity.SetOpt(UserInfo); DbContext.SaveChanges(); LogFactory.GetLogger().Info($"{UserName}用户在{DateTime.Now}将客户Id为{reqModel.ClientId}在{reqModel.ValueDate}结算日的预付金占用由{worstCastClientPayable}改为{reqModel.HoldingDeposit}"); ReCalcBalance(reqModel.ValueDate.Value, clientSpan, (client.IsTradeCredit ?? 0) == 1); return true; } public bool UnlockWorstCastClientPayable(ClientMarginModifyRequestModel reqModel) { CheckModel(reqModel, out var client); var clientSpan = DbContext.client_span.FirstOrDefault(c => c.ClientId == reqModel.ClientId && c.ValueDate == reqModel.ValueDate && c.SpanType == ClientSpan.SpanType_Eod); if (clientSpan == null) { return false; } clientSpan.OptId = UserId; clientSpan.OptName = UserName; clientSpan.OptDate = DateTime.Now; clientSpan.ModifiedFlag = false; DbContext.SaveChanges(); LogFactory.GetLogger().Info($"{UserName}用户在{DateTime.Now}将客户Id为{reqModel.ClientId}在{reqModel.ValueDate}结算日的预付金占用修改锁定给解除了"); return true; } /// /// 修改预付金占用后,重新结算 /// private void ReCalcBalance(DateTime valueDate, ClientSpan clientSpan, bool isTradeCredit) { var clientBalanceDaily = DbContext.ClientBalanceDaily.FirstOrDefault(c => c.ClientId == clientSpan.ClientId && c.BalanceDate == valueDate); if (clientBalanceDaily == null) { return; } //预付金可取上浮比率 var marginRatio = valuedateBLL.SystemDate.MarginRatio ?? 0.15; var marginMaxRatio = marginRatio + 0.02; #region 应缴预付金 预付金余额 可取预付金 追保额度 //预付金占用 var payableMargin = clientSpan == null || clientSpan.WorstCastClientPayable == null ? 0.0 : clientSpan.WorstCastClientPayable.Value; var twoSideMargin = clientSpan == null ? 0.0 : clientSpan.TwoSideMargin ?? 0.0; var otherSideMargin = clientSpan == null ? 0.0 : clientSpan.OtherSideMargin ?? 0.0; var mySideMargin = clientSpan == null ? 0.0 : clientSpan.MySideMargin ?? 0.0; var deltaMargin = clientSpan == null ? 0.0 : clientSpan.DeltaMargin ?? 0.0; //预付金余额 var marginBalance = clientBalanceDaily.MarginBalance ?? 0; //可取预付金为预付金余额 - 应缴预付金(上浮2%) var advisableMargin = Math.Max(marginBalance + payableMargin * marginMaxRatio / marginRatio, 0); //计算追保金额 维持预付金带方向 所以计算追保金额是 为相加 //var isTradeCredit = (client.IsTradeCredit ?? 0) == 1; double lineOfCredit; #region 客户授信 资信等级 //获取客户授信 var credits = DbContext.credit.Where(t => t.ClientId == clientSpan.ClientId); if (credits.Any()) { lineOfCredit = credits.Sum(t => t.Credit ?? 0); } else { lineOfCredit = 0.0; } #endregion double margin; //是否期权费授信 if (isTradeCredit) { margin = Math.Min(marginBalance + lineOfCredit + payableMargin, 0); } else { //期权费授信不可以支付权利金时 margin = Math.Min(Math.Max(marginBalance, 0) + lineOfCredit + payableMargin, 0) + Math.Min(marginBalance, 0); } #endregion #region 重新保存clientbalancedaily和clientbalance clientBalanceDaily.PayableMargin = payableMargin; clientBalanceDaily.TwoSideMargin = twoSideMargin; clientBalanceDaily.OtherSideMargin = otherSideMargin; clientBalanceDaily.MySideMargin = mySideMargin; clientBalanceDaily.DeltaMargin = deltaMargin; clientBalanceDaily.AdvisableMargin = advisableMargin; clientBalanceDaily.Margin = margin; clientBalanceDaily.IsPayableMarginManual = true; DbContext.SaveChanges(); #endregion } } public class ClientMarginModifyRequestModel { public int ClientId { get; set; } public DateTime? ValueDate { get; set; } public double HoldingDeposit { get; set; } } }