diff --git a/Framework/YLErp.Core/Configuration/Abstract/IErpConfig.cs b/Framework/YLErp.Core/Configuration/Abstract/IErpConfig.cs index 8e00b1b4..5e597013 100644 --- a/Framework/YLErp.Core/Configuration/Abstract/IErpConfig.cs +++ b/Framework/YLErp.Core/Configuration/Abstract/IErpConfig.cs @@ -696,6 +696,12 @@ namespace YLErp.Configuration /// 确认书生成时是否自动用印 /// bool IsAutoSealAfterGeneratedBook { get; } + + /// + /// 收益互换浮动收益端默认为我方收取,并隐藏收支方向 + /// + bool SwapFloatingIncomeReceiveOnlyMode { get; } + /// /// 衡泰内证账号 /// @@ -725,4 +731,4 @@ namespace YLErp.Configuration /// string EodExecCallbackUrl { get; } } -} \ No newline at end of file +} diff --git a/Framework/YLErp.Core/Configuration/ProjectSettings.cs b/Framework/YLErp.Core/Configuration/ProjectSettings.cs index f88f6d9c..7b4fe8ca 100644 --- a/Framework/YLErp.Core/Configuration/ProjectSettings.cs +++ b/Framework/YLErp.Core/Configuration/ProjectSettings.cs @@ -811,6 +811,12 @@ namespace YLErp /// 确认书生成时是否自动用印 /// public bool IsAutoSealAfterGeneratedBook { get; set; } = false; + + /// + /// 收益互换浮动收益端默认为我方收取,并隐藏收支方向 + /// + public bool SwapFloatingIncomeReceiveOnlyMode { get; set; } = false; + /// /// 衡泰内证账号 /// @@ -842,4 +848,4 @@ namespace YLErp public string EodExecCallbackUrl { get; set; } = string.Empty; } } -} \ No newline at end of file +} diff --git a/YLErpDAL/Modules/AppModule/AppUpgrader.cs b/YLErpDAL/Modules/AppModule/AppUpgrader.cs index 945744b1..583afcb1 100644 --- a/YLErpDAL/Modules/AppModule/AppUpgrader.cs +++ b/YLErpDAL/Modules/AppModule/AppUpgrader.cs @@ -306,6 +306,7 @@ namespace YLErp.Modules.AppModule //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.IsAutoSealAfterGeneratedBook", "false", "bool", "确认书生成时是否自动用印(IsAutoSealAndUploadFiles勾选时生效)"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ReportFileBeginNumber", "0", "int", "报送文件开始编号"); + configService.AddDataIfNotExists("ProjectConfig", "Erp.SwapFloatingIncomeReceiveOnlyMode", "false", "bool", "收益互换浮动收益端默认为我方收取,并隐藏收支方向"); RemoveUnUsed(configService); } diff --git a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml index 4d3d6a5a..0e702cde 100644 --- a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml +++ b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml @@ -4,6 +4,7 @@ Layout = "~/Views/Shared/_InfoLayout.cshtml"; bool isUseApproval = ViewBag.isUseApproval; bool isShowReCheckClose = ViewBag.IsShowReCheckClose; + bool hideFloatingIncomeDirection = PS.Config.ErpElement.SwapFloatingIncomeReceiveOnlyMode; } @section CSS{ @@ -140,7 +141,10 @@ - + @if (!hideFloatingIncomeDirection) + { + + } @@ -154,7 +158,10 @@ - + @if (!hideFloatingIncomeDirection) + { + + } diff --git a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml index d7683a3b..184177a4 100644 --- a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml +++ b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml @@ -4,6 +4,7 @@ Layout = "~/Views/Shared/_InfoLayout.cshtml"; bool isUseApproval = ViewBag.isUseApproval; bool isShowReCheckClose = ViewBag.IsShowReCheckClose; + bool hideFloatingIncomeDirection = PS.Config.ErpElement.SwapFloatingIncomeReceiveOnlyMode; } @section CSS{ @@ -179,7 +180,10 @@
收支方向收支方向多空方向 标的代码 期初标的交割全价%浮动端平仓盈亏
{{floatPosition.PayDirection==1?"收取":"支付"}}{{floatPosition.PayDirection==1?"收取":"支付"}} {{floatPosition.PositionType==1?"多头":"空头"}}
- + @if (!hideFloatingIncomeDirection) + { + + } @@ -193,7 +197,10 @@ - + @if (!hideFloatingIncomeDirection) + { + + } diff --git a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml index 0b92e12f..bf22e849 100644 --- a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml +++ b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml @@ -80,7 +80,8 @@ tradingPlaceMap = places, clearingAgencyMap = agencys, timeUnits = GlobalData.AllTimeUnits(), - otcFormatConfig = otcFormatConfig + otcFormatConfig = otcFormatConfig, + swapFloatingIncomeReceiveOnlyMode = PS.Config.ErpElement.SwapFloatingIncomeReceiveOnlyMode }; //pageObj.clearingAgencyMap.Remove("甲方"); //pageObj.clearingAgencyMap.Remove("已方"); @@ -444,7 +445,7 @@
收支方向收支方向多空方向 标的代码 期初标的交割全价%浮动端平仓盈亏
{{floatPosition.PayDirection==1?"收取":"支付"}}{{floatPosition.PayDirection==1?"收取":"支付"}} {{floatPosition.PositionType==1?"多头":"空头"}}
- + @@ -456,7 +457,7 @@ -
收支方向收支方向 多空方向 标的代码 期初标的交割全价%交易费用后付
+ diff --git a/YLErpWeb/Views/SwapTrade2/TradeView.cshtml b/YLErpWeb/Views/SwapTrade2/TradeView.cshtml index 5ba38ed5..cde7fed6 100644 --- a/YLErpWeb/Views/SwapTrade2/TradeView.cshtml +++ b/YLErpWeb/Views/SwapTrade2/TradeView.cshtml @@ -30,6 +30,7 @@ var positions = trade.swap_positions.Where(x=>x.PosiDirection>0&&x.IsInitial).ToList(); var realPositions = trade.swap_positions.Where(x => x.PosiDirection > 0 && !x.IsInitial).ToList(); var sr = trade.trade_extend.ExtendObj.SettlementRules; + bool hideFloatingIncomeDirection = PS.Config.ErpElement.SwapFloatingIncomeReceiveOnlyMode; string SwapPriceData(decimal? value) => value?.ToString(CultureInfo.InvariantCulture) ?? string.Empty; } @section CSS{ @@ -365,10 +366,13 @@
-
-
-
-
+ @if (singleTrade || !hideFloatingIncomeDirection) + { +
+
+
+
+ } @if (trade.swap_positions != null) { var paySwapPositions = trade.swap_positions.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode) && x.IsInitial&&x.PosiStartDate==trade.StartDate).ToList(); @@ -378,7 +382,10 @@
- + @if (!hideFloatingIncomeDirection) + { + + } @@ -396,7 +403,10 @@ var bgclass = item.PosiDirection == (int)SwapDirectionEnum.收取 ? "swapget" : "swappay"; var multiplier = ConsGlobal.InstrumentType.IsBond(item.UnderlyingInstrumentType) ? 100 : 1; - + @if (!hideFloatingIncomeDirection) + { + + }
收支方向收支方向多空方向 标的代码 @spotPriceTitle
@((SwapDirectionEnum)item.PosiDirection)@((SwapDirectionEnum)item.PosiDirection)@(item.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头") @item.UnderlyingCode @@ -435,7 +445,7 @@ } - else + else if (!hideFloatingIncomeDirection) {
@@ -577,10 +587,13 @@
-
-
-
-
+ @if (singleTrade || realPositions.Any(x => !string.IsNullOrEmpty(x.UnderlyingCode)) || !hideFloatingIncomeDirection) + { +
+
+
+
+ } @if (trade.swap_positions != null) { var paySwapPositions = trade.swap_positions.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode) && !x.IsInitial).ToList(); @@ -590,7 +603,10 @@
- + @if (!hideFloatingIncomeDirection) + { + + } @@ -609,9 +625,12 @@ var bgclass = item.PosiDirection == 1 ? "swapget" : "swappay"; var multiplier = ConsGlobal.InstrumentType.IsBond(item.UnderlyingInstrumentType) ? 100 : 1; - + @if (!hideFloatingIncomeDirection) + { + + } @@ -639,7 +658,7 @@
收支方向收支方向多空方向 标的代码 @spotPriceTitle
- @((SwapDirectionEnum)item.PosiDirection) - + @((SwapDirectionEnum)item.PosiDirection) + @(item.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头")
} - else + else if (!hideFloatingIncomeDirection) {
@@ -797,7 +816,10 @@
- + @if (!hideFloatingIncomeDirection) + { + + } @if (isBond) @@ -817,7 +839,10 @@ - + @if (!hideFloatingIncomeDirection) + { + + } @if (isBond) @@ -993,7 +1018,10 @@
收支方向收支方向多空方向 标的代码浮动端平仓盈亏
@((SwapDirectionEnum)closeFloat.PayDirection)@((SwapDirectionEnum)closeFloat.PayDirection)@(closeFloat.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头") @closeFloat.UnderlyingCode
- + @if (!hideFloatingIncomeDirection) + { + + } @if (isBond) @@ -1013,7 +1041,10 @@ - + @if (!hideFloatingIncomeDirection) + { + + } @if (isBond) diff --git a/YLErpWeb/fe-tests/eodPositionRisks.test.js b/YLErpWeb/fe-tests/eodPositionRisks.test.js new file mode 100644 index 00000000..908528da --- /dev/null +++ b/YLErpWeb/fe-tests/eodPositionRisks.test.js @@ -0,0 +1,39 @@ +const fs = require('fs'); +const path = require('path'); +const vm = require('vm'); + +function loadEodPositionRiskHelpers() { + const filePath = path.join(__dirname, '../wwwroot/Scripts/app/swaptrade/EodPositionRisks.js'); + const code = fs.readFileSync(filePath, 'utf8') + '\nmodule.exports = { TradeDirectionFormat };'; + const sandbox = { + module: { exports: {} }, + exports: {}, + $() { }, + main: { + numberFormat() { + return function () { }; + } + } + }; + + vm.runInNewContext(code, sandbox, { filename: filePath }); + return sandbox.module.exports; +} + +const { TradeDirectionFormat } = loadEodPositionRiskHelpers(); + +describe('互换日终持仓交易方向', () => { + test.each([ + [1, 1, '多头'], + [1, 2, '空头'], + [2, 1, '空头'], + [2, 2, '多头'] + ])('收支方向=%i,多空方向=%i时展示%s', (posiDirection, positionType, expected) => { + const row = { eodPosition: { PosiDirection: posiDirection, PositionType: positionType } }; + expect(TradeDirectionFormat(positionType, {}, row)).toBe(expected); + }); + + test('无有效浮动端方向时不展示交易方向', () => { + expect(TradeDirectionFormat(1, {}, { eodPosition: { PosiDirection: 0, PositionType: 1 } })).toBe(''); + }); +}); diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js index e6780644..8d799ab1 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js @@ -136,20 +136,14 @@ function colModelGridEodPosition() { align: 'center', sortIndex: i++, sortable: true - }, { - name: 'eodPosition.PosiDirection', - label: '[浮动]收支方向', - index: 'eodPosition.PosiDirection', - width: 90, - align: 'center', - formatter: DrictionFormat }, { name: 'eodPosition.PositionType', - label: '标的多空(B/S)', + label: '交易方向', index: 'eodPosition.PositionType', width: 90, align: 'center', - formatter: PositionTypeFormat + formatter: TradeDirectionFormat, + sortable: false }, { name: 'eodPosition.UnderlyingCode', label: '标的代码', @@ -825,14 +819,21 @@ function NullableStockEqvNotionalFormat(cellValue, options, rowObject) { function PosiStatusFormat(cellValue, options, rowObject) { return cellValue == 1 ? "已平" : "正常"; } -function PositionTypeFormat(cellValue, options, rowObject) { - if (cellValue == 1) { - return "B"; +function TradeDirectionFormat(cellValue, options, rowObject) { + var eodPosition = rowObject && rowObject.eodPosition; + if (!eodPosition) { + return ""; } - if (cellValue == 2) { - return "S"; + + var posiDirection = Number(eodPosition.PosiDirection); + var positionType = Number(eodPosition.PositionType); + if (posiDirection === 2) { + positionType = positionType === 1 ? 2 : positionType === 2 ? 1 : 0; + } else if (posiDirection !== 1) { + return ""; } - return ""; + + return positionType === 1 ? "多头" : positionType === 2 ? "空头" : ""; } function DrictionFormat(cellValue, options, rowObject) { if (cellValue == 1) { diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js index b43786aa..7f0e627c 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js @@ -310,7 +310,10 @@ const vue = new Vue({ changeStructureType() { this.trade.StockEqvNotional = 0; let direction = this.trade.trade_extend.ExtendObj.Direction; - if (direction !== 1 && direction !== 2) { + if (page.swapFloatingIncomeReceiveOnlyMode) { + direction = 1; + this.trade.trade_extend.ExtendObj.Direction = direction; + } else if (direction !== 1 && direction !== 2) { direction = 2; this.trade.trade_extend.ExtendObj.Direction = direction; } @@ -1626,7 +1629,12 @@ const vue = new Vue({ thisObj.syncPosiFeeModeByItem(thisObj.paySwapList[0]); } } - + + if (page.isAdd && page.swapFloatingIncomeReceiveOnlyMode) { + thisObj.trade.trade_extend.ExtendObj.Direction = 1; + thisObj.paySwapList.forEach(x => x.PosiDirection = 1); + } + if (thisObj.paySwapList.length == 0) { thisObj.trade.trade_extend.ExtendObj.Direction = thisObj.trade.trade_extend.ExtendObj.Direction == 0 ? 2 : thisObj.trade.trade_extend.ExtendObj.Direction; var direction = thisObj.trade.trade_extend.ExtendObj.Direction;
收支方向收支方向多空方向 标的代码浮动端平仓盈亏
@((SwapDirectionEnum)closeFloat.PayDirection)@((SwapDirectionEnum)closeFloat.PayDirection)@(closeFloat.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头") @closeFloat.UnderlyingCode