using BaseOUDAL; using NPOI.SS.Formula.Functions; using System.Collections.Specialized; using System.Linq; using YLErp.BLL; using YLErp.Model.Enum; using YLErp.Modules.EodModule.QueryModule; namespace YLErp.Modules.FinancialModule { /// /// 用友财务凭证服务 /// public class YYFinancialVoucherService : YLBaseService { DateTime _valueDate; private static Dictionary YYClientCodes = new Dictionary(); private static List ExcludedClients = new List(); private static List ExcludedTrade = new List { "商品期货", "场内期权" }; private readonly NameValueCollection _kemuCodeNv; public YYFinancialVoucherService(OptUserInfo userInfo) : base(userInfo) { _valueDate = valuedateBLL.ValueDate; using (var db = new ErpBaseContext()) { var dictId = db.Dictionaries.FirstOrDefault(x => x.Name == "用友客商编码")?.Id; if (dictId != null) { YYClientCodes = db.DictionaryItems.Where(x => x.DictId == dictId).ToDictionary(x => x.Name, x => x.ShortName); } var dictId2 = db.Dictionaries.FirstOrDefault(x => x.Name == "财务凭证排除客户项")?.Id; if (dictId2 != null) { ExcludedClients = db.DictionaryItems.Where(x => x.DictId == dictId2).Select(x => x.ShortName).ToList(); } _kemuCodeNv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode); } } /// /// 获取客商编码 /// /// /// private string GetClientYYCode(string namekey) { if (!string.IsNullOrWhiteSpace(namekey) && YYClientCodes.Any()) { if (YYClientCodes.ContainsKey(namekey)) { return YYClientCodes[namekey]; } } return string.Empty; } /// /// 获得出入金数据 /// /// /// public List GetCashInOutData(FinancialVoucherReq req) { var result = new List(); using (var db = new YLContext()) { var states = new List { "已确认", "已结算" }; var directions = new List { "出金", "入金" }; var cashInCashOutQuery = from cico in db.ClientCashInCashOut where directions.Contains(cico.Direction) && !ExcludedClients.Contains(cico.ClientName) && cico.ValidState != "InValid" && states.Contains(cico.State) select cico; if (req.StartDate != DateTime.MinValue && req.StartDate != default) { cashInCashOutQuery = cashInCashOutQuery.Where(d => d.HappenDate >= req.StartDate); } if (req.EndDate != DateTime.MinValue && req.EndDate != default) { DateTime HappenDateTemp = req.EndDate.AddDays(1); cashInCashOutQuery = cashInCashOutQuery.Where(d => d.HappenDate < HappenDateTemp); } var cashInCashOutList = cashInCashOutQuery.OrderByDescending(x => x.HappenDate).ToList(); var vextNum = 1; foreach (var cash in cashInCashOutList) { var isSeller = (cash.Direction == "入金") ? true : false; var lastStr = isSeller ? "期权交易入金款" : "期权交易出金款"; var tmpfcdto = new FinancialVoucherDto() { VoucherDate = cash.HappenDate?.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = $"{(isSeller ? "收到" : "支付") + cash.ClientName + lastStr}", SubjectCode = _kemuCodeNv[isSeller ? "出入金入金" : "出入金出金"], Debtor = Math.Abs(cash.Money ?? 0).OtcFormatMoney(grouping: false), Creditor = "", AccountingItem = isSeller ? "银行账户+100FX13R9997" : $"客商辅助核算+{GetClientYYCode(cash.ClientName)}", }; result.Add(tmpfcdto); var tmpfcPairdto = new FinancialVoucherDto() { VoucherDate = cash.HappenDate?.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = $"{(isSeller ? "收到" : "支付") + cash.ClientName + lastStr}", SubjectCode = _kemuCodeNv[isSeller ? "出入金出金" : "出入金入金"], Debtor = "", Creditor = Math.Abs(cash.Money ?? 0).OtcFormatMoney(grouping: false), AccountingItem = isSeller ? $"客商辅助核算+{GetClientYYCode(cash.ClientName)}" : "银行账户+100FX13R9997" }; result.Add(tmpfcPairdto); } } return result; } /// /// 获得成交数据 /// /// /// public List GetOTCConfirmedData(FinancialVoucherReq req) { var result = new List(); using (var db = new YLContext()) { var tradesQuery = from tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && !ExcludedTrade.Contains(c.TradeType) && c.ValidState != "InValid") select tds; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.TradeDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.TradeDate); } var tradesList = tradesQuery.OrderByDescending(x => x.TradeDate).ToList(); var vextNum = 1; foreach (var trade in tradesList) { var isBuyer = IsBuyer(trade.BuySell); var tmpfcdto = new FinancialVoucherDto() { VoucherDate = trade.TradeDate?.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = $"{(isBuyer ? "应付" : "应收") + trade.ClientName + "商品场外期权费" + trade.TradeNumber}", SubjectCode = _kemuCodeNv[isBuyer ? "借方成交入金" : "借方成交出金"], Debtor = Math.Abs(trade.TradePrice ?? 0).OtcFormatMoney(grouping: false), Creditor = "", AccountingItem = isBuyer ? "" : $"客商辅助核算+{GetClientYYCode(trade.ClientName)}", }; result.Add(tmpfcdto); var tmpfcPairdto = new FinancialVoucherDto() { VoucherDate = trade.TradeDate?.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = $"{(isBuyer ? "应付" : "应收") + trade.ClientName + "商品场外期权费" + trade.TradeNumber}", SubjectCode = _kemuCodeNv[isBuyer ? "贷方成交出金" : "贷方成交入金"], Debtor = "", Creditor = Math.Abs(trade.TradePrice ?? 0).OtcFormatMoney(grouping: false), AccountingItem = isBuyer ? $"客商辅助核算+{GetClientYYCode(trade.ClientName)}" : "" }; result.Add(tmpfcPairdto); } } return result; } /// /// 获得部分/提前终止数据 /// /// /// public List GetOTCMaturityData(FinancialVoucherReq req) { var result = new List(); using (var db = new YLContext()) { //一次提前终止 产生四条记录 var tradesQuery = from tcs in db.trade_cash.Where(c => c.Action == "系统操作-平仓费" && c.ValidState != "InValid" && !c.IsDeleted) join td in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && !ExcludedTrade.Contains(c.TradeType)) on tcs.TradeId equals td.id select tcs; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.ValueDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.ValueDate); } var tcList = tradesQuery.OrderByDescending(x => x.ValueDate).ToList(); var vextNum = 1; foreach (var cash in tcList) { var trade = db.trade.Find(cash.TradeId); if (trade == null) { continue; } var isBuyer = IsBuyer(trade.BuySell); var notional = cash.Action == ClientCashInCashOut.系统操作_行权费 ? cash.Notional : (cash.UnwindNotional ?? 0); var occupyRate = cash.UnwindPercentRate; var amount = Math.Abs(cash.Amount).OtcFormatMoney(grouping: false); var partTradePrice = Math.Abs(((occupyRate ?? 0) * (trade.TradePrice ?? 0))).OtcFormatMoney(grouping: false); var summary = $"确认{trade.ClientName + "商品场外期权提前终止投资收益" + trade.TradeNumber}";////确认&公司名称&商品场外期权提前终止投资收益&交易编号 //终止部分-期权费 var tmpfcdto = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "借方期权费入金" : "借方期权费出金"], Debtor = partTradePrice, Creditor = "", AccountingItem = isBuyer ? "部门档案+008" : "", }; result.Add(tmpfcdto); var tmpfcPairdto = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "贷方期权费出金" : "贷方期权费入金"], Debtor = "", Creditor = partTradePrice, AccountingItem = isBuyer ? $"" : "部门档案+008" }; result.Add(tmpfcPairdto); //终止部分-终止费 if (double.Parse(amount) != 0) { var tmpfcPairdto2 = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "借方终止费入金" : "借方终止费出金"], Debtor = amount, Creditor = "", AccountingItem = isBuyer ? $"客商辅助核算+{GetClientYYCode(trade.ClientName)}" : "部门档案+008" }; result.Add(tmpfcPairdto2); var tmpfcPairdto3 = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "贷方终止费出金" : "贷方终止费入金"], Debtor = "", Creditor = amount, AccountingItem = isBuyer ? "部门档案+008" : $"客商辅助核算+{GetClientYYCode(trade.ClientName)}" }; result.Add(tmpfcPairdto3); } } } return result; } /// /// 获得部分/到期数据 /// /// /// public List GetOTCTerminationData(FinancialVoucherReq req) { var result = new List(); using (var db = new YLContext()) { //一次提前终止 产生四条记录 var tradesQuery = from tcs in db.trade_cash.Where(c => c.Action == "系统操作-行权费" && c.ValidState != "InValid" && !c.IsDeleted) join td in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && !ExcludedTrade.Contains(c.TradeType)) on tcs.TradeId equals td.id select tcs; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.ValueDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.ValueDate); } var tcList = tradesQuery.OrderByDescending(x => x.ValueDate).ToList(); var vextNum = 1; foreach (var cash in tcList) { var trade = db.trade.Find(cash.TradeId); if (trade == null) { continue; } var isBuyer = IsBuyer(trade.BuySell); var notional = cash.Action == ClientCashInCashOut.系统操作_行权费 ? (cash.Notional) : (cash.UnwindNotional ?? 0); var occupyRate = cash.UnwindPercentRate; var amount = Math.Abs(cash.Amount).OtcFormatMoney(grouping: false); var summary = $"确认{trade.ClientName + "商品场外期权到期投资收益" + trade.TradeNumber}";////确认&公司名称&商品场外期权提前终止投资收益&交易编号 //终止部分-期权费 var tmpfcdto = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "借方期权费入金" : "借方期权费出金"], Debtor = Math.Abs(((occupyRate ?? 0) * (trade.TradePrice ?? 0))).OtcFormatMoney(grouping: false), Creditor = "", AccountingItem = isBuyer ? "部门档案+008" : "", }; result.Add(tmpfcdto); var tmpfcPairdto = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "贷方期权费出金" : "贷方期权费入金"], Debtor = "", Creditor = Math.Abs((occupyRate ?? 0) * (trade.TradePrice ?? 0)).OtcFormatMoney(grouping: false), AccountingItem = isBuyer ? $"" : "部门档案+008" }; result.Add(tmpfcPairdto); //终止部分-终止费 if (double.Parse(amount) != 0 && !( (trade.OptionType == "看涨" && trade.Strike > cash.FinalPrice) || (trade.OptionType == "看跌" && trade.Strike < cash.FinalPrice)) ) //虚值行权 { var tmpfcPairdto2 = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "借方终止费入金" : "借方终止费出金"], Debtor = amount, Creditor = "", AccountingItem = isBuyer ? $"客商辅助核算+{GetClientYYCode(trade.ClientName)}" : "部门档案+008" }; result.Add(tmpfcPairdto2); var tmpfcPairdto3 = new FinancialVoucherDto() { VoucherDate = cash.ValueDate.ToString("yyyy-MM-dd"), VoucherExtNum = vextNum++, Summary = summary, SubjectCode = _kemuCodeNv[isBuyer ? "贷方终止费出金" : "贷方终止费入金"], Debtor = "", Creditor = amount, AccountingItem = isBuyer ? "部门档案+008" : $"客商辅助核算+{GetClientYYCode(trade.ClientName)}" }; result.Add(tmpfcPairdto3); } } } return result; } private bool IsBuyer(string srcStr) { if (srcStr == "空头开仓" || srcStr == "多头平仓" || srcStr == "卖出") { return false; } if (srcStr == "多头开仓" || srcStr == "空头平仓" || srcStr == "买入") { return true; } return false; } #region 中粮用友导出数据 /// /// 客户买权成交 /// /// /// public List GetBuyDealData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "卖出" && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") select tds; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.TradeDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.TradeDate); } var tradesList = tradesQuery.OrderByDescending(x => x.TradeDate).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var amount = tradesList.Where(n => n.ClientId == clientId).Sum(x => x.TradePrice).OtcFormatMoney(); var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["借方期权费(买权)"], Currency = "CNY", Debtor = amount, LocalDebtor = amount, AccountingItem1 = ksCode, }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方期权费(买权)"], Currency = "CNY", Creditor = amount, LocalCreditor = amount, AccountingItem1 = "00061195:部门", AccountingItem2 = ksCode, }; result.Add(creditDate); } } return result; } /// /// 客户买权持仓盈亏 /// /// /// public List GetBuyPositionLossData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "卖出" && ConsTrade.PositionTradeStatusList.Contains(c.TradeStatus) && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") select tds; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.TradeDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.TradeDate); } var tradesList = tradesQuery.OrderByDescending(x => x.TradeDate).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var tradeIdList = tradesList.Select(n => n.id).ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); var eodTrade = db.eod_trade_position.Where(n => tradeIdList.Contains(n.TradeId)).ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var positionPnL = eodTrade.Where(n => n.ClientId == clientId).Sum(x => x.PositionPnL).OtcFormatMoney(); var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["借方浮动盈亏(买权)"], Currency = "CNY", Debtor = positionPnL, LocalDebtor = positionPnL, AccountingItem2 = ksCode, }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方浮动盈亏(买权)"], Currency = "CNY", Creditor = positionPnL, LocalCreditor = positionPnL, AccountingItem2 = "yspywbgt:人员档案", AccountingItem3 = ksCode, AccountingItem4 = "0011195:产品信息", }; result.Add(creditDate); } } return result; } /// /// 客户买权平仓盈亏 /// /// /// public List GetBuyCloseLossesData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tdCash in db.trade_cash join tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "卖出" && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") on tdCash.TradeId equals tds.id where (tdCash.Action == "系统操作-平仓费" || tdCash.Action == "系统操作-行权费") && tdCash.ValidState != "InValid" && !tdCash.IsDeleted select new { tdCash, tds }; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.tdCash.ValueDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.tdCash.ValueDate); } var tradesList = tradesQuery.OrderByDescending(x => x.tds.TradeDate).Select(x => x.tds).ToList(); var tradeCashList = tradesQuery.OrderByDescending(x => x.tdCash.ValueDate).Select(x => x.tdCash).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var curTradeList = tradesList.Where(n => n.ClientId == clientId).ToList(); // 开仓权利金 var amount = curTradeList.Sum(x => x.TradePrice); var winLoss = 0D; foreach (var item in curTradeList) { var curTradeCashList = tradeCashList.Where(n => n.TradeId == item.id).ToList(); foreach (var cashItem in curTradeCashList) { //交易都是卖出 //winLoss += cashItem.Amount + (item.TradePrice ?? 0) * (cashItem.UnwindPercentRate ?? 0) * 1; winLoss += CalculationModule.TradeCalcHelper.CalcWinLoss(item.TradeType, item.BuySell, (item.TradePrice ?? 0), (cashItem.UnwindPercentRate ?? 0), cashItem.Amount); } } var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["借方终止成本(买权)"], Currency = "CNY", Debtor = amount.OtcFormatMoney(), LocalDebtor = amount.OtcFormatMoney(), AccountingItem1 = "00061195:部门", AccountingItem2 = ksCode, Abstract = "平仓买权成本" }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方终止盈亏(买权)"], Currency = "CNY", Creditor = winLoss.OtcFormatMoney(), LocalCreditor = winLoss.OtcFormatMoney(), AccountingItem1 = "00061195:部门", AccountingItem2 = "yspywbgt:人员档案", AccountingItem3 = ksCode, AccountingItem4 = "0011195:产品信息", Abstract = "平仓买权盈亏" }; var creditDate2 = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方终止往来(买权)"], Currency = "CNY", Creditor = (amount - winLoss).OtcFormatMoney(), LocalCreditor = (amount - winLoss).OtcFormatMoney(), AccountingItem1 = ksCode, Abstract = "平仓买权往来" }; result.Add(creditDate); result.Add(creditDate2); } } return result; } /// /// 客户卖权成交 /// /// /// public List GetSellDealData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "买入" && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") select tds; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.TradeDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.TradeDate); } var tradesList = tradesQuery.OrderByDescending(x => x.TradeDate).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var amount = tradesList.Where(n => n.ClientId == clientId).Sum(x => x.TradePrice).OtcFormatMoney(); var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["借方期权费(卖权)"], Currency = "CNY", Debtor = amount, LocalDebtor = amount, AccountingItem1 = "00061195:部门", AccountingItem2 = ksCode, AccountingItem3 = "0011195:产品信息" }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方期权费(卖权)"], Currency = "CNY", Creditor = amount, LocalCreditor = amount, AccountingItem1 = ksCode, }; result.Add(creditDate); } } return result; } /// /// 客户卖权持仓盈亏 /// /// /// public List GetSellPositionLossData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "买入" && ConsTrade.PositionTradeStatusList.Contains(c.TradeStatus) && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") select tds; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.TradeDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.TradeDate); } var tradesList = tradesQuery.OrderByDescending(x => x.TradeDate).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var tradeIdList = tradesList.Select(n => n.id).ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); var eodTrade = db.eod_trade_position.Where(n => tradeIdList.Contains(n.TradeId)).ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var positionPnL = eodTrade.Where(n => n.ClientId == clientId).Sum(x => x.PositionPnL).OtcFormatMoney(); var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["借方浮动盈亏(卖权)"], Currency = "CNY", Debtor = positionPnL, LocalDebtor = positionPnL, AccountingItem2 = ksCode, AccountingItem3 = "0011195:产品信息", }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方浮动盈亏(卖权)"], Currency = "CNY", Creditor = positionPnL, LocalCreditor = positionPnL, AccountingItem2 = "yspywbgt:人员档案", AccountingItem3 = ksCode, AccountingItem4 = "0011195:产品信息", }; result.Add(creditDate); } } return result; } /// /// 客户卖权平仓盈亏 /// /// /// public List GetSellCloseLossesData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var tradesQuery = from tdCash in db.trade_cash join tds in db.trade.Where(c => !ExcludedClients.Contains(c.ClientName) && c.ValidState != "InValid" && c.BuySell == "买入" && (c.TradeType != "结构化交易" || c.IsGroup == 1) && c.TradeType != "收益互换") on tdCash.TradeId equals tds.id where (tdCash.Action == "系统操作-平仓费" || tdCash.Action == "系统操作-行权费") && tdCash.ValidState != "InValid" && !tdCash.IsDeleted select new { tdCash, tds }; if (req.StartDate != default) { tradesQuery = tradesQuery.Where(x => x.tdCash.ValueDate >= req.StartDate); } if (req.EndDate != default) { tradesQuery = tradesQuery.Where(x => req.EndDate >= x.tdCash.ValueDate); } var tradesList = tradesQuery.OrderByDescending(x => x.tds.TradeDate).Select(x => x.tds).ToList(); var tradeCashList = tradesQuery.OrderByDescending(x => x.tdCash.ValueDate).Select(x => x.tdCash).ToList(); var clientIdList = tradesList.Select(n => n.ClientId).Distinct().ToList(); var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); foreach (var clientId in clientIdList) { var client = clients.FirstOrDefault(n => n.id == clientId); var curTradeList = tradesList.Where(n => n.ClientId == clientId).ToList(); // 开仓权利金 var amount = curTradeList.Sum(x => x.TradePrice); var winLoss = 0D; foreach (var item in curTradeList) { var curTradeCashList = tradeCashList.Where(n => n.TradeId == item.id).ToList(); foreach (var cashItem in curTradeCashList) { //交易都是买入 //winLoss += cashItem.Amount + ((item.TradePrice ?? 0) * (cashItem.UnwindPercentRate ?? 0) * -1); winLoss += CalculationModule.TradeCalcHelper.CalcWinLoss(item.TradeType, item.BuySell, (item.TradePrice ?? 0), (cashItem.UnwindPercentRate ?? 0), cashItem.Amount); } } var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方终止成本(卖权)"], Currency = "CNY", Creditor = amount.OtcFormatMoney(), LocalCreditor = amount.OtcFormatMoney(), AccountingItem1 = "00061195:部门", AccountingItem2 = ksCode, AccountingItem3 = "0011195:产品信息", Abstract = "平仓卖权成本" }; result.Add(debitData); var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方终止盈亏(卖权)"], Currency = "CNY", Creditor = winLoss.OtcFormatMoney(), LocalCreditor = winLoss.OtcFormatMoney(), AccountingItem1 = "00061195:部门", AccountingItem2 = "yspywbgt:人员档案", AccountingItem3 = ksCode, AccountingItem4 = "0011195:产品信息", Abstract = "平仓卖权盈亏" }; var creditDate2 = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakingPerson = req.MakingPerson, MakeDate = now, AccountCode = nv["贷方终止往来(卖权)"], Currency = "CNY", Creditor = ((amount + winLoss) * -1).OtcFormatMoney(), LocalCreditor = ((amount + winLoss) * -1).OtcFormatMoney(), AccountingItem1 = ksCode, Abstract = "平仓卖权往来" }; result.Add(creditDate); result.Add(creditDate2); } } return result; } /// /// 客户出入金 /// /// /// public List GetDepositWithdrawData(ZLFinancialVoucherReq req) { var result = new List(); var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.YongYouKeMuCode) ?? new System.Collections.Specialized.NameValueCollection(); var now = DateTime.Now.ToString("yyyy-MM-dd"); using (var db = new YLContext()) { var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList(); var states = new List { "已确认", "已结算" }; var directions = new List { "出金", "入金" }; var cashInCashOutQuery = from cico in db.ClientCashInCashOut where directions.Contains(cico.Direction) && !ExcludedClients.Contains(cico.ClientName) && cico.ValidState != "InValid" && states.Contains(cico.State) select cico; if (req.StartDate != DateTime.MinValue && req.StartDate != default) { cashInCashOutQuery = cashInCashOutQuery.Where(d => d.HappenDate >= req.StartDate); } if (req.EndDate != DateTime.MinValue && req.EndDate != default) { DateTime HappenDateTemp = req.EndDate.AddDays(1); cashInCashOutQuery = cashInCashOutQuery.Where(d => d.HappenDate < HappenDateTemp); } var cashInCashOutList = cashInCashOutQuery.OrderByDescending(x => x.HappenDate).ToList(); foreach (var cash in cashInCashOutList) { var client = clients.FirstOrDefault(n => n.id == cash.ClientId); var ksCode = $"{GetClientYYCode(client.Name)}:客商"; var isDeposit = false; if (cash.Direction == "入金") { isDeposit = true; } var debitData = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakeDate = now, MakingPerson = req.MakingPerson, Abstract = $"{cash.HappenDate?.ToString("yyyyMMdd")}{client.Name}场外期权{cash.Direction}", AccountCode = nv[$"借方{cash.Direction}"], Currency="CNY", Debtor=cash.Money.OtcFormatMoney(), LocalDebtor=cash.Money.OtcFormatMoney(), }; var creditDate = new ZLFinancialVoucherDto { VoucherNumber = req.VoucherNumber, MakeDate = now, MakingPerson = req.MakingPerson, Abstract = $"{cash.HappenDate?.ToString("yyyyMMdd")}{client.Name}场外期权{cash.Direction}", AccountCode = nv[$"贷方{cash.Direction}"], Currency = "CNY", Creditor = cash.Money.OtcFormatMoney(), LocalCreditor = cash.Money.OtcFormatMoney(), }; //入金 if (isDeposit) { debitData.AccountingItem1 = ksCode; creditDate.AccountingItem1 = "110060194018010018096:银行账户"; creditDate.AccountingItem2 = "02:使用权是否受限"; } //出金 else { debitData.AccountingItem1 = "110060194018010018096:银行账户"; debitData.AccountingItem2 = "02:使用权是否受限"; creditDate.AccountingItem1 = ksCode; } result.Add(debitData); result.Add(creditDate); } } return result; } } #endregion } /// /// 请求参数 /// public class FinancialVoucherReq { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public FinancialVoucher_YongYouEnum VoucherType { get; set; } } /// /// 用友-导出凭证模型 /// public class FinancialVoucherDto { /// /// 制单日期 /// public string VoucherDate { get; set; } /// /// 凭证分录号 /// public int VoucherExtNum { get; set; } /// /// 摘要 /// public string Summary { get; set; } /// /// 科目编码 /// public string SubjectCode { get; set; } /// /// 原币借方 /// public string Debtor { get; set; } /// /// 原币贷方 /// public string Creditor { get; set; } /// /// 核算项1 /// public string AccountingItem { get; set; } } /// /// 请求参数 /// public class ZLFinancialVoucherReq { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public FinancialVoucher_YongYouEnum_ZhongLiang ZLVoucherType { get; set; } /// /// 凭证号,中粮用友导出凭证用 /// public string VoucherNumber { get; set; } /// /// 制单人,中粮用友导出凭证用 /// public string MakingPerson { get; set; } } /// /// 中粮用友-导出凭证模型 /// public class ZLFinancialVoucherDto { /// /// 凭证号 /// public string VoucherNumber { get; set; } /// /// 制单人 /// public string MakingPerson { get; set; } /// /// 制单日期 导出日期 /// public string MakeDate { get; set; } /// /// 摘要 /// public string Abstract { get; set; } /// /// 科目编码 /// public string AccountCode { get; set; } /// /// 币种 /// public string Currency { get; set; } /// /// 原币借方 /// public string Debtor { get; set; } /// /// 本币借方 /// public string LocalDebtor { get; set; } /// /// 原币贷方 /// public string Creditor { get; set; } /// /// 本币贷方 /// public string LocalCreditor { get; set; } /// /// 核算项1 /// public string AccountingItem1 { get; set; } /// /// 核算项2 /// public string AccountingItem2 { get; set; } /// /// 核算项3 /// public string AccountingItem3 { get; set; } /// /// 核算项4 /// public string AccountingItem4 { get; set; } }